mysqlnd_portability.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
  2. This file is public domain and comes with NO WARRANTY of any kind */
  3. /*
  4. Parts of the original, which are not applicable to mysqlnd have been removed.
  5. With small modifications, mostly casting but adding few more macros by
  6. Andrey Hristov <andrey@php.net> . The additions are in the public domain and
  7. were added to improve the header file, to get it more consistent.
  8. */
  9. #ifndef MYSQLND_PORTABILITY_H
  10. #define MYSQLND_PORTABILITY_H
  11. #ifndef __attribute
  12. #if !defined(__GNUC__)
  13. #define __attribute(A)
  14. #endif
  15. #endif
  16. #ifdef __CYGWIN__
  17. /* We use a Unix API, so pretend it's not Windows */
  18. #undef WIN
  19. #undef WIN32
  20. #undef _WIN
  21. #undef _WIN32
  22. #undef _WIN64
  23. #undef __WIN__
  24. #undef __WIN32__
  25. #endif /* __CYGWIN__ */
  26. #if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
  27. # include "ext/mysqlnd/config-win.h"
  28. #endif /* _WIN32... */
  29. #if __STDC_VERSION__ < 199901L && !defined(atoll)
  30. /* "inline" is a keyword */
  31. #define atoll atol
  32. #endif
  33. #include "php_stdint.h"
  34. #if SIZEOF_LONG_LONG > 4 && !defined(_LONG_LONG)
  35. #define _LONG_LONG 1 /* For AIX string library */
  36. #endif
  37. /* Go around some bugs in different OS and compilers */
  38. #ifdef PHP_WIN32
  39. #ifndef L64
  40. #define L64(x) x##i64
  41. #endif
  42. #else
  43. #ifndef L64
  44. #define L64(x) x##LL
  45. #endif
  46. #endif
  47. #define int1store(T,A) do { *((int8_t*) (T)) = (A); } while(0)
  48. #define uint1korr(A) (*(((uint8_t*)(A))))
  49. /* Bit values are sent in reverted order of bytes, compared to normal !!! */
  50. #define bit_uint2korr(A) ((uint16_t) (((uint16_t) (((unsigned char*) (A))[1])) +\
  51. ((uint16_t) (((unsigned char*) (A))[0]) << 8)))
  52. #define bit_uint3korr(A) ((uint32_t) (((uint32_t) (((unsigned char*) (A))[2])) +\
  53. (((uint32_t) (((unsigned char*) (A))[1])) << 8) +\
  54. (((uint32_t) (((unsigned char*) (A))[0])) << 16)))
  55. #define bit_uint4korr(A) ((uint32_t) (((uint32_t) (((unsigned char*) (A))[3])) +\
  56. (((uint32_t) (((unsigned char*) (A))[2])) << 8) +\
  57. (((uint32_t) (((unsigned char*) (A))[1])) << 16) +\
  58. (((uint32_t) (((unsigned char*) (A))[0])) << 24)))
  59. #define bit_uint5korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[4])) +\
  60. (((uint32_t) (((unsigned char*) (A))[3])) << 8) +\
  61. (((uint32_t) (((unsigned char*) (A))[2])) << 16) +\
  62. (((uint32_t) (((unsigned char*) (A))[1])) << 24)) +\
  63. (((uint64_t) (((unsigned char*) (A))[0])) << 32))
  64. #define bit_uint6korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[5])) +\
  65. (((uint32_t) (((unsigned char*) (A))[4])) << 8) +\
  66. (((uint32_t) (((unsigned char*) (A))[3])) << 16) +\
  67. (((uint32_t) (((unsigned char*) (A))[2])) << 24)) +\
  68. (((uint64_t) (((uint32_t) (((unsigned char*) (A))[1])) +\
  69. (((uint32_t) (((unsigned char*) (A))[0]) << 8)))) <<\
  70. 32))
  71. #define bit_uint7korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[6])) +\
  72. (((uint32_t) (((unsigned char*) (A))[5])) << 8) +\
  73. (((uint32_t) (((unsigned char*) (A))[4])) << 16) +\
  74. (((uint32_t) (((unsigned char*) (A))[3])) << 24)) +\
  75. (((uint64_t) (((uint32_t) (((unsigned char*) (A))[2])) +\
  76. (((uint32_t) (((unsigned char*) (A))[1])) << 8) +\
  77. (((uint32_t) (((unsigned char*) (A))[0])) << 16))) <<\
  78. 32))
  79. #define bit_uint8korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[7])) +\
  80. (((uint32_t) (((unsigned char*) (A))[6])) << 8) +\
  81. (((uint32_t) (((unsigned char*) (A))[5])) << 16) +\
  82. (((uint32_t) (((unsigned char*) (A))[4])) << 24)) +\
  83. (((uint64_t) (((uint32_t) (((unsigned char*) (A))[3])) +\
  84. (((uint32_t) (((unsigned char*) (A))[2])) << 8) +\
  85. (((uint32_t) (((unsigned char*) (A))[1])) << 16) +\
  86. (((uint32_t) (((unsigned char*) (A))[0])) << 24))) <<\
  87. 32))
  88. /*
  89. ** Define-funktions for reading and storing in machine independent format
  90. ** (low byte first)
  91. */
  92. /* Optimized store functions for Intel x86, non-valid for WIN64. __i386__ is GCC */
  93. #if defined(__i386__) && !defined(_WIN64)
  94. #define sint2korr(A) (*((int16_t *) (A)))
  95. #define sint3korr(A) ((int32_t) ((((zend_uchar) (A)[2]) & 128) ? \
  96. (((uint32_t) 255L << 24) | \
  97. (((uint32_t) (zend_uchar) (A)[2]) << 16) |\
  98. (((uint32_t) (zend_uchar) (A)[1]) << 8) | \
  99. ((uint32_t) (zend_uchar) (A)[0])) : \
  100. (((uint32_t) (zend_uchar) (A)[2]) << 16) |\
  101. (((uint32_t) (zend_uchar) (A)[1]) << 8) | \
  102. ((uint32_t) (zend_uchar) (A)[0])))
  103. #define sint4korr(A) (*((zend_long *) (A)))
  104. #define uint2korr(A) (*((uint16_t *) (A)))
  105. #define uint3korr(A) (uint32_t) (((uint32_t) ((zend_uchar) (A)[0])) +\
  106. (((uint32_t) ((zend_uchar) (A)[1])) << 8) +\
  107. (((uint32_t) ((zend_uchar) (A)[2])) << 16))
  108. #define uint4korr(A) (*((zend_ulong *) (A)))
  109. #define uint8korr(A) (*((uint64_t *) (A)))
  110. #define sint8korr(A) (*((int64_t *) (A)))
  111. #define int2store(T,A) *((uint16_t*) (T))= (uint16_t) (A)
  112. #define int3store(T,A) { \
  113. *(T)= (zend_uchar) ((A));\
  114. *(T+1)=(zend_uchar) (((uint32_t) (A) >> 8));\
  115. *(T+2)=(zend_uchar) (((A) >> 16)); }
  116. #define int4store(T,A) *((zend_long *) (T))= (zend_long) (A)
  117. #define int5store(T,A) { \
  118. *((zend_uchar *)(T))= (zend_uchar)((A));\
  119. *(((zend_uchar *)(T))+1)=(zend_uchar) (((A) >> 8));\
  120. *(((zend_uchar *)(T))+2)=(zend_uchar) (((A) >> 16));\
  121. *(((zend_uchar *)(T))+3)=(zend_uchar) (((A) >> 24)); \
  122. *(((zend_uchar *)(T))+4)=(zend_uchar) (((A) >> 32)); }
  123. #define int8store(T,A) *((uint64_t *) (T))= (uint64_t) (A)
  124. typedef union {
  125. double v;
  126. zend_long m[2];
  127. } float8get_union;
  128. #define float8get(V,M) { ((float8get_union *)&(V))->m[0] = *((zend_long*) (M)); \
  129. ((float8get_union *)&(V))->m[1] = *(((zend_long*) (M))+1); }
  130. #define float8store(T,V) { *((zend_long *) (T)) = ((float8get_union *)&(V))->m[0]; \
  131. *(((zend_long *) (T))+1) = ((float8get_union *)&(V))->m[1]; }
  132. #define float4get(V,M) { *((float *) &(V)) = *((float*) (M)); }
  133. /* From Andrey Hristov based on float8get */
  134. #define floatget(V,M) memcpy((char*) &(V),(char*) (M),sizeof(float))
  135. #endif /* __i386__ */
  136. /* If we haven't defined sint2korr, which is because the platform is not x86 or it's WIN64 */
  137. #ifndef sint2korr
  138. #define sint2korr(A) (int16_t) (((int16_t) ((zend_uchar) (A)[0])) +\
  139. ((int16_t) ((int16_t) (A)[1]) << 8))
  140. #define sint3korr(A) ((int32_t) ((((zend_uchar) (A)[2]) & 128) ? \
  141. (((uint32_t) 255L << 24) | \
  142. (((uint32_t) (zend_uchar) (A)[2]) << 16) |\
  143. (((uint32_t) (zend_uchar) (A)[1]) << 8) | \
  144. ((uint32_t) (zend_uchar) (A)[0])) : \
  145. (((uint32_t) (zend_uchar) (A)[2]) << 16) |\
  146. (((uint32_t) (zend_uchar) (A)[1]) << 8) | \
  147. ((uint32_t) (zend_uchar) (A)[0])))
  148. #define sint4korr(A) (int32_t) (((uint32_t) ((A)[0])) +\
  149. (((uint32_t) ((A)[1]) << 8)) +\
  150. (((uint32_t) ((A)[2]) << 16)) +\
  151. (((uint32_t) ((A)[3]) << 24)))
  152. #define sint8korr(A) (int64_t) uint8korr(A)
  153. #define uint2korr(A) (uint16_t) (((uint16_t) ((zend_uchar) (A)[0])) +\
  154. ((uint16_t) ((zend_uchar) (A)[1]) << 8))
  155. #define uint3korr(A) (uint32_t) (((uint32_t) ((zend_uchar) (A)[0])) +\
  156. (((uint32_t) ((zend_uchar) (A)[1])) << 8) +\
  157. (((uint32_t) ((zend_uchar) (A)[2])) << 16))
  158. #define uint4korr(A) (uint32_t) (((uint32_t) ((zend_uchar) (A)[0])) +\
  159. (((uint32_t) ((zend_uchar) (A)[1])) << 8) +\
  160. (((uint32_t) ((zend_uchar) (A)[2])) << 16) +\
  161. (((uint32_t) ((zend_uchar) (A)[3])) << 24))
  162. #define uint8korr(A) ((uint64_t)(((uint32_t) ((zend_uchar) (A)[0])) +\
  163. (((uint32_t) ((zend_uchar) (A)[1])) << 8) +\
  164. (((uint32_t) ((zend_uchar) (A)[2])) << 16) +\
  165. (((uint32_t) ((zend_uchar) (A)[3])) << 24)) +\
  166. (((uint64_t) (((uint32_t) ((zend_uchar) (A)[4])) +\
  167. (((uint32_t) ((zend_uchar) (A)[5])) << 8) +\
  168. (((uint32_t) ((zend_uchar) (A)[6])) << 16) +\
  169. (((uint32_t) ((zend_uchar) (A)[7])) << 24))) << 32))
  170. #define int2store(T,A) do { uint32_t def_temp= (uint32_t) (A) ;\
  171. *((zend_uchar*) (T)) = (zend_uchar)(def_temp); \
  172. *((zend_uchar*) (T+1)) = (zend_uchar)((def_temp >> 8)); } while (0)
  173. #define int3store(T,A) do { /*lint -save -e734 */\
  174. *(((char *)(T))) = (char) ((A));\
  175. *(((char *)(T))+1) = (char) (((A) >> 8));\
  176. *(((char *)(T))+2) = (char) (((A) >> 16)); \
  177. /*lint -restore */} while (0)
  178. #define int4store(T,A) do { \
  179. *(((char *)(T))) = (char) ((A));\
  180. *(((char *)(T))+1) = (char) (((A) >> 8));\
  181. *(((char *)(T))+2) = (char) (((A) >> 16));\
  182. *(((char *)(T))+3) = (char) (((A) >> 24)); } while (0)
  183. #define int5store(T,A) do { \
  184. *(((char *)(T))) = (char)((A));\
  185. *(((char *)(T))+1) = (char)(((A) >> 8));\
  186. *(((char *)(T))+2) = (char)(((A) >> 16));\
  187. *(((char *)(T))+3) = (char)(((A) >> 24)); \
  188. *(((char *)(T))+4) = (char)(((A) >> 32)); } while (0)
  189. #define int8store(T,A) { uint32_t def_temp= (uint32_t) (A), def_temp2= (uint32_t) ((A) >> 32); \
  190. int4store((T),def_temp); \
  191. int4store((T+4),def_temp2); \
  192. }
  193. #ifdef WORDS_BIGENDIAN
  194. #define float4get(V,M) do { float def_temp;\
  195. ((char*) &def_temp)[0] = (M)[3];\
  196. ((char*) &def_temp)[1] = (M)[2];\
  197. ((char*) &def_temp)[2] = (M)[1];\
  198. ((char*) &def_temp)[3] = (M)[0];\
  199. (V)=def_temp; } while (0)
  200. #define float8store(T,V) do { \
  201. *(((char *)(T))) = (char) ((char *) &(V))[7];\
  202. *(((char *)(T))+1) = (char) ((char *) &(V))[6];\
  203. *(((char *)(T))+2) = (char) ((char *) &(V))[5];\
  204. *(((char *)(T))+3) = (char) ((char *) &(V))[4];\
  205. *(((char *)(T))+4) = (char) ((char *) &(V))[3];\
  206. *(((char *)(T))+5) = (char) ((char *) &(V))[2];\
  207. *(((char *)(T))+6) = (char) ((char *) &(V))[1];\
  208. *(((char *)(T))+7) = (char) ((char *) &(V))[0]; } while (0)
  209. #define float8get(V,M) do { double def_temp;\
  210. ((char*) &def_temp)[0] = (M)[7];\
  211. ((char*) &def_temp)[1] = (M)[6];\
  212. ((char*) &def_temp)[2] = (M)[5];\
  213. ((char*) &def_temp)[3] = (M)[4];\
  214. ((char*) &def_temp)[4] = (M)[3];\
  215. ((char*) &def_temp)[5] = (M)[2];\
  216. ((char*) &def_temp)[6] = (M)[1];\
  217. ((char*) &def_temp)[7] = (M)[0];\
  218. (V) = def_temp; \
  219. } while (0)
  220. #else
  221. #define float4get(V,M) memcpy((char*) &(V),(char*) (M),sizeof(float))
  222. #if defined(__FLOAT_WORD_ORDER) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
  223. #define float8store(T,V) do { \
  224. *(((char *)(T)))= ((char *) &(V))[4];\
  225. *(((char *)(T))+1)=(char) ((char *) &(V))[5];\
  226. *(((char *)(T))+2)=(char) ((char *) &(V))[6];\
  227. *(((char *)(T))+3)=(char) ((char *) &(V))[7];\
  228. *(((char *)(T))+4)=(char) ((char *) &(V))[0];\
  229. *(((char *)(T))+5)=(char) ((char *) &(V))[1];\
  230. *(((char *)(T))+6)=(char) ((char *) &(V))[2];\
  231. *(((char *)(T))+7)=(char) ((char *) &(V))[3];} while (0)
  232. #define float8get(V,M) do { double def_temp;\
  233. ((char*) &def_temp)[0]=(M)[4];\
  234. ((char*) &def_temp)[1]=(M)[5];\
  235. ((char*) &def_temp)[2]=(M)[6];\
  236. ((char*) &def_temp)[3]=(M)[7];\
  237. ((char*) &def_temp)[4]=(M)[0];\
  238. ((char*) &def_temp)[5]=(M)[1];\
  239. ((char*) &def_temp)[6]=(M)[2];\
  240. ((char*) &def_temp)[7]=(M)[3];\
  241. (V) = def_temp; } while (0)
  242. #endif /* __FLOAT_WORD_ORDER */
  243. #endif /* WORDS_BIGENDIAN */
  244. #endif /* sint2korr */
  245. /* To here if the platform is not x86 or it's WIN64 */
  246. /* Define-funktions for reading and storing in machine format from/to
  247. short/long to/from some place in memory V should be a (not
  248. register) variable, M is a pointer to byte */
  249. #ifndef float8get
  250. #ifdef WORDS_BIGENDIAN
  251. #define float8get(V,M) memcpy((char*) &(V),(char*) (M), sizeof(double))
  252. #define float8store(T,V) memcpy((char*) (T),(char*) &(V), sizeof(double))
  253. #else
  254. #define float8get(V,M) memcpy((char*) &(V),(char*) (M),sizeof(double))
  255. #define float8store(T,V) memcpy((char*) (T),(char*) &(V),sizeof(double))
  256. #endif /* WORDS_BIGENDIAN */
  257. #endif /* float8get */
  258. #endif /* MYSQLND_PORTABILITY_H */