00001 #include "VariadicSQLParser.h"
00002 #include "BitStream.h"
00003 #include <stdarg.h>
00004
00005 using namespace VariadicSQLParser;
00006
00007 struct TypeMapping
00008 {
00009 char inputType;
00010 const char *type;
00011 };
00012 const int NUM_TYPE_MAPPINGS=7;
00013 TypeMapping typeMappings[NUM_TYPE_MAPPINGS] =
00014 {
00015 {'i', "int"},
00016 {'d', "int"},
00017 {'s', "text"},
00018 {'b', "bool"},
00019 {'f', "numeric"},
00020 {'g', "double precision"},
00021 {'a', "bytea"},
00022 };
00023 unsigned int GetTypeMappingIndex(char c)
00024 {
00025 unsigned int i;
00026 for (i=0; i < NUM_TYPE_MAPPINGS; i++ )
00027 if (typeMappings[i].inputType==c)
00028 return i;
00029 return (unsigned int)-1;
00030 }
00031 const char* VariadicSQLParser::GetTypeMappingAtIndex(int i)
00032 {
00033 return typeMappings[i].type;
00034 }
00035 void VariadicSQLParser::GetTypeMappingIndices( const char *format, DataStructures::List<IndexAndType> &indices )
00036 {
00037 bool previousCharWasPercentSign;
00038 unsigned int i;
00039 unsigned int typeMappingIndex;
00040 indices.Clear(false, __FILE__, __LINE__);
00041 unsigned int len = (unsigned int) strlen(format);
00042 previousCharWasPercentSign=false;
00043 for (i=0; i < len; i++)
00044 {
00045 if (previousCharWasPercentSign==true )
00046 {
00047 typeMappingIndex = GetTypeMappingIndex(format[i]);
00048 if (typeMappingIndex!=(unsigned int) -1)
00049 {
00050 IndexAndType iat;
00051 iat.strIndex=i-1;
00052 iat.typeMappingIndex=typeMappingIndex;
00053 indices.Insert(iat, __FILE__, __LINE__ );
00054 }
00055 }
00056
00057 previousCharWasPercentSign=format[i]=='%';
00058 }
00059 }
00060 void VariadicSQLParser::ExtractArguments( va_list argptr, const DataStructures::List<IndexAndType> &indices, char ***argumentBinary, int **argumentLengths )
00061 {
00062 if (indices.Size()==0)
00063 return;
00064
00065 unsigned int i;
00066 *argumentBinary=RakNet::OP_NEW_ARRAY<char *>(indices.Size(), __FILE__,__LINE__);
00067 *argumentLengths=RakNet::OP_NEW_ARRAY<int>(indices.Size(), __FILE__,__LINE__);
00068
00069 char **paramData=*argumentBinary;
00070 int *paramLength=*argumentLengths;
00071
00072 int variadicArgIndex;
00073 for (variadicArgIndex=0, i=0; i < indices.Size(); i++, variadicArgIndex++)
00074 {
00075 switch (typeMappings[indices[i].typeMappingIndex].inputType)
00076 {
00077 case 'i':
00078 case 'd':
00079 {
00080 int val = va_arg( argptr, int );
00081 paramLength[i]=sizeof(val);
00082 paramData[i]=(char*) rakMalloc_Ex(paramLength[i], __FILE__, __LINE__);
00083 memcpy(paramData[i], &val, paramLength[i]);
00084 if (RakNet::BitStream::IsNetworkOrder()==false) RakNet::BitStream::ReverseBytesInPlace((unsigned char*) paramData[i], paramLength[i]);
00085 }
00086 break;
00087 case 's':
00088 {
00089 char* val = va_arg( argptr, char* );
00090 paramLength[i]=(int) strlen(val);
00091 paramData[i]=(char*) rakMalloc_Ex(paramLength[i]+1, __FILE__, __LINE__);
00092 memcpy(paramData[i], val, paramLength[i]+1);
00093 }
00094 break;
00095 case 'b':
00096 {
00097 bool val = (va_arg( argptr, int )!=0);
00098 paramLength[i]=sizeof(val);
00099 paramData[i]=(char*) rakMalloc_Ex(paramLength[i], __FILE__, __LINE__);
00100 memcpy(paramData[i], &val, paramLength[i]);
00101 if (RakNet::BitStream::IsNetworkOrder()==false) RakNet::BitStream::ReverseBytesInPlace((unsigned char*) paramData[i], paramLength[i]);
00102 }
00103 break;
00104 case 'f':
00105 {
00106
00107 float val = (float) va_arg( argptr, double );
00108
00109 paramLength[i]=sizeof(val);
00110 paramData[i]=(char*) rakMalloc_Ex(paramLength[i], __FILE__, __LINE__);
00111 memcpy(paramData[i], &val, paramLength[i]);
00112 if (RakNet::BitStream::IsNetworkOrder()==false) RakNet::BitStream::ReverseBytesInPlace((unsigned char*) paramData[i], paramLength[i]);
00113 }
00114 break;
00115 case 'g':
00116 {
00117 double val = va_arg( argptr, double );
00118 paramLength[i]=sizeof(val);
00119 paramData[i]=(char*) rakMalloc_Ex(paramLength[i], __FILE__, __LINE__);
00120 memcpy(paramData[i], &val, paramLength[i]);
00121 if (RakNet::BitStream::IsNetworkOrder()==false) RakNet::BitStream::ReverseBytesInPlace((unsigned char*) paramData[i], paramLength[i]);
00122 }
00123 break;
00124 case 'a':
00125 {
00126 char* val = va_arg( argptr, char* );
00127 paramLength[i]=va_arg( argptr, unsigned int );
00128 paramData[i]=(char*) rakMalloc_Ex(paramLength[i], __FILE__, __LINE__);
00129 memcpy(paramData[i], val, paramLength[i]);
00130 }
00131 break;
00132 }
00133 }
00134
00135 }
00136 void VariadicSQLParser::FreeArguments(const DataStructures::List<IndexAndType> &indices, char **argumentBinary, int *argumentLengths)
00137 {
00138 if (indices.Size()==0)
00139 return;
00140
00141 unsigned int i;
00142 for (i=0; i < indices.Size(); i++)
00143 rakFree_Ex(argumentBinary[i],__FILE__,__LINE__);
00144 RakNet::OP_DELETE_ARRAY(argumentBinary,__FILE__,__LINE__);
00145 RakNet::OP_DELETE_ARRAY(argumentLengths,__FILE__,__LINE__);
00146 }