Skip to content

Commit cef8afe

Browse files
committed
Move tools to utils.{c,h} + fix bug with reference encoding
closes gh-93
1 parent 776d820 commit cef8afe

File tree

7 files changed

+133
-60
lines changed

7 files changed

+133
-60
lines changed

config.m4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ if test "$PHP_TARANTOOL" != "no"; then
1111
src/tarantool_proto.c \
1212
src/tarantool_tp.c \
1313
src/tarantool_exception.c \
14+
src/utils.c \
1415
src/third_party/msgpuck.c \
1516
src/third_party/sha1.c \
1617
src/third_party/base64_tp.c \

src/tarantool.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include "tarantool_network.h"
1313
#include "tarantool_exception.h"
1414

15+
#include "utils.h"
16+
1517
int __tarantool_authenticate(tarantool_connection *obj);
1618

1719
double
@@ -466,8 +468,8 @@ static int64_t tarantool_step_recv(
466468
} else {
467469
tarantool_throw_exception(
468470
"Bad error field type. Expected"
469-
" STRING, got %s", op_to_string(
470-
z_error_str));
471+
" STRING, got %s",
472+
tutils_op_to_string(z_error_str));
471473
goto error;
472474
}
473475
} else {
@@ -601,7 +603,8 @@ int convert_iterator(zval *iter, int all) {
601603
return Z_LVAL_P(iter);
602604
} else if (Z_TYPE_P(iter) != IS_STRING) {
603605
tarantool_throw_exception("Bad iterator type, expected NULL/STR"
604-
"ING/LONG, got %s", op_to_string(iter));
606+
"ING/LONG, got %s",
607+
tutils_op_to_string(iter));
605608
}
606609
const char *iter_str = Z_STRVAL_P(iter);
607610
size_t iter_str_len = Z_STRLEN_P(iter);
@@ -660,7 +663,7 @@ int get_spaceno_by_name(tarantool_connection *obj, zval *name) {
660663
}
661664

662665
if (tarantool_schema_add_spaces(obj->schema, resp.data, resp.data_len)) {
663-
// fprintf(stderr, "%s", php_base64_encode(resp.data, resp.data_len)->val);
666+
tutils_hexdump_base(stderr, "\n", resp.data, resp.data_len);
664667
tarantool_throw_parsingexception("schema (space)");
665668
return FAILURE;
666669
}
@@ -720,7 +723,7 @@ int get_indexno_by_name(tarantool_connection *obj, int space_no,
720723
}
721724

722725
if (tarantool_schema_add_indexes(obj->schema, resp.data, resp.data_len)) {
723-
// fprintf(stderr, "%s", php_base64_encode(resp.data, resp.data_len)->val);
726+
tutils_hexdump_base(stderr, "\n", resp.data, resp.data_len);
724727
tarantool_throw_parsingexception("schema (index)");
725728
return FAILURE;
726729
}
@@ -775,7 +778,7 @@ int get_fieldno_by_name(tarantool_connection *obj, uint32_t space_no,
775778
}
776779

