31 #include <Zend/zend_operators.h>
32 #include <Zend/zend_exceptions.h>
40 ZEND_BEGIN_ARG_INFO_EX(arg_check_optional, 0, 0, 1)
44 ZEND_BEGIN_ARG_INFO_EX(arg_check_message, 0, 0, 2)
46 ZEND_ARG_INFO(0,
klass)
49 ZEND_BEGIN_ARG_INFO_EX(arg_check_repeated, 0, 0, 2)
51 ZEND_ARG_INFO(0,
type)
52 ZEND_ARG_INFO(0,
klass)
55 ZEND_BEGIN_ARG_INFO_EX(arg_check_map, 0, 0, 3)
59 ZEND_ARG_INFO(0,
klass)
63 PHP_ME(Util, checkInt32, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
64 PHP_ME(Util, checkUint32, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
65 PHP_ME(Util, checkInt64, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
66 PHP_ME(Util, checkUint64, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
67 PHP_ME(Util, checkEnum, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
68 PHP_ME(Util, checkFloat, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
69 PHP_ME(Util, checkDouble, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
70 PHP_ME(Util, checkBool, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
71 PHP_ME(Util, checkString, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
72 PHP_ME(Util, checkBytes, arg_check_optional, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
73 PHP_ME(Util, checkMessage, arg_check_message, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
74 PHP_ME(Util, checkMapField, arg_check_map, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
75 PHP_ME(Util, checkRepeatedField, arg_check_repeated,
76 ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
81 zend_class_entry class_type;
82 INIT_CLASS_ENTRY(class_type,
"Google\\Protobuf\\Internal\\GPBUtil",
84 util_type = zend_register_internal_class(&class_type TSRMLS_CC);
97 int base = 10, digits = 0, dp_or_e = 0;
98 double local_dval = 0.0;
105 while (*
str ==
' ' || *
str ==
'\t' || *
str ==
'\n' ||
106 *
str ==
'\r' || *
str ==
'\v' || *
str ==
'\f') {
112 if (*
ptr ==
'-' || *
ptr ==
'+') {
116 if (ZEND_IS_DIGIT(*
ptr)) {
125 while (*
ptr ==
'0') {
136 if (ZEND_IS_DIGIT(*
ptr) || (
base == 16 && ZEND_IS_XDIGIT(*
ptr))) {
138 }
else if (
base == 10) {
139 if (*
ptr ==
'.' && dp_or_e < 1) {
141 }
else if ((*
ptr ==
'e' || *
ptr ==
'E') && dp_or_e < 2) {
142 const char *e =
ptr + 1;
144 if (*e ==
'-' || *e ==
'+') {
147 if (ZEND_IS_DIGIT(*e)) {
163 local_dval = zend_hex_strtod(
str, &
ptr);
167 }
else if (*
ptr ==
'.' && ZEND_IS_DIGIT(
ptr[1])) {
174 local_dval = zend_strtod(
str, &
ptr);
175 }
else if (dp_or_e != -1) {
176 dp_or_e = (*
ptr++ ==
'.') ? 1 : 2;
183 zend_error(E_NOTICE,
"A non well formed numeric value encountered");
187 if (
type == IS_LONG) {
191 if (!(
cmp < 0 || (
cmp == 0 && *
str ==
'-'))) {
193 *dval = zend_strtod(
str, NULL);
200 *lval = strtoll(
str, NULL,
base);
211 #define CONVERT_TO_INTEGER(type) \
212 static bool convert_int64_to_##type(int64_t val, type##_t* type##_value) { \
213 *type##_value = (type##_t)val; \
217 static bool convert_double_to_##type(double val, type##_t* type##_value) { \
218 *type##_value = (type##_t)zend_dval_to_lval(val); \
222 static bool convert_string_to_##type(const char* val, int len, \
223 type##_t* type##_value) { \
227 switch (convert_numeric_string(val, len, &lval, &dval)) { \
229 return convert_double_to_##type(dval, type##_value); \
232 return convert_int64_to_##type(lval, type##_value); \
235 zend_throw_exception(NULL, \
236 "Given string value cannot be converted to integer.", \
242 bool protobuf_convert_to_##type(zval* from, type##_t* to) { \
244 switch (Z_TYPE_P(from)) { \
246 return convert_int64_to_##type(Z_LVAL_P(from), to); \
249 return convert_double_to_##type(Z_DVAL_P(from), to); \
252 return convert_string_to_##type(Z_STRVAL_P(from), Z_STRLEN_P(from), \
256 zend_throw_exception(NULL, \
257 "Given value cannot be converted to integer.", \
270 #undef CONVERT_TO_INTEGER
272 #define CONVERT_TO_FLOAT(type) \
273 static bool convert_int64_to_##type(int64_t val, type* type##_value) { \
274 *type##_value = (type)val; \
278 static bool convert_double_to_##type(double val, type* type##_value) { \
279 *type##_value = (type)val; \
283 static bool convert_string_to_##type(const char* val, int len, \
284 type* type##_value) { \
289 switch (convert_numeric_string(val, len, &lval, &dval)) { \
291 *type##_value = (type)dval; \
295 *type##_value = (type)lval; \
299 zend_throw_exception(NULL, \
300 "Given string value cannot be converted to integer.", \
306 bool protobuf_convert_to_##type(zval* from, type* to) { \
308 switch (Z_TYPE_P(from)) { \
310 return convert_int64_to_##type(Z_LVAL_P(from), to); \
313 return convert_double_to_##type(Z_DVAL_P(from), to); \
316 return convert_string_to_##type(Z_STRVAL_P(from), Z_STRLEN_P(from), \
320 zend_throw_exception(NULL, \
321 "Given value cannot be converted to integer.", \
332 #undef CONVERT_TO_FLOAT
336 switch (Z_TYPE_P(
from)) {
337 #if PHP_MAJOR_VERSION < 7
356 char* strval = Z_STRVAL_P(
from);
358 if (Z_STRLEN_P(
from) == 0 ||
359 (Z_STRLEN_P(
from) == 1 && Z_STRVAL_P(
from)[0] ==
'0')) {
366 zend_throw_exception(
367 NULL,
"Given value cannot be converted to bool.",
376 #if PHP_MAJOR_VERSION >= 7
377 if (Z_ISREF_P(
from)) {
382 switch (Z_TYPE_P(
from)) {
386 #if PHP_MAJOR_VERSION < 7
400 zend_throw_exception(
401 NULL,
"Given value cannot be converted to string.",
416 #define PHP_TYPE_CHECK(type) \
417 PHP_METHOD(Util, check##type) {}
430 #undef PHP_TYPE_CHECK
434 zend_class_entry*
klass = NULL;
435 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
"o!C", &val, &
klass) ==
442 if (!instanceof_function(Z_OBJCE_P(val),
klass TSRMLS_CC)) {
443 zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
444 "Given value is not an instance of %s.",
448 RETURN_ZVAL(val, 1, 0);
452 zval* val, zval* return_value) {
453 #if PHP_MAJOR_VERSION >= 7
454 if (Z_ISREF_P(val)) {
460 if (Z_TYPE_P(val) == IS_ARRAY) {
461 HashTable*
table = HASH_OF(val);
462 HashPosition pointer;
465 #if PHP_MAJOR_VERSION < 7
475 for (zend_hash_internal_pointer_reset_ex(
table, &pointer);
478 zend_hash_move_forward_ex(
table, &pointer)) {
486 }
else if (Z_TYPE_P(val) == IS_OBJECT) {
488 zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
489 "Given value is not an instance of %s.",
495 zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
496 "Incorrect repeated field type.");
500 zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
501 "Expect a repeated field of %s, but %s is given.",
505 RETURN_ZVAL(val, 1, 0);
507 zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
508 "Incorrect repeated field type.");
516 const zend_class_entry*
klass = NULL;
517 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
"zl|C", &val, &
type,
518 &
klass) == FAILURE) {
521 RETURN_ZVAL(val, 1, 0);
526 #if PHP_MAJOR_VERSION >= 7
527 if (Z_ISREF_P(val)) {
533 if (Z_TYPE_P(val) == IS_ARRAY) {
534 HashTable*
table = Z_ARRVAL_P(val);
535 HashPosition pointer;
539 #if PHP_MAJOR_VERSION < 7
541 MAKE_STD_ZVAL(map_field);
548 &map_field TSRMLS_CC);
550 for (zend_hash_internal_pointer_reset_ex(
table, &pointer);
553 zend_hash_move_forward_ex(
table, &pointer)) {
554 zend_hash_get_current_key_zval_ex(
table, &
key, &pointer);
562 }
else if (Z_TYPE_P(val) == IS_OBJECT) {
563 if (!instanceof_function(Z_OBJCE_P(val),
map_field_type TSRMLS_CC)) {
564 zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
565 "Given value is not an instance of %s.",
571 zend_throw_exception(
572 NULL,
"Incorrect map field key type.",
577 zend_throw_exception(
578 NULL,
"Incorrect map field value type.",
583 zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
584 "Expect a map field of %s, but %s is given.",
588 RETURN_ZVAL(val, 1, 0);
590 zend_throw_exception(
591 NULL,
"Incorrect map field type.",
600 const zend_class_entry*
klass = NULL;
601 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
"zll|C", &val, &
key_type,
605 RETURN_ZVAL(val, 1, 0);