28
28
#else
29
29
#include <sys/param.h>
30
30
#endif
31
- #include "pack.h"
32
31
#ifdef HAVE_PWD_H
33
32
#ifdef PHP_WIN32
34
33
#include "win32/pwd.h"
50
49
} \
51
50
outputpos += (a)*(b);
52
51
52
+ typedef enum {
53
+ PHP_LITTLE_ENDIAN ,
54
+ PHP_BIG_ENDIAN ,
55
+ } php_pack_endianness ;
56
+
53
57
#ifdef WORDS_BIGENDIAN
54
- #define MACHINE_LITTLE_ENDIAN 0
58
+ # define MACHINE_LITTLE_ENDIAN 0
59
+ # define PHP_MACHINE_ENDIAN PHP_BIG_ENDIAN
55
60
#else
56
- #define MACHINE_LITTLE_ENDIAN 1
61
+ # define MACHINE_LITTLE_ENDIAN 1
62
+ # define PHP_MACHINE_ENDIAN PHP_LITTLE_ENDIAN
63
+ #endif
64
+
65
+ #ifdef ZEND_ENABLE_ZVAL_LONG64
66
+ # define PHP_LONG_BSWAP (u ) ZEND_BYTES_SWAP64(u)
67
+ #else
68
+ # define PHP_LONG_BSWAP (u ) ZEND_BYTES_SWAP32(u)
57
69
#endif
58
70
59
71
typedef ZEND_SET_ALIGNED (1 , uint16_t unaligned_uint16_t ) ;
@@ -62,40 +74,19 @@ typedef ZEND_SET_ALIGNED(1, uint64_t unaligned_uint64_t);
62
74
typedef ZEND_SET_ALIGNED (1 , unsigned int unaligned_uint ) ;
63
75
typedef ZEND_SET_ALIGNED (1 , int unaligned_int ) ;
64
76
65
- /* Mapping of byte from char (8bit) to long for machine endian */
66
- static int byte_map [1 ];
67
-
68
- /* Mappings of bytes from int (machine dependent) to int for machine endian */
69
- static int int_map [sizeof (int )];
70
-
71
- /* Mappings of bytes from shorts (16bit) for all endian environments */
72
- static int machine_endian_short_map [2 ];
73
- static int big_endian_short_map [2 ];
74
- static int little_endian_short_map [2 ];
75
-
76
- /* Mappings of bytes from longs (32bit) for all endian environments */
77
- static int machine_endian_long_map [4 ];
78
- static int big_endian_long_map [4 ];
79
- static int little_endian_long_map [4 ];
80
-
81
- #if SIZEOF_ZEND_LONG > 4
82
- /* Mappings of bytes from quads (64bit) for all endian environments */
83
- static int machine_endian_longlong_map [8 ];
84
- static int big_endian_longlong_map [8 ];
85
- static int little_endian_longlong_map [8 ];
86
- #endif
87
-
88
77
/* {{{ php_pack */
89
- static void php_pack (zval * val , size_t size , int * map , char * output )
78
+ static void php_pack (const zval * val , size_t size , php_pack_endianness endianness , char * output )
90
79
{
91
- size_t i ;
92
- char * v ;
80
+ zend_ulong zl = zval_get_long (val );
93
81
94
- convert_to_long (val );
95
- v = (char * ) & Z_LVAL_P (val );
82
+ const char * v = (const char * ) & zl ;
83
+ if ((endianness == PHP_LITTLE_ENDIAN ) != MACHINE_LITTLE_ENDIAN ) {
84
+ zl = PHP_LONG_BSWAP (zl );
85
+ v += sizeof (zend_long ) - size ;
86
+ }
96
87
97
- for ( i = 0 ; i < size ; i ++ ) {
98
- * output ++ = v [ map [ i ]] ;
88
+ while ( size -- > 0 ) {
89
+ * output ++ = * v ++ ;
99
90
}
100
91
}
101
92
/* }}} */
@@ -529,7 +520,7 @@ PHP_FUNCTION(pack)
529
520
case 'c' :
530
521
case 'C' :
531
522
while (arg -- > 0 ) {
532
- php_pack (& argv [currentarg ++ ], 1 , byte_map , & ZSTR_VAL (output )[outputpos ]);
523
+ php_pack (& argv [currentarg ++ ], 1 , PHP_MACHINE_ENDIAN , & ZSTR_VAL (output )[outputpos ]);
533
524
outputpos ++ ;
534
525
}
535
526
break ;
@@ -538,16 +529,16 @@ PHP_FUNCTION(pack)
538
529
case 'S' :
539
530
case 'n' :
540
531
case 'v' : {
541
- int * map = machine_endian_short_map ;
532
+ php_pack_endianness endianness = PHP_MACHINE_ENDIAN ;
542
533
543
534
if (code == 'n' ) {
544
- map = big_endian_short_map ;
535
+ endianness = PHP_BIG_ENDIAN ;
545
536
} else if (code == 'v' ) {
546
- map = little_endian_short_map ;
537
+ endianness = PHP_LITTLE_ENDIAN ;
547
538
}
548
539
549
540
while (arg -- > 0 ) {
550
- php_pack (& argv [currentarg ++ ], 2 , map , & ZSTR_VAL (output )[outputpos ]);
541
+ php_pack (& argv [currentarg ++ ], 2 , endianness , & ZSTR_VAL (output )[outputpos ]);
551
542
outputpos += 2 ;
552
543
}
553
544
break ;
@@ -556,7 +547,7 @@ PHP_FUNCTION(pack)
556
547
case 'i' :
557
548
case 'I' :
558
549
while (arg -- > 0 ) {
559
- php_pack (& argv [currentarg ++ ], sizeof (int ), int_map , & ZSTR_VAL (output )[outputpos ]);
550
+ php_pack (& argv [currentarg ++ ], sizeof (int ), PHP_MACHINE_ENDIAN , & ZSTR_VAL (output )[outputpos ]);
560
551
outputpos += sizeof (int );
561
552
}
562
553
break ;
@@ -565,16 +556,16 @@ PHP_FUNCTION(pack)
565
556
case 'L' :
566
557
case 'N' :
567
558
case 'V' : {
568
- int * map = machine_endian_long_map ;
559
+ php_pack_endianness endianness = PHP_MACHINE_ENDIAN ;
569
560
570
561
if (code == 'N' ) {
571
- map = big_endian_long_map ;
562
+ endianness = PHP_BIG_ENDIAN ;
572
563
} else if (code == 'V' ) {
573
- map = little_endian_long_map ;
564
+ endianness = PHP_LITTLE_ENDIAN ;
574
565
}
575
566
576
567
while (arg -- > 0 ) {
577
- php_pack (& argv [currentarg ++ ], 4 , map , & ZSTR_VAL (output )[outputpos ]);
568
+ php_pack (& argv [currentarg ++ ], 4 , endianness , & ZSTR_VAL (output )[outputpos ]);
578
569
outputpos += 4 ;
579
570
}
580
571
break ;
@@ -585,16 +576,16 @@ PHP_FUNCTION(pack)
585
576
case 'Q' :
586
577
case 'J' :
587
578
case 'P' : {
588
- int * map = machine_endian_longlong_map ;
579
+ php_pack_endianness endianness = PHP_MACHINE_ENDIAN ;
589
580
590
581
if (code == 'J' ) {
591
- map = big_endian_longlong_map ;
582
+ endianness = PHP_BIG_ENDIAN ;
592
583
} else if (code == 'P' ) {
593
- map = little_endian_longlong_map ;
584
+ endianness = PHP_LITTLE_ENDIAN ;
594
585
}
595
586
596
587
while (arg -- > 0 ) {
597
- php_pack (& argv [currentarg ++ ], 8 , map , & ZSTR_VAL (output )[outputpos ]);
588
+ php_pack (& argv [currentarg ++ ], 8 , endianness , & ZSTR_VAL (output )[outputpos ]);
598
589
outputpos += 8 ;
599
590
}
600
591
break ;
@@ -1199,127 +1190,3 @@ PHP_FUNCTION(unpack)
1199
1190
}
1200
1191
}
1201
1192
/* }}} */
1202
-
1203
- /* {{{ PHP_MINIT_FUNCTION */
1204
- PHP_MINIT_FUNCTION (pack )
1205
- {
1206
- int i ;
1207
-
1208
- if (MACHINE_LITTLE_ENDIAN ) {
1209
- /* Where to get lo to hi bytes from */
1210
- byte_map [0 ] = 0 ;
1211
-
1212
- for (i = 0 ; i < (int )sizeof (int ); i ++ ) {
1213
- int_map [i ] = i ;
1214
- }
1215
-
1216
- machine_endian_short_map [0 ] = 0 ;
1217
- machine_endian_short_map [1 ] = 1 ;
1218
- big_endian_short_map [0 ] = 1 ;
1219
- big_endian_short_map [1 ] = 0 ;
1220
- little_endian_short_map [0 ] = 0 ;
1221
- little_endian_short_map [1 ] = 1 ;
1222
-
1223
- machine_endian_long_map [0 ] = 0 ;
1224
- machine_endian_long_map [1 ] = 1 ;
1225
- machine_endian_long_map [2 ] = 2 ;
1226
- machine_endian_long_map [3 ] = 3 ;
1227
- big_endian_long_map [0 ] = 3 ;
1228
- big_endian_long_map [1 ] = 2 ;
1229
- big_endian_long_map [2 ] = 1 ;
1230
- big_endian_long_map [3 ] = 0 ;
1231
- little_endian_long_map [0 ] = 0 ;
1232
- little_endian_long_map [1 ] = 1 ;
1233
- little_endian_long_map [2 ] = 2 ;
1234
- little_endian_long_map [3 ] = 3 ;
1235
-
1236
- #if SIZEOF_ZEND_LONG > 4
1237
- machine_endian_longlong_map [0 ] = 0 ;
1238
- machine_endian_longlong_map [1 ] = 1 ;
1239
- machine_endian_longlong_map [2 ] = 2 ;
1240
- machine_endian_longlong_map [3 ] = 3 ;
1241
- machine_endian_longlong_map [4 ] = 4 ;
1242
- machine_endian_longlong_map [5 ] = 5 ;
1243
- machine_endian_longlong_map [6 ] = 6 ;
1244
- machine_endian_longlong_map [7 ] = 7 ;
1245
- big_endian_longlong_map [0 ] = 7 ;
1246
- big_endian_longlong_map [1 ] = 6 ;
1247
- big_endian_longlong_map [2 ] = 5 ;
1248
- big_endian_longlong_map [3 ] = 4 ;
1249
- big_endian_longlong_map [4 ] = 3 ;
1250
- big_endian_longlong_map [5 ] = 2 ;
1251
- big_endian_longlong_map [6 ] = 1 ;
1252
- big_endian_longlong_map [7 ] = 0 ;
1253
- little_endian_longlong_map [0 ] = 0 ;
1254
- little_endian_longlong_map [1 ] = 1 ;
1255
- little_endian_longlong_map [2 ] = 2 ;
1256
- little_endian_longlong_map [3 ] = 3 ;
1257
- little_endian_longlong_map [4 ] = 4 ;
1258
- little_endian_longlong_map [5 ] = 5 ;
1259
- little_endian_longlong_map [6 ] = 6 ;
1260
- little_endian_longlong_map [7 ] = 7 ;
1261
- #endif
1262
- }
1263
- else {
1264
- zval val ;
1265
- int size = sizeof (Z_LVAL (val ));
1266
- Z_LVAL (val )= 0 ; /*silence a warning*/
1267
-
1268
- /* Where to get hi to lo bytes from */
1269
- byte_map [0 ] = size - 1 ;
1270
-
1271
- for (i = 0 ; i < (int )sizeof (int ); i ++ ) {
1272
- int_map [i ] = size - (sizeof (int ) - i );
1273
- }
1274
-
1275
- machine_endian_short_map [0 ] = size - 2 ;
1276
- machine_endian_short_map [1 ] = size - 1 ;
1277
- big_endian_short_map [0 ] = size - 2 ;
1278
- big_endian_short_map [1 ] = size - 1 ;
1279
- little_endian_short_map [0 ] = size - 1 ;
1280
- little_endian_short_map [1 ] = size - 2 ;
1281
-
1282
- machine_endian_long_map [0 ] = size - 4 ;
1283
- machine_endian_long_map [1 ] = size - 3 ;
1284
- machine_endian_long_map [2 ] = size - 2 ;
1285
- machine_endian_long_map [3 ] = size - 1 ;
1286
- big_endian_long_map [0 ] = size - 4 ;
1287
- big_endian_long_map [1 ] = size - 3 ;
1288
- big_endian_long_map [2 ] = size - 2 ;
1289
- big_endian_long_map [3 ] = size - 1 ;
1290
- little_endian_long_map [0 ] = size - 1 ;
1291
- little_endian_long_map [1 ] = size - 2 ;
1292
- little_endian_long_map [2 ] = size - 3 ;
1293
- little_endian_long_map [3 ] = size - 4 ;
1294
-
1295
- #if SIZEOF_ZEND_LONG > 4
1296
- machine_endian_longlong_map [0 ] = size - 8 ;
1297
- machine_endian_longlong_map [1 ] = size - 7 ;
1298
- machine_endian_longlong_map [2 ] = size - 6 ;
1299
- machine_endian_longlong_map [3 ] = size - 5 ;
1300
- machine_endian_longlong_map [4 ] = size - 4 ;
1301
- machine_endian_longlong_map [5 ] = size - 3 ;
1302
- machine_endian_longlong_map [6 ] = size - 2 ;
1303
- machine_endian_longlong_map [7 ] = size - 1 ;
1304
- big_endian_longlong_map [0 ] = size - 8 ;
1305
- big_endian_longlong_map [1 ] = size - 7 ;
1306
- big_endian_longlong_map [2 ] = size - 6 ;
1307
- big_endian_longlong_map [3 ] = size - 5 ;
1308
- big_endian_longlong_map [4 ] = size - 4 ;
1309
- big_endian_longlong_map [5 ] = size - 3 ;
1310
- big_endian_longlong_map [6 ] = size - 2 ;
1311
- big_endian_longlong_map [7 ] = size - 1 ;
1312
- little_endian_longlong_map [0 ] = size - 1 ;
1313
- little_endian_longlong_map [1 ] = size - 2 ;
1314
- little_endian_longlong_map [2 ] = size - 3 ;
1315
- little_endian_longlong_map [3 ] = size - 4 ;
1316
- little_endian_longlong_map [4 ] = size - 5 ;
1317
- little_endian_longlong_map [5 ] = size - 6 ;
1318
- little_endian_longlong_map [6 ] = size - 7 ;
1319
- little_endian_longlong_map [7 ] = size - 8 ;
1320
- #endif
1321
- }
1322
-
1323
- return SUCCESS ;
1324
- }
1325
- /* }}} */
0 commit comments