777780
if (tarantool_schema_add_spaces(obj->schema, resp.data, resp.data_len)) {
778-
// fprintf(stderr, "%s", php_base64_encode(resp.data, resp.data_len)->val);
781+
tutils_hexdump_base(stderr, "\n", resp.data, resp.data_len);
779782
tarantool_throw_parsingexception("schema (space)");
780783
return FAILURE;
781784
}
@@ -859,7 +862,7 @@ int tarantool_uwrite_op(tarantool_connection *obj, zval *op, uint32_t pos,
859862
THROW_EXC("Field ARG must be provided and must be LONG "
860863
"or DOUBLE for '%s' at position %d (got '%s')",
861864
Z_STRVAL_P(opstr), pos,
862-
op_to_string(oparg));
865+
tutils_op_to_string(oparg));
863866
goto cleanup;
864867
}
865868
php_tp_encode_uother(obj->value, Z_STRVAL_P(opstr)[0],
@@ -876,7 +879,7 @@ int tarantool_uwrite_op(tarantool_connection *obj, zval *op, uint32_t pos,
876879
THROW_EXC("Field ARG must be provided and must be LONG "
877880
"for '%s' at position %d (got '%s')",
878881
Z_STRVAL_P(opstr), pos,
879-
op_to_string(oparg));
882+
tutils_op_to_string(oparg));
880883
goto cleanup;
881884
}
882885
php_tp_encode_uother(obj->value, Z_STRVAL_P(opstr)[0],
@@ -1221,15 +1224,15 @@ int __tarantool_authenticate(tarantool_connection *obj) {
12211224
if (tarantool_schema_add_spaces(obj->schema, resp.data,
12221225
resp.data_len) &&
12231226
status != FAILURE) {
1224-
// fprintf(stderr, "%s", php_base64_encode(resp.data, resp.data_len)->val);
1227+
tutils_hexdump_base(stderr, "\n", resp.data, resp.data_len);
12251228
tarantool_throw_parsingexception("schema (space)");
12261229
status = FAILURE;
12271230
}
12281231
} else if (resp.sync == index_sync) {
12291232
if (tarantool_schema_add_indexes(obj->schema, resp.data,
12301233
resp.data_len) &&
12311234
status != FAILURE) {
1232-
// fprintf(stderr, "%s", php_base64_encode(resp.data, resp.data_len)->val);
1235+
tutils_hexdump_base(stderr, "\n", resp.data, resp.data_len);
12331236
tarantool_throw_parsingexception("schema (index)");
12341237
status = FAILURE;
12351238
}

src/tarantool_msgpack.c

Lines changed: 15 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,9 @@ void php_mp_pack_array_recursively(smart_string *str, zval *val) {
122122
size_t key_index = 0;
123123
for (; key_index < n; ++key_index) {
124124
data = zend_hash_index_find(ht, key_index);
125-
if (!data || data == val ||
126-
(Z_TYPE_P(data) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data)) && Z_ARRVAL_P(data)->u.v.nApplyCount > 1)) {
125+
if (!data || data == val || (Z_TYPE_P(data) == IS_ARRAY &&
126+
ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data)) &&
127+
Z_ARRVAL_P(data)->u.v.nApplyCount > 1)) {
127128
php_mp_pack_nil(str);
128129
} else {
129130
if (Z_TYPE_P(data) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data)))
@@ -164,8 +165,9 @@ void php_mp_pack_hash_recursively(smart_string *str, zval *val) {
164165
break;
165166
}
166167
data = zend_hash_get_current_data_ex(ht, &pos);
167-
if (!data || data == val ||
168-
(Z_TYPE_P(data) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data)) && Z_ARRVAL_P(data)->u.v.nApplyCount > 1)) {
168+
if (!data || data == val || (Z_TYPE_P(data) == IS_ARRAY &&
169+
ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data)) &&
170+
Z_ARRVAL_P(data)->u.v.nApplyCount > 1)) {
169171
php_mp_pack_nil(str);
170172
} else {
171173
if (Z_TYPE_P(data) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data)))
@@ -178,6 +180,9 @@ void php_mp_pack_hash_recursively(smart_string *str, zval *val) {
178180
}
179181

