From c64bdc80ccd87aecad244bd070a9b625410ee39d Mon Sep 17 00:00:00 2001
From: Israel Brewster <israel@brewstersoft.com>
Date: Fri, 19 Dec 2014 08:40:21 -0900
Subject: [PATCH 1/3] Update with changes to fix several bugs and reduce
 compiler warnings

---
 lib4d_sql/base64.c        |   45 +-
 lib4d_sql/base64.h        |    8 +-
 lib4d_sql/communication.c |  998 +++++++++++++---------
 lib4d_sql/fourd.c         |  889 ++++++++++---------
 lib4d_sql/fourd.h         |  544 ++++++------
 lib4d_sql/fourd_int.h     |  161 ++--
 lib4d_sql/fourd_interne.c | 1709 ++++++++++++++++++++-----------------
 lib4d_sql/fourd_result.c  |   39 +-
 lib4d_sql/fourd_type.c    |  308 ++++---
 lib4d_sql/fourd_type.h    |  144 ++--
 lib4d_sql/sqlstate.c      |   59 +-
 lib4d_sql/utils.c         |   71 +-
 lib4d_sql/utils.h         |   29 +
 13 files changed, 2889 insertions(+), 2115 deletions(-)

diff --git a/lib4d_sql/base64.c b/lib4d_sql/base64.c
index 1958afc..b6c1730 100644
--- a/lib4d_sql/base64.c
+++ b/lib4d_sql/base64.c
@@ -1,21 +1,22 @@
 /*
-   +----------------------------------------------------------------------+
-   | PHP Version 5                                                        |
-   +----------------------------------------------------------------------+
-   | Copyright (c) 1997-2008 The PHP Group                                |
-   +----------------------------------------------------------------------+
-   | This source file is subject to version 3.01 of the PHP license,      |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.php.net/license/3_01.txt                                  |
-   | If you did not receive a copy of the PHP license and are unable to   |
-   | obtain it through the world-wide-web, please send a note to          |
-   | license@php.net so we can mail you a copy immediately.               |
-   +----------------------------------------------------------------------+
-   | Author: Jim Winstead <jimw@php.net>                                  |
-   +----------------------------------------------------------------------+
+ +----------------------------------------------------------------------+
+ | PHP Version 5                                                        |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2008 The PHP Group                                |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license,      |
+ | that is bundled with this package in the file LICENSE, and is        |
+ | available through the world-wide-web at the following url:           |
+ | http://www.php.net/license/3_01.txt                                  |
+ | If you did not receive a copy of the PHP license and are unable to   |
+ | obtain it through the world-wide-web, please send a note to          |
+ | license@php.net so we can mail you a copy immediately.               |
+ +----------------------------------------------------------------------+
+ | Author: Jim Winstead <jimw@php.net>                                  |
+ +----------------------------------------------------------------------+
  */
-/* $Id: base64.c,v 1.43.2.2.2.4 2007/12/31 07:20:12 sebastian Exp $ */
+
+/* $Id: base64.c 287670 2009-08-25 08:35:39Z fourd $ */
 
 #include <string.h>
 #include <stdlib.h>
