VariadicSQLParser.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. #include "VariadicSQLParser.h"
  11. #include "BitStream.h"
  12. #include <stdarg.h>
  13. using namespace VariadicSQLParser;
  14. struct TypeMapping
  15. {
  16. char inputType;
  17. const char *type;
  18. };
  19. const int NUM_TYPE_MAPPINGS=7;
  20. TypeMapping typeMappings[NUM_TYPE_MAPPINGS] =
  21. {
  22. {'i', "int"},
  23. {'d', "int"},
  24. {'s', "text"},
  25. {'b', "bool"},
  26. {'f', "numeric"},
  27. {'g', "double precision"},
  28. {'a', "bytea"},
  29. };
  30. unsigned int GetTypeMappingIndex(char c)
  31. {
  32. unsigned int i;
  33. for (i=0; i < (unsigned int) NUM_TYPE_MAPPINGS; i++ )
  34. if (typeMappings[i].inputType==c)
  35. return i;
  36. return (unsigned int)-1;
  37. }
  38. const char* VariadicSQLParser::GetTypeMappingAtIndex(int i)
  39. {
  40. return typeMappings[i].type;
  41. }
  42. void VariadicSQLParser::GetTypeMappingIndices( const char *format, DataStructures::List<IndexAndType> &indices )
  43. {
  44. bool previousCharWasPercentSign;
  45. unsigned int i;
  46. unsigned int typeMappingIndex;
  47. indices.Clear(false, _FILE_AND_LINE_);
  48. unsigned int len = (unsigned int) strlen(format);
  49. previousCharWasPercentSign=false;
  50. for (i=0; i < len; i++)
  51. {
  52. if (previousCharWasPercentSign==true )
  53. {
  54. typeMappingIndex = GetTypeMappingIndex(format[i]);
  55. if (typeMappingIndex!=(unsigned int) -1)
  56. {
  57. IndexAndType iat;
  58. iat.strIndex=i-1;
  59. iat.typeMappingIndex=typeMappingIndex;
  60. indices.Insert(iat, _FILE_AND_LINE_ );
  61. }
  62. }
  63. previousCharWasPercentSign=format[i]=='%';
  64. }
  65. }
  66. void VariadicSQLParser::ExtractArguments( va_list argptr, const DataStructures::List<IndexAndType> &indices, char ***argumentBinary, int **argumentLengths )
  67. {
  68. if (indices.Size()==0)
  69. return;
  70. unsigned int i;
  71. *argumentBinary=RakNet::OP_NEW_ARRAY<char *>(indices.Size(), _FILE_AND_LINE_);
  72. *argumentLengths=RakNet::OP_NEW_ARRAY<int>(indices.Size(), _FILE_AND_LINE_);
  73. char **paramData=*argumentBinary;
  74. int *paramLength=*argumentLengths;
  75. int variadicArgIndex;
  76. for (variadicArgIndex=0, i=0; i < indices.Size(); i++, variadicArgIndex++)
  77. {
  78. switch (typeMappings[indices[i].typeMappingIndex].inputType)
  79. {
  80. case 'i':
  81. case 'd':
  82. {
  83. int val = va_arg( argptr, int );
  84. paramLength[i]=sizeof(val);
  85. paramData[i]=(char*) rakMalloc_Ex(paramLength[i], _FILE_AND_LINE_);
  86. memcpy(paramData[i], &val, paramLength[i]);
  87. if (RakNet::BitStream::IsNetworkOrder()==false) RakNet::BitStream::ReverseBytesInPlace((unsigned char*) paramData[i], paramLength[i]);
  88. }
  89. break;
  90. case 's':
  91. {
  92. char* val = va_arg( argptr, char* );
  93. paramLength[i]=(int) strlen(val);
  94. paramData[i]=(char*) rakMalloc_Ex(paramLength[i]+1, _FILE_AND_LINE_);
  95. memcpy(paramData[i], val, paramLength[i]+1);
  96. }
  97. break;
  98. case 'b':
  99. {
  100. bool val = (va_arg( argptr, int )!=0);
  101. paramLength[i]=sizeof(val);
  102. paramData[i]=(char*) rakMalloc_Ex(paramLength[i], _FILE_AND_LINE_);
  103. memcpy(paramData[i], &val, paramLength[i]);
  104. if (RakNet::BitStream::IsNetworkOrder()==false) RakNet::BitStream::ReverseBytesInPlace((unsigned char*) paramData[i], paramLength[i]);
  105. }
  106. break;
  107. /*
  108. case 'f':
  109. {
  110. // On MSVC at least, this only works with double as the 2nd param
  111. float val = (float) va_arg( argptr, double );
  112. //float val = va_arg( argptr, float );
  113. paramLength[i]=sizeof(val);
  114. paramData[i]=(char*) rakMalloc_Ex(paramLength[i], _FILE_AND_LINE_);
  115. memcpy(paramData[i], &val, paramLength[i]);
  116. if (RakNet::BitStream::IsNetworkOrder()==false) RakNet::BitStream::ReverseBytesInPlace((unsigned char*) paramData[i], paramLength[i]);
  117. }
  118. break;
  119. */
  120. // On MSVC at least, this only works with double as the 2nd param
  121. case 'f':
  122. case 'g':
  123. {
  124. double val = va_arg( argptr, double );
  125. paramLength[i]=sizeof(val);
  126. paramData[i]=(char*) rakMalloc_Ex(paramLength[i], _FILE_AND_LINE_);
  127. memcpy(paramData[i], &val, paramLength[i]);
  128. if (RakNet::BitStream::IsNetworkOrder()==false) RakNet::BitStream::ReverseBytesInPlace((unsigned char*) paramData[i], paramLength[i]);
  129. }
  130. break;
  131. case 'a':
  132. {
  133. char* val = va_arg( argptr, char* );
  134. paramLength[i]=va_arg( argptr, unsigned int );
  135. paramData[i]=(char*) rakMalloc_Ex(paramLength[i], _FILE_AND_LINE_);
  136. memcpy(paramData[i], val, paramLength[i]);
  137. }
  138. break;
  139. }
  140. }
  141. }
  142. void VariadicSQLParser::FreeArguments(const DataStructures::List<IndexAndType> &indices, char **argumentBinary, int *argumentLengths)
  143. {
  144. if (indices.Size()==0)
  145. return;
  146. unsigned int i;
  147. for (i=0; i < indices.Size(); i++)
  148. rakFree_Ex(argumentBinary[i],_FILE_AND_LINE_);
  149. RakNet::OP_DELETE_ARRAY(argumentBinary,_FILE_AND_LINE_);
  150. RakNet::OP_DELETE_ARRAY(argumentLengths,_FILE_AND_LINE_);
  151. }
粤ICP备19079148号