xref: /PHP-7.0/ext/mysqlnd/mysqlnd_portability.h (revision f2ab731a)
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 /*
5   Parts of the original, which are not applicable to mysqlnd have been removed.
6 
7   With small modifications, mostly casting but adding few more macros by
8   Andrey Hristov <andrey@php.net> . The additions are in the public domain and
9   were added to improve the header file, to get it more consistent.
10 */
11 
12 #ifndef MYSQLND_PORTABILITY_H
13 #define MYSQLND_PORTABILITY_H
14 
15 
16 
17 /* Comes from global.h as OFFSET, renamed to STRUCT_OFFSET */
18 #define STRUCT_OFFSET(t, f)   ((size_t)(char *)&((t *)0)->f)
19 
20 #ifndef __attribute
21 #if !defined(__GNUC__)
22 #define __attribute(A)
23 #endif
24 #endif
25 
26 #ifdef __CYGWIN__
27 /* We use a Unix API, so pretend it's not Windows */
28 #undef WIN
29 #undef WIN32
30 #undef _WIN
31 #undef _WIN32
32 #undef _WIN64
33 #undef __WIN__
34 #undef __WIN32__
35 #endif /* __CYGWIN__ */
36 
37 #if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
38 #  include "ext/mysqlnd/config-win.h"
39 #endif /* _WIN32... */
40 
41 #if __STDC_VERSION__ < 199901L && !defined(atoll)
42   /* "inline" is a keyword */
43   #define atoll atol
44 #endif
45 
46 #include "php_stdint.h"
47 
48 #if SIZEOF_LONG_LONG > 4 && !defined(_LONG_LONG)
49 #define _LONG_LONG 1        /* For AIX string library */
50 #endif
51 
52 
53 /* Go around some bugs in different OS and compilers */
54 #if defined(_HPUX_SOURCE) && defined(HAVE_SYS_STREAM_H)
55 #include <sys/stream.h>        /* HPUX 10.20 defines ulong here. UGLY !!! */
56 #define HAVE_ULONG
57 #endif
58 
59 
60 #if SIZEOF_LONG_LONG > 4
61 #define HAVE_LONG_LONG 1
62 #endif
63 
64 #ifdef PHP_WIN32
65 #define MYSQLND_LLU_SPEC "%I64u"
66 #define MYSQLND_LL_SPEC "%I64d"
67 #define MYSQLND_SZ_T_SPEC "%Id"
68 #ifndef L64
69 #define L64(x) x##i64
70 #endif
71 #else
72 
73 #if __i386__
74 #define MYSQLND_LL_SPEC	"%lli"
75 #define MYSQLND_LLU_SPEC "%llu"
76 #endif
77 
78 #if __ia64__
79 #define MYSQLND_LL_SPEC	"%li"
80 #define MYSQLND_LLU_SPEC "%lu"
81 #endif
82 
83 #if __powerpc64__ || __ppc64__
84 #define MYSQLND_LL_SPEC	"%li"
85 #define MYSQLND_LLU_SPEC "%lu"
86 #endif
87 
88 #if (__powerpc__ || __ppc__ ) && !(__powerpc64__ || __ppc64__)
89 #define MYSQLND_LL_SPEC	"%lli"
90 #define MYSQLND_LLU_SPEC "%llu"
91 #endif
92 
93 #if __x86_64__
94 #define MYSQLND_LL_SPEC	"%li"
95 #define MYSQLND_LLU_SPEC "%lu"
96 #endif
97 
98 #if __s390x__
99 #define MYSQLND_LL_SPEC	"%li"
100 #define MYSQLND_LLU_SPEC "%lu"
101 #endif
102 
103 #if __s390__ && !__s390x__
104 #define MYSQLND_LL_SPEC	"%lli"
105 #define MYSQLND_LLU_SPEC "%llu"
106 #endif
107 
108 #ifdef _AIX
109 #define MYSQLND_LL_SPEC "%lli"
110 #define MYSQLND_LLU_SPEC "%llu"
111 #endif
112 
113 #ifndef MYSQLND_LL_SPEC
114   #if SIZEOF_LONG == 8
115     #define MYSQLND_LL_SPEC "%li"
116   #elif SIZEOF_LONG == 4
117     #define MYSQLND_LL_SPEC "%lli"
118   #endif
119 #endif
120 
121 #ifndef MYSQLND_LLU_SPEC
122   #if SIZEOF_LONG == 8
123     #define MYSQLND_LLU_SPEC "%lu"
124   #elif SIZEOF_LONG == 4
125     #define MYSQLND_LLU_SPEC "%llu"
126    #endif
127 #endif /* MYSQLND_LLU_SPEC*/
128 
129 
130 #define MYSQLND_SZ_T_SPEC "%zd"
131 #ifndef L64
132 #define L64(x) x##LL
133 #endif
134 #endif
135 
136 
137 #define int1store(T,A)	do { *((int8_t*) (T)) = (A); } while(0)
138 #define uint1korr(A)	(*(((uint8_t*)(A))))
139 
140 /* Bit values are sent in reverted order of bytes, compared to normal !!! */
141 #define bit_uint2korr(A) ((uint16_t) (((uint16_t) (((unsigned char*) (A))[1])) +\
142                                    ((uint16_t) (((unsigned char*) (A))[0]) << 8)))
143 #define bit_uint3korr(A) ((uint32_t) (((uint32_t) (((unsigned char*) (A))[2])) +\
144                                    (((uint32_t) (((unsigned char*) (A))[1])) << 8) +\
145                                    (((uint32_t) (((unsigned char*) (A))[0])) << 16)))
146 #define bit_uint4korr(A) ((uint32_t) (((uint32_t) (((unsigned char*) (A))[3])) +\
147                                    (((uint32_t) (((unsigned char*) (A))[2])) << 8) +\
148                                    (((uint32_t) (((unsigned char*) (A))[1])) << 16) +\
149                                    (((uint32_t) (((unsigned char*) (A))[0])) << 24)))
150 #define bit_uint5korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[4])) +\
151                                     (((uint32_t) (((unsigned char*) (A))[3])) << 8) +\
152                                     (((uint32_t) (((unsigned char*) (A))[2])) << 16) +\
153                                    (((uint32_t) (((unsigned char*) (A))[1])) << 24)) +\
154                                     (((uint64_t) (((unsigned char*) (A))[0])) << 32))
155 #define bit_uint6korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[5])) +\
156                                     (((uint32_t) (((unsigned char*) (A))[4])) << 8) +\
157                                     (((uint32_t) (((unsigned char*) (A))[3])) << 16) +\
158                                     (((uint32_t) (((unsigned char*) (A))[2])) << 24)) +\
159                         (((uint64_t) (((uint32_t) (((unsigned char*) (A))[1])) +\
160                                     (((uint32_t) (((unsigned char*) (A))[0]) << 8)))) <<\
161                                      32))
162 #define bit_uint7korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[6])) +\
163                                     (((uint32_t) (((unsigned char*) (A))[5])) << 8) +\
164                                     (((uint32_t) (((unsigned char*) (A))[4])) << 16) +\
165                                    (((uint32_t) (((unsigned char*) (A))[3])) << 24)) +\
166                         (((uint64_t) (((uint32_t) (((unsigned char*) (A))[2])) +\
167                                     (((uint32_t) (((unsigned char*) (A))[1])) << 8) +\
168                                     (((uint32_t) (((unsigned char*) (A))[0])) << 16))) <<\
169                                      32))
170 #define bit_uint8korr(A) ((uint64_t)(((uint32_t) (((unsigned char*) (A))[7])) +\
171                                     (((uint32_t) (((unsigned char*) (A))[6])) << 8) +\
172                                     (((uint32_t) (((unsigned char*) (A))[5])) << 16) +\
173                                     (((uint32_t) (((unsigned char*) (A))[4])) << 24)) +\
174                         (((uint64_t) (((uint32_t) (((unsigned char*) (A))[3])) +\
175                                     (((uint32_t) (((unsigned char*) (A))[2])) << 8) +\
176                                     (((uint32_t) (((unsigned char*) (A))[1])) << 16) +\
177                                     (((uint32_t) (((unsigned char*) (A))[0])) << 24))) <<\
178                                     32))
179 
180 
181 /*
182 ** Define-funktions for reading and storing in machine independent format
183 **  (low byte first)
184 */
185 
186 /* Optimized store functions for Intel x86, non-valid for WIN64. __i386__ is GCC */
187 #if defined(__i386__) && !defined(_WIN64)
188 #define sint2korr(A)    (*((int16_t *) (A)))
189 #define sint3korr(A)    ((int32_t) ((((zend_uchar) (A)[2]) & 128) ? \
190                    (((uint32_t) 255L << 24) | \
191                    (((uint32_t) (zend_uchar) (A)[2]) << 16) |\
192                    (((uint32_t) (zend_uchar) (A)[1]) << 8) | \
193                     ((uint32_t) (zend_uchar) (A)[0])) : \
194                    (((uint32_t) (zend_uchar) (A)[2]) << 16) |\
195                    (((uint32_t) (zend_uchar) (A)[1]) << 8) | \
196                     ((uint32_t) (zend_uchar) (A)[0])))
197 #define sint4korr(A)  (*((zend_long *) (A)))
198 
199 #define uint2korr(A)  (*((uint16_t *) (A)))
200 #define uint3korr(A)  (uint32_t) (((uint32_t) ((zend_uchar) (A)[0])) +\
201                                (((uint32_t) ((zend_uchar) (A)[1])) << 8) +\
202                                (((uint32_t) ((zend_uchar) (A)[2])) << 16))
203 #define uint4korr(A)  (*((zend_ulong *) (A)))
204 
205 
206 
207 #define uint8korr(A)    (*((uint64_t *) (A)))
208 #define sint8korr(A)    (*((int64_t *) (A)))
209 #define int2store(T,A)    *((uint16_t*) (T))= (uint16_t) (A)
210 #define int3store(T,A)   { \
211                   *(T)=  (zend_uchar) ((A));\
212                   *(T+1)=(zend_uchar) (((uint32_t) (A) >> 8));\
213                   *(T+2)=(zend_uchar) (((A) >> 16)); }
214 #define int4store(T,A)    *((zend_long *) (T))= (zend_long) (A)
215 #define int5store(T,A)    { \
216               *((zend_uchar *)(T))= (zend_uchar)((A));\
217               *(((zend_uchar *)(T))+1)=(zend_uchar) (((A) >> 8));\
218               *(((zend_uchar *)(T))+2)=(zend_uchar) (((A) >> 16));\
219               *(((zend_uchar *)(T))+3)=(zend_uchar) (((A) >> 24)); \
220               *(((zend_uchar *)(T))+4)=(zend_uchar) (((A) >> 32)); }
221 
222 /* From Andrey Hristov, based on int5store() */
223 #define int6store(T,A)    { \
224               *(((zend_uchar *)(T)))= (zend_uchar)((A));\
225               *(((zend_uchar *)(T))+1))=(zend_uchar) (((A) >> 8));\
226               *(((zend_uchar *)(T))+2))=(zend_uchar) (((A) >> 16));\
227               *(((zend_uchar *)(T))+3))=(zend_uchar) (((A) >> 24)); \
228               *(((zend_uchar *)(T))+4))=(zend_uchar) (((A) >> 32)); \
229               *(((zend_uchar *)(T))+5))=(zend_uchar) (((A) >> 40)); }
230 
231 #define int8store(T,A)    *((uint64_t *) (T))= (uint64_t) (A)
232 
233 typedef union {
234   double v;
235   zend_long m[2];
236 } float8get_union;
237 #define float8get(V,M)    { ((float8get_union *)&(V))->m[0] = *((zend_long*) (M)); \
238                             ((float8get_union *)&(V))->m[1] = *(((zend_long*) (M))+1); }
239 #define float8store(T,V) { *((zend_long *) (T))     = ((float8get_union *)&(V))->m[0]; \
240                            *(((zend_long *) (T))+1) = ((float8get_union *)&(V))->m[1]; }
241 #define float4get(V,M)	{ *((float *) &(V)) = *((float*) (M)); }
242 /* From Andrey Hristov based on float8get */
243 #define floatget(V,M)    memcpy((char*) &(V),(char*) (M),sizeof(float))
244 #endif /* __i386__ */
245 
246 
247 /* If we haven't defined sint2korr, which is because the platform is not x86 or it's WIN64 */
248 #ifndef sint2korr
249 #define sint2korr(A)    (int16_t) (((int16_t) ((zend_uchar) (A)[0])) +\
250                                  ((int16_t) ((int16_t) (A)[1]) << 8))
251 #define sint3korr(A)    ((int32_t) ((((zend_uchar) (A)[2]) & 128) ? \
252                   (((uint32_t) 255L << 24) | \
253                   (((uint32_t) (zend_uchar) (A)[2]) << 16) |\
254                   (((uint32_t) (zend_uchar) (A)[1]) << 8) | \
255                    ((uint32_t) (zend_uchar) (A)[0])) : \
256                   (((uint32_t) (zend_uchar) (A)[2]) << 16) |\
257                   (((uint32_t) (zend_uchar) (A)[1]) << 8) | \
258                   ((uint32_t) (zend_uchar) (A)[0])))
259 #define sint4korr(A)  (int32_t) (((int32_t) ((zend_uchar) (A)[0])) +\
260                               (((int32_t) ((zend_uchar) (A)[1]) << 8)) +\
261                               (((int32_t) ((zend_uchar) (A)[2]) << 16)) +\
262                               (((int32_t) ((int16_t) (A)[3]) << 24)))
263 
264 #define sint8korr(A)  (int64_t) uint8korr(A)
265 #define uint2korr(A)  (uint16_t) (((uint16_t) ((zend_uchar) (A)[0])) +\
266                                ((uint16_t) ((zend_uchar) (A)[1]) << 8))
267 #define uint3korr(A)  (uint32_t) (((uint32_t) ((zend_uchar) (A)[0])) +\
268                                (((uint32_t) ((zend_uchar) (A)[1])) << 8) +\
269                                (((uint32_t) ((zend_uchar) (A)[2])) << 16))
270 #define uint4korr(A)  (uint32_t) (((uint32_t) ((zend_uchar) (A)[0])) +\
271                                (((uint32_t) ((zend_uchar) (A)[1])) << 8) +\
272                                (((uint32_t) ((zend_uchar) (A)[2])) << 16) +\
273                                (((uint32_t) ((zend_uchar) (A)[3])) << 24))
274 
275 #define uint8korr(A)	((uint64_t)(((uint32_t) ((zend_uchar) (A)[0])) +\
276 									(((uint32_t) ((zend_uchar) (A)[1])) << 8) +\
277 									(((uint32_t) ((zend_uchar) (A)[2])) << 16) +\
278 									(((uint32_t) ((zend_uchar) (A)[3])) << 24)) +\
279 									(((uint64_t) (((uint32_t) ((zend_uchar) (A)[4])) +\
280 									(((uint32_t) ((zend_uchar) (A)[5])) << 8) +\
281 									(((uint32_t) ((zend_uchar) (A)[6])) << 16) +\
282 									(((uint32_t) ((zend_uchar) (A)[7])) << 24))) << 32))
283 
284 
285 #define int2store(T,A)  do { uint32_t def_temp= (uint32_t) (A) ;\
286                   *((zend_uchar*) (T))  =  (zend_uchar)(def_temp); \
287                   *((zend_uchar*) (T+1)) = (zend_uchar)((def_temp >> 8)); } while (0)
288 #define int3store(T,A)  do { /*lint -save -e734 */\
289                   *(((char *)(T)))   = (char) ((A));\
290                   *(((char *)(T))+1) = (char) (((A) >> 8));\
291                   *(((char *)(T))+2) = (char) (((A) >> 16)); \
292                   /*lint -restore */} while (0)
293 #define int4store(T,A)  do { \
294                   *(((char *)(T)))   = (char) ((A));\
295                   *(((char *)(T))+1) = (char) (((A) >> 8));\
296                   *(((char *)(T))+2) = (char) (((A) >> 16));\
297                   *(((char *)(T))+3) = (char) (((A) >> 24)); } while (0)
298 #define int5store(T,A)  do { \
299                   *(((char *)(T)))   = (char)((A));\
300                   *(((char *)(T))+1) = (char)(((A) >> 8));\
301                   *(((char *)(T))+2) = (char)(((A) >> 16));\
302                   *(((char *)(T))+3) = (char)(((A) >> 24)); \
303                   *(((char *)(T))+4) = (char)(((A) >> 32)); } while (0)
304 /* Based on int5store() from Andrey Hristov */
305 #define int6store(T,A)  do { \
306                   *(((char *)(T)))   = (char)((A));\
307                   *(((char *)(T))+1) = (char)(((A) >> 8));\
308                   *(((char *)(T))+2) = (char)(((A) >> 16));\
309                   *(((char *)(T))+3) = (char)(((A) >> 24)); \
310                   *(((char *)(T))+4) = (char)(((A) >> 32)); \
311                   *(((char *)(T))+5) = (char)(((A) >> 40)); } while (0)
312 #define int8store(T,A)        { uint32_t def_temp= (uint32_t) (A), def_temp2= (uint32_t) ((A) >> 32); \
313                   int4store((T),def_temp); \
314                   int4store((T+4),def_temp2); \
315                 }
316 #ifdef WORDS_BIGENDIAN
317 #define float4get(V,M)   do { float def_temp;\
318                           ((char*) &def_temp)[0] = (M)[3];\
319                           ((char*) &def_temp)[1] = (M)[2];\
320                           ((char*) &def_temp)[2] = (M)[1];\
321                           ((char*) &def_temp)[3] = (M)[0];\
322                           (V)=def_temp; } while (0)
323 #define float8store(T,V)  do { \
324                            *(((char *)(T)))   = (char) ((char *) &(V))[7];\
325                            *(((char *)(T))+1) = (char) ((char *) &(V))[6];\
326                            *(((char *)(T))+2) = (char) ((char *) &(V))[5];\
327                            *(((char *)(T))+3) = (char) ((char *) &(V))[4];\
328                            *(((char *)(T))+4) = (char) ((char *) &(V))[3];\
329                            *(((char *)(T))+5) = (char) ((char *) &(V))[2];\
330                            *(((char *)(T))+6) = (char) ((char *) &(V))[1];\
331                            *(((char *)(T))+7) = (char) ((char *) &(V))[0]; } while (0)
332 
333 #define float8get(V,M)   do { double def_temp;\
334                           ((char*) &def_temp)[0] = (M)[7];\
335                           ((char*) &def_temp)[1] = (M)[6];\
336                           ((char*) &def_temp)[2] = (M)[5];\
337                           ((char*) &def_temp)[3] = (M)[4];\
338                           ((char*) &def_temp)[4] = (M)[3];\
339                           ((char*) &def_temp)[5] = (M)[2];\
340                           ((char*) &def_temp)[6] = (M)[1];\
341                           ((char*) &def_temp)[7] = (M)[0];\
342                           (V) = def_temp; \
343                          } while (0)
344 #else
345 #define float4get(V,M)   memcpy((char*) &(V),(char*) (M),sizeof(float))
346 
347 #if defined(__FLOAT_WORD_ORDER) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
348 #define float8store(T,V)  do { \
349                          *(((char *)(T)))= ((char *) &(V))[4];\
350                          *(((char *)(T))+1)=(char) ((char *) &(V))[5];\
351                          *(((char *)(T))+2)=(char) ((char *) &(V))[6];\
352                          *(((char *)(T))+3)=(char) ((char *) &(V))[7];\
353                          *(((char *)(T))+4)=(char) ((char *) &(V))[0];\
354                          *(((char *)(T))+5)=(char) ((char *) &(V))[1];\
355                          *(((char *)(T))+6)=(char) ((char *) &(V))[2];\
356                          *(((char *)(T))+7)=(char) ((char *) &(V))[3];} while (0)
357 #define float8get(V,M) do { double def_temp;\
358                          ((char*) &def_temp)[0]=(M)[4];\
359                          ((char*) &def_temp)[1]=(M)[5];\
360                          ((char*) &def_temp)[2]=(M)[6];\
361                          ((char*) &def_temp)[3]=(M)[7];\
362                          ((char*) &def_temp)[4]=(M)[0];\
363                          ((char*) &def_temp)[5]=(M)[1];\
364                          ((char*) &def_temp)[6]=(M)[2];\
365                          ((char*) &def_temp)[7]=(M)[3];\
366                          (V) = def_temp; } while (0)
367 #endif /* __FLOAT_WORD_ORDER */
368 
369 #endif /* WORDS_BIGENDIAN */
370 
371 #endif /* sint2korr */
372 /* To here if the platform is not x86 or it's WIN64 */
373 
374 
375 /* Define-funktions for reading and storing in machine format from/to
376    short/long to/from some place in memory V should be a (not
377    register) variable, M is a pointer to byte */
378 
379 #ifndef float8get
380 
381 #ifdef WORDS_BIGENDIAN
382 #define float8get(V,M)		memcpy((char*) &(V),(char*)  (M), sizeof(double))
383 #define float8store(T,V)	memcpy((char*)  (T),(char*) &(V), sizeof(double))
384 #else
385 #define float8get(V,M)    memcpy((char*) &(V),(char*) (M),sizeof(double))
386 #define float8store(T,V)  memcpy((char*) (T),(char*) &(V),sizeof(double))
387 #endif /* WORDS_BIGENDIAN */
388 
389 #endif /* float8get */
390 
391 #endif /* MYSQLND_PORTABILITY_H */
392 
393 
394 /*
395  * Local variables:
396  * tab-width: 4
397  * c-basic-offset: 4
398  * End:
399  * vim600: noet sw=4 ts=4 fdm=marker
400  * vim<600: noet sw=4 ts=4
401  */
402