@@ -55,13 +56,13 @@ static const short base64_reverse_table[256] = {
 
 /* {{{ php_base64_encode */
 //PHPAPI 
-unsigned char *base64_encode(const unsigned char *str, int length, int *ret_length)
+unsigned char *base64_encode(const char *str, size_t length, int *ret_length)
 {
-	const unsigned char *current = str;
+	const char *current = str;
 	unsigned char *p;
 	unsigned char *result;
 
-	if ((length + 2) < 0 || ((length + 2) / 3) >= (1 << (sizeof(int) * 8 - 2))) {
+	if (((length + 2) / 3) >= (1 << (sizeof(int) * 8 - 2))) {
 		if (ret_length != NULL) {
 			*ret_length = 0;
 		}
@@ -137,7 +138,7 @@ void php_base64_init(void)
 /* }}} */
 
 //PHPAPI 
-unsigned char *base64_decode(const unsigned char *str, int length, int *ret_length)
+unsigned char *base64_decode(const char *str, size_t length, int *ret_length)
 {
 	return base64_decode_ex(str, length, ret_length, 0);
 }
@@ -145,9 +146,9 @@ unsigned char *base64_decode(const unsigned char *str, int length, int *ret_leng
 /* {{{ php_base64_decode */
 /* as above, but backwards. :) */
 //PHPAPI 
-unsigned char *base64_decode_ex(const unsigned char *str, int length, int *ret_length, int strict)
+unsigned char *base64_decode_ex(const char *str, size_t length, int *ret_length, int strict)
 {
-	const unsigned char *current = str;
+	const char *current = str;
 	int ch, i = 0, j = 0, k;
 	/* this sucks for threaded environments */
 	unsigned char *result;
diff --git a/lib4d_sql/base64.h b/lib4d_sql/base64.h
index c068f87..d405c6d 100644
--- a/lib4d_sql/base64.h
+++ b/lib4d_sql/base64.h
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: base64.h,v 1.14.2.1.2.3 2007/12/31 07:20:12 sebastian Exp $ */
+/* $Id: base64.h 279540 2009-04-29 08:57:22Z splanquart $ */
 
 #ifndef BASE64_H
 #define BASE64_H
@@ -25,11 +25,11 @@
 //PHP_FUNCTION(base64_encode);
 
 //PHPAPI extern 
-unsigned char *base64_encode(const unsigned char *, int, int *);
+unsigned char *base64_encode(const char *, size_t, int *);
 //PHPAPI extern 
-unsigned char *base64_decode_ex(const unsigned char *, int, int *, int);
+unsigned char *base64_decode_ex(const char *, size_t, int *, int);
 //PHPAPI extern 
-unsigned char *base64_decode(const unsigned char *, int, int *);
+unsigned char *base64_decode(const char *, size_t, int *);
 
 #endif /* BASE64_H */
 
diff --git a/lib4d_sql/communication.c b/lib4d_sql/communication.c
index ebbb71a..a3cbf9b 100644
--- a/lib4d_sql/communication.c
+++ b/lib4d_sql/communication.c
@@ -1,383 +1,615 @@
-#include "fourd.h"
-#include "fourd_int.h"
-#include "base64.h"
-#include <string.h>
-
-
-
-
-int socket_connect(FOURD *cnx,const char *host,unsigned int port)
-{
-	//WSADATA wsaData;
-	
-	struct addrinfo *result = NULL,
-					*ptr = NULL,
-					hints;
-	int iResult=0;
-	//SOCKET ConnectSocket = INVALID_SOCKET;
-
-	char sport[50];
-	sprintf_s(sport,50,"%d",port);
-
-	/*
-	// Initialize Winsock
-    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
-    if (iResult != 0) {
-        Printf("WSAStartup failed: %d\n", iResult);
-        return 1;
-    }
-	*/
-
-	//initialize Hints
-	ZeroMemory( &hints, sizeof(hints) );
-	hints.ai_family = AF_INET;
-	hints.ai_socktype = SOCK_STREAM;
-	hints.ai_protocol = IPPROTO_TCP;
-
-	// Resolve the server address and port
-	iResult = getaddrinfo(host, sport, &hints, &result);
-	if ( iResult != 0 ) {
-		Printf("getaddrinfo failed: %d : %s\n", iResult,gai_strerror(iResult));
-		cnx->error_code=-iResult;
-		strncpy_s(cnx->error_string,2048,gai_strerror(iResult),2048);
-		return 1;
-	}
-	//Printf("getaddrinfo ok\n");
-
-		
-	// Attempt to connect to the first address returned by
-	// the call to getaddrinfo
-	ptr=result;
-
-	// Create a SOCKET for connecting to server
-	cnx->socket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
-	if (cnx->socket == INVALID_SOCKET) {
-		Printf("Error at socket(): %ld\n", WSAGetLastError());
-		cnx->error_code=-WSAGetLastError();
-		strncpy_s(cnx->error_string,2048,"Unable to create socket",2048);
-		freeaddrinfo(result);
-		return 1;
-	}
-	//Printf("Socket Ok\n");
-	// Connect to server.
-	iResult = connect( cnx->socket, ptr->ai_addr, (int)ptr->ai_addrlen);
-	if (iResult == SOCKET_ERROR) {
-		Printf("Error at socket(): %ld\n", WSAGetLastError());
-		cnx->error_code=-WSAGetLastError();
-		strncpy_s(cnx->error_string,2048,"Unable to connect to server",2048);
-		freeaddrinfo(result);
-		closesocket(cnx->socket);
-		cnx->socket = INVALID_SOCKET;
-		return 1;
-	}
-	//Printf("Connexion ok\n");
-
-
-
-	
-	// Should really try the next address returned by getaddrinfo
-	// if the connect call failed
-	// But for this simple example we just free the resources
-	// returned by getaddrinfo and print an error message
-
-	freeaddrinfo(result);
-
-	if (cnx->socket == INVALID_SOCKET) {
-		Printf("Unable to connect to server!\n");
-		cnx->error_code=-1;
-		strncpy_s(cnx->error_string,2048,"Unable to connect to server",2048);
-		return 1;
-	}
-	//Printf("fin de la fonction\n");
-
-	return 0;
-}
-
-void socket_disconnect(FOURD *cnx)
-{
-	int iResult=0;
-	// shutdown the send half of the connection since no more data will be sent
-	#ifdef WIN32
-	iResult = shutdown(cnx->socket, SD_SEND);
-	if (iResult == SOCKET_ERROR) {
-		Printf("shutdown failed: %d\n", WSAGetLastError());
-		closesocket(cnx->socket);
-		cnx->connected=0;
-		return ;
-	}
-	#endif
-	closesocket(cnx->socket);
-	cnx->connected=0;
-	//Printf("Disconnect ok\n");
-}
-int socket_send(FOURD *cnx,const char*msg)
-{
-	int iResult;
-	//Printf("Send-len:%d\n",strlen(msg))
-	Printf("Send:\n%s",msg);
-	// Send an initial buffer
-	iResult = send( cnx->socket, msg, (int)strlen(msg), 0 );
-	if (iResult == SOCKET_ERROR) {
-		Printf("send failed: %d\n", WSAGetLastError());
-		socket_disconnect(cnx);
-		return 1;
-	}
-	return 0;
-}
-int socket_send_data(FOURD *cnx,const char*msg,int len)
-{
-	int iResult;
-	Printf("Send:%d bytes\n",len);
-	PrintData(msg,len);
-	Printf("\n");
-	// Send an initial buffer
-	iResult = send( cnx->socket, msg, len, 0 );
-	if (iResult == SOCKET_ERROR) {
-		Printf("send failed: %d\n", WSAGetLastError());
-		socket_disconnect(cnx);
-		return 1;
-	}
-	return 0;
-}
-
-int socket_receiv_header(FOURD *cnx,FOURD_RESULT *state)
-{
-	int iResult=0;
-	int offset=0;
-	int len=0;
-	int crlf=0;
-	char *fin_header=NULL;
-	//read the HEADER only
-	do 
-	{
-		offset+=iResult;
-		iResult = recv(cnx->socket,state->header+offset,1, 0);
-		len+=iResult;
-		if(len>3)
-		{
-			if(state->header[offset-3]=='\r'
-			 &&state->header[offset-2]=='\n'
-			 &&state->header[offset-1]=='\r'
-			 &&state->header[offset  ]=='\n')
-			 crlf=1;
-		}
-
-	}while(iResult>0 && !crlf);
-	if(!crlf)
-	{
-		Printf("Error: Header-end not found\n");
-		return 1;
-	}
-	state->header[len]=0;
-	state->header_size=len;
-	Printf("Receiv:\n%s",state->header);
-	//there we must add reading data
-	//before analyse header 
-	//see COLUMN-TYPES section
-	return 0;
-}
-int socket_receiv_data(FOURD *cnx,FOURD_RESULT *state)
-{
-	int iResult=0;
-	int offset=0;
-	int len=0;
-	int end_row=0;
-	unsigned int nbCol=state->row_type.nbColumn;
-	unsigned int nbRow=state->row_count_sent;
-	unsigned int r,c;
-	FOURD_TYPE *colType;
-	FOURD_ELEMENT *pElmt=NULL;
-	char status_code=0;
-	int elmt_size=0;
-	int elmts_offset=0;
-	Printf("---Debut de socket_receiv_data\n");
-	colType=calloc(nbCol,sizeof(FOURD_TYPE));
-	//bufferize Column type
-	for(c=0;c<state->row_type.nbColumn;c++)
-		colType[c]=state->row_type.Column[c].type;
-
-	/* allocate nbElmt in state->elmt */
-	state->elmt=calloc(nbCol*nbRow,sizeof(FOURD_ELEMENT));
-	
-	Printf("Debut de socket_receiv_data\n");
-	Printf("state->row_count:%d\t\tstate->row_count_sent:%d\n",state->row_count,state->row_count_sent);
-	Printf("NbRow to read: %d\n",nbRow);
-	/* read all row */
-	for(r=0;r<nbRow;r++)
-	{
-		/* read status_code and row_id */
-		if(state->updateability)  /* rowId is send only if row updateablisity */
-		{
-			int row_id=0;
-			iResult = recv(cnx->socket,&status_code,sizeof(status_code), 0);
-			//Printf("status_code for row:0x%X\n",status_code);
-			len+=iResult;
-			switch(status_code)
-			{
-			case '0':
-				break;
-			case '1':
-				/* pElmt->elmt=calloc(vk_sizeof(colType[0]),1); */
-				iResult = recv(cnx->socket,(char*)&row_id,sizeof(row_id), 0);
-				/* Printf("row_id:%d\n",row_id); */
-				len+=iResult;
-				break;
-			case '2':
-				Printferr("Error during reading data\n");
-				iResult = recv(cnx->socket,(char*)&(state->error_code),sizeof(state->error_code), 0);
-				len+=iResult;
-				return 1;	/* return on error */
-				break;
-			default:
-				Printferr("Status code 0x%X not supported in data\n",status_code);
-				break;
-			}
-		}
-		else {
-			Printf("Not read rowid\n");
-		}
-		/* read all columns */
-		for(c=0;c<nbCol;c++,elmts_offset++)
-		{
-			pElmt=&(state->elmt[elmts_offset]);
-			pElmt->type=colType[c];
-
-			//read column status code
-			iResult = recv(cnx->socket,&status_code,1, 0);
-			len+=iResult;
-			switch(status_code)
-			{
-			case '2'://error
-				Printferr("Error during reading data\n");
-				iResult = recv(cnx->socket,(char*)&(state->error_code),sizeof(state->error_code), 0);
-				len+=iResult;
-				return 1;//on sort en erreur
-				break;
-			case '0'://null value
-				Printf("Read null value\n");
-				pElmt->null=1;
-				break;
-			case '1'://value
-				pElmt->null=0;
-				switch(colType[c])
-				{
-				case VK_BOOLEAN:
-				case VK_BYTE:
-				case VK_WORD:
-				case VK_LONG:
-				case VK_LONG8:
-				case VK_REAL:
-				case VK_DURATION:
-					pElmt->pValue=calloc(vk_sizeof(colType[c]),1);
-					iResult = recv(cnx->socket,(pElmt->pValue),vk_sizeof(colType[c]), 0);
-					len+=iResult;
-					//Printf("Long: %d\n",*((int*)pElmt->pValue));
-					break;
-				case VK_TIMESTAMP:
-					{
-						FOURD_TIMESTAMP *tmp;
-						tmp=calloc(sizeof(FOURD_TIMESTAMP),1);
-						pElmt->pValue=tmp;
-						iResult = recv(cnx->socket,(char*)&(tmp->year),sizeof(short), 0);
-						len+=iResult;
-						iResult = recv(cnx->socket,&(tmp->mounth),sizeof(char), 0);
-						len+=iResult;
-						iResult = recv(cnx->socket,&(tmp->day),sizeof(char), 0);
-						len+=iResult;
-						iResult = recv(cnx->socket,(char*)&(tmp->milli),sizeof(unsigned int), 0);
-						len+=iResult;
-					}
-					break;
-				case VK_FLOAT:
-					{
-						//int exp;char sign;int data_length;void* data;
-						FOURD_FLOAT *tmp;
-						tmp=calloc(sizeof(FOURD_FLOAT),1);
-						pElmt->pValue=tmp;
-
-						iResult = recv(cnx->socket,(char*)&(tmp->exp),sizeof(int), 0);
-						len+=iResult;
-						iResult = recv(cnx->socket,&(tmp->sign),sizeof(char), 0);
-						len+=iResult;
-						iResult = recv(cnx->socket,(char*)&(tmp->data_length),sizeof(int), 0);
-						len+=iResult;
-						iResult = recv(cnx->socket,(tmp->data),tmp->data_length, 0);
-						len+=iResult;
-
-						//Printferr("Float not supported\n");
-					}
-					break;
-				case VK_STRING:
-					{
-						int data_length=0;
-						FOURD_STRING *str;
-						//read negative value of length of string
-						str=calloc(1,sizeof(FOURD_STRING));
-						pElmt->pValue=str;					
-						iResult = recv(cnx->socket,(char*)&data_length,4, 0);
-						len+=iResult;
-						data_length=-data_length;
-						//Printf("Size of String: %d\n",data_length);
-						str->length=data_length;
-						str->data=calloc(1,data_length*2+2);
-						iResult = recv(cnx->socket,(str->data),(data_length*2), 0);
-						str->data[data_length*2]=0;
-						str->data[data_length*2+1]=0;
-						len+=iResult;
-						/*
-						{
-							int length=0;
-							char *chaine=NULL;
-							chaine=base64_encode((unsigned char*)str->data,data_length*2,&length);
-							Printf("Chaine: %s\n",chaine);
-							free(chaine);
-						}*/
-					}
-					break;
-				case VK_IMAGE:
-					//Printferr("Image-Type not supported\n");
-					//break;
-				case VK_BLOB:
-					{
-						int data_length=0;
-						FOURD_BLOB *blob;
-						//read negative value of length of string
-						blob=calloc(1,sizeof(FOURD_BLOB));
-						pElmt->pValue=blob;
-						iResult = recv(cnx->socket,(char*)&data_length,4, 0);
-						len+=iResult;
-						blob->length=data_length;
-						blob->data=calloc(1,data_length);
-						iResult = recv(cnx->socket,blob->data,data_length, 0);
-						len+=iResult;
-						//Printf("Blob: %d Bytes\n",data_length);
-					}
-					Printferr("Blob not supported\n");
-					break;
-				default:
-					Printferr("Type not supported (%s)\n",stringFromType(colType[c]));
-					break;
-				}
-				break;
-			default:
-				Printferr("Status code 0x%X not supported in data\n",status_code);
-				break;
-			}
-		}
-	}
-	Printf("---Fin de socket_receiv_data\n");
-	return 0;
-}
-int socket_receiv_update_count(FOURD *cnx,FOURD_RESULT *state)
-{
-	FOURD_LONG8 data=0;
-	int iResult=0;
-	int len=0;
-	iResult = recv(cnx->socket,(char*)&data,8, 0);
-	len+=iResult;
-	Printf("Ox%X\n",data);
-	cnx->updated_row=data;
-	Printf("\n");
-
-	return 0;
-}
\ No newline at end of file
+/*
+  +----------------------------------------------------------------------+
+  | lib4D_SQL                                                            |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2009 The PHP Group                                     |
+  +----------------------------------------------------------------------+
+  |                                                                      |
+  | This source file is subject to version 3.01 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available through the world-wide-web at the following url:           |
+  | http://www.php.net/license/3_01.txt                                  |
+  |                                                                      |
+  | Its original copy is usable under several licenses and is available  |
+  | through the world-wide-web at the following url:                     |
+  | http://freshmeat.net/projects/lib4d_sql                              |
+  |                                                                      |
+  | Unless required by applicable law or agreed to in writing, software  |
+  | distributed under the License is distributed on an "AS IS" BASIS,    |
+  | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or      |
+  | implied. See the License for the specific language governing         |
+  | permissions and limitations under the License.                       |
+  +----------------------------------------------------------------------+
+  | Contributed by: 4D <php@4d.fr>, http://www.4d.com                    |
+  |                 Alter Way, http://www.alterway.fr                    |
+  | Authors: Stephane Planquart <stephane.planquart@o4db.com>            |
+  |          Alexandre Morgaut <php@4d.fr>                               |
+  +----------------------------------------------------------------------+
+*/
+
+#include "fourd.h"
+#include "fourd_int.h"
+#include "base64.h"
+#include <string.h>
+#include <time.h>
+#ifdef WIN32
+#define EINPROGRESS WSAEWOULDBLOCK
+#else
+#include <fcntl.h>
+#endif
+
+long frecv(SOCKET s,unsigned char *buf,int len,int flags)
+{
+	int rec=0;
+	long iResult=0;
+	do{
+		iResult=recv(s,buf+rec,len-rec, 0);
+		if(iResult<0){
+			return iResult;
+		}else {
+			rec+=iResult;
+		}
+	}while(rec<len);
+	return rec;
+}
+
+int socket_connect(FOURD *cnx,const char *host,unsigned int port)
+{
+	//WSADATA wsaData;
+	
+	struct addrinfo *result = NULL,
+					*ptr = NULL,
+					hints;
+	int iResult=0;
+	//SOCKET ConnectSocket = INVALID_SOCKET;
+
+	char sport[50];
+	sprintf_s(sport,50,"%d",port);
+
+	/*
+	// Initialize Winsock
+    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
+    if (iResult != 0) {
+        Printf("WSAStartup failed: %d\n", iResult);
+        return 1;
+    }
+	*/
+
+	//initialize Hints
+	ZeroMemory( &hints, sizeof(hints) );
+	hints.ai_family = AF_INET;
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_protocol = IPPROTO_TCP;
+
+	// Resolve the server address and port
+	iResult = getaddrinfo(host, sport, &hints, &result);
+	if ( iResult != 0 ) {
+		Printf("getaddrinfo failed: %d : %s\n", iResult,gai_strerror(iResult));
+		cnx->error_code=-iResult;
+		strncpy_s(cnx->error_string,2048,gai_strerror(iResult),2048);
+		return 1;
+	}
+	//Printf("getaddrinfo ok\n");
+
+		
+	// Attempt to connect to the first address returned by
+	// the call to getaddrinfo
+	ptr=result;
+
+	// Create a SOCKET for connecting to server
+	cnx->socket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
+	if (cnx->socket == INVALID_SOCKET) {
+		Printf("Error at socket(): %ld\n", WSAGetLastError());
+		cnx->error_code=-WSAGetLastError();
+		strncpy_s(cnx->error_string,2048,"Unable to create socket",2048);
+		freeaddrinfo(result);
+		return 1;
+	}
+	//Printf("Socket Ok\n");
+	// Connect to server.
+	iResult = connect( cnx->socket, ptr->ai_addr, (int)ptr->ai_addrlen);
+	if (iResult == SOCKET_ERROR) {
+		Printf("Error at socket(): %ld\n", WSAGetLastError());
+		cnx->error_code=-WSAGetLastError();
+		strncpy_s(cnx->error_string,2048,"Unable to connect to server",2048);
+		freeaddrinfo(result);
+		closesocket(cnx->socket);
+		cnx->socket = INVALID_SOCKET;
+		return 1;
+	}
+	//Printf("Connexion ok\n");
+
+
+
+	
+	// Should really try the next address returned by getaddrinfo
+	// if the connect call failed
+	// But for this simple example we just free the resources
+	// returned by getaddrinfo and print an error message
+
+	freeaddrinfo(result);
+
+	if (cnx->socket == INVALID_SOCKET) {
+		Printf("Unable to connect to server!\n");
+		cnx->error_code=-1;
+		strncpy_s(cnx->error_string,2048,"Unable to connect to server",2048);
+		return 1;
+	}
+	//Printf("fin de la fonction\n");
+
+	return 0;
+}
+
+void socket_disconnect(FOURD *cnx)
+{
+	// shutdown the send half of the connection since no more data will be sent
+	#ifdef WIN32
+	iResult = shutdown(cnx->socket, SD_SEND);
+	if (iResult == SOCKET_ERROR) {
+		Printf("shutdown failed: %d\n", WSAGetLastError());
+		closesocket(cnx->socket);
+		cnx->connected=0;
+		return ;
+	}
+	#endif
+	closesocket(cnx->socket);
+	cnx->connected=0;
+	//Printf("Disconnect ok\n");
+}
+
+int socket_send(FOURD *cnx,const char*msg)
+{
+	long iResult;
+	//Printf("Send-len:%d\n",strlen(msg))
+	Printf("Send:\n%s",msg);
+	// Send an initial buffer
+	iResult = send( cnx->socket, msg, (int)strlen(msg), 0 );
+	if (iResult == SOCKET_ERROR) {
+		Printf("send failed: %d\n", WSAGetLastError());
+		socket_disconnect(cnx);
+		return 1;
+	}
+	return 0;
+}
+int socket_send_data(FOURD *cnx,const char*msg,int len)
+{
+	long iResult;
+	Printf("Send:%d bytes\n",len);
+	PrintData(msg,len);
+	Printf("\n");
+	// Send an initial buffer
+	iResult = send( cnx->socket, msg, len, 0 );
+	if (iResult == SOCKET_ERROR) {
+		Printf("send failed: %d\n", WSAGetLastError());
+		socket_disconnect(cnx);
+		return 1;
+	}
+	return 0;
+}
+
+int socket_receiv_header(FOURD *cnx,FOURD_RESULT *state)
+{
+	long iResult=0;
+	int offset=0;
+	int len=0;
+	int crlf=0;
+	//read the HEADER only
+	do 
+	{
+		offset+=iResult;
+		iResult = recv(cnx->socket,state->header+offset,1, 0);
+		len+=iResult;
+		if(len>3)
+		{
+			if(state->header[offset-3]=='\r'
+			 &&state->header[offset-2]=='\n'
+			 &&state->header[offset-1]=='\r'
+			 &&state->header[offset  ]=='\n')
+			 crlf=1;
+		}
+
+	}while(iResult>0 && !crlf);
+	if(!crlf)
+	{
+		Printf("Error: Header-end not found\n");
+		return 1;
+	}
+	state->header[len]=0;
+	state->header_size=len;
+	Printf("Receiv:\n%s",state->header);
+	//there we must add reading data
+	//before analyse header 
+	//see COLUMN-TYPES section
+	return 0;
+}
+int socket_receiv_data(FOURD *cnx,FOURD_RESULT *state)
+{
+	long iResult=0;
+	int len=0;
+	//int end_row=0;
+	unsigned int nbCol=state->row_type.nbColumn;
+	unsigned int nbRow=state->row_count_sent;
+	unsigned int r,c;
+	FOURD_TYPE *colType;
+	FOURD_ELEMENT *pElmt=NULL;
+	unsigned char status_code=0;
+	//int elmt_size=0;
+	int elmts_offset=0;
+	Printf("---Debut de socket_receiv_data\n");
+	colType=calloc(nbCol,sizeof(FOURD_TYPE));
+	//bufferize Column type
+	for(c=0;c<state->row_type.nbColumn;c++)
+		colType[c]=state->row_type.Column[c].type;
+	Printf("nbCol*nbRow:%d\n",nbCol*nbRow);
+	/* allocate nbElmt in state->elmt */
+	state->elmt=calloc(nbCol*nbRow,sizeof(FOURD_ELEMENT));
+	
+	Printf("Debut de socket_receiv_data\n");
+	Printf("state->row_count:%d\t\tstate->row_count_sent:%d\n",state->row_count,state->row_count_sent);
+	Printf("NbRow to read: %d\n",nbRow);
+	/* read all row */
+	for(r=0;r<nbRow;r++)
+	{
+		/* read status_code and row_id */
+		if(state->updateability)  /* rowId is send only if row updateablisity */
+		{
+			int row_id=0;
+			status_code=0;
+			iResult = frecv(cnx->socket,&status_code,sizeof(status_code), 0);
+			//Printf("status_code for row:0x%X\n",status_code);
+			len+=iResult;
+			switch(status_code)
+			{
+			case '0':
+				break;
+			case '1':
+				/* pElmt->elmt=calloc(vk_sizeof(colType[0]),1); */
+				iResult = frecv(cnx->socket,(unsigned char*)&row_id,sizeof(row_id), 0);
+				/* Printf("row_id:%d\n",row_id); */
+				len+=iResult;
+				break;
+			case '2':
+				Printferr("Error during reading data\n");
+				iResult = frecv(cnx->socket,(unsigned char*)&(state->error_code),sizeof(state->error_code), 0);
+				len+=iResult;
+				return 1;	/* return on error */
+				break;
+			default:
+				Printferr("Status code 0x%X not supported in data at row %d column %d\n",status_code,(elmts_offset-c+1)/nbCol+1,c+1);
+				break;
+			}
+		}
+		else {
+			Printf("Not read rowid\n");
+		}
+		/* read all columns */
+		for(c=0;c<nbCol;c++,elmts_offset++)
+		{
+			pElmt=&(state->elmt[elmts_offset]);
+			pElmt->type=colType[c];
+
+			//read column status code
+			status_code=0;
+			iResult = frecv(cnx->socket,&status_code,1, 0);
+			Printf("status: %2X\n",status_code);
+			len+=iResult;
+			switch(status_code)
+			{
+			case '2'://error
+				Printferr("Error during reading data\n");
+				iResult = frecv(cnx->socket,(unsigned char*)&(state->error_code),sizeof(state->error_code), 0);
+				len+=iResult;
+				return 1;//on sort en erreur
+				break;
+			case '0'://null value
+				Printf("Read null value\n");
+				pElmt->null=1;
+				break;
+			case '1'://value
+				pElmt->null=0;
+				switch(colType[c])
+				{
+				case VK_BOOLEAN:
+				case VK_BYTE:
+				case VK_WORD:
+				case VK_LONG:
+				case VK_LONG8:
+				case VK_REAL:
+				case VK_DURATION:
+					pElmt->pValue=calloc(1,vk_sizeof(colType[c]));
+					iResult = frecv(cnx->socket,(pElmt->pValue),vk_sizeof(colType[c]), 0);
+					len+=iResult;
+					//Printf("Long: %d\n",*((int*)pElmt->pValue));
+					break;
+				case VK_TIMESTAMP:
+					{
+						FOURD_TIMESTAMP *tmp;
+						tmp=calloc(1,sizeof(FOURD_TIMESTAMP));
+						pElmt->pValue=tmp;
+						iResult = frecv(cnx->socket,(unsigned char*)&(tmp->year),sizeof(short), 0);
+						Printf("year: %04X",tmp->year);
+						len+=iResult;
+						iResult = frecv(cnx->socket,&(tmp->mounth),sizeof(char), 0);
+						Printf("    mounth: %02X",tmp->mounth);
+						len+=iResult;
+						iResult = frecv(cnx->socket,&(tmp->day),sizeof(char), 0);
+						Printf("    day: %02X",tmp->day);
+						len+=iResult;
+						iResult = frecv(cnx->socket,(unsigned char*)&(tmp->milli),sizeof(unsigned int), 0);
+						Printf("    milli: %08X\n",tmp->milli);
+						len+=iResult;
+					}
+					break;
+				case VK_FLOAT:
+					{
+						//int exp;char sign;int data_length;void* data;
+						FOURD_FLOAT *tmp;
+						tmp=calloc(1,sizeof(FOURD_FLOAT));
+						pElmt->pValue=tmp;
+
+						iResult = frecv(cnx->socket,(unsigned char*)&(tmp->exp),sizeof(int), 0);
+						len+=iResult;
+						iResult = frecv(cnx->socket,&(tmp->sign),sizeof(char), 0);
+						len+=iResult;
+						iResult = frecv(cnx->socket,(unsigned char*)&(tmp->data_length),sizeof(int), 0);
+						len+=iResult;
+						iResult = frecv(cnx->socket,(tmp->data),tmp->data_length, 0);
+						len+=iResult;
+
+						Printferr("Float not supported\n");
+					}
+					break;
+				case VK_STRING:
+					{
+						int data_length=0;
+						FOURD_STRING *str;
+						//read negative value of length of string
+						str=calloc(1,sizeof(FOURD_STRING));
+						pElmt->pValue=str;					
+						iResult = frecv(cnx->socket,(unsigned char*)&data_length,4, 0);
+						len+=iResult;
+						Printf("String length: %08X\n",data_length);
+						data_length=-data_length;
+						str->length=data_length;
+						str->data=calloc(data_length*2+2,1);
+						if(data_length==0){	//correct read for empty string  
+							str->data[0]=0;
+							str->data[1]=0;
+						}
+						else {
+							iResult = frecv(cnx->socket,(str->data),(data_length*2), 0);
+							str->data[data_length*2]=0;
+							str->data[data_length*2+1]=0;
+							len+=iResult;
+						}
+						/*
+						{
+							int length=0;
+							char *chaine=NULL;
+							chaine=base64_encode((unsigned char*)str->data,data_length*2,&length);
+							Printf("Chaine: %s\n",chaine);
+							free(chaine);
+						}*/
+					}
+					break;
+				case VK_IMAGE:
+					//Printferr("Image-Type not supported\n");
+					//break;
+				case VK_BLOB:
+					{
+						int data_length=0;
+						FOURD_BLOB *blob;
+						//read negative value of length of string
+						blob=calloc(1,sizeof(FOURD_BLOB));
+						pElmt->pValue=blob;
+						iResult = frecv(cnx->socket,(unsigned char*)&data_length,4, 0);
+						Printf("Blob length: %08X\n",data_length);
+						len+=iResult;
+						if(data_length==0){
+							blob->length=0;
+							blob->data=NULL;
+							pElmt->null=1;
+						}else{
+							blob->length=data_length;
+							blob->data=calloc(data_length,1);
+							iResult = frecv(cnx->socket,blob->data,data_length, 0);
+							len+=iResult;
+						}
+						//Printf("Blob: %d Bytes\n",data_length);
+					}
+					//Printferr("Blob not supported\n");
+					break;
+				default:
+					Printferr("Type not supported (%s) at row %d column %d\n",stringFromType(colType[c]),(elmts_offset-c+1)/nbCol+1,c+1);
+					break;
+				}
+				break;
+			default:
+				Printferr("Status code 0x%X not supported in data at row %d column %d\n",status_code,(elmts_offset-c+1)/nbCol+1,c+1);
+				break;
+			}
+		}
+	}
+	Printf("---Fin de socket_receiv_data\n");
+	return 0;
+}
+int socket_receiv_update_count(FOURD *cnx,FOURD_RESULT *state)
+{
+	FOURD_LONG8 data=0;
+	long iResult=0;
+	int len=0;
+	iResult = frecv(cnx->socket,(unsigned char*)&data,8, 0);
+	len+=iResult;
+	Printf("Ox%X\n",data);
+	cnx->updated_row=data;
+	Printf("\n");
+
+	return 0;
+}
+int set_sock_blocking(int socketd, int block)
+{
+	int ret = 0;
+	int flags;
+	int myflag = 0;
+
+#ifdef WIN32
+	/* with ioctlsocket, a non-zero sets nonblocking, a zero sets blocking */
+	flags = !block;
+	if (ioctlsocket(socketd, FIONBIO, &flags) == SOCKET_ERROR) {
+		/*char *error_string;
+		
+		error_string = php_socket_strerror(WSAGetLastError(), NULL, 0);
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", error_string);
+		efree(error_string);*/
+		ret = 1;
+	}
+#else
+	flags = fcntl(socketd, F_GETFL);
+#ifdef O_NONBLOCK
+	myflag = O_NONBLOCK; /* POSIX version */
+#elif defined(O_NDELAY)
+	myflag = O_NDELAY;   /* old non-POSIX version */
+#endif
+	if (!block) {
+		flags |= myflag;
+	} else {
+		flags &= ~myflag;
+	}
+	fcntl(socketd, F_SETFL, flags);
+#endif
+	return ret;
+}
+
+int socket_connect_timeout(FOURD *cnx,const char *host,unsigned int port,int timeout)
+{
+	//WSADATA wsaData;
+	
+	struct addrinfo *result = NULL,
+					*ptr = NULL,
+					hints;
+	int iResult=0,valopt=0;
+	/*SOCKET ConnectSocket = INVALID_SOCKET; */
+	struct timeval tv; 
+	fd_set myset; 
+	socklen_t lon;
+	
+	//int nbTryConnect=0;
+	char sport[50];
+	sprintf_s(sport,50,"%d",port);
+
+	/*
+	Initialize Winsock
+    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
+    if (iResult != 0) {
+        Printf("WSAStartup failed: %d\n", iResult);
+        return 1;
+    }
+	*/
+
+	/* initialize Hints */
+	ZeroMemory( &hints, sizeof(hints) );
+	hints.ai_family = AF_INET;
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_protocol = IPPROTO_TCP;
+
+	/* Resolve the server address and port */
+	iResult = getaddrinfo(host, sport, &hints, &result);
+	if ( iResult != 0 ) {
+		Printf("getaddrinfo failed: %d : %s\n", iResult,gai_strerror(iResult));
+		cnx->error_code=-iResult;
+		strncpy_s(cnx->error_string,2048,gai_strerror(iResult),2048);
+		return 1;
+	}
+	/* Printf("getaddrinfo ok\n"); */
+
+		
+	/*Attempt to connect to the first address returned by
+	 the call to getaddrinfo */
+	ptr=result;
+
+	/* Create a SOCKET for connecting to server */
+	cnx->socket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
+	if (cnx->socket == INVALID_SOCKET) {
+		Printf("Error at socket(): %ld\n", WSAGetLastError());
+		cnx->error_code=-WSAGetLastError();
+		strncpy_s(cnx->error_string,2048,"Unable to create socket",2048);
+		freeaddrinfo(result);
+		return 1;
+	}
+	int flag=1;
+	// if we get an error here, we can safely ignore it. The connection may be slower, but it should
+	// still work.
+	setsockopt(cnx->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
+	
+	/* Printf("Socket Ok\n"); */
+	/*set Non blocking socket */
+	set_sock_blocking(cnx->socket,0);
+	/* Connect to server. */
+	iResult = connect( cnx->socket, ptr->ai_addr, (int)ptr->ai_addrlen);
+	if(iResult<0){
+		if (WSAGetLastError() == EINPROGRESS) { 
+        tv.tv_sec = timeout; 
+        tv.tv_usec = 0; 
+        FD_ZERO(&myset); 
+        FD_SET(cnx->socket, &myset); 
+        if (select(cnx->socket+1, NULL, &myset, NULL, &tv) > 0) { 
+					lon = sizeof(int); 
+					getsockopt(cnx->socket, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon); 
+					if (valopt) { 
+						fprintf(stderr, "Error in connection() %d - %s\n", valopt, strerror(valopt));
+						cnx->error_code=valopt;
+						strncpy_s(cnx->error_string,2048,strerror(valopt),2048);
+						freeaddrinfo(result);
+						closesocket(cnx->socket);
+						cnx->socket = INVALID_SOCKET;
+						return 1;
+					} 
+					/*connection ok*/
+        } 
+        else { 
+			/*fprintf(stderr, "Timeout or error() %d - %s\n", valopt, strerror(valopt)); */
+			cnx->error_code=3011;
+			strncpy_s(cnx->error_string,2048,"Connect timed out",2048);
+			freeaddrinfo(result);
+			closesocket(cnx->socket);
+			cnx->socket = INVALID_SOCKET;
+			return 1;
+        } 
+     } 
+     else { 
+        /*fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno)); */
+        cnx->error_code=-WSAGetLastError();
+			strncpy_s(cnx->error_string,2048,"Error connecting",2048);
+			freeaddrinfo(result);
+			closesocket(cnx->socket);
+			cnx->socket = INVALID_SOCKET;
+        return 1;
+     } 
+
+		
+	}
+		
+	/* Printf("Connexion ok\n"); */
+
+
+	/*set blocking socket */
+	set_sock_blocking(cnx->socket,1);
+
+	
+	/* Should really try the next address returned by getaddrinfo
+	   if the connect call failed
+	   But for this simple example we just free the resources
+	   returned by getaddrinfo and print an error message */
+
+	freeaddrinfo(result);
+
+	if (cnx->socket == INVALID_SOCKET) {
+		Printf("Unable to connect to server!\n");
+		cnx->error_code=-1;
+		strncpy_s(cnx->error_string,2048,"Unable to connect to server",2048);
+		return 1;
+	}
+	/* Printf("fin de la fonction\n"); */
+
+	return 0;
+}
diff --git a/lib4d_sql/fourd.c b/lib4d_sql/fourd.c
index da31eb6..191fc3d 100644
--- a/lib4d_sql/fourd.c
+++ b/lib4d_sql/fourd.c
@@ -1,386 +1,505 @@
-#include "fourd.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "fourd.h"
-#include "fourd_int.h"
-
-FOURD* fourd_init()
-{
-	int iResult=0;
-	FOURD* cnx=calloc(1,sizeof(FOURD));
-
-	cnx->socket = INVALID_SOCKET;
-	cnx->connected=0;
-	cnx->init=0;
-	#ifdef WIN32
-	// Initialize Winsock
-    iResult = WSAStartup(MAKEWORD(2,2), &cnx->wsaData);
-    if (iResult != 0) {
-        Printf("WSAStartup failed: %d\n", iResult);
-        return NULL;
-    }
-  #endif
-	cnx->init=1;
-	return cnx;
-}
-
-int fourd_connect(FOURD *cnx,const char *host,const char *user,const char *password,const char *base,unsigned int port)
-{
-	if(!cnx->init)
-	{
-		//not init
-		Printferr("Erreur: FOURD object did not initialised\n");
-		cnx->error_code=-1;
-		strncpy_s(cnx->error_string,2048,"FOURD object did not initialised",2048);
-		return 1;
-	}
-	if(cnx->connected)
-	{
-		//d�j� connecter
-		Printferr("Erreur: already connected\n");
-		cnx->error_code=-1;
-		strncpy_s(cnx->error_string,2048,"Already connected",2048);
-		return 1;
-	}
-	if(socket_connect_timeout(cnx,host,port,15))
-	{
-		//erreur de connection
-		Printferr("Erreur in socket_connect\n");
-		cnx->connected=0;
-		//cnx->error_code=-1;
-		//strncpy_s(cnx->error_string,2048,"Error during connection",2048);
-		return 1;
-	}
-	if(login(cnx,1,user,((password==NULL)?"":password),DEFAULT_IMAGE_TYPE)!=0)
-	{
-		//erreur de login
-		Printferr("Erreur: in login function\n");
-		cnx->connected=0;
-		if(cnx->error_code==0) {
-			cnx->error_code=-1;
-			strncpy_s(cnx->error_string,2048,"Error during login",2048);
-		}
-		return 1;
-	}
-	cnx->connected=1;
-	//Printferr("Erreur: not erreur\n");
-	cnx->error_code=0;
-	strncpy_s(cnx->error_string,2048,"",2048);
-	return 0;
-}
-int fourd_close(FOURD *cnx)
-{
-	if(logout(cnx,4)!=0)
-		return 1;
-	if(quit(cnx,5)!=0)
-		return 1;
-	socket_disconnect(cnx);
-	return 0;
-}
-void fourd_free(FOURD* cnx)
-{
-#ifdef WIN32
-	WSACleanup();
-#endif
-	free(cnx);
-}
-
-
-FOURD_LONG8 fourd_affected_rows(FOURD *cnx)
-{
-	return cnx->updated_row;
-}
-int fourd_errno(FOURD *cnx)
-{
-	return (int)cnx->error_code;
-}
-const char * fourd_error(FOURD *cnx)
-{
-	return cnx->error_string;
-}
-int fourd_exec(FOURD *cnx,const char *query)
-{
-	return _query(cnx,3,query,NULL);
-}
-FOURD_RESULT* fourd_query(FOURD *cnx,const char *query)
-{
-	FOURD_RESULT* result;
-	
-	result=calloc(1,sizeof(FOURD_RESULT));
-	result->cnx=cnx;
-	if(_query(cnx,3,query,result)==0)
-	{
-		result->numRow=-1;
-		return result;
-	}
-	else
-	{
-		fourd_free_result(result);
-		return NULL;
-	}
-}
-void fourd_free_result(FOURD_RESULT *res)
-{
-	if(res!=NULL && res->elmt!=NULL)
-			_free_data_result(res);
-	Free(res);
-}
-int fourd_next_row(FOURD_RESULT *res)
-{
-	res->numRow++;
-	if(res->numRow>=res->row_count)
-		return 0;	/*error*/
-	if(res->numRow > res->first_row+res->row_count_sent-1) { /*row out of local result_set but in serveur statement */
-		if(_fetch_result(res,123))
-			return 0;
-	}
-	return 1;
-}
-int fourd_close_statement(FOURD_RESULT *res)
-{
-	if(close_statement(res,7)!=0)
-		return 1;
-	return 0;
-}
-FOURD_LONG * fourd_field_long(FOURD_RESULT *res,unsigned int numCol)
-{
-	unsigned int nbCol=res->row_type.nbColumn;
-	unsigned int nbRow=res->row_count;
-	FOURD_ELEMENT *elmt;
-	unsigned int indexElmt=0;	/*index of element in table <> numRow*nbCol + numCol */
-	//if(res->numRow>=nbRow)	//what can is do in this case...
-	indexElmt=(res->numRow-res->first_row)*nbCol+numCol;
-	elmt=&(res->elmt[indexElmt]);
-	if(elmt->null==0)
-	{
-		FOURD_LONG x=*((int *)elmt->pValue);
-		//printf("/////%d//////",x);
-		return (FOURD_LONG *)elmt->pValue;
-	}
-	return 0;
-}
-FOURD_STRING * fourd_field_string(FOURD_RESULT *res,unsigned int numCol)
-{
-	int nbCol=res->row_type.nbColumn;
-	int nbRow=res->row_count;
-	unsigned int indexElmt=0;	/*index of element in table <> numRow*nbCol + numCol */
-	FOURD_ELEMENT *elmt=NULL;
-	//if(res->numRow>=nbRow)	//what can is do in this case...
-	//	return NULL;
-	indexElmt=(res->numRow-res->first_row)*nbCol+numCol;
-	elmt=&(res->elmt[indexElmt]);
-	if(elmt->null==0)
-	{
-		//FOURD_STRING x=*((int *)elmt->pValue);
-		//printf("/////%d//////",x);
-		FOURD_STRING *x=(FOURD_STRING *)elmt->pValue;
-		return x;
-	}
-	return NULL;
-}
-void * fourd_field(FOURD_RESULT *res,unsigned int numCol)
-{
-	unsigned int nbCol=res->row_type.nbColumn;
-	unsigned int nbRow=res->row_count;
-	unsigned int indexElmt=0;	/*index of element in table <> numRow*nbCol + numCol */
-	FOURD_ELEMENT *elmt=NULL;
-
-	if(res->numRow>=nbRow){	
-		res->cnx->error_code=-1;
-		sprintf_s(res->cnx->error_string,2048,"num Row out of bounds",2048);
-		return NULL;
-	}
-	if(numCol>=nbCol){
-		res->cnx->error_code=-1;
-		sprintf_s(res->cnx->error_string,2048,"num Column out of bounds",2048);
-		return NULL;
-	}
-	indexElmt=(res->numRow-res->first_row)*nbCol+numCol;
-
-	elmt=&(res->elmt[indexElmt]);
-	if(elmt->null!=0) {	/*if elmt is null*/
-		return NULL;
-	}
-	return elmt->pValue;
-}
-int fourd_field_to_string(FOURD_RESULT *res,unsigned int numCol,char **value,int *len)
-{
-	unsigned int nbCol=res->row_type.nbColumn;
-	unsigned int nbRow=res->row_count;
-	FOURD_ELEMENT *elmt=NULL;
-	unsigned int indexElmt=0;	/*index of element in table <> numRow*nbCol + numCol */
-	if(res->numRow>=nbRow){	
-		*value=NULL;
-		*len=0;
-		res->cnx->error_code=-1;
-		sprintf_s(res->cnx->error_string,2048,"num Row out of bounds",2048);
-		return 0;
-	}
-	if(numCol>=nbCol){
-		*value=NULL;
-		*len=0;
-		res->cnx->error_code=-1;
-		sprintf_s(res->cnx->error_string,2048,"num Column out of bounds",2048);
-		return 0;
-	}
-	indexElmt=(res->numRow-res->first_row)*nbCol+numCol;
-	elmt=&(res->elmt[indexElmt]);
-	if(elmt->null!=0) {	/*if elmt is null*/
-		*value=NULL;
-		*len=0;
-	}
-	else {
-		switch(elmt->type) {
-		case VK_BOOLEAN:
-			{
-				*value=calloc(2,sizeof(char));
-				sprintf_s(*value,2,"%s",(*((FOURD_BOOLEAN *)elmt->pValue)==0?"1":"0"));
-				*len=strlen(*value);
-				return 1;
-			}
-		case VK_BYTE:
-		case VK_WORD:
-		case VK_LONG:
-		case VK_LONG8:
-		case VK_DURATION:
-			{
-				*value=calloc(22,sizeof(char));
-				sprintf_s(*value,22,"%d",*((FOURD_LONG *)elmt->pValue));
-				*len=strlen(*value);
-				return 1;
-			}
-			break;
-		case VK_REAL:
-			{
-				*value=calloc(64,sizeof(char));	
-				sprintf_s(*value,64,"%lf",*((FOURD_REAL *)elmt->pValue));
-				*len=strlen(*value);
-				return 1;
-			}
-			break;
-		case VK_FLOAT:
-			//Varying length
-			return 0;
-			break;
-		case VK_TIME:
-		case VK_TIMESTAMP:
-			{
-				FOURD_TIMESTAMP *t=elmt->pValue;
-				unsigned int h,m,s,milli;
-				milli=t->milli;
-				h=milli/(60*60*1000);
-				milli-=h*(60*60*1000);
-				m=milli/(60*1000);
-				milli-=m*(60*1000);
-				s=milli/(1000);
-				milli-=s*(1000);
-
-				*value=calloc(24,sizeof(char));	
-				sprintf_s(*value,24,"%0.4d/%0.2d/%0.2d %0.2d:%0.2d:%0.2d.%0.3d",t->year,t->mounth,t->day,h,m,s,milli);
-				*len=strlen(*value);
-				return 1;
-			}
-		case VK_STRING:
-			{
-				FOURD_STRING *str=elmt->pValue;
-				int size=0;
-				*value=NULL;
-				size=str->length;
-				*value=calloc(size,2);	/*2 bytes per char*/
-				memcpy(*value,str->data,str->length*2);
-				*len=str->length*2;
-				return 1;
-			}
-		case VK_BLOB:
-		case VK_IMAGE:
-			//Varying length
-			return 0;
-			break;
-		}
-		return 0;
-	} 
-	return 0;
-}
-
-const char * fourd_get_column_name(FOURD_RESULT *res,unsigned int numCol)
-{
-	unsigned int nbCol=res->row_type.nbColumn;
-	if(numCol>=nbCol  || numCol<0)
-		return "";
-	if(res->row_type.Column==NULL)
-		return "";
-	return res->row_type.Column[numCol].sColumnName;
-}
-FOURD_TYPE fourd_get_column_type(FOURD_RESULT *res,unsigned int numCol)
-{
-	unsigned int nbCol=res->row_type.nbColumn;
-	FOURD_TYPE type=VK_UNKNOW;
-	if(numCol>=nbCol  || numCol<0)
-		return 0;
-	if(res->row_type.Column==NULL)
-		return 0;
-	type=res->row_type.Column[numCol].type;
-	return type;
-}
-int fourd_num_columns(FOURD_RESULT *res)
-{
-	return res->row_type.nbColumn;
-}
-
-FOURD_STATEMENT * fourd_prepare_statement(FOURD *cnx,const char *query)
-{
-	FOURD_STATEMENT* state=NULL;
-	if(cnx==NULL || !cnx->connected || query==NULL)
-		return NULL;
-	state=calloc(1,sizeof(FOURD_STATEMENT));
-	state->cnx=cnx;
-
-	/* allocate arbitrarily five elements in this table */
-	state->nbAllocElement=5;
-	state->elmt=calloc(state->nbAllocElement,sizeof(FOURD_ELEMENT));	
-	state->nb_element=0;
-
-	/* copy query into statement */
-	sprintf_s(state->query,MAX_HEADER_SIZE,"%s",query);
-	return state;
-}
-int fourd_bind_param(FOURD_STATEMENT *state,unsigned int numParam,FOURD_TYPE type, void *val)
-{
-	/* realloc the size of memory if necessary */
-	if(numParam>=state->nbAllocElement) {
-		state->nbAllocElement=numParam+5;
-		state->elmt=realloc(state->elmt,(sizeof(FOURD_ELEMENT)*state->nbAllocElement));
-	}
-	if(numParam>=state->nb_element) {
-		state->nb_element=numParam+1;	/*zero-based index */
-	}
-	state->elmt[numParam].type=type;
-	if(val==NULL) {
-		state->elmt[numParam].null=1;
-		state->elmt[numParam].pValue=NULL;
-	}
-	else {
-		state->elmt[numParam].null=0;
-		state->elmt[numParam].pValue=_copy(type,val);
-	}
-	return 0;
-}
-FOURD_RESULT *fourd_exec_statement(FOURD_STATEMENT *state)
-{
-	FOURD_RESULT *result=NULL;
-	result=calloc(1,sizeof(FOURD_RESULT));
-	result->cnx=state->cnx;
-	if(_query_param(state->cnx,6,state->query,state->nb_element,state->elmt,result)==0)
-	{
-		result->numRow=-1;
-		return result;
-	}
-	else
-	{
-		fourd_free_result(result);
-		return NULL;
-	}
+/*
+  +----------------------------------------------------------------------+
+  | lib4D_SQL                                                            |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2009 The PHP Group                                     |
+  +----------------------------------------------------------------------+
+  |                                                                      |
+  | This source file is subject to version 3.01 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available through the world-wide-web at the following url:           |
+  | http://www.php.net/license/3_01.txt                                  |
+  |                                                                      |
+  | Its original copy is usable under several licenses and is available  |
+  | through the world-wide-web at the following url:                     |
+  | http://freshmeat.net/projects/lib4d_sql                              |
+  |                                                                      |
+  | Unless required by applicable law or agreed to in writing, software  |
+  | distributed under the License is distributed on an "AS IS" BASIS,    |
+  | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or      |
+  | implied. See the License for the specific language governing         |
+  | permissions and limitations under the License.                       |
+  +----------------------------------------------------------------------+
+  | Contributed by: 4D <php@4d.fr>, http://www.4d.com                    |
+  |                 Alter Way, http://www.alterway.fr                    |
+  | Authors: Stephane Planquart <stephane.planquart@o4db.com>            |
+  |          Alexandre Morgaut <php@4d.fr>                               |
+  +----------------------------------------------------------------------+
+*/
+
+#include "fourd.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "fourd.h"
+#include "fourd_int.h"
+#include "base64.h"
+
+FOURD* fourd_init()
+{
+	//int iResult=0;
+	FOURD* cnx=calloc(1,sizeof(FOURD));
+
+	cnx->socket = INVALID_SOCKET;
+	cnx->connected=0;
+	cnx->init=0;
+	#ifdef WIN32
+	// Initialize Winsock
+    iResult = WSAStartup(MAKEWORD(2,2), &cnx->wsaData);
+    if (iResult != 0) {
+        Printf("WSAStartup failed: %d\n", iResult);
+        return NULL;
+    }
+  #endif
+	cnx->init=1;
+	fourd_set_preferred_image_types(cnx,DEFAULT_IMAGE_TYPE);
+	return cnx;
+}
+
+int fourd_connect(FOURD *cnx,const char *host,const char *user,const char *password,const char *base,unsigned int port)
+{
+	if(!cnx->init)
+	{
+		//not init
+		Printferr("Erreur: FOURD object did not initialised\n");
+		cnx->error_code=-1;
+		strncpy_s(cnx->error_string,2048,"FOURD object did not initialised",2048);
+		return 1;
+	}
+	if(cnx->connected)
+	{
+		//deja connecter
+		Printferr("Erreur: already connected\n");
+		cnx->error_code=-1;
+		strncpy_s(cnx->error_string,2048,"Already connected",2048);
+		return 1;
+	}
+	if(socket_connect_timeout(cnx,host,port,15))
+	{
+		//erreur de connection
+		Printferr("Erreur in socket_connect\n");
+		cnx->connected=0;
+		//cnx->error_code=-1;
+		//strncpy_s(cnx->error_string,2048,"Error during connection",2048);
+		return 1;
+	}
+	if(dblogin(cnx,1,user,((password==NULL)?"":password),cnx->preferred_image_types)!=0)
+	{
+		//erreur de login
+		Printferr("Erreur: in login function\n");
+		cnx->connected=0;
+		if(cnx->error_code==0) {
+			cnx->error_code=-1;
+			strncpy_s(cnx->error_string,2048,"Error during login",2048);
+		}
+		return 1;
+	}
+	cnx->connected=1;
+	//Printferr("Erreur: not erreur\n");
+	cnx->error_code=0;
+	strncpy_s(cnx->error_string,2048,"",2048);
+	return 0;
+}
+int fourd_close(FOURD *cnx)
+{
+	if(dblogout(cnx,4)!=0)
+		return 1;
+	if(quit(cnx,5)!=0)
+		return 1;
+	socket_disconnect(cnx);
+	return 0;
+}
+void fourd_free(FOURD* cnx)
+{
+#ifdef WIN32
+	WSACleanup();
+#endif
+	free(cnx);
+}
+
+
+FOURD_LONG8 fourd_affected_rows(FOURD *cnx)
+{
+	return cnx->updated_row;
+}
+int fourd_errno(FOURD *cnx)
+{
+	return (int)cnx->error_code;
+}
+const char * fourd_error(FOURD *cnx)
+{
+	return cnx->error_string;
+}
+int fourd_exec(FOURD *cnx,const char *query)
+{
+	return _query(cnx,3,query,NULL,cnx->preferred_image_types,100);
+}
+FOURD_RESULT* fourd_query(FOURD *cnx,const char *query)
+{
+	FOURD_RESULT* result;
+	
+	result=calloc(1,sizeof(FOURD_RESULT));
+	result->cnx=cnx;
+	if(_query(cnx,3,query,result,cnx->preferred_image_types,100)==0)
+	{
+		result->numRow=-1;
+		return result;
+	}
+	else
+	{
+		fourd_free_result(result);
+		return NULL;
+	}
+}
+void fourd_free_result(FOURD_RESULT *res)
+{
+	if(res!=NULL && res->elmt!=NULL)
+			_free_data_result(res);
+	Free(res);
+}
+int fourd_next_row(FOURD_RESULT *res)
+{
+	res->numRow++;
+	if(res->numRow>=res->row_count)
+		return 0;	/*error*/
+	if(res->numRow > res->first_row+res->row_count_sent-1) { /*row out of local result_set but in serveur statement */
+		if(_fetch_result(res,123))
+			return 0;
+	}
+	return 1;
+}
+int fourd_close_statement(FOURD_RESULT *res)
+{
+	if(close_statement(res,7)!=0)
+		return 1;
+	return 0;
+}
+FOURD_LONG * fourd_field_long(FOURD_RESULT *res,unsigned int numCol)
+{
+	unsigned int nbCol=res->row_type.nbColumn;
+	//unsigned int nbRow=res->row_count;
+	FOURD_ELEMENT *elmt;
+	unsigned int indexElmt=0;	/*index of element in table <> numRow*nbCol + numCol */
+	//if(res->numRow>=nbRow)	//what can is do in this case...
+	indexElmt=(res->numRow-res->first_row)*nbCol+numCol;
+	elmt=&(res->elmt[indexElmt]);
+	if(elmt->null==0)
+	{
+		//FOURD_LONG x=*((int *)elmt->pValue);
+		//printf("/////%d//////",x);
+		return (FOURD_LONG *)elmt->pValue;
+	}
+	return 0;
+}
+FOURD_STRING * fourd_field_string(FOURD_RESULT *res,unsigned int numCol)
+{
+	int nbCol=res->row_type.nbColumn;
+	//int nbRow=res->row_count;
+	unsigned int indexElmt=0;	/*index of element in table <> numRow*nbCol + numCol */
+	FOURD_ELEMENT *elmt=NULL;
+	//if(res->numRow>=nbRow)	//what can is do in this case...
+	//	return NULL;
+	indexElmt=(res->numRow-res->first_row)*nbCol+numCol;
+	elmt=&(res->elmt[indexElmt]);
+	if(elmt->null==0)
+	{
+		//FOURD_STRING x=*((int *)elmt->pValue);
+		//printf("/////%d//////",x);
+		FOURD_STRING *x=(FOURD_STRING *)elmt->pValue;
+		return x;
+	}
+	return NULL;
+}
+void * fourd_field(FOURD_RESULT *res,unsigned int numCol)
+{
+	unsigned int nbCol=res->row_type.nbColumn;
+	unsigned int nbRow=res->row_count;
+	unsigned int indexElmt=0;	/*index of element in table <> numRow*nbCol + numCol */
+	FOURD_ELEMENT *elmt=NULL;
+
+	if(res->numRow>=nbRow){	
+		res->cnx->error_code=-1;
+		sprintf_s(res->cnx->error_string,2048,"num Row out of bounds",2048);
+		return NULL;
+	}
+	if(numCol>=nbCol){
+		res->cnx->error_code=-1;
+		sprintf_s(res->cnx->error_string,2048,"num Column out of bounds",2048);
+		return NULL;
+	}
+	indexElmt=(res->numRow-res->first_row)*nbCol+numCol;
+
+	elmt=&(res->elmt[indexElmt]);
+	if(elmt->null!=0) {	/*if elmt is null*/
+		return NULL;
+	}
+	return elmt->pValue;
+}
+
+int fourd_field_to_string(FOURD_RESULT *res,unsigned int numCol,char **value,size_t *len)
+{
+	unsigned int nbCol=res->row_type.nbColumn;
+	unsigned int nbRow=res->row_count;
+	FOURD_ELEMENT *elmt=NULL;
+	unsigned int indexElmt=0;	/*index of element in table <> numRow*nbCol + numCol */
+	if(res->numRow>=nbRow){	
+		*value=NULL;
+		*len=0;
+		res->cnx->error_code=-1;
+		sprintf_s(res->cnx->error_string,2048,"num Row out of bounds",2048);
+		return 0;
+	}
+	if(numCol>=nbCol){
+		*value=NULL;
+		*len=0;
+		res->cnx->error_code=-1;
+		sprintf_s(res->cnx->error_string,2048,"num Column out of bounds",2048);
+		return 0;
+	}
+	indexElmt=(res->numRow-res->first_row)*nbCol+numCol;
+	elmt=&(res->elmt[indexElmt]);
+	if(elmt->null!=0) {	/*if elmt is null*/
+		*value=NULL;
+		*len=0;
+	}
+	else {
+		switch(elmt->type) {
+		case VK_BOOLEAN:
+			{
+				*value=calloc(2,sizeof(char));
+				sprintf_s(*value,2,"%s",(*((FOURD_BOOLEAN *)elmt->pValue)==0?"1":"0"));
+				*len=strlen(*value);
+				return 1;
+			}
+		case VK_BYTE:
+		case VK_WORD:
+		case VK_LONG:
+		case VK_LONG8:
+		case VK_DURATION:
+			{
+				*value=calloc(22,sizeof(char));
+				sprintf_s(*value,22,"%d",*((FOURD_LONG *)elmt->pValue));
+				*len=strlen(*value);
+				return 1;
+			}
+			break;
+		case VK_REAL:
+			{
+				*value=calloc(64,sizeof(char));	
+				sprintf_s(*value,64,"%lf",*((FOURD_REAL *)elmt->pValue));
+				*len=strlen(*value);
+				return 1;
+			}
+			break;
+		case VK_FLOAT:
+			//Varying length
+			return 0;
+			break;
+		case VK_TIME:
+		case VK_TIMESTAMP:
+			{
+				FOURD_TIMESTAMP *t=elmt->pValue;
+				unsigned int h,m,s,milli;
+				milli=t->milli;
+				h=milli/(60*60*1000);
+				milli-=h*(60*60*1000);
+				m=milli/(60*1000);
+				milli-=m*(60*1000);
+				s=milli/(1000);
+				milli-=s*(1000);
+
+				*value=calloc(24,sizeof(char));	
+				sprintf_s(*value,24,"%0.4d/%0.2d/%0.2d %0.2d:%0.2d:%0.2d.%0.3d",t->year,t->mounth,t->day,h,m,s,milli);
+				*len=strlen(*value);
+				return 1;
+			}
+		case VK_STRING:
+			{
+				FOURD_STRING *str=elmt->pValue;
+				int size=0;
+				*value=NULL;
+				size=str->length;
+				*value=calloc(size,2);	/*2 bytes per char*/
+				memcpy(*value,str->data,str->length*2);
+				*len=str->length*2;
+				return 1;
+			}
+		case VK_BLOB:
+		case VK_IMAGE:
+			//Varying length
+			return 0;
+			break;
+		default:
+				return 0; //since this is what would happen if it just fell out of the switch statement anyway.
+				break;
+		}
+		return 0;
+	} 
+	return 0;
+}
+
+const char * fourd_get_column_name(FOURD_RESULT *res,unsigned int numCol)
+{
+	unsigned int nbCol=res->row_type.nbColumn;
+	if(numCol>=nbCol)
+		return "";
+	if(res->row_type.Column==NULL)
+		return "";
+	return res->row_type.Column[numCol].sColumnName;
+}
+
+FOURD_TYPE fourd_get_column_type(FOURD_RESULT *res,unsigned int numCol)
+{
+	unsigned int nbCol=res->row_type.nbColumn;
+	FOURD_TYPE type=VK_UNKNOW;
+	if(numCol>=nbCol)
+		return 0;
+	if(res->row_type.Column==NULL)
+		return 0;
+	type=res->row_type.Column[numCol].type;
+	return type;
+}
+
+int fourd_num_columns(FOURD_RESULT *res)
+{
+	return res->row_type.nbColumn;
+}
+
+FOURD_STATEMENT * fourd_prepare_statement(FOURD *cnx,const char *query)
+{
+	FOURD_STATEMENT* state=NULL;
+	if(cnx==NULL || !cnx->connected || query==NULL)
+		return NULL;
+	state=calloc(1,sizeof(FOURD_STATEMENT));
+	state->cnx=cnx;
+	state->query=(char *)malloc(strlen(query)+1);
+
+	/* allocate arbitrarily five elements in this table */
+	state->nbAllocElement=5;
+	state->elmt=calloc(state->nbAllocElement,sizeof(FOURD_ELEMENT));	
+	state->nb_element=0;
+	
+	/* copy query into statement */
+	sprintf(state->query,"%s",query);
+	fourd_set_statement_preferred_image_types(state,cnx->preferred_image_types);
+	
+	
+	char *msg;
+	FOURD_RESULT *res=calloc(1,sizeof(FOURD_RESULT));
+	unsigned char *request_b64;
+	int len;
+
+	request_b64=base64_encode(query,strlen(query),&len);
+	char *format_str="003 PREPARE-STATEMENT\r\nSTATEMENT-BASE64:%s\r\n\r\n";
+	unsigned long buff_size=strlen(format_str)+strlen((const char *)request_b64)+2; //add some extra for good measure.
+	msg=(char *)malloc(buff_size);
+	snprintf(msg,buff_size,format_str,request_b64);
+	free(request_b64);
+
+	cnx->updated_row=-1;
+	socket_send(cnx,msg);
+	free(msg);
+	
+	if(receiv_check(cnx,res)!=0)
+		return NULL;
+	
+	switch(res->resultType)	{
+		case UPDATE_COUNT:
+			//get Update-count: Nb row updated
+			cnx->updated_row=-1;
+			//socket_receiv_update_count(cnx,res);
+			_free_data_result(res);
+			break;
+		case RESULT_SET:
+			//get data
+			socket_receiv_data(cnx,res);
+			cnx->updated_row=-1;
+			break;
+		default:
+			Printferr("Error: Result-Type not supported in query");
+	}
+	free(res);
+
+	
+	return state;
+}
+
+
+int fourd_bind_param(FOURD_STATEMENT *state,unsigned int numParam,FOURD_TYPE type, void *val)
+{
+	/* realloc the size of memory if necessary */
+	if(numParam>=state->nbAllocElement) {
+		state->nbAllocElement=numParam+5;
+		state->elmt=realloc(state->elmt,(sizeof(FOURD_ELEMENT)*state->nbAllocElement));
+	}
+	if(numParam>=state->nb_element) {
+		state->nb_element=numParam+1;	/*zero-based index */
+	}
+	state->elmt[numParam].type=type;
+	if(val==NULL) {
+		state->elmt[numParam].null=1;
+		state->elmt[numParam].pValue=NULL;
+	}
+	else {
+		state->elmt[numParam].null=0;
+		state->elmt[numParam].pValue=_copy(type,val);
+	}
+	return 0;
+}
+FOURD_RESULT *fourd_exec_statement(FOURD_STATEMENT *state, int res_size)
+{
+	FOURD_RESULT *result=NULL;
+	result=calloc(1,sizeof(FOURD_RESULT));
+	result->cnx=state->cnx;
+	if(_query_param(state->cnx,6,state->query,state->nb_element,state->elmt,result,state->preferred_image_types,res_size)==0)
+	{
+		result->numRow=-1;
+		return result;
+	}
+	else
+	{
+		fourd_free_result(result);
+		return NULL;
+	}
+}
+void fourd_set_preferred_image_types(FOURD* cnx,const char *types)
+{
+	if(cnx->preferred_image_types)	{
+		Free(cnx->preferred_image_types);
+	}
+	if(types)	{
+		cnx->preferred_image_types=malloc(strlen(types)+1);
+		sprintf_s(cnx->preferred_image_types,strlen(types)+1,"%s",types);
+	}
+	else	{
+		cnx->preferred_image_types=NULL;
+	}
+
+}
+void fourd_set_statement_preferred_image_types(FOURD_STATEMENT *state,const char *types)
+{
+	if(state->preferred_image_types)	{
+		Free(state->preferred_image_types);
+	}
+	if(types)	{
+		state->preferred_image_types=malloc(strlen(types)+1);
+		sprintf_s(state->preferred_image_types,strlen(types)+1,"%s",types);
+	}
+	else	{
+		state->preferred_image_types=NULL;
+	}
+}
+const char* fourd_get_preferred_image_types(FOURD* cnx)
+{
+	return cnx->preferred_image_types;
+}
+const char* fourd_get_statement_preferred_image_types(FOURD_STATEMENT *state)
+{
+	return state->preferred_image_types;
+}
+void fourd_timeout(FOURD* cnx,int timeout)
+{
+	cnx->timeout=timeout;
 }
\ No newline at end of file
diff --git a/lib4d_sql/fourd.h b/lib4d_sql/fourd.h
index 9dac57a..fb745ce 100644
--- a/lib4d_sql/fourd.h
+++ b/lib4d_sql/fourd.h
@@ -1,252 +1,292 @@
-#ifndef __FOURD__
-#define __FOURD__ 1
-
-#ifdef WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <Wspiapi.h>
-#else
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <unistd.h> /* close */
-#include <errno.h>
-#include <netdb.h> /* gethostbyname */
-#define INVALID_SOCKET -1
-#define SOCKET_ERROR -1
-#define closesocket(s) close(s)
-typedef int SOCKET;
-typedef struct sockaddr_in SOCKADDR_IN;
-typedef struct sockaddr SOCKADDR;
-typedef struct in_addr IN_ADDR;
-
-#endif 
-
-
-#define VERBOSE 0
-
-
-//taille maximal de 2K pour les envoi de requ�te 
-//#define BUFFER_LENGTH 131072
-//taille maximal de 128K pour les r�ponse
-#define BUFFER_LENGTH 131072
-#define ERROR_STRING_LENGTH 2048
-
-#define MAX_HEADER_SIZE 2048
-#define DEFAULT_IMAGE_TYPE "jpg"
-#define MAX_LENGTH_COLUMN_NAME 255
-
-#define FOURD_OK 0
-#define FOURD_ERROR 1
-
-
-
-typedef enum
-{
-	VK_UNKNOW=0,
-	VK_BOOLEAN,
-	VK_BYTE,
-	VK_WORD,
-	VK_LONG,
-	VK_LONG8,
-	VK_REAL,
-	VK_FLOAT,
-	VK_TIME,
-	VK_TIMESTAMP,
-	VK_DURATION,
-	VK_TEXT,
-	VK_STRING,
-	VK_BLOB,
-	VK_IMAGE 
-}FOURD_TYPE;
-/******************************/
-/* parse and format FOUR_TYPE */
-/******************************/
-FOURD_TYPE typeFromString(const char *type);
-const char* stringFromType(FOURD_TYPE type);
-/******************************************************************/
-/* vk_sizeof                                                      */
-/******************************************************************/
-/* return sizeof type or -1 if varying length or 0 if unknow type */
-/******************************************************************/
-int vk_sizeof(FOURD_TYPE type);
-
-/***************/
-/* Result-Type */
-/***************/
-typedef enum
-{
-	UNKNOW=0,
-	UPDATE_COUNT,
-	RESULT_SET
-}FOURD_RESULT_TYPE;
-FOURD_RESULT_TYPE resultTypeFromString(const char *type);
-const char* stringFromResultType(FOURD_RESULT_TYPE type);
-
-/*********************/
-/* Structure of VK_* */
-/*********************/
-#ifdef WIN32
-typedef short FOURD_BOOLEAN;
-typedef short FOURD_BYTE;
-typedef short FOURD_WORD;
-typedef	int FOURD_LONG;
-typedef	__int64 FOURD_LONG8;
-typedef	double FOURD_REAL;
-typedef	struct{int exp;char sign;int data_length;void* data;}FOURD_FLOAT;
-typedef	struct{short year;char mounth;char day;unsigned int milli;}FOURD_TIMESTAMP;
-typedef	__int64 FOURD_DURATION;//in milliseconds
-typedef	struct{int length;unsigned char *data;}FOURD_STRING;
-typedef	struct{int length;void *data;}FOURD_BLOB;
-//typedef	struct{}FOURD_IMAGE; 
-#else
-typedef short FOURD_BOOLEAN;
-typedef short FOURD_BYTE;
-typedef short FOURD_WORD;
-typedef int FOURD_LONG;
-typedef long long FOURD_LONG8;
-typedef double FOURD_REAL;
-typedef struct{int exp;char sign;int data_length;void* data;}FOURD_FLOAT;
-typedef struct{short year;char mounth;char day;unsigned int milli;}FOURD_TIMESTAMP;
-typedef long long FOURD_DURATION;//in milliseconds
-typedef struct{int length;unsigned char *data;}FOURD_STRING;
-typedef struct{int length;void *data;}FOURD_BLOB;
-//typedef       struct{}FOURD_IMAGE;
-
-#endif
-
-
-typedef struct{
-	//Socket Win32
-#ifdef WIN32
-	WSADATA wsaData;
-	SOCKET socket;
-#else
-	int socket;
-#endif
-
-	int init;		/*boolean*/
-	int connected;	/*boolean*/
-
-	/*deprecated: use FOURD_RESULT*/
-	/*char reponse[BUFFER_LENGTH];
-	int reponse_len;*/
-
-	//status
-	int status;//1 pour OK, 0 pour KO
-	FOURD_LONG8 error_code;
-	char error_string[ERROR_STRING_LENGTH];
-
-	//updated row
-	FOURD_LONG8 updated_row;
-
-} FOURD;
-
-typedef struct{
-	FOURD_TYPE type;
-	char null;//0 not null, 1 null
-	void *pValue;
-}FOURD_ELEMENT;
-
-typedef struct{
-	char sType[255];
-	FOURD_TYPE type;
-	char sColumnName[MAX_LENGTH_COLUMN_NAME];
-}FOURD_COLUMN;
-
-typedef struct{
-	unsigned int nbColumn;
-	FOURD_COLUMN *Column;
-}FOURD_ROW_TYPE;
-
-typedef struct{
-	FOURD *cnx;
-	char header[MAX_HEADER_SIZE];
-	unsigned int header_size;
-
-	/*state of statement (OK or KO)*/
-	int status;	/*FOURD_OK or FOURD_ERRROR*/
-	FOURD_LONG8 error_code;
-	char error_string[ERROR_STRING_LENGTH];
-	
-	/*result of parse header
-	  RESULT_SET for select
-	  UPDATE_COUNT for insert, update, delete*/
-	FOURD_RESULT_TYPE resultType;
-	
-	/*Id of statement used with 4D SQL-serveur*/
-	int id_statement;
-	/*Id commande use for request */
-	int id_commande;
-	/*updateability is true or false */
-	int updateability;
-
-	/*total of row count */
-	unsigned int row_count;
-
-	/*row count in data buffer
-	  for little select, row_count_sent = row_cout
-	  for big select, row_count_sent = 100 for the first result_set
-	*/
-	unsigned int row_count_sent;
-	/*num of the first row 
-	for the first response in big select
-	with default parametre on serveur : 0 */
-	unsigned int first_row;
-	
-	/* row_type of this statement 
-	   containe column count, column name and column type*/
-	FOURD_ROW_TYPE row_type;
-
-	/*data*/
-	FOURD_ELEMENT *elmt;
-
-	/*current row index*/
-	unsigned int numRow;
-}FOURD_RESULT;
-
-typedef struct {
-	FOURD *cnx;
-	char query[MAX_HEADER_SIZE];	/*MAX_HEADER_SIZE is user because the query is insert into header*/
-	unsigned int nb_element;
-	unsigned int nbAllocElement;
-	FOURD_ELEMENT *elmt;
-}FOURD_STATEMENT;
-
-
-FOURD* fourd_init();
-int fourd_connect(FOURD *cnx,const char *host,const char *user,const char *password,const char *base,unsigned int port);
-int fourd_close(FOURD *cnx);
-int fourd_exec(FOURD *cnx,const char *query);
-FOURD_LONG8 fourd_affected_rows(FOURD *cnx);
-//gestion des erreurs
-int fourd_errno(FOURD *cnx);
-const char * fourd_error(FOURD *cnx);
-const char * fourd_sqlstate(FOURD *cnx);
-void fourd_free(FOURD* cnx);
-
-
-/*function on FOURD_RESULT*/
-FOURD_LONG8 fourd_num_rows(FOURD_RESULT *result);
-FOURD_RESULT *fourd_query(FOURD *cnx,const char *query);
-int fourd_close_statement(FOURD_RESULT *res);
-void fourd_free_result(FOURD_RESULT *res);
-
-/*function for field*/
-FOURD_LONG * fourd_field_long(FOURD_RESULT *res,unsigned int numCol);
-FOURD_STRING * fourd_field_string(FOURD_RESULT *res,unsigned int numCol);
-void * fourd_field(FOURD_RESULT *res,unsigned int numCol);
-int fourd_next_row(FOURD_RESULT *res);
-
-const char * fourd_get_column_name(FOURD_RESULT *res,unsigned int numCol);
-FOURD_TYPE fourd_get_column_type(FOURD_RESULT *res,unsigned int numCol);
-int fourd_num_columns(FOURD_RESULT *res);
-int fourd_field_to_string(FOURD_RESULT *res,unsigned int numCol,char **value,int *len);	
-
-
-FOURD_STATEMENT * fourd_prepare_statement(FOURD *cnx,const char *query);
-int fourd_bind_param(FOURD_STATEMENT *state,unsigned int numParam,FOURD_TYPE type, void *val);
-FOURD_RESULT *fourd_exec_statement(FOURD_STATEMENT *state);
-#endif
+/*
+  +----------------------------------------------------------------------+
+  | lib4D_SQL                                                            |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2009 The PHP Group                                     |
+  +----------------------------------------------------------------------+
+  |                                                                      |
+  | This source file is subject to version 3.01 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available through the world-wide-web at the following url:           |
+  | http://www.php.net/license/3_01.txt                                  |
+  |                                                                      |
+  | Its original copy is usable under several licenses and is available  |
+  | through the world-wide-web at the following url:                     |
+  | http://freshmeat.net/projects/lib4d_sql                              |
+  |                                                                      |
+  | Unless required by applicable law or agreed to in writing, software  |
+  | distributed under the License is distributed on an "AS IS" BASIS,    |
+  | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or      |
+  | implied. See the License for the specific language governing         |
+  | permissions and limitations under the License.                       |
+  +----------------------------------------------------------------------+
+  | Contributed by: 4D <php@4d.fr>, http://www.4d.com                    |
+  |                 Alter Way, http://www.alterway.fr                    |
+  | Authors: Stephane Planquart <stephane.planquart@o4db.com>            |
+  |          Alexandre Morgaut <php@4d.fr>                               |
+  +----------------------------------------------------------------------+
+*/
+#ifndef __FOURD__
+#define __FOURD__ 1
+
+#ifdef WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <Wspiapi.h>
+#else
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <unistd.h> /* close */
+#include <errno.h>
+#include <netdb.h> /* gethostbyname */
+#define INVALID_SOCKET -1
+#define SOCKET_ERROR -1
+#define closesocket(s) close(s)
+typedef int SOCKET;
+typedef struct sockaddr_in SOCKADDR_IN;
+typedef struct sockaddr SOCKADDR;
+typedef struct in_addr IN_ADDR;
+
+#endif 
+
+
+#define VERBOSE 0
+
+
+/* taille maximal de 2K pour les envoi de requ�te  */
+/* #define BUFFER_LENGTH 131072 */
+/* taille maximal de 128K pour les r�ponse */
+#define BUFFER_LENGTH 131072
+#define ERROR_STRING_LENGTH 2048
+
+#define MAX_HEADER_SIZE 2048
+#define DEFAULT_IMAGE_TYPE "jpg"
+#define MAX_LENGTH_COLUMN_NAME 255
+
+#define FOURD_OK 0
+#define FOURD_ERROR 1
+
+
+
+typedef enum
+{
+	VK_UNKNOW=0,
+	VK_BOOLEAN,
+	VK_BYTE,
+	VK_WORD,
+	VK_LONG,
+	VK_LONG8,
+	VK_REAL,
+	VK_FLOAT,
+	VK_TIME,
+	VK_TIMESTAMP,
+	VK_DURATION,
+	VK_TEXT,
+	VK_STRING,
+	VK_BLOB,
+	VK_IMAGE 
+}FOURD_TYPE;
+/******************************/
+/* parse and format FOUR_TYPE */
+/******************************/
+FOURD_TYPE typeFromString(const char *type);
+const char* stringFromType(FOURD_TYPE type);
+/******************************************************************/
+/* vk_sizeof                                                      */
+/******************************************************************/
+/* return sizeof type or -1 if varying length or 0 if unknow type */
+/******************************************************************/
+int vk_sizeof(FOURD_TYPE type);
+
+/***************/
+/* Result-Type */
+/***************/
+typedef enum
+{
+	UNKNOW=0,
+	UPDATE_COUNT,
+	RESULT_SET
+}FOURD_RESULT_TYPE;
+FOURD_RESULT_TYPE resultTypeFromString(const char *type);
+const char* stringFromResultType(FOURD_RESULT_TYPE type);
+
+/*********************/
+/* Structure of VK_* */
+/*********************/
+#ifdef WIN32
+typedef short FOURD_BOOLEAN;
+typedef short FOURD_BYTE;
+typedef short FOURD_WORD;
+typedef	int FOURD_LONG;
+typedef	__int64 FOURD_LONG8;
+typedef	double FOURD_REAL;
+typedef	struct{int exp;char sign;int data_length;void* data;}FOURD_FLOAT;
+typedef	struct{short year;char mounth;char day;unsigned int milli;}FOURD_TIMESTAMP;
+typedef	__int64 FOURD_DURATION;//in milliseconds
+typedef	struct{int length;unsigned char *data;}FOURD_STRING;
+typedef	struct{int length;void *data;}FOURD_BLOB;
+/* typedef	struct{}FOURD_IMAGE;  */
+#else
+typedef short FOURD_BOOLEAN;
+typedef short FOURD_BYTE;
+typedef short FOURD_WORD;
+typedef int FOURD_LONG;
+typedef long long FOURD_LONG8;
+typedef double FOURD_REAL;
+typedef struct{int exp;unsigned char sign;int data_length;void* data;}FOURD_FLOAT;
+typedef struct{short year;unsigned char mounth;unsigned char day;unsigned int milli;}FOURD_TIMESTAMP;
+typedef long long FOURD_DURATION;//in milliseconds
+typedef struct{int length;unsigned char *data;}FOURD_STRING;
+typedef struct{int length;void *data;}FOURD_BLOB;
+/* typedef       struct{}FOURD_IMAGE; */
+
+#endif
+
+
+typedef struct{
+	/* Socket Win32 */
+#ifdef WIN32
+	WSADATA wsaData;
+	SOCKET socket;
+#else
+	int socket;
+#endif
+
+	int init;		/*boolean*/
+	int connected;	/*boolean*/
+
+	/*deprecated: use FOURD_RESULT*/
+	/*char reponse[BUFFER_LENGTH];
+	int reponse_len;*/
+
+	/* status */
+	int status;//1 pour OK, 0 pour KO
+	FOURD_LONG8 error_code;
+	char error_string[ERROR_STRING_LENGTH];
+
+	/* updated row */
+	FOURD_LONG8 updated_row;
+	
+	/* PREFERRED-IMAGE-TYPES */
+	char *preferred_image_types;
+	int timeout;
+
+} FOURD;
+
+typedef struct{
+	FOURD_TYPE type;
+	char null;//0 not null, 1 null
+	void *pValue;
+}FOURD_ELEMENT;
+
+typedef struct{
+	char sType[255];
+	FOURD_TYPE type;
+	char sColumnName[MAX_LENGTH_COLUMN_NAME];
+}FOURD_COLUMN;
+
+typedef struct{
+	unsigned int nbColumn;
+	FOURD_COLUMN *Column;
+}FOURD_ROW_TYPE;
+
+typedef struct{
+	FOURD *cnx;
+	char header[MAX_HEADER_SIZE];
+	unsigned int header_size;
+
+	/*state of statement (OK or KO)*/
+	int status;	/*FOURD_OK or FOURD_ERRROR*/
+	FOURD_LONG8 error_code;
+	char error_string[ERROR_STRING_LENGTH];
+	
+	/*result of parse header
+	  RESULT_SET for select
+	  UPDATE_COUNT for insert, update, delete*/
+	FOURD_RESULT_TYPE resultType;
+	
+	/*Id of statement used with 4D SQL-serveur*/
+	int id_statement;
+	/*Id commande use for request */
+	int id_commande;
+	/*updateability is true or false */
+	int updateability;
+
+	/*total of row count */
+	unsigned int row_count;
+
+	/*row count in data buffer
+	  for little select, row_count_sent = row_cout
+	  for big select, row_count_sent = 100 for the first result_set
+	*/
+	unsigned int row_count_sent;
+	/*num of the first row 
+	for the first response in big select
+	with default parametre on serveur : 0 */
+	unsigned int first_row;
+	
+	/* row_type of this statement 
+	   containe column count, column name and column type*/
+	FOURD_ROW_TYPE row_type;
+
+	/*data*/
+	FOURD_ELEMENT *elmt;
+
+	/*current row index*/
+	unsigned int numRow;
+}FOURD_RESULT;
+
+typedef struct {
+	FOURD *cnx;
+	char *query;	/*MAX_HEADER_SIZE is using because the query is insert into header*/
+	unsigned int nb_element;
+	unsigned int nbAllocElement;
+	FOURD_ELEMENT *elmt;
+	/* PREFERRED-IMAGE-TYPES */
+	char *preferred_image_types;
+}FOURD_STATEMENT;
+
+
+FOURD* fourd_init();
+int fourd_connect(FOURD *cnx,const char *host,const char *user,const char *password,const char *base,unsigned int port);
+int fourd_close(FOURD *cnx);
+int fourd_exec(FOURD *cnx,const char *query);
+FOURD_LONG8 fourd_affected_rows(FOURD *cnx);
+//gestion des erreurs
+int fourd_errno(FOURD *cnx);
+const char * fourd_error(FOURD *cnx);
+const char * fourd_sqlstate(FOURD *cnx);
+void fourd_free(FOURD* cnx);
+void fourd_timeout(FOURD* cnx,int timeout);
+
+/*function on FOURD_RESULT*/
+FOURD_LONG8 fourd_num_rows(FOURD_RESULT *result);
+FOURD_RESULT *fourd_query(FOURD *cnx,const char *query);
+int fourd_close_statement(FOURD_RESULT *res);
+void fourd_free_result(FOURD_RESULT *res);
+
+/*function for field*/
+FOURD_LONG * fourd_field_long(FOURD_RESULT *res,unsigned int numCol);
+FOURD_STRING * fourd_field_string(FOURD_RESULT *res,unsigned int numCol);
+void * fourd_field(FOURD_RESULT *res,unsigned int numCol);
+int fourd_next_row(FOURD_RESULT *res);
+
+const char * fourd_get_column_name(FOURD_RESULT *res,unsigned int numCol);
+FOURD_TYPE fourd_get_column_type(FOURD_RESULT *res,unsigned int numCol);
+int fourd_num_columns(FOURD_RESULT *res);
+int fourd_field_to_string(FOURD_RESULT *res,unsigned int numCol,char **value,size_t *len);
+
+
+FOURD_STATEMENT * fourd_prepare_statement(FOURD *cnx,const char *query);
+int fourd_bind_param(FOURD_STATEMENT *state,unsigned int numParam,FOURD_TYPE type, void *val);
+FOURD_RESULT *fourd_exec_statement(FOURD_STATEMENT *state, int res_size);
+
+void fourd_set_preferred_image_types(FOURD* cnx,const char *types);
+void fourd_set_statement_preferred_image_types(FOURD_STATEMENT *state,const char *types);
+const char* fourd_get_preferred_image_types(FOURD* cnx);
+const char* fourd_get_statement_preferred_image_types(FOURD_STATEMENT *state);
+#endif
diff --git a/lib4d_sql/fourd_int.h b/lib4d_sql/fourd_int.h
index e269613..52bfae0 100644
--- a/lib4d_sql/fourd_int.h
+++ b/lib4d_sql/fourd_int.h
@@ -1,68 +1,97 @@
-#ifndef __FOURD_INT__
-#define __FOURD_INT__ 1
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-int Printf(const char* format,...);
-int Printferr(const char* format,...);
-
-/*******************/
-/* communication.c */
-/*******************/
-int socket_connect(FOURD *cnx,const char *host,unsigned int port);
-void socket_disconnect(FOURD *cnx);
-int socket_send(FOURD *cnx,const char*msg);
-int socket_send_data(FOURD *cnx,const char*msg,int len);
-//int socket_receiv(FOURD *cnx);
-int socket_receiv_header(FOURD *cnx,FOURD_RESULT *state);
-int socket_receiv_data(FOURD *cnx,FOURD_RESULT *state);
+/*
+  +----------------------------------------------------------------------+
+  | lib4D_SQL                                                            |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2009 The PHP Group                                     |
+  +----------------------------------------------------------------------+
+  |                                                                      |
+  | This source file is subject to version 3.01 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available through the world-wide-web at the following url:           |
+  | http://www.php.net/license/3_01.txt                                  |
+  |                                                                      |
+  | Its original copy is usable under several licenses and is available  |
+  | through the world-wide-web at the following url:                     |
+  | http://freshmeat.net/projects/lib4d_sql                              |
+  |                                                                      |
+  | Unless required by applicable law or agreed to in writing, software  |
+  | distributed under the License is distributed on an "AS IS" BASIS,    |
+  | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or      |
+  | implied. See the License for the specific language governing         |
+  | permissions and limitations under the License.                       |
+  +----------------------------------------------------------------------+
+  | Contributed by: 4D <php@4d.fr>, http://www.4d.com                    |
+  |                 Alter Way, http://www.alterway.fr                    |
+  | Authors: Stephane Planquart <stephane.planquart@o4db.com>            |
+  |          Alexandre Morgaut <php@4d.fr>                               |
+  +----------------------------------------------------------------------+
+*/
+#ifndef __FOURD_INT__
+#define __FOURD_INT__ 1
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+int Printf(const char* format,...);
+int Printferr(const char* format,...);
+
+/*******************/
+/* communication.c */
+/*******************/
+int socket_connect(FOURD *cnx,const char *host,unsigned int port);
+void socket_disconnect(FOURD *cnx);
+int socket_send(FOURD *cnx,const char*msg);
+int socket_send_data(FOURD *cnx,const char*msg,int len);
+//int socket_receiv(FOURD *cnx);
+int socket_receiv_header(FOURD *cnx,FOURD_RESULT *state);
+int socket_receiv_data(FOURD *cnx,FOURD_RESULT *state);
 int socket_receiv_update_count(FOURD *cnx,FOURD_RESULT *state);
 int set_sock_blocking(int socketd, int block);
-int socket_connect_timeout(FOURD *cnx,const char *host,unsigned int port,unsigned int timeout);
-/*******************/
-/* fourd_interne.c */
-/*******************/
-//return 0 for OK et -1 for no readable header and error_code
-int login(FOURD *cnx,unsigned short int id_cnx,const char *user,const char*pwd,const char*image_type);
-int logout(FOURD *cnx,unsigned short int id_cmd);
-int quit(FOURD *cnx,unsigned short int id_cmd);
-//return 0 for OK et -1 for no readable header and error_code
-int _query(FOURD *cnx,unsigned short int id_cmd,const char *request,FOURD_RESULT *result);
-int __fetch_result(FOURD *cnx,unsigned short int id_cmd,int statement_id,int command_index,unsigned int first_row,unsigned int last_row,FOURD_RESULT *result);
-int _fetch_result(FOURD_RESULT *res,unsigned short int id_cmd);
-int get(const char* msg,const char* section,char *valeur,int max_length);
-//FOURD_LONG8 get_status(FOURD* cnx);
-//int traite_header_reponse(FOURD* cnx);
-int traite_header_response(FOURD_RESULT* cnx);
-FOURD_LONG8 _get_status(const char *header,int *status,FOURD_LONG8 *error_code,char *error_string);
-int receiv_check(FOURD *cnx,FOURD_RESULT *state);
-void _free_data_result(FOURD_RESULT *res);
-//clear connection attribut
-void _clear_atrr_cnx(FOURD *cnx);
-int close_statement(FOURD_RESULT *res,unsigned short int id_cmd);
-
-int _query_param(FOURD *cnx,unsigned short int id_cmd, const char *request,unsigned int nbParam, const FOURD_ELEMENT *param,FOURD_RESULT *result); 
-
-/*********************/
-/* Memory Allocation */
-/*********************/
-void *_copy(FOURD_TYPE type,void *org);
-char *_serialize(char *data,int *size, FOURD_TYPE type, void *pObj);
-void Free(void *p);
-void FreeFloat(FOURD_FLOAT *p);
-void FreeString(FOURD_STRING *p);
-void FreeBlob(FOURD_BLOB *p);
-void PrintData(const void *data,unsigned int size);
-#ifndef WIN32
-	void ZeroMemory (void *s, size_t n);
-#define WSAGetLastError() errno
-#define strtok_s(a,b,c) strtok(a,b)
-#define strcpy_s(s,size,cs) strncpy(s,cs,size)
-#define strncpy_s(s,ms,cs,size) strncpy(s,cs,size)
-	int sprintf_s(char *buff,int size,const char* format,...);
-	int _snprintf_s(char *buff, int size, int count, const char *format,...);
-#endif
-
-
-#endif
+int socket_connect_timeout(FOURD *cnx,const char *host,unsigned int port,int timeout);
+/*******************/
+/* fourd_interne.c */
+/*******************/
+//return 0 for OK et -1 for no readable header and error_code
+int dblogin(FOURD *cnx,unsigned short int id_cnx,const char *user,const char*pwd,const char*image_type);
+int dblogout(FOURD *cnx,unsigned short int id_cmd);
+int quit(FOURD *cnx,unsigned short int id_cmd);
+//return 0 for OK et -1 for no readable header and error_code
+int _query(FOURD *cnx,unsigned short int id_cmd,const char *request,FOURD_RESULT *result,const char*image_type, int res_size);
+int __fetch_result(FOURD *cnx,unsigned short int id_cmd,int statement_id,int command_index,unsigned int first_row,unsigned int last_row,FOURD_RESULT *result);
+int _fetch_result(FOURD_RESULT *res,unsigned short int id_cmd);
+int get(const char* msg,const char* section,char *valeur,int max_length);
+//FOURD_LONG8 get_status(FOURD* cnx);
+//int traite_header_reponse(FOURD* cnx);
+int traite_header_response(FOURD_RESULT* cnx);
+FOURD_LONG8 _get_status(const char *header,int *status,FOURD_LONG8 *error_code,char *error_string);
+int receiv_check(FOURD *cnx,FOURD_RESULT *state);
+void _free_data_result(FOURD_RESULT *res);
+//clear connection attribut
+void _clear_atrr_cnx(FOURD *cnx);
+int close_statement(FOURD_RESULT *res,unsigned short int id_cmd);
+
+int _query_param(FOURD *cnx,unsigned short int id_cmd, const char *request,unsigned int nbParam, const FOURD_ELEMENT *param,FOURD_RESULT *result,const char*image_type, int res_size);
+int _is_multi_query(const char *request);
+int _valid_query(FOURD *cnx,const char *request);
+/*********************/
+/* Memory Allocation */
+/*********************/
+void *_copy(FOURD_TYPE type,void *org);
+char *_serialize(char *data,unsigned int *size, FOURD_TYPE type, void *pObj);
+void Free(void *p);
+void FreeFloat(FOURD_FLOAT *p);
+void FreeString(FOURD_STRING *p);
+void FreeBlob(FOURD_BLOB *p);
+void PrintData(const void *data,unsigned int size);
+#ifndef WIN32
+	void ZeroMemory (void *s, size_t n);
+#define WSAGetLastError() errno
+#define strtok_s(a,b,c) strtok(a,b)
+#define strcpy_s(s,size,cs) strncpy(s,cs,size)
+#define strncpy_s(s,ms,cs,size) strncpy(s,cs,size)
+	int sprintf_s(char *buff,size_t size,const char* format,...);
+	int _snprintf_s(char *buff, size_t size, size_t count, const char *format,...);
+#endif
+
+
+#endif
diff --git a/lib4d_sql/fourd_interne.c b/lib4d_sql/fourd_interne.c
index 09ce6ef..0e7e8f8 100644
--- a/lib4d_sql/fourd_interne.c
+++ b/lib4d_sql/fourd_interne.c
@@ -1,797 +1,970 @@
-#include "fourd.h"
-#include "fourd_int.h"
-#include "base64.h"
-#include "utils.h"
-#include <stdarg.h>
+/*
+  +----------------------------------------------------------------------+
+  | lib4D_SQL                                                            |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2009 The PHP Group                                     |
+  +----------------------------------------------------------------------+
+  |                                                                      |
+  | This source file is subject to version 3.01 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available through the world-wide-web at the following url:           |
+  | http://www.php.net/license/3_01.txt                                  |
+  |                                                                      |
+  | Its original copy is usable under several licenses and is available  |
+  | through the world-wide-web at the following url:                     |
+  | http://freshmeat.net/projects/lib4d_sql                              |
+  |                                                                      |
+  | Unless required by applicable law or agreed to in writing, software  |
+  | distributed under the License is distributed on an "AS IS" BASIS,    |
+  | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or      |
+  | implied. See the License for the specific language governing         |
+  | permissions and limitations under the License.                       |
+  +----------------------------------------------------------------------+
+  | Contributed by: 4D <php@4d.fr>, http://www.4d.com                    |
+  |                 Alter Way, http://www.alterway.fr                    |
+  | Authors: Stephane Planquart <stephane.planquart@o4db.com>            |
+  |          Alexandre Morgaut <php@4d.fr>                               |
+  +----------------------------------------------------------------------+
+*/
+
+#include "fourd.h"
+#include "fourd_int.h"
+#include "base64.h"
+#include "utils.h"
+#include <stdarg.h>
 #define __STATEMENT_BASE64__ 1
-#define __LOGIN_BASE64__ 1
-int Printf(const char* format,...)
-{
-#if VERBOSE
-	va_list ap;
-	va_start(ap,format);
-	vprintf(format,ap);
-	
-	return 0;
-#else
-	return 0;
-#endif
-}
-int Printferr(const char* format,...)
-{
-#if VERBOSE
-	va_list ap;
-	va_start(ap,format);
-	vfprintf(stderr,format,ap);
-	
-	return 0;
-#else
-	return 0;
-#endif
-}
-#ifndef WIN32
-void ZeroMemory (void *s, size_t n)
-{
-	bzero(s,n);
-}
-int sprintf_s(char *buff,int size,const char* format,...)
-{
-	va_list ap;
-	va_start(ap,format);
-	vsnprintf(buff,size,format,ap);
-}
-int _snprintf_s(char *buff, int size, int count, const char *format,...)
-{
-	va_list ap;
-	va_start(ap,format);
-	vsnprintf(buff,((size>count)?count:size),format,ap);
-}
-int _snprintf(char *buff, int size, const char *format,...)
-{
-	va_list ap;
-	va_start(ap,format);
-	vsnprintf(buff,size,format,ap);
-}
-#endif
-int login(FOURD *cnx,unsigned short int id_cnx,const char *user,const char*pwd,const char*image_type)
-{
-	char msg[2048];
+#define __LOGIN_BASE64__ 1
+int Printf(const char* format,...)
+{
+#if VERBOSE
+	va_list ap;
+	va_start(ap,format);
+	vprintf(format,ap);
+	
+	return 0;
+#else
+	return 0;
+#endif
+}
+int Printferr(const char* format,...)
+{
+#if VERBOSE
+	va_list ap;
+	va_start(ap,format);
+	vfprintf(stderr,format,ap);
+	
+	return 0;
+#else
+	return 0;
+#endif
+}
+#ifndef WIN32
+void ZeroMemory (void *s, size_t n)
+{
+	bzero(s,n);
+}
+int sprintf_s(char *buff,size_t size,const char* format,...)
+{
+	va_list ap;
+	va_start(ap,format);
+	vsnprintf(buff,size,format,ap);
+	return 0;
+}
+int _snprintf_s(char *buff, size_t size, size_t count, const char *format,...)
+{
+	va_list ap;
+	va_start(ap,format);
+	vsnprintf(buff,((size>count)?count:size),format,ap);
+	return 0;
+}
+int _snprintf(char *buff, int size, const char *format,...)
+{
+	va_list ap;
+	va_start(ap,format);
+	vsnprintf(buff,size,format,ap);
+	return 0;
+}
+#endif
+int dblogin(FOURD *cnx,unsigned short int id_cnx,const char *user,const char*pwd,const char*image_type)
+{
+	char msg[2048];
 	FOURD_RESULT state;
-	char *user_b64=NULL,*pwd_b64=NULL;
-	int len;
+	unsigned char *user_b64=NULL,*pwd_b64=NULL;
+	int len;
 	_clear_atrr_cnx(cnx);
-#if __LOGIN_BASE64__
+#if __LOGIN_BASE64__
 	user_b64=base64_encode(user,strlen(user),&len);
-	pwd_b64=base64_encode(pwd,strlen(pwd),&len);
+	pwd_b64=base64_encode(pwd,strlen(pwd),&len);
 	sprintf_s(msg,2048,"%03d LOGIN \r\nUSER-NAME-BASE64:%s\r\nUSER-PASSWORD-BASE64:%s\r\nPREFERRED-IMAGE-TYPES:%s\r\nREPLY-WITH-BASE64-TEXT:Y\r\nPROTOCOL-VERSION:0.1a\r\n\r\n",id_cnx,user_b64,pwd_b64,image_type);
 	free(user_b64);
-	free(pwd_b64);
+	free(pwd_b64);
 #else
 	sprintf_s(msg,2048,"%03d LOGIN \r\nUSER-NAME:%s\r\nUSER-PASSWORD:%s\r\nPREFERRED-IMAGE-TYPES:%s\r\nREPLY-WITH-BASE64-TEXT:Y\r\nPROTOCOL-VERSION:0.1a\r\n\r\n",id_cnx,user,pwd,image_type);
-#endif
-	socket_send(cnx,msg);
-	if(receiv_check(cnx,&state)!=0)
-		return 1;
-		
-	return 0;
-}
-//return 0 if ok 1 if error
-int _query(FOURD *cnx,unsigned short int id_cmd,const char *request,FOURD_RESULT *result)
-{
-	char msg[MAX_HEADER_SIZE];
+#endif
+	socket_send(cnx,msg);
+	if(receiv_check(cnx,&state)!=0)
+		return 1;
+		
+	return 0;
+}
+//return 0 if ok 1 if error
+int _query(FOURD *cnx,unsigned short int id_cmd,const char *request,FOURD_RESULT *result,const char*image_type, int res_size)
+{
+	char *msg;
 	FOURD_RESULT *res;
-	char *request_b64;
+	unsigned char *request_b64;
 	int len;
-	Printf("---Debut de _query\n");
-	_clear_atrr_cnx(cnx);
-
-	if(result!=NULL)
-		res=result;
-	else
+	Printf("---Debut de _query\n");
+	_clear_atrr_cnx(cnx);
+	if(!_valid_query(cnx,request)) {
+		return 1;
+	}
+	if(result!=NULL)
+		res=result;
+	else
 		res=calloc(1,sizeof(FOURD_RESULT));
 #if __STATEMENT_BASE64__
 	request_b64=base64_encode(request,strlen(request),&len);
-	sprintf_s(msg,2048,"%03d EXECUTE-STATEMENT\r\nSTATEMENT-BASE64:%s\r\nOutput-Mode:%s\r\n\r\n",id_cmd,request_b64,"release");
-	Free(request_b64);
-#else
-	sprintf_s(msg,2048,"%03d EXECUTE-STATEMENT\r\nSTATEMENT:%s\r\nOutput-Mode:%s\r\n\r\n",id_cmd,request,"release");
-#endif
+	char *format_str="%03d EXECUTE-STATEMENT\r\nSTATEMENT-BASE64:%s\r\nOutput-Mode:%s\r\nFIRST-PAGE-SIZE:%i\r\nPREFERRED-IMAGE-TYPES:%s\r\n\r\n";
+	size_t buff_size=strlen(format_str)+strlen((const char *)request_b64)+42; //add some extra for the additional arguments and a bit more for good measure.
+	msg=(char *)malloc(buff_size);
+	snprintf(msg,buff_size,format_str,id_cmd,request_b64,"release",res_size,image_type);
+	free(request_b64);
+#else
+	char *format_str="%03d EXECUTE-STATEMENT\r\nSTATEMENT:%s\r\nOutput-Mode:%s\r\nFIRST-PAGE-SIZE:%i\r\nPREFERRED-IMAGE-TYPES:%s\r\n\r\n";
+	size_t buff_size=strlen(format_str)+strlen(request)+42; //add some extra for the additional arguments and a bit more for good measure.
+	msg=(char *)malloc(buff_size);
+	snprintf(msg, buff_size,format_str,id_cmd,request,"release",res_size,image_type);
+#endif
+
 	cnx->updated_row=-1;
-	socket_send(cnx,msg);
-	if(receiv_check(cnx,res)!=0) {
+	socket_send(cnx,msg);
+	free(msg);
+	
+	if(receiv_check(cnx,res)!=0)
 		return 1;
-	}
-	switch(res->resultType)	{
-	case UPDATE_COUNT:
-		//get Update-count: Nb row updated
-		cnx->updated_row=-1;
-		socket_receiv_update_count(cnx,res);		
-		_free_data_result(res);
-		break;
-	case RESULT_SET:
-		//get data
-		socket_receiv_data(cnx,res);
-		cnx->updated_row=-1;
+
+	switch(res->resultType)	{
+	case UPDATE_COUNT:
+		//get Update-count: Nb row updated
+		cnx->updated_row=-1;
+		socket_receiv_update_count(cnx,res);		
+		_free_data_result(res);
+		break;
+	case RESULT_SET:
+		//get data
+		socket_receiv_data(cnx,res);
+		cnx->updated_row=-1;
 		if(result==NULL) {
-			_free_data_result(res);
-		}
-		break;
-	default:
-		Printferr("Error: Result-Type not supported in query");
-	}
-	//if(traite_header_reponse(cnx)!=0)
-	//	return 1;
+			_free_data_result(res);
+		}
+		break;
+	default:
+		Printferr("Error: Result-Type not supported in query");
+	}
+	//if(traite_header_reponse(cnx)!=0)
+	//	return 1;
 	if(result==NULL) {
 		Free(res);
 	}
 	Printf("---Fin de _query\n");
-	return 0;
-}
-int _query_param(FOURD *cnx,unsigned short int id_cmd, const char *request,unsigned int nbParam, const FOURD_ELEMENT *param,FOURD_RESULT *result)
-{
-	char msg[MAX_HEADER_SIZE];
+	return 0;
+}
+
+int _query_param(FOURD *cnx,unsigned short int id_cmd, const char *request,unsigned int nbParam, const FOURD_ELEMENT *param,FOURD_RESULT *result,const char*image_type,int res_size)
+{
+	char *msg=NULL;
 	FOURD_RESULT *res;
-	char *request_b64;
-	int len;
-	char sParam[MAX_HEADER_SIZE];
-	unsigned int i=0;
-	char *data=NULL;
-	unsigned int data_len=0;
+	unsigned char *request_b64=NULL;
+	int len;
+	char *sParam=NULL;
+	unsigned int i=0;
+	char *data=NULL;
+	unsigned int data_len=0;
 	unsigned int size=0;
-	Printf("---Debut de _query_param\n");
-	if(nbParam<=0)
-		return _query(cnx,id_cmd,request,result);
-	_clear_atrr_cnx(cnx);
-
-	if(result!=NULL)
-		res=result;
-	else
-		res=calloc(1,sizeof(FOURD_RESULT));
-	
-
-	/* construct param list */
-	sprintf_s(sParam,MAX_HEADER_SIZE-1,"");
-	for(i=0;i<nbParam;i++) {
-		sprintf_s(sParam+strlen(sParam),MAX_HEADER_SIZE-1-strlen(sParam)," %s",stringFromType(param[i].type));
-	}
-	/* construct data */
-	for(i=0;i<nbParam;i++) {
-		if(param[i].null==0) {
-			data=realloc(data,++size);
-			memset(data+(size-1),'1',1);
-			data=_serialize(data,&size,param[i].type,param[i].pValue);
+	//Printf("---Debut de _query_param\n");
+	if(!_valid_query(cnx,request)) {
+		return 1;
+	}
+	if(nbParam<=0)
+		return _query(cnx,id_cmd,request,result,image_type,res_size);
+	_clear_atrr_cnx(cnx);
+
+	if(result!=NULL)
+		res=result;
+	else
+		res=calloc(1,sizeof(FOURD_RESULT));
+	
+
+	/* construct param list */
+	size_t paramlen=(nbParam+1)*13; //the longest type name is 12 characters, and we add a space between each parameter.
+									// add a 1 to the number of parameters because I am paranoid.
+	
+	sParam=calloc(paramlen, sizeof(char)); //initalized to zero, so we should be able to call strlen() on it without problem
+	
+	for(i=0;i<nbParam;i++) {
+		snprintf(sParam+strlen(sParam),paramlen-1-strlen(sParam)," %s",stringFromType(param[i].type));
+		
+		/* construct data */
+		if(param[i].null==0) {
+			data=realloc(data,++size);
+			memset(data+(size-1),'1',1);
+			data=_serialize(data,&size,param[i].type,param[i].pValue);
 		} else {
-			Printf("Serialize a null value\n");
-			data=realloc(data,++size);
-			memset(data+(size-1),'0',1);
-		}
-	}
-	data_len=size;
-	/* construct Header */
+			Printf("Serialize a null value\n");
+			data=realloc(data,++size);
+			memset(data+(size-1),'0',1);
+		}
+	}
+
+	data_len=size;
+	/* construct Header */
 #if __STATEMENT_BASE64__
-	request_b64=base64_encode(request,strlen(request),&len);
-	sprintf_s(msg,2048,"%03d EXECUTE-STATEMENT\r\nSTATEMENT-BASE64:%s\r\nOutput-Mode:%s\r\nPARAMETER-TYPES:%s\r\n\r\n",id_cmd,request_b64,"release",sParam);
+	request_b64=base64_encode(request,strlen(request),&len);
+	char *msg_format="%03d EXECUTE-STATEMENT\r\nSTATEMENT-BASE64:%s\r\nOutput-Mode:%s\r\nFIRST-PAGE-SIZE:%i\r\nPREFERRED-IMAGE-TYPES:%s\r\nPARAMETER-TYPES:%s\r\n\r\n";
+	size_t msg_length=strlen((const char *)request_b64)+strlen(msg_format)+strlen(image_type)+strlen(sParam)+20;
+	msg=malloc(msg_length);
+	snprintf(msg,msg_length,msg_format,id_cmd,request_b64,"release",res_size,image_type,sParam);
 	free(request_b64);
-#else
-	sprintf_s(msg,MAX_HEADER_SIZE-1,"%03d EXECUTE-STATEMENT\r\nSTATEMENT:%s\r\nOutput-Mode:%s\r\nPARAMETER-TYPES:%s\r\n\r\n",id_cmd,request,"release",sParam);
-#endif
-	
-
-	socket_send(cnx,msg);
-	socket_send_data(cnx,data,data_len);
-	if(receiv_check(cnx,res)!=0)
-		return 1;
-
-	switch(res->resultType)	{
-	case UPDATE_COUNT:
-		//get Update-count: Nb row updated
-		socket_receiv_update_count(cnx,res);		
-		_free_data_result(res);
-		break;
-	case RESULT_SET:
-		//get data
-		socket_receiv_data(cnx,res);
-		cnx->updated_row=-1;
-		if(result==NULL) {
-			_free_data_result(res);
-		}
-		break;
-	default:
-		Printferr("Error: Result-Type not supported in query");
-	}
-	//if(traite_header_reponse(cnx)!=0)
-	//	return 1;
-	if(result==NULL)
-		Free(res);
-	return 0;
-}
-/* low level commande 
-   command_index and statement_id is identify by result of execute statement commande */
-int __fetch_result(FOURD *cnx,unsigned short int id_cmd,int statement_id,int command_index,unsigned int first_row,unsigned int last_row,FOURD_RESULT *result)
-{
-	char msg[2048];
-	
-	
-	_clear_atrr_cnx(cnx);
-
-	if(result==NULL) {
-		return 0;
-	}
-	sprintf_s(msg,2048,"%03d FETCH-RESULT\r\nSTATEMENT-ID:%d\r\nCOMMAND-INDEX:%03d\r\nFIRST-ROW-INDEX:%d\r\nLAST-ROW-INDEX:%d\r\nOutput-Mode:%s\r\n\r\n",id_cmd,statement_id,command_index,first_row,last_row,"release");
-	socket_send(cnx,msg);
-	if(receiv_check(cnx,result)!=0)
-		return 1;
-	socket_receiv_data(cnx,result);
-
-	return 0;
-}
-/*get next row set in result_set*/
-int _fetch_result(FOURD_RESULT *res,unsigned short int id_cmd)
-{
-	FOURD *cnx=res->cnx;
-	FOURD_RESULT *nRes=NULL;
-	void *last_data=NULL;
-	int id_statement=res->id_statement;
-	unsigned int first_row=res->first_row+res->row_count_sent;
-	unsigned int last_row=res->first_row+res->row_count_sent+99;
-	if(last_row>=res->row_count) {
-		last_row=res->row_count-1;
-	}
-
-	nRes=calloc(1,sizeof(FOURD_RESULT));
-	_clear_atrr_cnx(cnx);
-	/*set paramature unsed in socket_receiv */
-	nRes->first_row=first_row;
-	nRes->row_count_sent=last_row-first_row+1;
-	nRes->cnx=res->cnx;
-	nRes->row_type=res->row_type;
-	/*get new Result set in new FOURD_RESULT*/
-	if(__fetch_result(cnx,123,res->id_statement,0,first_row,last_row,nRes)){
-		return 1;
-	}
-	/*switch data between res and nRes FOURD_RESULT*/
-	last_data=res->elmt;
-	res->elmt=nRes->elmt;
-	nRes->elmt=last_data;	/*important for free memory after */
-	res->first_row=first_row;
-	res->row_count_sent=last_row-first_row+1;
-	res->error_code=nRes->error_code;
-	last_data=res->error_string;
-	sprintf_s(res->error_string,sizeof(res->error_string),"%s",nRes->error_string);
-	res->status=nRes->status;
-	
-
-	/*free memory */
-	_free_data_result(nRes);
-	Free(nRes);
-	
-	return 0;
-
-}
-int close_statement(FOURD_RESULT *res,unsigned short int id_cmd)
-{
-	char msg[2048];	
-	FOURD *cnx=NULL;
-	FOURD_RESULT state;
-
-	if(res==NULL)
-		return 0;
-	cnx=res->cnx;
-	_clear_atrr_cnx(cnx);
-	sprintf_s(msg,2048,"%03d CLOSE-STATEMENT\r\nSTATEMENT-ID:%d\r\n\r\n",id_cmd,res->id_statement);
-	socket_send(cnx,msg);
-	if(receiv_check(cnx,&state)!=0) {
-		return 1;
-	}
-	return 0;
-}
-//return 0 if ok 1 if error
-int logout(FOURD *cnx,unsigned short int id_cmd)
-{
-	char msg[2048];
-	FOURD_RESULT state;
-	_clear_atrr_cnx(cnx);
-	sprintf_s(msg,2048,"%03d LOGOUT\r\n\r\n",id_cmd);
-	socket_send(cnx,msg);
-	if(receiv_check(cnx,&state)!=0) {
-		return 1;
-	}
-	return 0;
-}
-int quit(FOURD *cnx,unsigned short int id_cmd)
-{
-	char msg[2048];
-	FOURD_RESULT state;
-	_clear_atrr_cnx(cnx);
-	sprintf_s(msg,2048,"%03d QUIT\r\n\r\n",id_cmd);
-	socket_send(cnx,msg);
-	if(receiv_check(cnx,&state)!=0) {
-		return 1;
-	}
-	return 0;
-}
-int get(const char* msg,const char* section,char *valeur,int max_length)
-{
-	char *loc=NULL;
-	char *fin=NULL;
-	loc=strstr(msg,section);
-	if(loc==NULL) {		
-		//printf("SECTION NON TROUVEE\n");
-		return -1;
-	}
-	loc+=strlen(section);
-	loc=strstr(loc,":");
-	if(loc==NULL) {
-		//printf("PAS DE : APRES LA SECTION\n");
-		return -1;
-	}
-	loc++;
-	fin=strstr(loc,"\n");
-	if(fin==NULL) {
-		//printf("PAS DE FIN DE LIGNE\n");
-		return -1;
-	}
-	if(*(fin-1)=='\r') {
-		//Printf("IL Y A CRLF\n");
-		#ifdef WIN32
-			fin--;
-		#endif
-	}
-	
-	_snprintf_s(valeur,max_length,fin-loc,"%s",loc);
-	valeur[fin-loc]=0;
-	//printf("La section %s contient '%s'\n",section,valeur);
-	if(strstr(section,"-Base64")!=NULL) {
-		//decode la valeur
-		char *valeur_decode=NULL;
-		int len_dec=0;
-		valeur_decode=base64_decode(valeur,strlen(valeur),&len_dec);
-		valeur_decode[len_dec]=0;
-		strncpy_s(valeur,max_length,valeur_decode,(size_t)len_dec);
-		valeur[len_dec]=0;
-		free(valeur_decode);
-	}
-	return 0;
-}
-FOURD_LONG8 _get_status(const char *header,int *status, FOURD_LONG8 *error_code,char *error_string)
-{
-	char *loc=NULL,*fin=NULL,sStatus[50];
-	*status=FOURD_ERROR;
-	loc=strstr(header," ");
-	if(loc==NULL) {
-		return -1;
-	}
-	loc++;
-	fin=strstr(loc,"\n");
-	if(fin==NULL) {
-		return -1;
-	}
-	if(*(fin-1)=='\r') {
-		#ifdef WIN32
-		fin--;
-		#endif
-	}
-	_snprintf_s(sStatus,50,fin-loc,"%s",loc);
-	status[fin-loc]=0;
-	if(strcmp(sStatus,"OK")==0) {
-		//it's ok
-		*error_code=0;
-		error_string[0]=0;
-		*status=FOURD_OK;
-		return 0;
-	}
-	else {
-		//there is an error
-		*status=FOURD_ERROR;
-		{
-			char error[50];
-			get(header,"Error-Code",error,50);
-			*error_code=atoi(error);
-		}
-		get(header,"Error-Description",error_string,ERROR_STRING_LENGTH);
-		return *error_code;
-	}
-	return -1;
-}
-
-
-void _alias_str_replace(char *list_alias)
-{
-	char *loc=list_alias;
-	char *locm=NULL;
-	while((loc=strstr(loc,"] ["))!=NULL) {
-		if((loc-list_alias)>1) {
-			locm=loc;
-			locm--;
-			if(locm[0]!=']') {
-				loc[1]='\r';
-			}
-			else {
-				loc++;
-			}
-		}
-		else {
-			loc[1]='\r';
-		}
-	}
-}
-int traite_header_response(FOURD_RESULT* state)
-{
-	char *header=state->header;
-	FOURD_LONG8 ret_get_status=0;
-	//get status in the header
-	state->elmt=0;
-	ret_get_status=_get_status(state->header,&(state->status),&(state->error_code),state->error_string);
-	if(ret_get_status<0) {	
-		//Technical error in parse header status
-		return 1;
-	}
-	else if(ret_get_status>0) {
-		//The header is error-header
-		//nothing to do with error-header
-		return 1;
-	}
-	//The header is ok-header
-	//get Column-Count
-	{
-		char column_count[250];
-		if(get(header,"Column-Count",column_count,250)==0) {
-			state->row_type.nbColumn=atoi(column_count);
-			//memory allocate for column name and column type
-			state->row_type.Column=calloc(state->row_type.nbColumn,sizeof(FOURD_COLUMN));
-			Printf("Column-Count:%d\n",state->row_type.nbColumn);
-		}
-	}
-	//get Column-Types
-	{
-		char column_type[2048];
-		char *column=NULL;
-		unsigned int num=0;
-		char *context=NULL;
-		if(get(header,"Column-Types",column_type,2048)==0) {
-			Printf("Column-Types => '%s'\n",column_type);
-			column = strtok_s(column_type, " ",&context);
-			if(column!=NULL)
-			do{
-				Printf("Column %d: %s (%s)\n",num+1,column,stringFromType(typeFromString(column)));
-				if(num<state->row_type.nbColumn) {
-					state->row_type.Column[num].type=typeFromString(column);
-					strncpy_s(state->row_type.Column[num].sType,255,column,strlen(column)+1);
-				}
-				else {
-					Printf("Error: There is more column than Column-Count\n");
-				}
-				num++;
-				column = strtok_s(NULL, " ",&context);
-			}while(column!=NULL);
-			Printf("Fin de la lecture des colonnes\n");
-		}
-	}
-	//get Column-Aliases-Base64
-	{
-		char column_alias[2048];
-		char *alias=NULL;
-		unsigned int num=0;
-		char *context=NULL;
-		if(get(header,"Column-Aliases-Base64",column_alias,2048)==0) {
-			/* delete the last espace char if exist */
-			if(column_alias[strlen(column_alias)-1]==' ') {
-				column_alias[strlen(column_alias)-1]=0;
-			}
-			Printf("Column-Aliases-Base64 => '%s'\n",column_alias);
-			_alias_str_replace(column_alias);
-			alias = strtok_s(column_alias, "\r",&context);
-			if(alias!=NULL)
-			do{				
-				Printf("Alias %d: '%s'\n",num+1,alias);
-				if(num<state->row_type.nbColumn) {
-					/* erase [] */
-					if(*alias=='[' && alias[strlen(alias)-1]==']') {
-						strncpy_s(state->row_type.Column[num].sColumnName,255,alias+1,strlen(alias)-2);
-					} else {
-						strncpy_s(state->row_type.Column[num].sColumnName,255,alias,strlen(alias));
-					}					
-				}else {
-					Printf("Error: There is more alias than Column-Count\n");
-				}
-				num++;
-				alias = strtok_s(NULL, "\r",&context);
-			}while(alias!=NULL);
-			Printf("Fin de la lecture des alias\n");
-		}
-	}
-	//get Row-Count
-	{
-		char row_count[250];
-		if(get(header,"Row-Count",row_count,250)==0) {
-			state->row_count=atoi(row_count);
-			Printf("Row-Count:%d\n",state->row_count);
-		}
-	}
-	//get Row-Count-Sent
-	{
-		char row_count[250];
-		if(get(header,"Row-Count-Sent",row_count,250)==0) {
-			Printf("Row-Count-Sent:\"%s\" <=lut\n",row_count);
-			state->row_count_sent=atoi(row_count);
-			Printf("Row-Count-Sent:%d\n",state->row_count_sent);
-		}
-	}
-	//get Statement-ID
-	{
-		char statement_id[250];
-		if(get(header,"Statement-ID",statement_id,250)==0) {
-			state->id_statement=atoi(statement_id);
-			Printf("Statement-ID:%d\n",state->id_statement);
-		}
-	}
-	//Column-Updateability
-	{
-		char updateability[250];
-		state->updateability=1;
-		if(get(header,"Column-Updateability",updateability,250)==0) {
-			state->updateability=(strstr(updateability,"Y")!=NULL);
-			Printf("Column-Updateability:%s\n",updateability);
-			Printf("Column-Updateability:%d\n",state->updateability);
-		}
-	}
-	//get Result-Type
-	{
-		char result_type[250];
-		if(get(header,"Result-Type",result_type,250)==0) {
-			strstrip(result_type);
-			//if Result-Type containt more than 1 Result-type => multirequete => not supproted by this driver
-			if(strstr(result_type," ")!=NULL)
-			{
-				//multiquery not supproted by this driver
-				Printf("Result-Type:'%s'\n",result_type);
-				Printf("Position %d\n",strstr(result_type," ")-result_type);
-				Printferr("Error: Multiquery not supported\n");
-				return 1;
-			}
-			state->resultType=resultTypeFromString(result_type);
-			switch(state->resultType) {
-			case UPDATE_COUNT:
-				break;
-			case RESULT_SET:
-				break;
-			case UNKNOW:
-			default:
-				Printf("Error: %d Result-Type not supported",result_type);
-				break;
-			}
-		}
-	}
-	return 0;
-}
-
-int receiv_check(FOURD *cnx,FOURD_RESULT *state)
+#else
+	char *msg_format="%03d EXECUTE-STATEMENT\r\nSTATEMENT:%s\r\nOutput-Mode:%s\r\nFIRST-PAGE-SIZE:%i\r\nPREFERRED-IMAGE-TYPES:%s\r\nPARAMETER-TYPES:%s\r\n\r\n";
+	size_t msg_length=strlen(request)+strlen(msg_format)+strlen(image_type)+strlen(sParam)+20;
+	msg=malloc(msg_length);
+	snprintf(msg,msg_length,msg_format,id_cmd,request,"release",res_size,image_type,sParam);
+#endif
+	
+	free(sParam);
+
+	socket_send(cnx,msg);
+	free(msg);
+	socket_send_data(cnx,data,data_len);
+	if(receiv_check(cnx,res)!=0)
+		return 1;
+
+	switch(res->resultType)	{
+	case UPDATE_COUNT:
+		//get Update-count: Nb row updated
+		socket_receiv_update_count(cnx,res);		
+		_free_data_result(res);
+		break;
+	case RESULT_SET:
+		//get data
+		socket_receiv_data(cnx,res);
+		cnx->updated_row=-1;
+		if(result==NULL) {
+			_free_data_result(res);
+		}
+		break;
+	default:
+		Printferr("Error: Result-Type not supported in query");
+	}
+	//if(traite_header_reponse(cnx)!=0)
+	//	return 1;
+	if(result==NULL)
+		Free(res);
+	return 0;
+}
+/* low level commande 
+   command_index and statement_id is identify by result of execute statement commande */
+int __fetch_result(FOURD *cnx,unsigned short int id_cmd,int statement_id,int command_index,unsigned int first_row,unsigned int last_row,FOURD_RESULT *result)
+{
+	char msg[2048];
+	
+	
+	_clear_atrr_cnx(cnx);
+
+	if(result==NULL) {
+		return 0;
+	}
+	sprintf_s(msg,2048,"%03d FETCH-RESULT\r\nSTATEMENT-ID:%d\r\nCOMMAND-INDEX:%03d\r\nFIRST-ROW-INDEX:%d\r\nLAST-ROW-INDEX:%d\r\nOutput-Mode:%s\r\n\r\n",id_cmd,statement_id,command_index,first_row,last_row,"release");
+	socket_send(cnx,msg);
+	if(receiv_check(cnx,result)!=0)
+		return 1;
+	socket_receiv_data(cnx,result);
+
+	return 0;
+}
+/*get next row set in result_set*/
+int _fetch_result(FOURD_RESULT *res,unsigned short int id_cmd)
+{
+	FOURD *cnx=res->cnx;
+	FOURD_RESULT *nRes=NULL;
+	void *last_data=NULL;
+	//int id_statement=res->id_statement;
+	unsigned int first_row=res->first_row+res->row_count_sent;
+	unsigned int last_row=res->first_row+res->row_count_sent+99;
+	if(last_row>=res->row_count) {
+		last_row=res->row_count-1;
+	}
+
+	nRes=calloc(1,sizeof(FOURD_RESULT));
+	_clear_atrr_cnx(cnx);
+	/*set paramature unsed in socket_receiv */
+	nRes->first_row=first_row;
+	nRes->row_count_sent=last_row-first_row+1;
+	nRes->cnx=res->cnx;
+	nRes->row_type=res->row_type;
+	nRes->updateability=res->updateability;
+	/*get new Result set in new FOURD_RESULT*/
+	if(__fetch_result(cnx,123,res->id_statement,0,first_row,last_row,nRes)){
+		return 1;
+	}
+	/*switch data between res and nRes FOURD_RESULT*/
+	last_data=res->elmt;
+	res->elmt=nRes->elmt;
+	nRes->elmt=last_data;	/*important for free memory after */
+	res->first_row=first_row;
+	res->row_count_sent=last_row-first_row+1;
+	res->error_code=nRes->error_code;
+	last_data=res->error_string;
+	sprintf_s(res->error_string,sizeof(res->error_string),"%s",nRes->error_string);
+	res->status=nRes->status;
+	
+
+	/*free memory */
+	_free_data_result(nRes);
+	Free(nRes);
+	
+	return 0;
+
+}
+int close_statement(FOURD_RESULT *res,unsigned short int id_cmd)
+{
+	char msg[2048];	
+	FOURD *cnx=NULL;
+	FOURD_RESULT state;
+
+	if(res==NULL)
+		return 0;
+	cnx=res->cnx;
+	_clear_atrr_cnx(cnx);
+	sprintf_s(msg,2048,"%03d CLOSE-STATEMENT\r\nSTATEMENT-ID:%d\r\n\r\n",id_cmd,res->id_statement);
+	socket_send(cnx,msg);
+	if(receiv_check(cnx,&state)!=0) {
+		return 1;
+	}
+	return 0;
+}
+//return 0 if ok 1 if error
+int dblogout(FOURD *cnx,unsigned short int id_cmd)
+{
+	char msg[2048];
+	FOURD_RESULT state;
+	_clear_atrr_cnx(cnx);
+	sprintf_s(msg,2048,"%03d LOGOUT\r\n\r\n",id_cmd);
+	socket_send(cnx,msg);
+	if(receiv_check(cnx,&state)!=0) {
+		return 1;
+	}
+	return 0;
+}
+int quit(FOURD *cnx,unsigned short int id_cmd)
+{
+	char msg[2048];
+	FOURD_RESULT state;
+	_clear_atrr_cnx(cnx);
+	sprintf_s(msg,2048,"%03d QUIT\r\n\r\n",id_cmd);
+	socket_send(cnx,msg);
+	if(receiv_check(cnx,&state)!=0) {
+		return 1;
+	}
+	return 0;
+}
+int get(const char* msg,const char* section,char *valeur,int max_length)
 {
+	char *loc=NULL;
+	char *fin=NULL;
+	loc=strstr(msg,section);
+	if(loc==NULL) {		
+		//printf("SECTION NON TROUVEE\n");
+		return -1;
+	}
+	loc+=strlen(section);
+	loc=strstr(loc,":");
+	if(loc==NULL) {
+		//printf("PAS DE : APRES LA SECTION\n");
+		return -1;
+	}
+	loc++;
+	fin=strstr(loc,"\n");
+	if(fin==NULL) {
+		//printf("PAS DE FIN DE LIGNE\n");
+		return -1;
+	}
+	if(*(fin-1)=='\r') {
+		//Printf("IL Y A CRLF\n");
+		#ifdef WIN32
+			fin--;
+		#endif
+	}
 	
+	_snprintf_s(valeur,max_length,fin-loc,"%s",loc);
+	valeur[fin-loc]=0;
+	//printf("La section %s contient '%s'\n",section,valeur);
+	if(strstr(section,"-Base64")!=NULL) {
+		//decode la valeur
+		unsigned char *valeur_decode=NULL;
+		int len_dec=0;
+		valeur_decode=base64_decode(valeur,strlen(valeur),&len_dec);
+		valeur_decode[len_dec]=0;
+		strncpy_s(valeur,max_length,(const char*)valeur_decode,(size_t)len_dec);
+		valeur[len_dec]=0;
+		free(valeur_decode);
+	}
+	return 0;
+}
+FOURD_LONG8 _get_status(const char *header,int *status, FOURD_LONG8 *error_code,char *error_string)
+{
+	char *loc=NULL,*fin=NULL,sStatus[50];
+	*status=FOURD_ERROR;
+	loc=strstr(header," ");
+	if(loc==NULL) {
+		return -1;
+	}
+	loc++;
+	fin=strstr(loc,"\n");
+	if(fin==NULL) {
+		return -1;
+	}
+	if(*(fin-1)=='\r') {
+		#ifdef WIN32
+		fin--;
+		#endif
+	}
+	_snprintf_s(sStatus,50,fin-loc,"%s",loc);
+	status[fin-loc]=0;
+	if(strcmp(sStatus,"OK")==0) {
+		//it's ok
+		*error_code=0;
+		error_string[0]=0;
+		*status=FOURD_OK;
+		return 0;
+	}
+	else {
+		//there is an error
+		*status=FOURD_ERROR;
+		{
+			char error[50];
+			get(header,"Error-Code",error,50);
+			*error_code=atoi(error);
+		}
+		get(header,"Error-Description",error_string,ERROR_STRING_LENGTH);
+		return *error_code;
+	}
+	return -1;
+}
+
+
+void _alias_str_replace(char *list_alias)
+{
+	char *loc=list_alias;
+	char *locm=NULL;
+	while((loc=strstr(loc,"] ["))!=NULL) {
+		if((loc-list_alias)>1) {
+			locm=loc;
+			locm--;
+			if(locm[0]!=']') {
+				loc[1]='\r';
+			}
+			else {
+				loc++;
+			}
+		}
+		else {
+			loc[1]='\r';
+		}
+	}
+}
+int traite_header_response(FOURD_RESULT* state)
+{
+	char *header=state->header;
+	FOURD_LONG8 ret_get_status=0;
+	//get status in the header
+	state->elmt=0;
+	ret_get_status=_get_status(state->header,&(state->status),&(state->error_code),state->error_string);
+	if(ret_get_status<0) {	
+		//Technical error in parse header status
+		return 1;
+	}
+	else if(ret_get_status>0) {
+		//The header is error-header
+		//nothing to do with error-header
+		return 1;
+	}
+	//The header is ok-header
+	//get Column-Count
+	{
+		char column_count[250];
+		if(get(header,"Column-Count",column_count,250)==0) {
+			state->row_type.nbColumn=atoi(column_count);
+			//memory allocate for column name and column type
+			state->row_type.Column=calloc(state->row_type.nbColumn,sizeof(FOURD_COLUMN));
+			Printf("Column-Count:%d\n",state->row_type.nbColumn);
+		}
+	}
+	//get Column-Types
+	{
+		char column_type[2048];
+		char *column=NULL;
+		unsigned int num=0;
+		//char *context=NULL;
+		if(get(header,"Column-Types",column_type,2048)==0) {
+			Printf("Column-Types => '%s'\n",column_type);
+			column = strtok_s(column_type, " ",&context);
+			if(column!=NULL)
+			do{
+				Printf("Column %d: %s (%s)\n",num+1,column,stringFromType(typeFromString(column)));
+				if(num<state->row_type.nbColumn) {
+					state->row_type.Column[num].type=typeFromString(column);
+					strncpy_s(state->row_type.Column[num].sType,255,column,strlen(column)+1);
+				}
+				else {
+					Printf("Error: There is more column than Column-Count\n");
+				}
+				num++;
+				column = strtok_s(NULL, " ",&context);
+			}while(column!=NULL);
+			Printf("Fin de la lecture des colonnes\n");
+		}
+	}
+	//get Column-Aliases-Base64
+	{
+		char column_alias[2048];
+		char *alias=NULL;
+		unsigned int num=0;
+		//char *context=NULL;
+		if(get(header,"Column-Aliases-Base64",column_alias,2048)==0) {
+			/* delete the last espace char if exist */
+			if(column_alias[strlen(column_alias)-1]==' ') {
+				column_alias[strlen(column_alias)-1]=0;
+			}
+			Printf("Column-Aliases-Base64 => '%s'\n",column_alias);
+			_alias_str_replace(column_alias);
+			alias = strtok_s(column_alias, "\r",&context);
+			if(alias!=NULL)
+			do{				
+				Printf("Alias %d: '%s'\n",num+1,alias);
+				if(num<state->row_type.nbColumn) {
+					/* erase [] */
+					if(*alias=='[' && alias[strlen(alias)-1]==']') {
+						strncpy_s(state->row_type.Column[num].sColumnName,255,alias+1,strlen(alias)-2);
+					} else {
+						strncpy_s(state->row_type.Column[num].sColumnName,255,alias,strlen(alias));
+					}					
+				}else {
+					Printf("Error: There is more alias than Column-Count\n");
+				}
+				num++;
+				alias = strtok_s(NULL, "\r",&context);
+			}while(alias!=NULL);
+			Printf("Fin de la lecture des alias\n");
+		}
+	}
+	//get Row-Count
+	{
+		char row_count[250];
+		if(get(header,"Row-Count",row_count,250)==0) {
+			state->row_count=atoi(row_count);
+			Printf("Row-Count:%d\n",state->row_count);
+		}
+	}
+	//get Row-Count-Sent
+	{
+		char row_count[250];
+		if(get(header,"Row-Count-Sent",row_count,250)==0) {
+			Printf("Row-Count-Sent:\"%s\" <=lut\n",row_count);
+			state->row_count_sent=atoi(row_count);
+			Printf("Row-Count-Sent:%d\n",state->row_count_sent);
+		}
+	}
+	//get Statement-ID
+	{
+		char statement_id[250];
+		if(get(header,"Statement-ID",statement_id,250)==0) {
+			state->id_statement=atoi(statement_id);
+			Printf("Statement-ID:%d\n",state->id_statement);
+		}
+	}
+	//Column-Updateability
+	{
+		char updateability[250];
+		//state->updateability=1;
+		if(get(header,"Column-Updateability",updateability,250)==0) {
+			state->updateability=(strstr(updateability,"Y")!=NULL);
+			Printf("Column-Updateability:%s\n",updateability);
+			Printf("Column-Updateability:%d\n",state->updateability);
+		}
+	}
+	//get Result-Type
+	{
+		char result_type[250];
+		if(get(header,"Result-Type",result_type,250)==0) {
+			strstrip(result_type);
+			//if Result-Type containt more than 1 Result-type => multirequete => not supproted by this driver
+			if(strstr(result_type," ")!=NULL)
+			{
+				//multiquery not supproted by this driver
+				Printf("Result-Type:'%s'\n",result_type);
+				Printf("Position %d\n",strstr(result_type," ")-result_type);
+				Printferr("Error: Multiquery not supported\n");
+				return 1;
+			}
+			state->resultType=resultTypeFromString(result_type);
+			switch(state->resultType) {
+			case UPDATE_COUNT:
+				break;
+			case RESULT_SET:
+				break;
+			case UNKNOW:
+			default:
+				Printf("Error: %d Result-Type not supported",result_type);
+				break;
+			}
+		}
+	}
+	return 0;
+}
+
+int receiv_check(FOURD *cnx,FOURD_RESULT *state)
+{
 	socket_receiv_header(cnx,state);
 	if(traite_header_response(state)!=0) {
-		Printferr("Error in traite_header_response\n");
-		cnx->status=state->status;
-		cnx->error_code=state->error_code;
-		//_snprintf_s(cnx->error_string,ERROR_STRING_LENGTH,strlen(state->error_string),"%s",state->error_string);
-		_snprintf(cnx->error_string,ERROR_STRING_LENGTH,"%s",state->error_string);
-		//strncpy_s(cnx->error_string,ERROR_STRING_LENGTH,state->error_string,strlen(state->error_string));
-		//printf("traite_header_response return 1=> une erreur\n");
-		return 1;
-	}
-	cnx->status=state->status;
-	cnx->error_code=state->error_code;
-	strncpy_s(cnx->error_string,ERROR_STRING_LENGTH,state->error_string,ERROR_STRING_LENGTH);
-	return 0;
-}
-void _clear_atrr_cnx(FOURD *cnx)
-{
-	cnx->error_code=0L;
-	strcpy_s(cnx->error_string,ERROR_STRING_LENGTH,"");
-	cnx->updated_row=0L;
-}
-void _free_data_result(FOURD_RESULT *res)
-{
-	//res->elmt
-	unsigned int nbCol=res->row_type.nbColumn;
-	unsigned int nbRow=res->row_count_sent;
-	unsigned int nbElmt=nbCol*nbRow;
-	unsigned int i=0;
-	FOURD_ELEMENT *pElmt=res->elmt;
-	if(pElmt==NULL) {
-		return;
-	}
-	for(i=0;i<nbElmt;i++,pElmt++) {
-		switch(pElmt->type) {
-			case VK_BOOLEAN:
-			case VK_BYTE:
-			case VK_WORD:
-			case VK_LONG:
-			case VK_LONG8:
-			case VK_REAL:
-			case VK_DURATION:
-			case VK_TIMESTAMP:
-			case VK_FLOAT:
-				Free(pElmt->pValue);
-				break;
-			case VK_STRING:
-				FreeString((FOURD_STRING *)pElmt->pValue);						
-				break;
-			case VK_BLOB:
-				FreeBlob((FOURD_BLOB *)pElmt->pValue);
-				break;
-			case VK_IMAGE:
-				Printferr("Image-Type not supported\n");
-				break;
-		}
-	}
-}
-void *_copy(FOURD_TYPE type,void *org)
-{
-	void *buff=NULL;
-	int size=0;
-	if(org!=NULL)
-	{
-		switch(type) {
-			case VK_BOOLEAN:
-			case VK_BYTE:
-			case VK_WORD:
-			case VK_LONG:
-				Printf("*******Bind %d ********\n",*(FOURD_LONG*)org);
-			case VK_LONG8:
-			case VK_REAL:
-			case VK_DURATION:
-			case VK_TIMESTAMP:
-				buff=calloc(1,vk_sizeof(type));
-				memcpy(buff,org,vk_sizeof(type));
-				break;
-			case VK_FLOAT:
-				{
-					FOURD_FLOAT *f=org;
-					FOURD_FLOAT *cp=NULL;
-					cp=calloc(1,sizeof(FOURD_FLOAT));
-					cp->data=calloc(1,f->data_length);
-					cp->exp=f->exp;
-					cp->sign=f->sign;
-					cp->data_length=f->data_length;
-					memcpy(cp->data,f->data,f->data_length);
-					buff=cp;
-				}
-				break;
-			case VK_STRING:
-				{
-					FOURD_STRING *src=org;
-					FOURD_STRING *cp=NULL;
-					cp=calloc(1,sizeof(FOURD_STRING));
-					cp->data=calloc(src->length,2);	/* 2 bytes per char */
-					cp->length=src->length;
-					memcpy(cp->data,src->data,src->length*2);  /* 2 bytes per char */
-					buff=cp;
-				}
-				break;
-			case VK_BLOB:
-				{
-					FOURD_BLOB *src=org;
-					FOURD_BLOB *cp=NULL;
-					cp=calloc(1,sizeof(FOURD_BLOB));
-					cp->data=calloc(src->length,1);	
-					cp->length=src->length;
-					memcpy(cp->data,src->data,src->length);
-					buff=cp;
-				}
-				break;
-			case VK_IMAGE:
-				Printferr("Image-Type not supported\n");
-				break;
-		}
-	}
-	return buff;
-}
-char *_serialize(char *data,int *size, FOURD_TYPE type, void *pObj)
-{
-	int lSize=0;
-	if(pObj!=NULL) {
-		switch(type) {
-			case VK_BOOLEAN:
-			case VK_BYTE:
-			case VK_WORD:
-			case VK_LONG:
-				Printf("*******Serialize %d ********\n",*(FOURD_LONG*)pObj);
-			case VK_LONG8:
-			case VK_REAL:
-			case VK_DURATION: 
-				lSize=vk_sizeof(type);
-				data=realloc(data,(*size)+lSize);
-				memcpy(data+*size,pObj,lSize);
-				*size+=lSize;
-				break;
-			case VK_TIMESTAMP:/* Use other procedure for serialize this one because structure can align */
-				{
-					FOURD_TIMESTAMP *o=pObj;
-					lSize=sizeof(o->year)+sizeof(o->mounth)+sizeof(o->day)+sizeof(o->milli);
-					data=realloc(data,(*size)+lSize);
-					memcpy(data+*size,&(o->year),2);
-					memcpy(data+*size+2,&(o->year),1);
-					memcpy(data+*size+3,&(o->year),1);
-					memcpy(data+*size+4,&(o->year),4);
-					*size+=lSize;
-				}
-				break;
-			case VK_FLOAT:
-				{
-					FOURD_FLOAT *o=pObj;
-					lSize=sizeof(o->exp)+sizeof(o->sign)+sizeof(o->data_length)+o->data_length;
-					data=realloc(data,(*size)+lSize);
-					memcpy(data+*size,&(o->exp),4);
-					memcpy(data+*size+4,&(o->sign),1);
-					memcpy(data+*size+5,&(o->data_length),4);
-					memcpy(data+*size+9,o->data,o->data_length);
-					*size+=lSize;
-				}
-				break;
-			case VK_STRING:
-				{
-					FOURD_STRING *o=pObj;
-					int len=o->length;
-					len=-len;
-					lSize=sizeof(o->length)+o->length*2;
-					data=realloc(data,(*size)+lSize);
-					memcpy(data+*size,&len,4);
-					memcpy(data+*size+4,o->data,o->length*2);
-					*size+=lSize;
-				}
-				break;
-			case VK_BLOB:
-				{
-					FOURD_BLOB *o=pObj;
-					lSize=sizeof(o->length)+o->length*2;
-					data=realloc(data,(*size)+lSize);
-					memcpy(data+*size,&(o->length),4);
-					memcpy(data+*size+4,o->data,o->length*2);
-					*size+=lSize;
-				}
-				break;
-			case VK_IMAGE:
-				Printferr("Image-Type not supported\n");
-				break;
-		}
-	}
-	return data;
-}void Free(void *p)
-{
-	if(p) {
-		free(p);
-		p=NULL;
-	}
-}
-void FreeFloat(FOURD_FLOAT *p)
-{
-	if(p) {
-		Free(p->data);
-		Free(p); 
-	}
-}
-void FreeString(FOURD_STRING *p)
-{
-	if(p) {
-		Free(p->data);
-		Free(p); 
-	}
-}
-void FreeBlob(FOURD_BLOB *p)
-{
-	if(p) {
-		Free(p->data);
-		Free(p);
-	}
-}
-void PrintData(const void *data,unsigned int size)
-{
-	const char *d=data;
-	unsigned int i=0;
-	if(size>=1)
-		Printf("0x%X",*(char *)(d+i));
-	for(i=1;i<size;i++) {
-		Printf(" 0x%X",*(char *)(d+i));
-	}
-}
\ No newline at end of file
+		Printferr("Error in traite_header_response\n");
+		cnx->status=state->status;
+		cnx->error_code=state->error_code;
+		//_snprintf_s(cnx->error_string,ERROR_STRING_LENGTH,strlen(state->error_string),"%s",state->error_string);
+		_snprintf(cnx->error_string,ERROR_STRING_LENGTH,"%s",state->error_string);
+		//strncpy_s(cnx->error_string,ERROR_STRING_LENGTH,state->error_string,strlen(state->error_string));
+		//printf("traite_header_response return 1=> une erreur\n");
+		return 1;
+	}
+	cnx->status=state->status;
+	cnx->error_code=state->error_code;
+	strncpy_s(cnx->error_string,ERROR_STRING_LENGTH,state->error_string,ERROR_STRING_LENGTH);
+	return 0;
+}
+void _clear_atrr_cnx(FOURD *cnx)
+{
+	cnx->error_code=0L;
+	strcpy_s(cnx->error_string,ERROR_STRING_LENGTH,"");
+	cnx->updated_row=0L;
+}
+void _free_data_result(FOURD_RESULT *res)
+{
+	//res->elmt
+	unsigned int nbCol=res->row_type.nbColumn;
+	unsigned int nbRow=res->row_count_sent;
+	unsigned int nbElmt=nbCol*nbRow;
+	unsigned int i=0;
+	FOURD_ELEMENT *pElmt=res->elmt;
+	if(pElmt==NULL) {
+		return;
+	}
+	for(i=0;i<nbElmt;i++,pElmt++) {
+		switch(pElmt->type) {
+			case VK_BOOLEAN:
+			case VK_BYTE:
+			case VK_WORD:
+			case VK_LONG:
+			case VK_LONG8:
+			case VK_REAL:
+			case VK_DURATION:
+			case VK_TIMESTAMP:
+			case VK_FLOAT:
+				Free(pElmt->pValue);
+				break;
+			case VK_STRING:
+				FreeString((FOURD_STRING *)pElmt->pValue);						
+				break;
+			case VK_BLOB:
+				FreeBlob((FOURD_BLOB *)pElmt->pValue);
+				break;
+			case VK_IMAGE:
+				Printferr("Image-Type not supported\n");
+				break;
+			default:
+				break;
+		}
+	}
+}
+void *_copy(FOURD_TYPE type,void *org)
+{
+	void *buff=NULL;
+	//int size=0;
+	if(org!=NULL)
+	{
+		switch(type) {
+			case VK_BOOLEAN:
+			case VK_BYTE:
+			case VK_WORD:
+			case VK_LONG:
+				Printf("*******Bind %d ********\n",*(FOURD_LONG*)org);
+			case VK_LONG8:
+			case VK_REAL:
+			case VK_DURATION:
+			case VK_TIMESTAMP:
+				buff=calloc(1,vk_sizeof(type));
+				memcpy(buff,org,vk_sizeof(type));
+				break;
+			case VK_FLOAT:
+				{
+					FOURD_FLOAT *f=org;
+					FOURD_FLOAT *cp=NULL;
+					cp=calloc(1,sizeof(FOURD_FLOAT));
+					cp->data=calloc(1,f->data_length);
+					cp->exp=f->exp;
+					cp->sign=f->sign;
+					cp->data_length=f->data_length;
+					memcpy(cp->data,f->data,f->data_length);
+					buff=cp;
+				}
+				break;
+			case VK_STRING:
+				{
+					FOURD_STRING *src=org;
+					FOURD_STRING *cp=NULL;
+					cp=calloc(1,sizeof(FOURD_STRING));
+					cp->data=calloc(src->length,2);	/* 2 bytes per char */
+					cp->length=src->length;
+					memcpy(cp->data,src->data,src->length*2);  /* 2 bytes per char */
+					buff=cp;
+				}
+				break;
+			case VK_BLOB:
+				{
+					FOURD_BLOB *src=org;
+					FOURD_BLOB *cp=NULL;
+					cp=calloc(1,sizeof(FOURD_BLOB));
+					cp->data=calloc(src->length,1);	
+					cp->length=src->length;
+					memcpy(cp->data,src->data,src->length);
+					buff=cp;
+				}
+				break;
+			case VK_IMAGE:
+				Printferr("Image-Type not supported\n");
+				break;
+			default:
+				break;
+		}
+	}
+	return buff;
+}
+char *_serialize(char *data,unsigned int *size, FOURD_TYPE type, void *pObj)
+{
+	int lSize=0;
+	if(pObj!=NULL) {
+		switch(type) {
+			case VK_BOOLEAN:
+			case VK_BYTE:
+			case VK_WORD:
+			case VK_LONG:
+				Printf("*******Serialize %d ********\n",*(FOURD_LONG*)pObj);
+			case VK_LONG8:
+			case VK_REAL:
+			case VK_DURATION: 
+				lSize=vk_sizeof(type);
+				data=realloc(data,(*size)+lSize);
+				memcpy(data+*size,pObj,lSize);
+				*size+=lSize;
+				break;
+			case VK_TIMESTAMP:/* Use other procedure for serialize this one because structure can align */
+				{
+					FOURD_TIMESTAMP *o=pObj;
+					lSize=sizeof(o->year)+sizeof(o->mounth)+sizeof(o->day)+sizeof(o->milli);
+					data=realloc(data,(*size)+lSize);
+					memcpy(data+*size,&(o->year),2);
+					memcpy(data+*size+2,&(o->year),1);
+					memcpy(data+*size+3,&(o->year),1);
+					memcpy(data+*size+4,&(o->year),4);
+					*size+=lSize;
+				}
+				break;
+			case VK_FLOAT:
+				{
+					FOURD_FLOAT *o=pObj;
+					lSize=sizeof(o->exp)+sizeof(o->sign)+sizeof(o->data_length)+o->data_length;
+					data=realloc(data,(*size)+lSize);
+					memcpy(data+*size,&(o->exp),4);
+					memcpy(data+*size+4,&(o->sign),1);
+					memcpy(data+*size+5,&(o->data_length),4);
+					memcpy(data+*size+9,o->data,o->data_length);
+					*size+=lSize;
+				}
+				break;
+			case VK_STRING:
+				{
+					FOURD_STRING *o=pObj;
+					int len=o->length;
+					len=-len;
+					lSize=sizeof(o->length)+o->length*2;
+					data=realloc(data,(*size)+lSize);
+					memcpy(data+*size,&len,4);
+					memcpy(data+*size+4,o->data,o->length*2);
+					*size+=lSize;
+				}
+				break;
+			case VK_BLOB:
+				{
+					FOURD_BLOB *o=pObj;
+					lSize=sizeof(o->length)+o->length*2;
+					data=realloc(data,(*size)+lSize);
+					memcpy(data+*size,&(o->length),4);
+					memcpy(data+*size+4,o->data,o->length*2);
+					*size+=lSize;
+				}
+				break;
+			case VK_IMAGE:
+				Printferr("Image-Type not supported\n");
+				break;
+			default:
+				break;
+		}
+	}
+	return data;
+}void Free(void *p)
+{
+	if(p) {
+		free(p);
+		p=NULL;
+	}
+}
+void FreeFloat(FOURD_FLOAT *p)
+{
+	if(p) {
+		Free(p->data);
+		Free(p); 
+	}
+}
+void FreeString(FOURD_STRING *p)
+{
+	if(p) {
+		Free(p->data);
+		Free(p); 
+	}
+}
+void FreeBlob(FOURD_BLOB *p)
+{
+	if(p) {
+		Free(p->data);
+		Free(p);
+	}
+}
+void PrintData(const void *data,unsigned int size)
+{
+	const char *d=data;
+	unsigned int i=0;
+	if(size>=1)
+		Printf("0x%X",*(char *)(d+i));
+	for(i=1;i<size;i++) {
+		Printf(" 0x%X",*(char *)(d+i));
+	}
+}
+int _is_multi_query(const char *request)
+{
+	int i=0;
+	size_t len;
+	int inCol=0;
+	int inStr=0;
+	int finFirst=0;
+	char car=0;
+	if(request==NULL){
+		return 0;
+	}
+	len=strlen(request);
+	if(len<1){
+		return 0;
+	}
+	for(i=0;i<len;i++){
+		
+		car=request[i];
+		switch(car){
+			case '[':
+				/* start of 4D object name */
+				if(!inStr){
+					if(!inCol){
+						/* printf("["); */
+						inCol=1;
+					}
+					else {
+						/* printf("_"); */
+					}
+				}else {
+					/* printf("s"); */
+				}
+				break;
+			case ']':
+				if(inStr){
+					/* printf("s"); */
+				}else if(inCol){
+					inCol=0;
+					/* printf("]"); */
+				}else {
+					if(i>1){ /* check the previous charactere */
+						if(request[i-1]==']'){
+							/* not end of colomn name */
+							inCol=1;
+							/* printf("-"); */
+						}else {
+							inCol=0;
+							/* printf("]"); */
+						}
+					}else {
+						/* printf("_");*/
+					}
+				}
+				
+				break;
+			case '\'':
+				if(!inCol){
+				/* printf("'");*/
+				if(inStr==0){
+					inStr=1;
+				}else{
+					inStr=0;
+				}
+				}else{
+					/* printf("c"); */
+				}
+				break;
+			case ';':
+				/* end of query */
+				if(!inCol && !inStr){
+					finFirst=1;
+					/* printf(";");*/
+				}else {
+					/*printf("_");*/
+				}
+				break;
+			default:
+				if(inCol){
+					/* printf("C"); */
+				}
+				else if(inStr){
+					/* printf("S"); */
+				}
+				else if(car==' '){
+					/*printf(" ");*/
+				}else{
+					if(finFirst){
+						/* printf("X"); */
+						return 1;
+					}else {
+						/* printf("*"); */
+					}
+				}
+				break;
+		}
+		
+	}
+	return 0;
+}
+int _valid_query(FOURD *cnx,const char *request)
+{
+	if(_is_multi_query(request)){
+		cnx->error_code=-5001;
+		sprintf_s(cnx->error_string,2048,"MultiQuery not supported",2048);
+		return 0;
+	}
+	return 1;
+}
diff --git a/lib4d_sql/fourd_result.c b/lib4d_sql/fourd_result.c
index 4648553..2c72a77 100644
--- a/lib4d_sql/fourd_result.c
+++ b/lib4d_sql/fourd_result.c
@@ -1,6 +1,35 @@
-#include "fourd.h"
-#include "fourd_int.h"
-FOURD_LONG8 fourd_num_rows(FOURD_RESULT *result)
-{
-	return result->row_count;
+/*
+  +----------------------------------------------------------------------+
+  | lib4D_SQL                                                            |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2009 The PHP Group                                     |
+  +----------------------------------------------------------------------+
+  |                                                                      |
+  | This source file is subject to version 3.01 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available through the world-wide-web at the following url:           |
+  | http://www.php.net/license/3_01.txt                                  |
+  |                                                                      |
+  | Its original copy is usable under several licenses and is available  |
+  | through the world-wide-web at the following url:                     |
+  | http://freshmeat.net/projects/lib4d_sql                              |
+  |                                                                      |
+  | Unless required by applicable law or agreed to in writing, software  |
+  | distributed under the License is distributed on an "AS IS" BASIS,    |
+  | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or      |
+  | implied. See the License for the specific language governing         |
+  | permissions and limitations under the License.                       |
+  +----------------------------------------------------------------------+
+  | Contributed by: 4D <php@4d.fr>, http://www.4d.com                    |
+  |                 Alter Way, http://www.alterway.fr                    |
+  | Authors: Stephane Planquart <stephane.planquart@o4db.com>            |
+  |          Alexandre Morgaut <php@4d.fr>                               |
+  +----------------------------------------------------------------------+
+*/
+
+#include "fourd.h"
+#include "fourd_int.h"
+FOURD_LONG8 fourd_num_rows(FOURD_RESULT *result)
+{
+	return result->row_count;
 }
\ No newline at end of file
diff --git a/lib4d_sql/fourd_type.c b/lib4d_sql/fourd_type.c
index d1a9eda..e62b0c7 100644
--- a/lib4d_sql/fourd_type.c
+++ b/lib4d_sql/fourd_type.c
@@ -1,137 +1,173 @@
-#include <stdio.h>
-#include <string.h>
-
-extern int Printf(const char* format,...);
-extern int Printferr(const char* format,...);
-#include "fourd.h"
-FOURD_TYPE typeFromString(const char *type)
-{
-	if(strcmp(type,"VK_BOOLEAN")==0)
-		return VK_BOOLEAN;  
-	if(strcmp(type,"VK_BYTE")==0)
-		return VK_BYTE;       
-	if(strcmp(type,"VK_WORD")==0)
-		return VK_WORD;      
-	if(strcmp(type,"VK_LONG")==0)
-		return VK_LONG;       
-	if(strcmp(type,"VK_LONG8")==0)
-		return VK_LONG8;      
-	if(strcmp(type,"VK_REAL")==0)
-		return VK_REAL;       
-	if(strcmp(type,"VK_FLOAT")==0)
-		return VK_FLOAT;      
-	if(strcmp(type,"VK_TIMESTAMP")==0)
-		return VK_TIMESTAMP;  
-	if(strcmp(type,"VK_TIME")==0)
-		return VK_TIMESTAMP;  
-	if(strcmp(type,"VK_DURATION")==0)
-		return VK_DURATION;   
-	if(strcmp(type,"VK_TEXT")==0)
-		return VK_STRING;     
-	if(strcmp(type,"VK_STRING")==0)
-		return VK_STRING;     
-	if(strcmp(type,"VK_BLOB")==0)
-		return VK_BLOB;       
-	if(strcmp(type,"VK_IMAGE")==0)
-		return VK_IMAGE;      
-	return VK_UNKNOW;
-}
-const char* stringFromType(FOURD_TYPE type)
-{
-	switch(type)
-	{
-	case VK_BOOLEAN:
-		return "VK_BOOLEAN";
-	case VK_BYTE:
-		return "VK_BYTE";
-	case VK_WORD:
-		return "VK_WORD";
-	case VK_LONG:
-		return "VK_LONG";
-	case VK_LONG8:
-		return "VK_LONG8";
-	case VK_REAL:
-		return "VK_REAL";
-	case VK_FLOAT:
-		return "VK_FLOAT";
-	case VK_TIMESTAMP:
-		return "VK_TIMESTAMP";
-	case VK_TIME:
-		return "VK_TIME";
-	case VK_DURATION:
-		return "VK_DURATION";
-	case VK_STRING:
-		return "VK_STRING";
-	case VK_BLOB:
-		return "VK_BLOB";
-	case VK_IMAGE:
-		return "VK_IMAGE";
-	default:
-		return "VK_UNKNOW";
-		break;
-	}
-}
-/******************************************************************/
-/* vk_sizeof                                                      */
-/******************************************************************/
-/* return sizeof type or -1 if varying length or 0 if unknow type */
-/******************************************************************/
-int vk_sizeof(FOURD_TYPE type)
-{
-	switch(type)
-	{
-	case VK_BOOLEAN:
-	case VK_BYTE:
-	case VK_WORD:
-		return 2;
-		break;
-	case VK_LONG:
-		return 4;
-		break;
-	case VK_LONG8:
-	case VK_REAL:
-	case VK_DURATION:
-		return 8;
-		break;
-	case VK_FLOAT:
-		//Varying length
-		return -1;
-		break;
-	case VK_TIME:
-	case VK_TIMESTAMP:	
-		return 8;
-		break;
-	case VK_TEXT:
-	case VK_STRING:
-	case VK_BLOB:
-	case VK_IMAGE:
-		//Varying length
-		return -1;
-		break;
-	}
-	//error type not found
-	Printf("Error: Unknow type in vk_sizeof function\n");
-	return 0;
-}
-
-FOURD_RESULT_TYPE resultTypeFromString(const char *type)
-{
-	if(strcmp(type,"Update-Count")==0)
-		return UPDATE_COUNT; 
-	if(strcmp(type,"Result-Set")==0)
-		return RESULT_SET; 
-	return UNKNOW;
-}
-const char* stringFromResultType(FOURD_RESULT_TYPE type)
-{
-	switch(type)
-	{
-	case UPDATE_COUNT:
-		return "Update-Count";
-		break;
-	case RESULT_SET:
-		return "Result-Set";
-		break;
-	}
-	return "Unknow";
+/*
+  +----------------------------------------------------------------------+
+  | lib4D_SQL                                                            |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2009 The PHP Group                                     |
+  +----------------------------------------------------------------------+
+  |                                                                      |
+  | This source file is subject to version 3.01 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available through the world-wide-web at the following url:           |
+  | http://www.php.net/license/3_01.txt                                  |
+  |                                                                      |
+  | Its original copy is usable under several licenses and is available  |
+  | through the world-wide-web at the following url:                     |
+  | http://freshmeat.net/projects/lib4d_sql                              |
+  |                                                                      |
+  | Unless required by applicable law or agreed to in writing, software  |
+  | distributed under the License is distributed on an "AS IS" BASIS,    |
+  | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or      |
+  | implied. See the License for the specific language governing         |
+  | permissions and limitations under the License.                       |
+  +----------------------------------------------------------------------+
+  | Contributed by: 4D <php@4d.fr>, http://www.4d.com                    |
+  |                 Alter Way, http://www.alterway.fr                    |
+  | Authors: Stephane Planquart <stephane.planquart@o4db.com>            |
+  |          Alexandre Morgaut <php@4d.fr>                               |
+  +----------------------------------------------------------------------+
+*/
+
+#include <stdio.h>
+#include <string.h>
+
+extern int Printf(const char* format,...);
+extern int Printferr(const char* format,...);
+#include "fourd.h"
+FOURD_TYPE typeFromString(const char *type)
+{
+	if(strcmp(type,"VK_BOOLEAN")==0)
+		return VK_BOOLEAN;  
+	if(strcmp(type,"VK_BYTE")==0)
+		return VK_BYTE;       
+	if(strcmp(type,"VK_WORD")==0)
+		return VK_WORD;      
+	if(strcmp(type,"VK_LONG")==0)
+		return VK_LONG;       
+	if(strcmp(type,"VK_LONG8")==0)
+		return VK_LONG8;      
+	if(strcmp(type,"VK_REAL")==0)
+		return VK_REAL;       
+	if(strcmp(type,"VK_FLOAT")==0)
+		return VK_FLOAT;      
+	if(strcmp(type,"VK_TIMESTAMP")==0)
+		return VK_TIMESTAMP;  
+	if(strcmp(type,"VK_TIME")==0)
+		return VK_TIMESTAMP;  
+	if(strcmp(type,"VK_DURATION")==0)
+		return VK_DURATION;   
+	if(strcmp(type,"VK_TEXT")==0)
+		return VK_STRING;     
+	if(strcmp(type,"VK_STRING")==0)
+		return VK_STRING;     
+	if(strcmp(type,"VK_BLOB")==0)
+		return VK_BLOB;       
+	if(strcmp(type,"VK_IMAGE")==0)
+		return VK_IMAGE;      
+	return VK_UNKNOW;
+}
+const char* stringFromType(FOURD_TYPE type)
+{
+	switch(type)
+	{
+	case VK_BOOLEAN:
+		return "VK_BOOLEAN";
+	case VK_BYTE:
+		return "VK_BYTE";
+	case VK_WORD:
+		return "VK_WORD";
+	case VK_LONG:
+		return "VK_LONG";
+	case VK_LONG8:
+		return "VK_LONG8";
+	case VK_REAL:
+		return "VK_REAL";
+	case VK_FLOAT:
+		return "VK_FLOAT";
+	case VK_TIMESTAMP:
+		return "VK_TIMESTAMP";
+	case VK_TIME:
+		return "VK_TIME";
+	case VK_DURATION:
+		return "VK_DURATION";
+	case VK_STRING:
+		return "VK_STRING";
+	case VK_BLOB:
+		return "VK_BLOB";
+	case VK_IMAGE:
+		return "VK_IMAGE";
+	default:
+		return "VK_UNKNOW";
+		break;
+	}
+}
+/******************************************************************/
+/* vk_sizeof                                                      */
+/******************************************************************/
+/* return sizeof type or -1 if varying length or 0 if unknow type */
+/******************************************************************/
+int vk_sizeof(FOURD_TYPE type)
+{
+	switch(type)
+	{
+	case VK_BOOLEAN:
+	case VK_BYTE:
+	case VK_WORD:
+		return 2;
+		break;
+	case VK_LONG:
+		return 4;
+		break;
+	case VK_LONG8:
+	case VK_REAL:
+	case VK_DURATION:
+		return 8;
+		break;
+	case VK_FLOAT:
+		//Varying length
+		return -1;
+		break;
+	case VK_TIME:
+	case VK_TIMESTAMP:	
+		return 8;
+		break;
+	case VK_TEXT:
+	case VK_STRING:
+	case VK_BLOB:
+	case VK_IMAGE:
+		//Varying length
+		return -1;
+		break;
+	default:
+			Printf("Error: Unknow type in vk_sizeof function\n");
+			return 0;
+			break;
+	}
+	//error type not found. Should now be handled by the default switch case
+	Printf("Error: Unknow type in vk_sizeof function\n");
+	return 0;
+}
+
+FOURD_RESULT_TYPE resultTypeFromString(const char *type)
+{
+	if(strcmp(type,"Update-Count")==0)
+		return UPDATE_COUNT; 
+	if(strcmp(type,"Result-Set")==0)
+		return RESULT_SET; 
+	return UNKNOW;
+}
+const char* stringFromResultType(FOURD_RESULT_TYPE type)
+{
+	switch(type)
+	{
+	case UPDATE_COUNT:
+		return "Update-Count";
+		break;
+	case RESULT_SET:
+		return "Result-Set";
+		break;
+	default:
+			return "Unknown";
+			break;
+	}
+	return "Unknown";
 }
\ No newline at end of file
diff --git a/lib4d_sql/fourd_type.h b/lib4d_sql/fourd_type.h
index d8c684b..574435f 100644
--- a/lib4d_sql/fourd_type.h
+++ b/lib4d_sql/fourd_type.h
@@ -1,59 +1,87 @@
-#ifndef __FOURD_TYPE__
-#define __FOURD_TYPE__
-typedef enum
-{
-	VK_UNKNOW=0,
-	VK_BOOLEAN,
-	VK_BYTE,
-	VK_WORD,
-	VK_LONG,
-	VK_LONG8,
-	VK_REAL,
-	VK_FLOAT,
-	VK_TIMESTAMP,
-	VK_DURATION,
-	VK_STRING,
-	VK_BLOB,
-	VK_IMAGE 
-}FOURD_TYPE;
-/******************************/
-/* parse and format FOUR_TYPE */
-/******************************/
-FOURD_TYPE typeFromString(const char *type);
-const char* stringFromType(FOURD_TYPE type);
-/******************************************************************/
-/* vk_sizeof                                                      */
-/******************************************************************/
-/* return sizeof type or -1 if varying length or 0 if unknow type */
-/******************************************************************/
-int vk_sizeof(FOURD_TYPE type);
-
-/***************/
-/* Result-Type */
-/***************/
-typedef enum
-{
-	UNKNOW=0,
-	UPDATE_COUNT,
-	RESULT_SET
-}FOURD_RESULT_TYPE;
-FOURD_RESULT_TYPE resultTypeFromString(const char *type);
-const char* stringFromResultType(FOURD_RESULT_TYPE type);
-
-/*********************/
-/* Structure of VK_* */
-/*********************/
-typedef short FOURD_BOOLEAN;
-typedef short FOURD_BYTE;
-typedef short FOURD_WORD;
-typedef	int FOURD_LONG;
-typedef	__int64 FOURD_LONG8;
-typedef	double FOURD_REAL;
-typedef	struct{int exp;char sign;int data_length;void* data;}FOURD_FLOAT;
-typedef	struct{short year;char mounth;char day;unsigned int milli;}FOURD_TIMESTAMP;
-typedef	__int64 FOURD_DURATION;//in milliseconds
-typedef	struct{int length;unsigned char *data;}FOURD_STRING;
-typedef	struct{unsigned int length;void *data;}FOURD_BLOB;
-//typedef	struct{}FOURD_IMAGE; 
-
+/*
+  +----------------------------------------------------------------------+
+  | lib4D_SQL                                                            |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2009 The PHP Group                                     |
+  +----------------------------------------------------------------------+
+  |                                                                      |
+  | This source file is subject to version 3.01 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available through the world-wide-web at the following url:           |
+  | http://www.php.net/license/3_01.txt                                  |
+  |                                                                      |
+  | Its original copy is usable under several licenses and is available  |
+  | through the world-wide-web at the following url:                     |
+  | http://freshmeat.net/projects/lib4d_sql                              |
+  |                                                                      |
+  | Unless required by applicable law or agreed to in writing, software  |
+  | distributed under the License is distributed on an "AS IS" BASIS,    |
+  | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or      |
+  | implied. See the License for the specific language governing         |
+  | permissions and limitations under the License.                       |
+  +----------------------------------------------------------------------+
+  | Contributed by: 4D <php@4d.fr>, http://www.4d.com                    |
+  |                 Alter Way, http://www.alterway.fr                    |
+  | Authors: Stephane Planquart <stephane.planquart@o4db.com>            |
+  |          Alexandre Morgaut <php@4d.fr>                               |
+  +----------------------------------------------------------------------+
+*/
+#ifndef __FOURD_TYPE__
+#define __FOURD_TYPE__
+typedef enum
+{
+	VK_UNKNOW=0,
+	VK_BOOLEAN,
+	VK_BYTE,
+	VK_WORD,
+	VK_LONG,
+	VK_LONG8,
+	VK_REAL,
+	VK_FLOAT,
+	VK_TIMESTAMP,
+	VK_DURATION,
+	VK_STRING,
+	VK_BLOB,
+	VK_IMAGE 
+}FOURD_TYPE;
+/******************************/
+/* parse and format FOUR_TYPE */
+/******************************/
+FOURD_TYPE typeFromString(const char *type);
+const char* stringFromType(FOURD_TYPE type);
+/******************************************************************/
+/* vk_sizeof                                                      */
+/******************************************************************/
+/* return sizeof type or -1 if varying length or 0 if unknow type */
+/******************************************************************/
+int vk_sizeof(FOURD_TYPE type);
+
+/***************/
+/* Result-Type */
+/***************/
+typedef enum
+{
+	UNKNOW=0,
+	UPDATE_COUNT,
+	RESULT_SET
+}FOURD_RESULT_TYPE;
+FOURD_RESULT_TYPE resultTypeFromString(const char *type);
+const char* stringFromResultType(FOURD_RESULT_TYPE type);
+
+/*********************/
+/* Structure of VK_* */
+/*********************/
+typedef short FOURD_BOOLEAN;
+typedef short FOURD_BYTE;
+typedef short FOURD_WORD;
+typedef	int FOURD_LONG;
+typedef	__int64 FOURD_LONG8;
+typedef	double FOURD_REAL;
+typedef	struct{int exp;char sign;int data_length;void* data;}FOURD_FLOAT;
+typedef	struct{short year;char mounth;char day;unsigned int milli;}FOURD_TIMESTAMP;
+typedef	__int64 FOURD_DURATION;//in milliseconds
+typedef	struct{int length;unsigned char *data;}FOURD_STRING;
+typedef	struct{unsigned int length;void *data;}FOURD_BLOB;
+//typedef	struct{}FOURD_IMAGE; 
+
 #endif
\ No newline at end of file
diff --git a/lib4d_sql/sqlstate.c b/lib4d_sql/sqlstate.c
index 062e54f..1bec5eb 100644
--- a/lib4d_sql/sqlstate.c
+++ b/lib4d_sql/sqlstate.c
@@ -1,19 +1,48 @@
-#include "fourd.h"
-const char * fourd_sqlstate(FOURD *cnx)
-{
-	switch(cnx->error_code){
-		case -10060: return "08001";/* Unable to connect to server => Client unable to establish connection */
-		case -1: return "01S00";
-		/*case 1105: return "08004";*/	/* Failed to authenticate. => Server rejected the connection */
-		
-		case 1101: return "42P01";	/* Failed to execute statement. => Undefined table <= TABLE DOES NOT EXIST */
+/*
+  +----------------------------------------------------------------------+
+  | lib4D_SQL                                                            |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2009 The PHP Group                                     |
+  +----------------------------------------------------------------------+
+  |                                                                      |
+  | This source file is subject to version 3.01 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available through the world-wide-web at the following url:           |
+  | http://www.php.net/license/3_01.txt                                  |
+  |                                                                      |
+  | Its original copy is usable under several licenses and is available  |
+  | through the world-wide-web at the following url:                     |
+  | http://freshmeat.net/projects/lib4d_sql                              |
+  |                                                                      |
+  | Unless required by applicable law or agreed to in writing, software  |
+  | distributed under the License is distributed on an "AS IS" BASIS,    |
+  | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or      |
+  | implied. See the License for the specific language governing         |
+  | permissions and limitations under the License.                       |
+  +----------------------------------------------------------------------+
+  | Contributed by: 4D <php@4d.fr>, http://www.4d.com                    |
+  |                 Alter Way, http://www.alterway.fr                    |
+  | Authors: Stephane Planquart <stephane.planquart@o4db.com>            |
+  |          Alexandre Morgaut <php@4d.fr>                               |
+  +----------------------------------------------------------------------+
+*/
+
+#include "fourd.h"
+const char * fourd_sqlstate(FOURD *cnx)
+{
+	switch(cnx->error_code){
+		case -10060: return "08001";/* Unable to connect to server => Client unable to establish connection */
+		case -1: return "01S00";
+		/*case 1105: return "08004";*/	/* Failed to authenticate. => Server rejected the connection */
+		
+		case 1101: return "42P01";	/* Failed to execute statement. => Undefined table <= TABLE DOES NOT EXIST */
 		case 1102: return "42S22";  /* Column not found <= colonne DOES NOT EXIST*/
 		case 1103: return "42P01";  /* Undefined table <= TABLE NOT DECLARED IN FROM CLAUSE */
 		case 1104: return "42702";  /* Ambiguous column <= AMBIGUOUS COLUMN NAME */
 		case 1105: return "42P09";  /* Ambiguous alias <= TABLE ALIAS SAME AS TABLE NAME */
 		case 1106: return "42P09";  /* Ambiguous alias <= DUPLICATE TABLE ALIAS */
 		case 1107: return "42P09";  /* Ambiguous alias <= DUPLICATE TABLE IN FROM CLAUSE  */
-		case 1108: return "HY004";	/* Failed to execute statement. => Invalid SQL data type <= INCOMPATIBLE TYPES */
+		case 1108: return "HY004";	/* Failed to execute statement. => Invalid SQL data type <= INCOMPATIBLE TYPES */
 		
 		case 1109: return "HY000";	/*  <= INVALID ORDER BY INDEX */
 		case 1110: return "42P08";	/* Ambiguous parameter <= WRONG AMOUNT OF PARAMETERS */
@@ -51,7 +80,7 @@ const char * fourd_sqlstate(FOURD *cnx)
 		case 1133: return "21S01";	/* Insert value list does not match column list <= DUPLICATE COLUMN IN INSERT */
 		case 1134: return "23502";	/* Not null violation <= COLUMN DOES NOT ALLOW NULLS */
 		case 1135: return "42701";	/* Duplicate column <= DUPLICATE COLUMN IN UPDATE */
-		case 1136: return "42P07";	/* Duplicate table <= TABLE ALREADY EXISTS */
+		case 1136: return "42P07";	/* Duplicate table <= TABLE ALREADY EXISTS */
 
 		case 1137: return "42701";	/* Duplicate column <= DUPLICATE COLUMN IN CREATE TABLE */
 		case 1138: return "42701";	/* Duplicate column <= DUPLICATE COLUMN IN COLUMN LIST */
@@ -100,7 +129,7 @@ const char * fourd_sqlstate(FOURD *cnx)
 		case 1220: return "HY000";	/*  <= FAILED TO LOAD RECORD */
 		case 1221: return "HY000";	/*  <= FAILED TO LOCK RECORD FOR WRITING */
 		case 1222: return "HY000";	/*  <= FAILED TO PUT SQL LOCK ON A TABLE */
-		
+		
 		case 1301: return "42601";	/* Failed to parse statement. => Syntax error */
 		
 		
@@ -178,7 +207,7 @@ const char * fourd_sqlstate(FOURD *cnx)
 		case 3013: return "HY000";	/*  <= BASE64 ENCODING ERROR */
 		case 3014: return "HY000";	/*  <= INVALID HEADER TERMINATOR */
 
-		
-		default: return "HY000";
-	}
+		case -5001: return "0LP01"; /* driver not support multiquery */
+		default: return "HY000";
+	}
 }
\ No newline at end of file
diff --git a/lib4d_sql/utils.c b/lib4d_sql/utils.c
index 63ae27f..054de2b 100644
--- a/lib4d_sql/utils.c
+++ b/lib4d_sql/utils.c
@@ -1,22 +1,51 @@
-#include <string.h>
-#define isspace(x) (x==' ')
-char *strstrip(char *s)
-{
-       size_t size;
-       char *end;
-
-       size = strlen(s);
-
-       if (!size)
-               return s;
-
-       end = s + size - 1;
-       while (end != s && isspace(*end))
-               end--;
-       *(end + 1) = '\0';
-
-       while (*s && isspace(*s))
-               s++;
-
-       return s;
+/*
+  +----------------------------------------------------------------------+
+  | lib4D_SQL                                                            |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2009 The PHP Group                                     |
+  +----------------------------------------------------------------------+
+  |                                                                      |
+  | This source file is subject to version 3.01 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available through the world-wide-web at the following url:           |
+  | http://www.php.net/license/3_01.txt                                  |
+  |                                                                      |
+  | Its original copy is usable under several licenses and is available  |
+  | through the world-wide-web at the following url:                     |
+  | http://freshmeat.net/projects/lib4d_sql                              |
+  |                                                                      |
+  | Unless required by applicable law or agreed to in writing, software  |
+  | distributed under the License is distributed on an "AS IS" BASIS,    |
+  | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or      |
+  | implied. See the License for the specific language governing         |
+  | permissions and limitations under the License.                       |
+  +----------------------------------------------------------------------+
+  | Contributed by: 4D <php@4d.fr>, http://www.4d.com                    |
+  |                 Alter Way, http://www.alterway.fr                    |
+  | Authors: Stephane Planquart <stephane.planquart@o4db.com>            |
+  |          Alexandre Morgaut <php@4d.fr>                               |
+  +----------------------------------------------------------------------+
+*/
+
+#include <string.h>
+#define isspace(x) (x==' ')
+char *strstrip(char *s)
+{
+       size_t size;
+       char *end;
+
+       size = strlen(s);
+
+       if (!size)
+               return s;
+
+       end = s + size - 1;
+       while (end != s && isspace(*end))
+               end--;
+       *(end + 1) = '\0';
+
+       while (*s && isspace(*s))
+               s++;
+
+       return s;
 }
\ No newline at end of file
diff --git a/lib4d_sql/utils.h b/lib4d_sql/utils.h
index aeded97..deb8944 100644
--- a/lib4d_sql/utils.h
+++ b/lib4d_sql/utils.h
@@ -1 +1,30 @@
+/*
+  +----------------------------------------------------------------------+
+  | lib4D_SQL                                                            |
+  +----------------------------------------------------------------------+
+  | Copyright (c) 2009 The PHP Group                                     |
+  +----------------------------------------------------------------------+
+  |                                                                      |
+  | This source file is subject to version 3.01 of the PHP license,      |
+  | that is bundled with this package in the file LICENSE, and is        |
+  | available through the world-wide-web at the following url:           |
+  | http://www.php.net/license/3_01.txt                                  |
+  |                                                                      |
+  | Its original copy is usable under several licenses and is available  |
+  | through the world-wide-web at the following url:                     |
+  | http://freshmeat.net/projects/lib4d_sql                              |
+  |                                                                      |
+  | Unless required by applicable law or agreed to in writing, software  |
+  | distributed under the License is distributed on an "AS IS" BASIS,    |
+  | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or      |
+  | implied. See the License for the specific language governing         |
+  | permissions and limitations under the License.                       |
+  +----------------------------------------------------------------------+
+  | Contributed by: 4D <php@4d.fr>, http://www.4d.com                    |
+  |                 Alter Way, http://www.alterway.fr                    |
+  | Authors: Stephane Planquart <stephane.planquart@o4db.com>            |
+  |          Alexandre Morgaut <php@4d.fr>                               |
+  +----------------------------------------------------------------------+
+*/
+
 char *strstrip(char *s);
\ No newline at end of file

From a9fb2a448c606926c1217821a0548a09ffdb9296 Mon Sep 17 00:00:00 2001
From: Israel Brewster <israel@brewstersoft.com>
Date: Mon, 22 Dec 2014 09:58:11 -0900
Subject: [PATCH 2/3] Fix memory leaks

---
 lib4d_sql/base64.c        |  0
 lib4d_sql/base64.h        |  0
 lib4d_sql/communication.c |  1 +
 lib4d_sql/fourd.c         | 66 ++++++++++++++++-----------------------
 lib4d_sql/fourd.h         |  5 ++-
 lib4d_sql/fourd_int.h     |  1 +
 lib4d_sql/fourd_interne.c | 51 ++++++++++++++++++++++++++++++
 lib4d_sql/fourd_result.c  |  0
 lib4d_sql/fourd_type.c    |  0
 lib4d_sql/fourd_type.h    |  0
 lib4d_sql/sqlstate.c      |  0
 lib4d_sql/utils.c         |  0
 lib4d_sql/utils.h         |  0
 13 files changed, 84 insertions(+), 40 deletions(-)
 mode change 100644 => 100755 lib4d_sql/base64.c
 mode change 100644 => 100755 lib4d_sql/base64.h
 mode change 100644 => 100755 lib4d_sql/communication.c
 mode change 100644 => 100755 lib4d_sql/fourd.c
 mode change 100644 => 100755 lib4d_sql/fourd.h
 mode change 100644 => 100755 lib4d_sql/fourd_int.h
 mode change 100644 => 100755 lib4d_sql/fourd_interne.c
 mode change 100644 => 100755 lib4d_sql/fourd_result.c
 mode change 100644 => 100755 lib4d_sql/fourd_type.c
 mode change 100644 => 100755 lib4d_sql/fourd_type.h
 mode change 100644 => 100755 lib4d_sql/sqlstate.c
 mode change 100644 => 100755 lib4d_sql/utils.c
 mode change 100644 => 100755 lib4d_sql/utils.h

diff --git a/lib4d_sql/base64.c b/lib4d_sql/base64.c
old mode 100644
new mode 100755
diff --git a/lib4d_sql/base64.h b/lib4d_sql/base64.h
old mode 100644
new mode 100755
diff --git a/lib4d_sql/communication.c b/lib4d_sql/communication.c
old mode 100644
new mode 100755
index a3cbf9b..9feb113
--- a/lib4d_sql/communication.c
+++ b/lib4d_sql/communication.c
@@ -431,6 +431,7 @@ int socket_receiv_data(FOURD *cnx,FOURD_RESULT *state)
 		}
 	}
 	Printf("---Fin de socket_receiv_data\n");
+	free(colType);
 	return 0;
 }
 int socket_receiv_update_count(FOURD *cnx,FOURD_RESULT *state)
diff --git a/lib4d_sql/fourd.c b/lib4d_sql/fourd.c
old mode 100644
new mode 100755
index 191fc3d..3f20772
--- a/lib4d_sql/fourd.c
+++ b/lib4d_sql/fourd.c
@@ -35,7 +35,6 @@
 
 #include "fourd.h"
 #include "fourd_int.h"
-#include "base64.h"
 
 FOURD* fourd_init()
 {
@@ -116,6 +115,9 @@ void fourd_free(FOURD* cnx)
 #ifdef WIN32
 	WSACleanup();
 #endif
+	if (cnx->preferred_image_types!=NULL)
+		free(cnx->preferred_image_types);
+
 	free(cnx);
 }
 
@@ -157,6 +159,7 @@ void fourd_free_result(FOURD_RESULT *res)
 {
 	if(res!=NULL && res->elmt!=NULL)
 			_free_data_result(res);
+	free(res->row_type.Column);
 	Free(res);
 }
 int fourd_next_row(FOURD_RESULT *res)
@@ -238,6 +241,12 @@ void * fourd_field(FOURD_RESULT *res,unsigned int numCol)
 	return elmt->pValue;
 }
 
+//This function is for use by the python 4d driver, as it appears to be the only
+//way to get this block of memory freed. Hopefully that will change.
+void _free_field_string(char **value){
+	free(*value);
+}
+
 int fourd_field_to_string(FOURD_RESULT *res,unsigned int numCol,char **value,size_t *len)
 {
 	unsigned int nbCol=res->row_type.nbColumn;
@@ -367,11 +376,28 @@ int fourd_num_columns(FOURD_RESULT *res)
 	return res->row_type.nbColumn;
 }
 
+void fourd_free_statement(FOURD_STATEMENT *state){
+	if (state->query!=NULL)
+		free(state->query);
+	
+	if(state->elmt!=NULL)
+		free(state->elmt);
+	
+	if (state->preferred_image_types!=NULL)
+		free(state->preferred_image_types);
+	
+	free(state);
+}
+
 FOURD_STATEMENT * fourd_prepare_statement(FOURD *cnx,const char *query)
 {
 	FOURD_STATEMENT* state=NULL;
 	if(cnx==NULL || !cnx->connected || query==NULL)
 		return NULL;
+	
+	if(_prepare_statement(cnx, 3, query)!=0)
+		return NULL;
+	
 	state=calloc(1,sizeof(FOURD_STATEMENT));
 	state->cnx=cnx;
 	state->query=(char *)malloc(strlen(query)+1);
@@ -385,44 +411,6 @@ FOURD_STATEMENT * fourd_prepare_statement(FOURD *cnx,const char *query)
 	sprintf(state->query,"%s",query);
 	fourd_set_statement_preferred_image_types(state,cnx->preferred_image_types);
 	
-	
-	char *msg;
-	FOURD_RESULT *res=calloc(1,sizeof(FOURD_RESULT));
-	unsigned char *request_b64;
-	int len;
-
-	request_b64=base64_encode(query,strlen(query),&len);
-	char *format_str="003 PREPARE-STATEMENT\r\nSTATEMENT-BASE64:%s\r\n\r\n";
-	unsigned long buff_size=strlen(format_str)+strlen((const char *)request_b64)+2; //add some extra for good measure.
-	msg=(char *)malloc(buff_size);
-	snprintf(msg,buff_size,format_str,request_b64);
-	free(request_b64);
-
-	cnx->updated_row=-1;
-	socket_send(cnx,msg);
-	free(msg);
-	
-	if(receiv_check(cnx,res)!=0)
-		return NULL;
-	
-	switch(res->resultType)	{
-		case UPDATE_COUNT:
-			//get Update-count: Nb row updated
-			cnx->updated_row=-1;
-			//socket_receiv_update_count(cnx,res);
-			_free_data_result(res);
-			break;
-		case RESULT_SET:
-			//get data
-			socket_receiv_data(cnx,res);
-			cnx->updated_row=-1;
-			break;
-		default:
-			Printferr("Error: Result-Type not supported in query");
-	}
-	free(res);
-
-	
 	return state;
 }
 
diff --git a/lib4d_sql/fourd.h b/lib4d_sql/fourd.h
old mode 100644
new mode 100755
index fb745ce..add33b1
--- a/lib4d_sql/fourd.h
+++ b/lib4d_sql/fourd.h
@@ -261,7 +261,11 @@ int fourd_errno(FOURD *cnx);
 const char * fourd_error(FOURD *cnx);
 const char * fourd_sqlstate(FOURD *cnx);
 void fourd_free(FOURD* cnx);
+void fourd_free_statement(FOURD_STATEMENT *state);
 void fourd_timeout(FOURD* cnx,int timeout);
+//For use by external non-c code that can't access/clear this block of memory
+//directly.
+void _free_field_string(char **value);
 
 /*function on FOURD_RESULT*/
 FOURD_LONG8 fourd_num_rows(FOURD_RESULT *result);
@@ -280,7 +284,6 @@ FOURD_TYPE fourd_get_column_type(FOURD_RESULT *res,unsigned int numCol);
 int fourd_num_columns(FOURD_RESULT *res);
 int fourd_field_to_string(FOURD_RESULT *res,unsigned int numCol,char **value,size_t *len);
 
-
 FOURD_STATEMENT * fourd_prepare_statement(FOURD *cnx,const char *query);
 int fourd_bind_param(FOURD_STATEMENT *state,unsigned int numParam,FOURD_TYPE type, void *val);
 FOURD_RESULT *fourd_exec_statement(FOURD_STATEMENT *state, int res_size);
diff --git a/lib4d_sql/fourd_int.h b/lib4d_sql/fourd_int.h
old mode 100644
new mode 100755
index 52bfae0..a6e3236
--- a/lib4d_sql/fourd_int.h
+++ b/lib4d_sql/fourd_int.h
@@ -70,6 +70,7 @@ void _free_data_result(FOURD_RESULT *res);
 void _clear_atrr_cnx(FOURD *cnx);
 int close_statement(FOURD_RESULT *res,unsigned short int id_cmd);
 
+int _prepare_statement(FOURD *cnx,unsigned short int id_cmd,const char *request);
 int _query_param(FOURD *cnx,unsigned short int id_cmd, const char *request,unsigned int nbParam, const FOURD_ELEMENT *param,FOURD_RESULT *result,const char*image_type, int res_size);
 int _is_multi_query(const char *request);
 int _valid_query(FOURD *cnx,const char *request);
diff --git a/lib4d_sql/fourd_interne.c b/lib4d_sql/fourd_interne.c
old mode 100644
new mode 100755
index 0e7e8f8..40731a6
--- a/lib4d_sql/fourd_interne.c
+++ b/lib4d_sql/fourd_interne.c
@@ -171,6 +171,53 @@ int _query(FOURD *cnx,unsigned short int id_cmd,const char *request,FOURD_RESULT
 	return 0;
 }
 
+int _prepare_statement(FOURD *cnx,unsigned short int id_cmd,const char *request){
+	char *msg;
+	FOURD_RESULT *res=calloc(1,sizeof(FOURD_RESULT));
+	int len;
+	
+#if __STATEMENT_BASE64__
+	unsigned char *request_b64;
+	request_b64=base64_encode(request,strlen(request),&len);
+	char *format_str="%03d PREPARE-STATEMENT\r\nSTATEMENT-BASE64: %s\r\n\r\n";
+	unsigned long buff_size=strlen(format_str)+strlen((const char *)request_b64)+2; //add some extra for good measure.
+	msg=(char *)malloc(buff_size);
+	snprintf(msg,buff_size,format_str,id_cmd,request_b64);
+	free(request_b64);
+#else
+	char *format_str="%03d PREPARE-STATEMENT\r\nSTATEMENT: %s\r\n\r\n";
+	unsigned long buff_size=strlen(format_str)+strlen(request)+2; //add some extra for good measure.
+	msg=(char *)malloc(buff_size);
+	snprintf(msg,buff_size,format_str,id_cmd,request_b64);
+#endif
+	
+	cnx->updated_row=-1;
+	socket_send(cnx,msg);
+	free(msg);
+	
+	if(receiv_check(cnx,res)!=0)
+		return 1;
+	
+	switch(res->resultType)	{
+		case UPDATE_COUNT:
+			//get Update-count: Nb row updated
+			cnx->updated_row=-1;
+			//socket_receiv_update_count(cnx,res);
+			_free_data_result(res);
+			break;
+		case RESULT_SET:
+			//get data
+			socket_receiv_data(cnx,res);
+			cnx->updated_row=-1;
+			break;
+		default:
+			Printferr("Error: Result-Type not supported in query");
+	}
+	fourd_free_result(res);
+
+	return 0;
+}
+
 int _query_param(FOURD *cnx,unsigned short int id_cmd, const char *request,unsigned int nbParam, const FOURD_ELEMENT *param,FOURD_RESULT *result,const char*image_type,int res_size)
 {
 	char *msg=NULL;
@@ -264,6 +311,7 @@ int _query_param(FOURD *cnx,unsigned short int id_cmd, const char *request,unsig
 		Free(res);
 	return 0;
 }
+
 /* low level commande 
    command_index and statement_id is identify by result of execute statement commande */
 int __fetch_result(FOURD *cnx,unsigned short int id_cmd,int statement_id,int command_index,unsigned int first_row,unsigned int last_row,FOURD_RESULT *result)
@@ -686,7 +734,10 @@ void _free_data_result(FOURD_RESULT *res)
 				break;
 		}
 	}
+	
+	free(res->elmt);
 }
+
 void *_copy(FOURD_TYPE type,void *org)
 {
 	void *buff=NULL;
diff --git a/lib4d_sql/fourd_result.c b/lib4d_sql/fourd_result.c
old mode 100644
new mode 100755
diff --git a/lib4d_sql/fourd_type.c b/lib4d_sql/fourd_type.c
old mode 100644
new mode 100755
diff --git a/lib4d_sql/fourd_type.h b/lib4d_sql/fourd_type.h
old mode 100644
new mode 100755
diff --git a/lib4d_sql/sqlstate.c b/lib4d_sql/sqlstate.c
old mode 100644
new mode 100755
diff --git a/lib4d_sql/utils.c b/lib4d_sql/utils.c
old mode 100644
new mode 100755
diff --git a/lib4d_sql/utils.h b/lib4d_sql/utils.h
old mode 100644
new mode 100755

From f01f73bccb30de9c1004b7a3b85acfc96eb451a4 Mon Sep 17 00:00:00 2001
From: Israel Brewster <israel@brewstersoft.com>
Date: Tue, 23 Dec 2014 08:10:18 -0900
Subject: [PATCH 3/3] Remove custom free function, it is no longer needed for
 other code

---
 lib4d_sql/fourd.c | 6 ------
 lib4d_sql/fourd.h | 3 ---
 2 files changed, 9 deletions(-)

diff --git a/lib4d_sql/fourd.c b/lib4d_sql/fourd.c
index 3f20772..92fa357 100755
--- a/lib4d_sql/fourd.c
+++ b/lib4d_sql/fourd.c
@@ -241,12 +241,6 @@ void * fourd_field(FOURD_RESULT *res,unsigned int numCol)
 	return elmt->pValue;
 }
 
-//This function is for use by the python 4d driver, as it appears to be the only
-//way to get this block of memory freed. Hopefully that will change.
-void _free_field_string(char **value){
-	free(*value);
-}
-
 int fourd_field_to_string(FOURD_RESULT *res,unsigned int numCol,char **value,size_t *len)
 {
 	unsigned int nbCol=res->row_type.nbColumn;
diff --git a/lib4d_sql/fourd.h b/lib4d_sql/fourd.h
index add33b1..3144bd3 100755
--- a/lib4d_sql/fourd.h
+++ b/lib4d_sql/fourd.h
@@ -263,9 +263,6 @@ const char * fourd_sqlstate(FOURD *cnx);
 void fourd_free(FOURD* cnx);
 void fourd_free_statement(FOURD_STATEMENT *state);
 void fourd_timeout(FOURD* cnx,int timeout);
-//For use by external non-c code that can't access/clear this block of memory
-//directly.
-void _free_field_string(char **value);
 
 /*function on FOURD_RESULT*/
 FOURD_LONG8 fourd_num_rows(FOURD_RESULT *result);