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@mysql.com> . 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) (*((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) (*((unsigned long *) (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) *((long *) (T))= (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 long m[2]; 236 } float8get_union; 237 #define float8get(V,M) { ((float8get_union *)&(V))->m[0] = *((long*) (M)); \ 238 ((float8get_union *)&(V))->m[1] = *(((long*) (M))+1); } 239 #define float8store(T,V) { *((long *) (T)) = ((float8get_union *)&(V))->m[0]; \ 240 *(((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