180182
void php_mp_pack(smart_string *str, zval *val) {
183+
if (Z_TYPE_P(val) == IS_REFERENCE)
184+
val = Z_REFVAL_P(val);
185+
181186
switch(Z_TYPE_P(val)) {
182187
case IS_NULL:
183188
php_mp_pack_nil(str);
@@ -189,10 +194,8 @@ void php_mp_pack(smart_string *str, zval *val) {
189194
php_mp_pack_double(str, (double )Z_DVAL_P(val));
190195
break;
191196
case IS_TRUE:
192-
php_mp_pack_bool(str, 1);
193-
break;
194197
case IS_FALSE:
195-
php_mp_pack_bool(str, 0);
198+
php_mp_pack_bool(str, Z_TYPE_P(val) == IS_TRUE ? 1 : 0);
196199
break;
197200
case IS_ARRAY:
198201
if (php_mp_is_hash(val))
@@ -270,42 +273,6 @@ ptrdiff_t php_mp_unpack_double(zval *oval, char **str) {
270273
return mp_sizeof_double(val);
271274
}
272275

273-
const char *op_to_string(zval *obj) {
274-
zend_uchar type = Z_TYPE_P(obj);
275-
switch(type) {
276-
case(IS_NULL):
277-
return "NULL";
278-
case(IS_LONG):
279-
return "LONG";
280-
case(IS_DOUBLE):
281-
return "DOUBLE";
282-
case(IS_TRUE):
283-
return "TRUE";
284-
case(IS_FALSE):
285-
return "FALSE";
286-
case(IS_ARRAY):
287-
return "ARRAY";
288-
case(IS_OBJECT):
289-
return "OBJECT";
290-
case(IS_STRING):
291-
return "STRING";
292-
case(IS_RESOURCE):
293-
return "RESOURCE";
294-
case(IS_CONSTANT):
295-
return "CONSTANT";
296-
#ifdef IS_CONSTANT_ARRAY
297-
case(IS_CONSTANT_ARRAY):
298-
return "CONSTANT_ARRAY";
299-
#endif
300-
#ifdef IS_CALLABLE
301-
case(IS_CALLABLE):
302-
return "CALLABLE";
303-
#endif
304-
default:
305-
return "UNKNOWN";
306-
}
307-
}
308-
309276
ptrdiff_t php_mp_unpack_map(zval *oval, char **str) {
310277
TSRMLS_FETCH();
311278
size_t len = mp_decode_map((const char **)str);
@@ -500,6 +467,9 @@ size_t php_mp_sizeof_hash_recursively(zval *val) {
500467

501468

502469
size_t php_mp_sizeof(zval *val) {
470+
if (Z_TYPE_P(val) == IS_REFERENCE)
471+
val = Z_REFVAL_P(val);
472+
503473
switch(Z_TYPE_P(val)) {
504474
case IS_NULL:
505475
return php_mp_sizeof_nil();
@@ -510,11 +480,9 @@ size_t php_mp_sizeof(zval *val) {
510480
case IS_DOUBLE:
511481
return php_mp_sizeof_double((double )Z_DVAL_P(val));
512482
break;
513-
case IS_FALSE:
514-
return php_mp_sizeof_bool(0);
515-
break;
516483
case IS_TRUE:
517-
return php_mp_sizeof_bool(1);
484+
case IS_FALSE:
485+
return php_mp_sizeof_bool(Z_TYPE_P(val) == IS_TRUE ? 1 : 0);
518486
break;
519487
case IS_ARRAY:
520488
if (php_mp_is_hash(val))

src/tarantool_msgpack.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33

44
#include "php_tarantool.h"
55

6-
#define PHP_MP_SERIALIZABLE_P(v) (Z_TYPE_P(v) == IS_NULL || \
6+
#define PHP_MP_SERIALIZABLE_P(v) (Z_TYPE_P(v) == IS_NULL || \
77
Z_TYPE_P(v) == IS_LONG || \
88
Z_TYPE_P(v) == IS_DOUBLE || \
99
Z_TYPE_P(v) == IS_FALSE || \
1010
Z_TYPE_P(v) == IS_TRUE || \
1111
Z_TYPE_P(v) == IS_ARRAY || \
12-
Z_TYPE_P(v) == IS_STRING)
12+
Z_TYPE_P(v) == IS_STRING || \
13+
Z_TYPE_P(v) == IS_REFERENCE)
1314

1415
size_t php_mp_check (const char *str, size_t str_size);
1516
void php_mp_pack (smart_string *buf, zval *val );
@@ -21,7 +22,6 @@ void php_mp_pack_package_size_basic (char *pos, size_t val);
2122
size_t php_mp_unpack_package_size (char *buf);
2223

2324
int php_mp_is_hash(zval *val);
24-
const char *op_to_string(zval *obj);
2525

2626
void php_mp_pack_nil(smart_string *str);
2727
void php_mp_pack_long_pos(smart_string *str, long val);

src/utils.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#include "php_tarantool.h"
2+
3+
#include "utils.h"
4+
5+
#include <stdio.h>
6+
7+
const char *tutils_op_to_string(zval *obj) {
8+
zend_uchar type = Z_TYPE_P(obj);
9+
switch(type) {
10+
case(IS_UNDEF):
11+
return "UNDEF";
12+
case(IS_NULL):
13+
return "NULL";
14+
case(IS_FALSE):
15+
return "FALSE";
16+
case(IS_TRUE):
17+
return "TRUE";
18+
case(IS_LONG):
19+
return "LONG";
20+
case(IS_DOUBLE):
21+
return "DOUBLE";
22+
case(IS_STRING):
23+
return "STRING";
24+
case(IS_ARRAY):
25+
return "ARRAY";
26+
case(IS_OBJECT):
27+
return "OBJECT";
28+
case(IS_RESOURCE):
29+
return "RESOURCE";
30+
case(IS_REFERENCE):
31+
return "REFERENCE";
32+
case(IS_CONSTANT):
33+
return "CONSTANT";
34+
case(IS_CONSTANT_AST):
35+
return "CONSTANT_AST";
36+
case(IS_CALLABLE):
37+
return "CALLABLE";
38+
default:
39+
return "UNKNOWN";
40+
}
41+
}
42+
43+
void tutils_hexdump_base (FILE *ostream, char *desc, const char *addr, size_t len) {
44+
size_t i;
45+
unsigned char buff[17];
46+
const unsigned char *pc = addr;
47+
48+
if (desc != NULL) {
49+
fprintf(ostream, "%s:\n", desc);
50+
}
51+
52+
for (i = 0; i < len; i++) {
53+
if (i % 16 == 0) {
54+
if (i != 0) fprintf(ostream, " %s\n", buff);
55+
fprintf(ostream, " %04x ", i);
56+
}
57+
58+
fprintf(ostream, " %02x", *pc);
59+
60+
if ((*pc < 0x20) || (*pc > 0x7e))
61+
buff[i % 16] = '.';
62+
else
63+
buff[i % 16] = *pc;
64+
buff[(i % 16) + 1] = '\0';
65+
++pc;
66+
}
67+
68+
while (i++ % 16 != 0) fprintf(ostream, " ");
69+
70+
fprintf(ostream, " %s\n\n", buff);
71+
}
72+
73+
void tutils_hexdump (char *desc, const char *addr, size_t len) {
74+
return tutils_hexdump_base(stdout, desc, addr, len);
75+
}
76+
77+
void tutils_hexdump_zs (char *desc, zend_string *val) {
78+
return tutils_hexdump(desc, ZSTR_VAL(val), ZSTR_LEN(val));
79+
}
80+
81+
void tutils_hexdump_ss (char *desc, smart_string *val) {
82+
return tutils_hexdump(desc, val->c, val->len);
83+
}

src/utils.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef PHP_TNT_UTILS_H
2+
#define PHP_TNT_UITLS_H
3+
4+
const char *tutils_op_to_string(zval *obj);
5+
void tutils_hexdump_base (FILE *ostream, char *desc, const char *addr, size_t len);
6+
void tutils_hexdump (char *desc, const char *addr, size_t len);
7+
void tutils_hexdump_zs (char *desc, zend_string *val);
8+
void tutils_hexdump_ss (char *desc, smart_string *val);
9+
10+
#endif /* PHP_TNT_UTILS_H */

test/MsgPackTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,12 @@ public function test_05_msgpack_string_keys() {
6969
$this->assertEquals($resp[0][2]['megusta'], array(1, 2, 3));
7070
$this->assertTrue(True);
7171
}
72+
73+
public function test_06_msgpack_array_reference() {
74+
$data = [
75+
'key1' => 'value1',
76+
];
77+
$link = &$data['key1'];
78+
self::$tarantool->call('test_4', [$data]);
79+
}
7280
}

0 commit comments

Comments
 (0)