diff options
Diffstat (limited to 'php')
25 files changed, 999 insertions, 434 deletions
diff --git a/php/ext/google/protobuf/array.c b/php/ext/google/protobuf/array.c index 215dcd46..e4a88c39 100644 --- a/php/ext/google/protobuf/array.c +++ b/php/ext/google/protobuf/array.c @@ -54,6 +54,16 @@ static zend_function_entry repeated_field_methods[] = { PHP_ME(RepeatedField, offsetSet, arginfo_offsetSet, ZEND_ACC_PUBLIC) PHP_ME(RepeatedField, offsetUnset, arginfo_offsetGet, ZEND_ACC_PUBLIC) PHP_ME(RepeatedField, count, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedField, getIterator, arginfo_void, ZEND_ACC_PUBLIC) + ZEND_FE_END +}; + +static zend_function_entry repeated_field_iter_methods[] = { + PHP_ME(RepeatedFieldIter, rewind, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedFieldIter, current, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedFieldIter, key, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedFieldIter, next, arginfo_void, ZEND_ACC_PUBLIC) + PHP_ME(RepeatedFieldIter, valid, arginfo_void, ZEND_ACC_PUBLIC) ZEND_FE_END }; @@ -70,11 +80,15 @@ static int repeated_field_has_dimension(zval *object, zval *offset TSRMLS_DC); static HashTable *repeated_field_get_gc(zval *object, zval ***table, int *n TSRMLS_DC); +static zend_object_value repeated_field_iter_create(zend_class_entry *ce TSRMLS_DC); +static void repeated_field_iter_free(void *object TSRMLS_DC); + // ----------------------------------------------------------------------------- // RepeatedField creation/desctruction // ----------------------------------------------------------------------------- zend_class_entry* repeated_field_type; +zend_class_entry* repeated_field_iter_type; zend_object_handlers* repeated_field_handlers; void repeated_field_init(TSRMLS_D) { @@ -86,8 +100,8 @@ void repeated_field_init(TSRMLS_D) { repeated_field_type = zend_register_internal_class(&class_type TSRMLS_CC); repeated_field_type->create_object = repeated_field_create; - zend_class_implements(repeated_field_type TSRMLS_CC, 2, spl_ce_ArrayAccess, - spl_ce_Countable); + zend_class_implements(repeated_field_type TSRMLS_CC, 3, spl_ce_ArrayAccess, + zend_ce_aggregate, spl_ce_Countable); repeated_field_handlers = PEMALLOC(zend_object_handlers); memcpy(repeated_field_handlers, zend_get_std_object_handlers(), @@ -386,3 +400,112 @@ PHP_METHOD(RepeatedField, count) { RETURN_LONG(zend_hash_num_elements(HASH_OF(intern->array))); } + +/** + * Return the beginning iterator. + * This will also be called for: foreach($arr) + * @return object Beginning iterator. + */ +PHP_METHOD(RepeatedField, getIterator) { + zval *iter_php = NULL; + MAKE_STD_ZVAL(iter_php); + Z_TYPE_P(iter_php) = IS_OBJECT; + Z_OBJVAL_P(iter_php) = repeated_field_iter_type->create_object( + repeated_field_iter_type TSRMLS_CC); + + RepeatedField *intern = zend_object_store_get_object(getThis() TSRMLS_CC); + RepeatedFieldIter *iter = zend_object_store_get_object(iter_php TSRMLS_CC); + iter->repeated_field = intern; + iter->position = 0; + + RETURN_ZVAL(iter_php, 1, 1); +} + +// ----------------------------------------------------------------------------- +// RepeatedFieldIter creation/desctruction +// ----------------------------------------------------------------------------- + +void repeated_field_iter_init(TSRMLS_D) { + zend_class_entry class_type; + const char* class_name = "Google\\Protobuf\\Internal\\RepeatedFieldIter"; + INIT_CLASS_ENTRY_EX(class_type, class_name, strlen(class_name), + repeated_field_iter_methods); + + repeated_field_iter_type = + zend_register_internal_class(&class_type TSRMLS_CC); + repeated_field_iter_type->create_object = repeated_field_iter_create; + + zend_class_implements(repeated_field_iter_type TSRMLS_CC, 1, + zend_ce_iterator); +} + +static zend_object_value repeated_field_iter_create( + zend_class_entry *ce TSRMLS_DC) { + zend_object_value retval = {0}; + RepeatedFieldIter *intern; + + intern = emalloc(sizeof(RepeatedFieldIter)); + memset(intern, 0, sizeof(RepeatedFieldIter)); + + zend_object_std_init(&intern->std, ce TSRMLS_CC); + object_properties_init(&intern->std, ce); + + intern->repeated_field = NULL; + intern->position = 0; + + retval.handle = zend_objects_store_put( + intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, + (zend_objects_free_object_storage_t)repeated_field_iter_free, + NULL TSRMLS_CC); + retval.handlers = zend_get_std_object_handlers(); + + return retval; +} + +static void repeated_field_iter_free(void *object TSRMLS_DC) { + RepeatedFieldIter *intern = object; + zend_object_std_dtor(&intern->std TSRMLS_CC); + efree(object); +} + +// ----------------------------------------------------------------------------- +// PHP RepeatedFieldIter Methods +// ----------------------------------------------------------------------------- + +PHP_METHOD(RepeatedFieldIter, rewind) { + RepeatedFieldIter *intern = zend_object_store_get_object(getThis() TSRMLS_CC); + intern->position = 0; +} + +PHP_METHOD(RepeatedFieldIter, current) { + RepeatedFieldIter *intern = zend_object_store_get_object(getThis() TSRMLS_CC); + RepeatedField *repeated_field = intern->repeated_field; + + long index; + void *memory; + + HashTable *table = HASH_OF(repeated_field->array); + + if (zend_hash_index_find(table, intern->position, (void **)&memory) == + FAILURE) { + zend_error(E_USER_ERROR, "Element at %ld doesn't exist.\n", index); + return; + } + native_slot_get(repeated_field->type, memory, return_value_ptr TSRMLS_CC); +} + +PHP_METHOD(RepeatedFieldIter, key) { + RepeatedFieldIter *intern = zend_object_store_get_object(getThis() TSRMLS_CC); + RETURN_LONG(intern->position); +} + +PHP_METHOD(RepeatedFieldIter, next) { + RepeatedFieldIter *intern = zend_object_store_get_object(getThis() TSRMLS_CC); + ++intern->position; +} + +PHP_METHOD(RepeatedFieldIter, valid) { + RepeatedFieldIter *intern = zend_object_store_get_object(getThis() TSRMLS_CC); + RETURN_BOOL(zend_hash_num_elements(HASH_OF(intern->repeated_field->array)) > + intern->position); +} diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c index 156eca07..6ea2cc93 100644 --- a/php/ext/google/protobuf/def.c +++ b/php/ext/google/protobuf/def.c @@ -250,28 +250,41 @@ PHP_METHOD(DescriptorPool, getGeneratedPool) { RETURN_ZVAL(generated_pool_php, 1, 0); } -static void convert_to_class_name_inplace(char *proto_name, - size_t pkg_name_len) { +static void convert_to_class_name_inplace(char *class_name, + const char* fullname, + const char* package_name) { size_t i; bool first_char = false; + size_t pkg_name_len = package_name == NULL ? 0 : strlen(package_name); - for (i = 0; i <= pkg_name_len + 1; i++) { - // PHP package uses camel case. - if (!first_char && proto_name[i] != '.') { - first_char = true; - proto_name[i] += 'A' - 'a'; - } - // php packages are divided by '\'. - if (proto_name[i] == '.') { - first_char = false; - proto_name[i] = '\\'; + // In php, class name cannot be Empty. + if (strcmp("google.protobuf.Empty", fullname) == 0) { + fullname = "google.protobuf.GPBEmpty"; + } + + if (pkg_name_len == 0) { + strcpy(class_name, fullname); + } else { + class_name[0] = '.'; + strcpy(&class_name[1], fullname); + for (i = 0; i <= pkg_name_len + 1; i++) { + // PHP package uses camel case. + if (!first_char && class_name[i] != '.') { + first_char = true; + class_name[i] += 'A' - 'a'; + } + // php packages are divided by '\'. + if (class_name[i] == '.') { + first_char = false; + class_name[i] = '\\'; + } } } // Submessage is concatenated with its containing messages by '_'. - for (i = pkg_name_len; i < strlen(proto_name); i++) { - if (proto_name[i] == '.') { - proto_name[i] = '_'; + for (i = pkg_name_len; i < strlen(class_name); i++) { + if (class_name[i] == '.') { + class_name[i] = '_'; } } } @@ -322,13 +335,13 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { upb_msgdef_mapentry(upb_downcast_msgdef(def))) { \ break; \ } \ - /* Prepend '.' to package name to make it absolute. */ \ + /* Prepend '.' to package name to make it absolute. In the 5 additional \ + * bytes allocated, one for '.', one for trailing 0, and 3 for 'GPB' if \ + * given message is google.protobuf.Empty.*/ \ const char *fullname = upb_##def_type_lower##_fullname(def_type_lower); \ - char *klass_name = ecalloc(sizeof(char), 2 + strlen(fullname)); \ - klass_name[0] = '.'; \ - strcpy(&klass_name[1], fullname); \ - size_t pkg_name_len = strlen(upb_filedef_package(files[0])); \ - convert_to_class_name_inplace(klass_name, pkg_name_len); \ + char *klass_name = ecalloc(sizeof(char), 5 + strlen(fullname)); \ + convert_to_class_name_inplace(klass_name, fullname, \ + upb_filedef_package(files[0])); \ zend_class_entry **pce; \ if (zend_lookup_class(klass_name, strlen(klass_name), &pce TSRMLS_CC) == \ FAILURE) { \ diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c index cb46031e..d8fbbe11 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -177,8 +177,8 @@ static zend_object_value message_create(zend_class_entry* ce TSRMLS_DC) { zend_object_std_init(&msg->std, ce TSRMLS_CC); object_properties_init(&msg->std, ce); - layout_init(desc->layout, message_data(msg), msg->std.properties_table - TSRMLS_CC); + layout_init(desc->layout, message_data(msg), + msg->std.properties_table TSRMLS_CC); return_value.handle = zend_objects_store_put( msg, (zend_objects_store_dtor_t)zend_objects_destroy_object, message_free, diff --git a/php/ext/google/protobuf/protobuf.c b/php/ext/google/protobuf/protobuf.c index 019bca29..ea85b999 100644 --- a/php/ext/google/protobuf/protobuf.c +++ b/php/ext/google/protobuf/protobuf.c @@ -156,6 +156,7 @@ static PHP_RSHUTDOWN_FUNCTION(protobuf) { static PHP_MINIT_FUNCTION(protobuf) { map_field_init(TSRMLS_C); repeated_field_init(TSRMLS_C); + repeated_field_iter_init(TSRMLS_C); gpb_type_init(TSRMLS_C); message_init(TSRMLS_C); descriptor_pool_init(TSRMLS_C); diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index 8a1d9261..fb5879dc 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -39,6 +39,9 @@ #define PHP_PROTOBUF_EXTNAME "protobuf" #define PHP_PROTOBUF_VERSION "3.1.0a1" +#define MAX_LENGTH_OF_INT64 20 +#define SIZEOF_INT64 8 + // ----------------------------------------------------------------------------- // Forward Declaration // ---------------------------------------------------------------------------- @@ -51,6 +54,7 @@ struct MessageField; struct MessageHeader; struct MessageLayout; struct RepeatedField; +struct RepeatedFieldIter; struct MapField; typedef struct DescriptorPool DescriptorPool; @@ -61,6 +65,7 @@ typedef struct MessageField MessageField; typedef struct MessageHeader MessageHeader; typedef struct MessageLayout MessageLayout; typedef struct RepeatedField RepeatedField; +typedef struct RepeatedFieldIter RepeatedFieldIter; typedef struct MapField MapField; // ----------------------------------------------------------------------------- @@ -77,6 +82,7 @@ void descriptor_pool_init(TSRMLS_D); void gpb_type_init(TSRMLS_D); void map_field_init(TSRMLS_D); void repeated_field_init(TSRMLS_D); +void repeated_field_iter_init(TSRMLS_D); void util_init(TSRMLS_D); void message_init(TSRMLS_D); @@ -366,6 +372,12 @@ struct RepeatedField { // (for message field only). }; +struct RepeatedFieldIter { + zend_object std; + RepeatedField* repeated_field; + long position; +}; + void repeated_field_create_with_type(zend_class_entry* ce, const upb_fielddef* field, zval** repeated_field TSRMLS_DC); @@ -383,6 +395,13 @@ PHP_METHOD(RepeatedField, offsetGet); PHP_METHOD(RepeatedField, offsetSet); PHP_METHOD(RepeatedField, offsetUnset); PHP_METHOD(RepeatedField, count); +PHP_METHOD(RepeatedField, getIterator); + +PHP_METHOD(RepeatedFieldIter, rewind); +PHP_METHOD(RepeatedFieldIter, current); +PHP_METHOD(RepeatedFieldIter, key); +PHP_METHOD(RepeatedFieldIter, next); +PHP_METHOD(RepeatedFieldIter, valid); // ----------------------------------------------------------------------------- // Oneof Field. diff --git a/php/ext/google/protobuf/storage.c b/php/ext/google/protobuf/storage.c index e94aa319..1d25a91b 100644 --- a/php/ext/google/protobuf/storage.c +++ b/php/ext/google/protobuf/storage.c @@ -174,11 +174,31 @@ CASE(FLOAT, DOUBLE, float) CASE(DOUBLE, DOUBLE, double) CASE(BOOL, BOOL, int8_t) CASE(INT32, LONG, int32_t) -CASE(INT64, LONG, int64_t) -CASE(UINT64, LONG, uint64_t) CASE(ENUM, LONG, uint32_t) #undef CASE + +#if SIZEOF_LONG == 4 +#define CASE(upb_type, c_type) \ + case UPB_TYPE_##upb_type: { \ + SEPARATE_ZVAL_IF_NOT_REF(cache); \ + char buffer[MAX_LENGTH_OF_INT64]; \ + sprintf(buffer, "%lld", DEREF(memory, c_type)); \ + ZVAL_STRING(*cache, buffer, 1); \ + return; \ + } +#else +#define CASE(upb_type, c_type) \ + case UPB_TYPE_##upb_type: { \ + SEPARATE_ZVAL_IF_NOT_REF(cache); \ + ZVAL_LONG(*cache, DEREF(memory, c_type)); \ + return; \ + } +#endif +CASE(UINT64, uint64_t) +CASE(INT64, int64_t) +#undef CASE + case UPB_TYPE_UINT32: { // Prepend bit-1 for negative numbers, so that uint32 value will be // consistent on both 32-bit and 64-bit architectures. diff --git a/php/ext/google/protobuf/type_check.c b/php/ext/google/protobuf/type_check.c index c215d72e..d12d0025 100644 --- a/php/ext/google/protobuf/type_check.c +++ b/php/ext/google/protobuf/type_check.c @@ -34,6 +34,7 @@ #include "utf8.h" static zend_class_entry* util_type; +static const char int64_min_digits[] = "9223372036854775808"; ZEND_BEGIN_ARG_INFO_EX(arg_check_optional, 0, 0, 1) ZEND_ARG_INFO(1, val) @@ -78,8 +79,128 @@ void util_init(TSRMLS_D) { // Type checking/conversion. // ----------------------------------------------------------------------------- +// This is modified from is_numeric_string in zend_operators.h. The behavior of +// this function is the same as is_numeric_string, except that this takes +// int64_t as input instead of long. +static zend_uchar convert_numeric_string( + const char *str, int length, int64_t *lval, double *dval) { + const char *ptr; + int base = 10, digits = 0, dp_or_e = 0; + double local_dval = 0.0; + zend_uchar type; + + if (length == 0) { + return IS_NULL; + } + + while (*str == ' ' || *str == '\t' || *str == '\n' || + *str == '\r' || *str == '\v' || *str == '\f') { + str++; + length--; + } + ptr = str; + + if (*ptr == '-' || *ptr == '+') { + ptr++; + } + + if (ZEND_IS_DIGIT(*ptr)) { + // Handle hex numbers + // str is used instead of ptr to disallow signs and keep old behavior. + if (length > 2 && *str == '0' && (str[1] == 'x' || str[1] == 'X')) { + base = 16; + ptr += 2; + } + + // Skip any leading 0s. + while (*ptr == '0') { + ptr++; + } + + // Count the number of digits. If a decimal point/exponent is found, + // it's a double. Otherwise, if there's a dval or no need to check for + // a full match, stop when there are too many digits for a int64 */ + for (type = IS_LONG; + !(digits >= MAX_LENGTH_OF_INT64 && dval); + digits++, ptr++) { +check_digits: + if (ZEND_IS_DIGIT(*ptr) || (base == 16 && ZEND_IS_XDIGIT(*ptr))) { + continue; + } else if (base == 10) { + if (*ptr == '.' && dp_or_e < 1) { + goto process_double; + } else if ((*ptr == 'e' || *ptr == 'E') && dp_or_e < 2) { + const char *e = ptr + 1; + + if (*e == '-' || *e == '+') { + ptr = e++; + } + if (ZEND_IS_DIGIT(*e)) { + goto process_double; + } + } + } + break; + } + + if (base == 10) { + if (digits >= MAX_LENGTH_OF_INT64) { + dp_or_e = -1; + goto process_double; + } + } else if (!(digits < SIZEOF_INT64 * 2 || + (digits == SIZEOF_INT64 * 2 && ptr[-digits] <= '7'))) { + if (dval) { + local_dval = zend_hex_strtod(str, &ptr); + } + type = IS_DOUBLE; + } + } else if (*ptr == '.' && ZEND_IS_DIGIT(ptr[1])) { +process_double: + type = IS_DOUBLE; + + // If there's a dval, do the conversion; else continue checking + // the digits if we need to check for a full match. + if (dval) { + local_dval = zend_strtod(str, &ptr); + } else if (dp_or_e != -1) { + dp_or_e = (*ptr++ == '.') ? 1 : 2; + goto check_digits; + } + } else { + return IS_NULL; + } + if (ptr != str + length) { + zend_error(E_NOTICE, "A non well formed numeric value encountered"); + return 0; + } + + if (type == IS_LONG) { + if (digits == MAX_LENGTH_OF_INT64 - 1) { + int cmp = strcmp(&ptr[-digits], int64_min_digits); + + if (!(cmp < 0 || (cmp == 0 && *str == '-'))) { + if (dval) { + *dval = zend_strtod(str, NULL); + } + + return IS_DOUBLE; + } + } + if (lval) { + *lval = strtoll(str, NULL, base); + } + return IS_LONG; + } else { + if (dval) { + *dval = local_dval; + } + return IS_DOUBLE; + } +} + #define CONVERT_TO_INTEGER(type) \ - static bool convert_long_to_##type(long val, type##_t* type##_value) { \ + static bool convert_int64_to_##type(int64_t val, type##_t* type##_value) { \ *type##_value = (type##_t)val; \ return true; \ } \ @@ -91,15 +212,15 @@ void util_init(TSRMLS_D) { \ static bool convert_string_to_##type(const char* val, int len, \ type##_t* type##_value) { \ - long lval; \ + int64_t lval; \ double dval; \ \ - switch (is_numeric_string(val, len, &lval, &dval, 0)) { \ + switch (convert_numeric_string(val, len, &lval, &dval)) { \ case IS_DOUBLE: { \ return convert_double_to_##type(dval, type##_value); \ } \ case IS_LONG: { \ - return convert_long_to_##type(lval, type##_value); \ + return convert_int64_to_##type(lval, type##_value); \ } \ default: \ zend_error(E_USER_ERROR, \ @@ -111,7 +232,7 @@ void util_init(TSRMLS_D) { bool protobuf_convert_to_##type(zval* from, type##_t* to) { \ switch (Z_TYPE_P(from)) { \ case IS_LONG: { \ - return convert_long_to_##type(Z_LVAL_P(from), to); \ + return convert_int64_to_##type(Z_LVAL_P(from), to); \ } \ case IS_DOUBLE: { \ return convert_double_to_##type(Z_DVAL_P(from), to); \ @@ -137,7 +258,7 @@ CONVERT_TO_INTEGER(uint64); #undef CONVERT_TO_INTEGER #define CONVERT_TO_FLOAT(type) \ - static bool convert_long_to_##type(long val, type* type##_value) { \ + static bool convert_int64_to_##type(int64_t val, type* type##_value) { \ *type##_value = (type)val; \ return true; \ } \ @@ -149,10 +270,10 @@ CONVERT_TO_INTEGER(uint64); \ static bool convert_string_to_##type(const char* val, int len, \ type* type##_value) { \ - long lval; \ + int64_t lval; \ double dval; \ \ - switch (is_numeric_string(val, len, &lval, &dval, 0)) { \ + switch (convert_numeric_string(val, len, &lval, &dval)) { \ case IS_DOUBLE: { \ *type##_value = (type)dval; \ return true; \ @@ -171,7 +292,7 @@ CONVERT_TO_INTEGER(uint64); bool protobuf_convert_to_##type(zval* from, type* to) { \ switch (Z_TYPE_P(from)) { \ case IS_LONG: { \ - return convert_long_to_##type(Z_LVAL_P(from), to); \ + return convert_int64_to_##type(Z_LVAL_P(from), to); \ } \ case IS_DOUBLE: { \ return convert_double_to_##type(Z_DVAL_P(from), to); \ diff --git a/php/src/Google/Protobuf/Internal/GPBUtil.php b/php/src/Google/Protobuf/Internal/GPBUtil.php index 417a9729..30d7350f 100644 --- a/php/src/Google/Protobuf/Internal/GPBUtil.php +++ b/php/src/Google/Protobuf/Internal/GPBUtil.php @@ -37,6 +37,28 @@ use Google\Protobuf\Internal\RepeatedField; class GPBUtil { + public function divideInt64ToInt32($value, &$high, &$low, $trim = false) + { + $isNeg = (bccomp($value, 0) < 0); + if ($isNeg) { + $value = bcsub(0, $value); + } + $high = (int) bcdiv(bcadd($value, 1), 4294967296); + $low = (int) bcmod($value, 4294967296); + if ($isNeg) { + $high = ~$high; + $low = ~$low; + $low++; + if (!$low) { + $high++; + } + } + + if ($trim) { + $high = 0; + } + } + public static function checkString(&$var, $check_utf8) { @@ -70,9 +92,14 @@ class GPBUtil public static function checkUint32(&$var) { if (is_numeric($var)) { - $var = intval($var); if (PHP_INT_SIZE === 8) { + $var = intval($var); $var |= ((-(($var >> 31) & 0x1)) & ~0xFFFFFFFF); + } else { + if (bccomp($var, 0x7FFFFFFF) > 0) { + $var = bcsub($var, "4294967296"); + } + $var = (int) $var; } } else { trigger_error("Expect integer.", E_USER_ERROR); @@ -82,7 +109,11 @@ class GPBUtil public static function checkInt64(&$var) { if (is_numeric($var)) { - $var = intval($var); + if (PHP_INT_SIZE == 8) { + $var = intval($var); + } else { + $var = bcdiv($var, 1, 0); + } } else { trigger_error("Expect integer.", E_USER_ERROR); } @@ -91,7 +122,11 @@ class GPBUtil public static function checkUint64(&$var) { if (is_numeric($var)) { - $var = intval($var); + if (PHP_INT_SIZE == 8) { + $var = intval($var); + } else { + $var = bcdiv($var, 1, 0); + } } else { trigger_error("Expect integer.", E_USER_ERROR); } diff --git a/php/src/Google/Protobuf/Internal/GPBWire.php b/php/src/Google/Protobuf/Internal/GPBWire.php index 0e741e15..7e2c124f 100644 --- a/php/src/Google/Protobuf/Internal/GPBWire.php +++ b/php/src/Google/Protobuf/Internal/GPBWire.php @@ -32,10 +32,6 @@ namespace Google\Protobuf\Internal; -use Google\Protobuf\Internal\GPBUtil; -use Google\Protobuf\Internal\Int64; -use Google\Protobuf\Internal\Uint64; - class GPBWire { @@ -150,20 +146,28 @@ class GPBWire public static function zigZagEncode64($int64) { - $a = $int64->copy()->leftShift(1); - $b = $int64->copy()->rightShift(63); - $result = $a->bitXor($b); - $uint64 = Uint64::newValue($result->high, $result->low); - return $uint64; + if (PHP_INT_SIZE == 4) { + if (bccomp($int64, 0) >= 0) { + return bcmul($int64, 2); + } else { + return bcsub(bcmul(bcsub(0, $int64), 2), 1); + } + } else { + return ($int64 << 1) ^ ($int64 >> 63); + } } public static function zigZagDecode64($uint64) { - $a = $uint64->copy()->rightShift(1); - $b = $uint64->oddMask(); - $result = $a->bitXor($b); - $int64 = Int64::newValue($result->high, $result->low); - return $int64; + if (PHP_INT_SIZE == 4) { + if (bcmod($uint64, 2) == 0) { + return bcdiv($uint64, 2, 0); + } else { + return bcsub(0, bcdiv(bcadd($uint64, 1), 2, 0)); + } + } else { + return (($uint64 >> 1) & 0x7FFFFFFFFFFFFFFF) ^ (-($uint64 & 1)); + } } public static function readInt32(&$input, &$value) @@ -227,11 +231,7 @@ class GPBWire public static function readSfixed64(&$input, &$value) { - if (!self::readFixed64($input, $value)) { - return false; - } - $value = Int64::newValue($value->high, $value->low); - return true; + return $input->readLittleEndian64($value); } public static function readFloat(&$input, &$value) @@ -259,7 +259,7 @@ class GPBWire if (!$input->readVarint64($value)) { return false; } - if ($value->high === 0 && $value->low === 0) { + if ($value == 0) { $value = false; } else { $value = true; @@ -324,8 +324,8 @@ class GPBWire public static function writeSint64(&$output, $value) { - $value = GPBWire::zigZagEncode64(GPBUtil::Int64($value)); - return $output->writeVarint64($value->toInteger()); + $value = GPBWire::zigZagEncode64($value); + return $output->writeVarint64($value); } public static function writeFixed32(&$output, $value) @@ -431,9 +431,8 @@ class GPBWire public static function sint64Size($value) { - $value = GPBUtil::Int64($value); $value = self::zigZagEncode64($value); - return self::varint64Size($value->toInteger()); + return self::varint64Size($value); } public static function varint64Size($value) diff --git a/php/src/Google/Protobuf/Internal/InputStream.php b/php/src/Google/Protobuf/Internal/InputStream.php index 18d07075..6d6c74e9 100644 --- a/php/src/Google/Protobuf/Internal/InputStream.php +++ b/php/src/Google/Protobuf/Internal/InputStream.php @@ -34,6 +34,24 @@ namespace Google\Protobuf\Internal; use Google\Protobuf\Internal\Uint64; +function combineInt32ToInt64($high, $low) +{ + $isNeg = $high < 0; + if ($isNeg) { + $high = ~$high; + $low = ~$low; + $low++; + if (!$low) { + $high++; + } + } + $result = bcadd(bcmul($high, 4294967296), $low); + if ($isNeg) { + $result = bcsub(0, $result); + } + return $result; +} + class InputStream { @@ -116,11 +134,23 @@ class InputStream if (!$this->readVarint64($var)) { return false; } - $var = $var->toInteger() & 0xFFFFFFFF; + + if (PHP_INT_SIZE == 4) { + $var = bcmod($var, 4294967296); + } else { + $var &= 0xFFFFFFFF; + } + // Convert large uint32 to int32. - if (PHP_INT_SIZE === 8 && ($var > 0x7FFFFFFF)) { - $var = $var | (0xFFFFFFFF << 32); + if ($var > 0x7FFFFFFF) { + if (PHP_INT_SIZE === 8) { + $var = $var | (0xFFFFFFFF << 32); + } else { + $var = bcsub($var, 4294967296); + } } + + $var = intval($var); return true; } @@ -130,7 +160,8 @@ class InputStream */ public function readVarint64(&$var) { - $result = new Uint64(0); + $high = 0; + $low = 0; $count = 0; $b = 0; @@ -142,12 +173,27 @@ class InputStream return false; } $b = ord($this->buffer[$this->current]); - $result->bitOr((new Uint64($b & 0x7F))->leftShift(7 * $count)); + $bits = 7 * $count; + if ($bits >= 32) { + $high |= (($b & 0x7F) << ($bits - 32)); + } else if ($bits > 25){ + $high_bits = $bits - 25; + $low = ($low | (($b & 0x7F) << $bits)) & (int) 0xFFFFFFFF; + $high = $b & ((0x1 << $high_bits) -1); + } else { + $low |= (($b & 0x7F) << $bits); + } + $this->advance(1); $count += 1; } while ($b & 0x80); - $var = $result; + if (PHP_INT_SIZE == 4) { + $var = combineInt32ToInt64($high, $low); + } else { + $var = ($high & 0xFFFFFFFF) << 32 | + ($low & 0xFFFFFFFF); + } return true; } @@ -161,7 +207,7 @@ class InputStream if (!$this->readVarint64($var)) { return false; } - $var = $var->toInteger(); + $var = (int)$var; return true; } @@ -197,7 +243,11 @@ class InputStream return false; } $high = unpack('V', $data)[1]; - $var = Uint64::newValue($high, $low); + if (PHP_INT_SIZE == 4) { + $var = combineInt32ToInt64($high, $low); + } else { + $var = ($high << 32) | $low; + } return true; } diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php index 7bdc6a8c..3d1f1598 100644 --- a/php/src/Google/Protobuf/Internal/Message.php +++ b/php/src/Google/Protobuf/Internal/Message.php @@ -125,6 +125,16 @@ class Message $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()]; $oneof_name = $oneof->getName(); $this->$oneof_name = new OneofField($oneof); + } else if ($field->getLabel() === GPBLabel::OPTIONAL && + PHP_INT_SIZE == 4) { + switch ($field->getType()) { + case GPBType::INT64: + case GPBType::UINT64: + case GPBType::FIXED64: + case GPBType::SFIXED64: + case GPBType::SINT64: + $this->$setter("0"); + } } } } @@ -210,13 +220,11 @@ class Message if (!GPBWire::readInt64($input, $value)) { return false; } - $value = $value->toInteger(); break; case GPBType::UINT64: if (!GPBWire::readUint64($input, $value)) { return false; } - $value = $value->toInteger(); break; case GPBType::INT32: if (!GPBWire::readInt32($input, $value)) { @@ -227,7 +235,6 @@ class Message if (!GPBWire::readFixed64($input, $value)) { return false; } - $value = $value->toInteger(); break; case GPBType::FIXED32: if (!GPBWire::readFixed32($input, $value)) { @@ -285,7 +292,6 @@ class Message if (!GPBWire::readSfixed64($input, $value)) { return false; } - $value = $value->toInteger(); break; case GPBType::SINT32: if (!GPBWire::readSint32($input, $value)) { @@ -296,7 +302,6 @@ class Message if (!GPBWire::readSint64($input, $value)) { return false; } - $value = $value->toInteger(); break; default: user_error("Unsupported type."); diff --git a/php/src/Google/Protobuf/Internal/OutputStream.php b/php/src/Google/Protobuf/Internal/OutputStream.php index fcc5ce6d..587ac352 100644 --- a/php/src/Google/Protobuf/Internal/OutputStream.php +++ b/php/src/Google/Protobuf/Internal/OutputStream.php @@ -90,8 +90,6 @@ class OutputStream public function writeRaw($data, $size) { if ($this->buffer_size < $size) { - var_dump($this->buffer_size); - var_dump($size); trigger_error("Output stream doesn't have enough buffer."); return false; } @@ -107,15 +105,28 @@ class OutputStream private static function writeVarintToArray($value, &$buffer, $trim = false) { $current = 0; - if ($trim) { - $value &= 0xFFFFFFFF; + + $high = 0; + $low = 0; + if (PHP_INT_SIZE == 4) { + GPBUtil::divideInt64ToInt32($value, $high, $low, $trim); + } else { + if ($trim) { + $low = $value & 0xFFFFFFFF; + } else { + $low = $value; + } } - while ($value >= 0x80 || $value < 0) { - $buffer[$current] = chr($value | 0x80); + + while ($low >= 0x80 || $low < 0) { + $buffer[$current] = chr($low | 0x80); $value = ($value >> 7) & ~(0x7F << ((PHP_INT_SIZE << 3) - 7)); + $carry = ($high & 0x7F) << ((PHP_INT_SIZE << 3) - 7); + $high = ($high >> 7) & ~(0x7F << ((PHP_INT_SIZE << 3) - 7)); + $low = (($low >> 7) & ~(0x7F << ((PHP_INT_SIZE << 3) - 7)) | $carry); $current++; } - $buffer[$current] = chr($value); + $buffer[$current] = chr($low); return $current + 1; } @@ -130,14 +141,24 @@ class OutputStream private static function writeLittleEndian64ToArray($value, &$buffer) { - $buffer[0] = chr($value & 0x000000FF); - $buffer[1] = chr(($value >> 8) & 0x000000FF); - $buffer[2] = chr(($value >> 16) & 0x000000FF); - $buffer[3] = chr(($value >> 24) & 0x000000FF); - $buffer[4] = chr(($value >> 32) & 0x000000FF); - $buffer[5] = chr(($value >> 40) & 0x000000FF); - $buffer[6] = chr(($value >> 48) & 0x000000FF); - $buffer[7] = chr(($value >> 56) & 0x000000FF); + $high = 0; + $low = 0; + if (PHP_INT_SIZE == 4) { + GPBUtil::divideInt64ToInt32($value, $high, $low); + } else { + $low = $value & 0xFFFFFFFF; + $high = ($value >> 32) & 0xFFFFFFFF; + } + + $buffer[0] = chr($low & 0x000000FF); + $buffer[1] = chr(($low >> 8) & 0x000000FF); + $buffer[2] = chr(($low >> 16) & 0x000000FF); + $buffer[3] = chr(($low >> 24) & 0x000000FF); + $buffer[4] = chr($high & 0x000000FF); + $buffer[5] = chr(($high >> 8) & 0x000000FF); + $buffer[6] = chr(($high >> 16) & 0x000000FF); + $buffer[7] = chr(($high >> 24) & 0x000000FF); return 8; } + } diff --git a/php/src/Google/Protobuf/Internal/Type.php b/php/src/Google/Protobuf/Internal/Type.php deleted file mode 100644 index 088f0e0c..00000000 --- a/php/src/Google/Protobuf/Internal/Type.php +++ /dev/null @@ -1,175 +0,0 @@ -<?php - -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -namespace Google\Protobuf\Internal; - -class GPBInteger -{ - public $high = 0; - public $low = 0; - - public function __construct($value = 0) - { - $this->low = $value & 0xFFFFFFFF; - if (PHP_INT_SIZE === 8) { - $this->high = ($value >> 32) & 0xFFFFFFFF; - } - } - - // Return 0 for unsigned integers and 1 for signed integers. - protected function sign() - { - trigger_error("Not implemented", E_ERROR); - } - - public function leftShift($count) - { - if ($count > 63) { - $this->low = 0; - $this->high = 0; - return; - } - if ($count > 32) { - $this->high = $this->low; - $this->low = 0; - $count -= 32; - } - $mask = (1 << $count) - 1; - $this->high = (($this->high << $count) & 0xFFFFFFFF) | - (($this->low >> (32 - $count)) & $mask); - $this->low = ($this->low << $count) & 0xFFFFFFFF; - - $this->high &= 0xFFFFFFFF; - $this->low &= 0xFFFFFFFF; - return $this; - } - - public function rightShift($count) - { - $sign = (($this->high & 0x80000000) >> 31) & $this->sign(); - if ($count > 63) { - $this->low = -$sign; - $this->high = -$sign; - return; - } - if ($count > 32) { - $this->low = $this->high; - $this->high = -$sign; - $count -= 32; - } - $this->low = (($this->low >> $count) & 0xFFFFFFFF) | - (($this->high << (32 - $count)) & 0xFFFFFFFF); - $this->high = (($this->high >> $count) | (-$sign << $count)); - - $this->high &= 0xFFFFFFFF; - $this->low &= 0xFFFFFFFF; - - return $this; - } - - public function bitOr($var) - { - $this->high |= $var->high; - $this->low |= $var->low; - return $this; - } - - public function bitXor($var) - { - $this->high ^= $var->high; - $this->low ^= $var->low; - return $this; - } - - public function bitAnd($var) - { - $this->high &= $var->high; - $this->low &= $var->low; - return $this; - } - - // Even: all zero; Odd: all one. - public function oddMask() - { - $low = (-($this->low & 1)) & 0xFFFFFFFF; - $high = $low; - return UInt64::newValue($high, $low); - } - - public function toInteger() - { - if (PHP_INT_SIZE === 8) { - return ($this->high << 32) | $this->low; - } else { - return $this->low; - } - } - - public function copy() - { - return static::newValue($this->high, $this->low); - } -} - -class Uint64 extends GPBInteger -{ - - public static function newValue($high, $low) - { - $uint64 = new Uint64(0); - $uint64->high = $high; - $uint64->low = $low; - return $uint64; - } - - protected function sign() - { - return 0; - } -} - -class Int64 extends GPBInteger -{ - - public static function newValue($high, $low) - { - $int64 = new Int64(0); - $int64->high = $high; - $int64->low = $low; - return $int64; - } - - protected function sign() - { - return 1; - } -} diff --git a/php/src/Google/Protobuf/descriptor.php b/php/src/Google/Protobuf/descriptor.php index afe08227..ef6b9dcf 100644 --- a/php/src/Google/Protobuf/descriptor.php +++ b/php/src/Google/Protobuf/descriptor.php @@ -215,6 +215,18 @@ class Descriptor return $desc; } } + +function addPrefixIfSpecial( + $name, + $package) +{ + if ($name === "Empty" && $package === "google.protobuf") { + return "GPBEmpty"; + } else { + return $name; + } +} + function getFullClassName( $proto, $containing, @@ -224,7 +236,8 @@ function getFullClassName( &$fullname) { // Full name needs to start with '.'. - $message_name_without_package = $proto->getName(); + $message_name_without_package = + addPrefixIfSpecial($proto->getName(), $package); if ($containing !== "") { $message_name_without_package = $containing . "." . $message_name_without_package; @@ -240,9 +253,13 @@ function getFullClassName( $class_name_without_package = implode('_', array_map('ucwords', explode('.', $message_name_without_package))); - $classname = - implode('\\', array_map('ucwords', explode('.', $package))). - "\\".$class_name_without_package; + if ($package === "") { + $classname = $class_name_without_package; + } else { + $classname = + implode('\\', array_map('ucwords', explode('.', $package))). + "\\".$class_name_without_package; + } } class OneofDescriptor diff --git a/php/tests/array_test.php b/php/tests/array_test.php index 09d4dc82..a79a08bc 100644 --- a/php/tests/array_test.php +++ b/php/tests/array_test.php @@ -65,6 +65,17 @@ class RepeatedFieldTest extends PHPUnit_Framework_TestCase $this->assertSame(3, $arr[6]); $arr [7]= MAX_INT32_STRING; $this->assertSame(MAX_INT32, $arr[7]); + + // Test foreach. + $arr = new RepeatedField(GPBType::INT32); + for ($i = 0; $i < 3; $i++) { + $arr []= $i; + } + $i = 0; + foreach ($arr as $val) { + $this->assertSame($i++, $val); + } + $this->assertSame(3, $i); } /** @@ -225,46 +236,68 @@ class RepeatedFieldTest extends PHPUnit_Framework_TestCase // Test append. $arr []= MAX_INT64; - $this->assertSame(MAX_INT64, $arr[0]); $arr []= MIN_INT64; - $this->assertEquals(MIN_INT64, $arr[1]); - $arr []= 1.1; - $this->assertSame(1, $arr[2]); - $arr []= '2'; - $this->assertSame(2, $arr[3]); $arr []= '3.1'; - $this->assertSame(3, $arr[4]); $arr []= MAX_INT64_STRING; - $this->assertSame(MAX_INT64, $arr[5]); $arr []= MIN_INT64_STRING; - $this->assertEquals(MIN_INT64, $arr[6]); + if (PHP_INT_SIZE == 4) { + $this->assertSame(MAX_INT64, $arr[0]); + $this->assertSame(MIN_INT64, $arr[1]); + $this->assertSame('1', $arr[2]); + $this->assertSame('2', $arr[3]); + $this->assertSame('3', $arr[4]); + $this->assertSame(MAX_INT64_STRING, $arr[5]); + $this->assertSame(MIN_INT64_STRING, $arr[6]); + } else { + $this->assertSame(MAX_INT64, $arr[0]); + $this->assertSame(MIN_INT64, $arr[1]); + $this->assertSame(1, $arr[2]); + $this->assertSame(2, $arr[3]); + $this->assertSame(3, $arr[4]); + $this->assertSame(MAX_INT64, $arr[5]); + $this->assertSame(MIN_INT64, $arr[6]); + } + $this->assertEquals(7, count($arr)); for ($i = 0; $i < count($arr); $i++) { $arr[$i] = 0; - $this->assertSame(0, $arr[$i]); + if (PHP_INT_SIZE == 4) { + $this->assertSame('0', $arr[$i]); + } else { + $this->assertSame(0, $arr[$i]); + } } // Test set. $arr [0]= MAX_INT64; - $this->assertSame(MAX_INT64, $arr[0]); $arr [1]= MIN_INT64; - $this->assertEquals(MIN_INT64, $arr[1]); - $arr [2]= 1.1; - $this->assertSame(1, $arr[2]); - $arr [3]= '2'; - $this->assertSame(2, $arr[3]); $arr [4]= '3.1'; - $this->assertSame(3, $arr[4]); $arr [5]= MAX_INT64_STRING; - $this->assertSame(MAX_INT64, $arr[5]); $arr [6]= MIN_INT64_STRING; - $this->assertEquals(MIN_INT64, $arr[6]); + + if (PHP_INT_SIZE == 4) { + $this->assertSame(MAX_INT64_STRING, $arr[0]); + $this->assertSame(MIN_INT64_STRING, $arr[1]); + $this->assertSame('1', $arr[2]); + $this->assertSame('2', $arr[3]); + $this->assertSame('3', $arr[4]); + $this->assertSame(MAX_INT64_STRING, $arr[5]); + $this->assertEquals(MIN_INT64_STRING, $arr[6]); + } else { + $this->assertSame(MAX_INT64, $arr[0]); + $this->assertSame(MIN_INT64, $arr[1]); + $this->assertSame(1, $arr[2]); + $this->assertSame(2, $arr[3]); + $this->assertSame(3, $arr[4]); + $this->assertSame(MAX_INT64, $arr[5]); + $this->assertEquals(MIN_INT64, $arr[6]); + } } /** @@ -315,38 +348,57 @@ class RepeatedFieldTest extends PHPUnit_Framework_TestCase // Test append. $arr []= MAX_UINT64; - $this->assertEquals(MAX_UINT64, $arr[0]); - $arr []= 1.1; - $this->assertSame(1, $arr[1]); - $arr []= '2'; - $this->assertSame(2, $arr[2]); $arr []= '3.1'; - $this->assertSame(3, $arr[3]); $arr []= MAX_UINT64_STRING; - $this->assertEquals(MAX_UINT64, $arr[4]); - $this->assertEquals(5, count($arr)); + if (PHP_INT_SIZE == 4) { + $this->assertSame(MAX_UINT64_STRING, $arr[0]); + $this->assertSame('1', $arr[1]); + $this->assertSame('2', $arr[2]); + $this->assertSame('3', $arr[3]); + $this->assertSame(MAX_UINT64_STRING, $arr[4]); + } else { + $this->assertSame(MAX_UINT64, $arr[0]); + $this->assertSame(1, $arr[1]); + $this->assertSame(2, $arr[2]); + $this->assertSame(3, $arr[3]); + $this->assertSame(MAX_UINT64, $arr[4]); + $this->assertSame(5, count($arr)); + } + + $this->assertSame(5, count($arr)); for ($i = 0; $i < count($arr); $i++) { $arr[$i] = 0; - $this->assertSame(0, $arr[$i]); + if (PHP_INT_SIZE == 4) { + $this->assertSame('0', $arr[$i]); + } else { + $this->assertSame(0, $arr[$i]); + } } // Test set. $arr [0]= MAX_UINT64; - $this->assertEquals(MAX_UINT64, $arr[0]); - $arr [1]= 1.1; - $this->assertSame(1, $arr[1]); - $arr [2]= '2'; - $this->assertSame(2, $arr[2]); $arr [3]= '3.1'; - $this->assertSame(3, $arr[3]); $arr [4]= MAX_UINT64_STRING; - $this->assertEquals(MAX_UINT64, $arr[4]); + + if (PHP_INT_SIZE == 4) { + $this->assertSame(MAX_UINT64_STRING, $arr[0]); + $this->assertSame('1', $arr[1]); + $this->assertSame('2', $arr[2]); + $this->assertSame('3', $arr[3]); + $this->assertSame(MAX_UINT64_STRING, $arr[4]); + } else { + $this->assertSame(MAX_UINT64, $arr[0]); + $this->assertSame(1, $arr[1]); + $this->assertSame(2, $arr[2]); + $this->assertSame(3, $arr[3]); + $this->assertSame(MAX_UINT64, $arr[4]); + } } /** diff --git a/php/tests/generated_class_test.php b/php/tests/generated_class_test.php index 56466cae..b3ecd3a1 100644 --- a/php/tests/generated_class_test.php +++ b/php/tests/generated_class_test.php @@ -1,6 +1,7 @@ <?php require_once('test.pb.php'); +require_once('test_no_namespace.pb.php'); require_once('test_util.php'); use Google\Protobuf\Internal\RepeatedField; @@ -147,17 +148,40 @@ class GeneratedClassTest extends PHPUnit_Framework_TestCase // Set float. $m->setOptionalInt64(1.1); - $this->assertSame(1, $m->getOptionalInt64()); + if (PHP_INT_SIZE == 4) { + $this->assertSame('1', $m->getOptionalInt64()); + } else { + $this->assertSame(1, $m->getOptionalInt64()); + } // Set string. $m->setOptionalInt64('2'); - $this->assertSame(2, $m->getOptionalInt64()); + if (PHP_INT_SIZE == 4) { + $this->assertSame('2', $m->getOptionalInt64()); + } else { + $this->assertSame(2, $m->getOptionalInt64()); + } + $m->setOptionalInt64('3.1'); - $this->assertSame(3, $m->getOptionalInt64()); + if (PHP_INT_SIZE == 4) { + $this->assertSame('3', $m->getOptionalInt64()); + } else { + $this->assertSame(3, $m->getOptionalInt64()); + } + $m->setOptionalInt64(MAX_INT64_STRING); - $this->assertSame(MAX_INT64, $m->getOptionalInt64()); + if (PHP_INT_SIZE == 4) { + $this->assertSame(MAX_INT64_STRING, $m->getOptionalInt64()); + } else { + $this->assertSame(MAX_INT64, $m->getOptionalInt64()); + } + $m->setOptionalInt64(MIN_INT64_STRING); - $this->assertEquals(MIN_INT64, $m->getOptionalInt64()); + if (PHP_INT_SIZE == 4) { + $this->assertSame(MIN_INT64_STRING, $m->getOptionalInt64()); + } else { + $this->assertSame(MIN_INT64, $m->getOptionalInt64()); + } } /** @@ -188,19 +212,41 @@ class GeneratedClassTest extends PHPUnit_Framework_TestCase // Set integer. $m->setOptionalUint64(MAX_UINT64); - $this->assertEquals(MAX_UINT64, $m->getOptionalUint64()); + if (PHP_INT_SIZE == 4) { + $this->assertSame(MAX_UINT64_STRING, $m->getOptionalUint64()); + } else { + $this->assertSame(MAX_UINT64, $m->getOptionalUint64()); + } // Set float. $m->setOptionalUint64(1.1); - $this->assertSame(1, $m->getOptionalUint64()); + if (PHP_INT_SIZE == 4) { + $this->assertSame('1', $m->getOptionalUint64()); + } else { + $this->assertSame(1, $m->getOptionalUint64()); + } // Set string. $m->setOptionalUint64('2'); - $this->assertSame(2, $m->getOptionalUint64()); + if (PHP_INT_SIZE == 4) { + $this->assertSame('2', $m->getOptionalUint64()); + } else { + $this->assertSame(2, $m->getOptionalUint64()); + } + $m->setOptionalUint64('3.1'); - $this->assertSame(3, $m->getOptionalUint64()); + if (PHP_INT_SIZE == 4) { + $this->assertSame('3', $m->getOptionalUint64()); + } else { + $this->assertSame(3, $m->getOptionalUint64()); + } + $m->setOptionalUint64(MAX_UINT64_STRING); - $this->assertEquals(MAX_UINT64, $m->getOptionalUint64()); + if (PHP_INT_SIZE == 4) { + $this->assertSame(MAX_UINT64_STRING, $m->getOptionalUint64()); + } else { + $this->assertSame(MAX_UINT64, $m->getOptionalUint64()); + } } /** @@ -554,4 +600,12 @@ class GeneratedClassTest extends PHPUnit_Framework_TestCase $this->assertSame('', $m->getOneofString()); $this->assertSame(1, $m->getOneofMessage()->getA()); } + + ######################################################### + # Test oneof field. + ######################################################### + + public function testMessageWithoutNamespace() { + $m = new NoNameSpace(); + } } diff --git a/php/tests/google/protobuf/empty.pb.php b/php/tests/google/protobuf/empty.pb.php new file mode 100644 index 00000000..fdd0fe4f --- /dev/null +++ b/php/tests/google/protobuf/empty.pb.php @@ -0,0 +1,28 @@ +<?php +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: google/protobuf/empty.proto + +namespace Google\Protobuf; + +use Google\Protobuf\Internal\DescriptorPool; +use Google\Protobuf\Internal\GPBType; +use Google\Protobuf\Internal\RepeatedField; +use Google\Protobuf\Internal\GPBUtil; + +class GPBEmpty extends \Google\Protobuf\Internal\Message +{ + +} + +$pool = DescriptorPool::getGeneratedPool(); + +$pool->internalAddGeneratedFile(hex2bin( + "0ab7010a1b676f6f676c652f70726f746f6275662f656d7074792e70726f" . + "746f120f676f6f676c652e70726f746f62756622070a05456d7074794276" . + "0a13636f6d2e676f6f676c652e70726f746f627566420a456d7074795072" . + "6f746f50015a276769746875622e636f6d2f676f6c616e672f70726f746f" . + "6275662f7074797065732f656d707479f80101a20203475042aa021e476f" . + "6f676c652e50726f746f6275662e57656c6c4b6e6f776e54797065736206" . + "70726f746f33" +)); + diff --git a/php/tests/map_field_test.php b/php/tests/map_field_test.php index d79d0da3..4e42361d 100644 --- a/php/tests/map_field_test.php +++ b/php/tests/map_field_test.php @@ -205,9 +205,14 @@ class MapFieldTest extends PHPUnit_Framework_TestCase { // Test integer argument. $arr[MAX_INT64] = MAX_INT64; - $this->assertSame(MAX_INT64, $arr[MAX_INT64]); $arr[MIN_INT64] = MIN_INT64; - $this->assertEquals(MIN_INT64, $arr[MIN_INT64]); + if (PHP_INT_SIZE == 4) { + $this->assertSame(MAX_INT64_STRING, $arr[MAX_INT64_STRING]); + $this->assertSame(MIN_INT64_STRING, $arr[MIN_INT64_STRING]); + } else { + $this->assertSame(MAX_INT64, $arr[MAX_INT64]); + $this->assertSame(MIN_INT64, $arr[MIN_INT64]); + } $this->assertEquals(2, count($arr)); unset($arr[MAX_INT64]); unset($arr[MIN_INT64]); @@ -215,20 +220,31 @@ class MapFieldTest extends PHPUnit_Framework_TestCase { // Test float argument. $arr[1.1] = 1.1; - $this->assertSame(1, $arr[1]); + if (PHP_INT_SIZE == 4) { + $this->assertSame('1', $arr['1']); + } else { + $this->assertSame(1, $arr[1]); + } $this->assertEquals(1, count($arr)); unset($arr[1.1]); $this->assertEquals(0, count($arr)); // Test string argument. $arr['2'] = '2'; - $this->assertSame(2, $arr[2]); $arr['3.1'] = '3.1'; - $this->assertSame(3, $arr[3]); $arr[MAX_INT64_STRING] = MAX_INT64_STRING; - $this->assertSame(MAX_INT64, $arr[MAX_INT64]); $arr[MIN_INT64_STRING] = MIN_INT64_STRING; - $this->assertEquals(MIN_INT64, $arr[MIN_INT64]); + if (PHP_INT_SIZE == 4) { + $this->assertSame('2', $arr['2']); + $this->assertSame('3', $arr['3']); + $this->assertSame(MAX_INT64_STRING, $arr[MAX_INT64_STRING]); + $this->assertSame(MIN_INT64_STRING, $arr[MIN_INT64_STRING]); + } else { + $this->assertSame(2, $arr[2]); + $this->assertSame(3, $arr[3]); + $this->assertSame(MAX_INT64, $arr[MAX_INT64]); + $this->assertSame(MIN_INT64, $arr[MIN_INT64]); + } $this->assertEquals(4, count($arr)); unset($arr['2']); unset($arr['3.1']); @@ -282,25 +298,41 @@ class MapFieldTest extends PHPUnit_Framework_TestCase { // Test integer argument. $arr[MAX_UINT64] = MAX_UINT64; - $this->assertEquals(MAX_UINT64, $arr[MAX_UINT64]); + if (PHP_INT_SIZE == 4) { + $this->assertSame(MAX_UINT64_STRING, $arr[MAX_UINT64_STRING]); + } else { + $this->assertSame(MAX_UINT64, $arr[MAX_UINT64]); + } $this->assertEquals(1, count($arr)); unset($arr[MAX_UINT64]); $this->assertEquals(0, count($arr)); // Test float argument. $arr[1.1] = 1.1; - $this->assertSame(1, $arr[1]); + if (PHP_INT_SIZE == 4) { + $this->assertSame('1', $arr['1']); + } else { + $this->assertSame(1, $arr[1]); + } $this->assertEquals(1, count($arr)); unset($arr[1.1]); $this->assertEquals(0, count($arr)); // Test string argument. $arr['2'] = '2'; - $this->assertSame(2, $arr[2]); $arr['3.1'] = '3.1'; - $this->assertSame(3, $arr[3]); $arr[MAX_UINT64_STRING] = MAX_UINT64_STRING; - $this->assertEquals(MAX_UINT64, $arr[MAX_UINT64]); + + if (PHP_INT_SIZE == 4) { + $this->assertSame('2', $arr['2']); + $this->assertSame('3', $arr['3']); + $this->assertSame(MAX_UINT64_STRING, $arr[MAX_UINT64_STRING]); + } else { + $this->assertSame(2, $arr[2]); + $this->assertSame(3, $arr[3]); + $this->assertSame(MAX_UINT64, $arr[MAX_UINT64]); + } + $this->assertEquals(3, count($arr)); unset($arr['2']); unset($arr['3.1']); diff --git a/php/tests/php_implementation_test.php b/php/tests/php_implementation_test.php index 82941dd2..485956cc 100644 --- a/php/tests/php_implementation_test.php +++ b/php/tests/php_implementation_test.php @@ -9,14 +9,10 @@ use Foo\TestMessage_Sub; use Foo\TestPackedMessage; use Google\Protobuf\Internal\InputStream; use Google\Protobuf\Internal\FileDescriptorSet; -use Google\Protobuf\Internal\GPBUtil; -use Google\Protobuf\Internal\Int64; -use Google\Protobuf\Internal\Uint64; use Google\Protobuf\Internal\GPBLabel; use Google\Protobuf\Internal\GPBType; use Google\Protobuf\Internal\GPBWire; use Google\Protobuf\Internal\OutputStream; -use Google\Protobuf\Internal\RepeatedField; class ImplementationTest extends TestBase { @@ -68,17 +64,17 @@ class ImplementationTest extends TestBase // Positive number. $input = new InputStream(hex2bin("01")); GPBWire::readInt64($input, $value); - $this->assertSame(1, $value->toInteger()); + $this->assertEquals(1, $value); // Negative number. $input = new InputStream(hex2bin("ffffffffffffffffff01")); GPBWire::readInt64($input, $value); - $this->assertSame(-1, $value->toInteger()); + $this->assertEquals(-1, $value); // Discard overflow bits. $input = new InputStream(hex2bin("ffffffffffffffffff0f")); GPBWire::readInt64($input, $value); - $this->assertSame(-1, $value->toInteger()); + $this->assertEquals(-1, $value); } public function testReadUint64() @@ -88,17 +84,17 @@ class ImplementationTest extends TestBase // Positive number. $input = new InputStream(hex2bin("01")); GPBWire::readUint64($input, $value); - $this->assertSame(1, $value->toInteger()); + $this->assertEquals(1, $value); // Negative number. $input = new InputStream(hex2bin("FFFFFFFFFFFFFFFFFF01")); GPBWire::readUint64($input, $value); - $this->assertSame(-1, $value->toInteger()); + $this->assertEquals(-1, $value); // Discard overflow bits. $input = new InputStream(hex2bin("FFFFFFFFFFFFFFFFFF0F")); GPBWire::readUint64($input, $value); - $this->assertSame(-1, $value->toInteger()); + $this->assertEquals(-1, $value); } public function testReadSint32() @@ -124,15 +120,15 @@ class ImplementationTest extends TestBase $input = new InputStream(hex2bin("00")); GPBWire::readSint64($input, $value); - $this->assertEquals(GPBUtil::Int64(0), $value); + $this->assertEquals(0, $value); $input = new InputStream(hex2bin("01")); GPBWire::readSint64($input, $value); - $this->assertEquals(GPBUtil::Int64(-1), $value); + $this->assertEquals(-1, $value); $input = new InputStream(hex2bin("02")); GPBWire::readSint64($input, $value); - $this->assertEquals(GPBUtil::Int64(1), $value); + $this->assertEquals(1, $value); } public function testReadFixed32() @@ -148,7 +144,11 @@ class ImplementationTest extends TestBase $value = null; $input = new InputStream(hex2bin("1234567812345678")); GPBWire::readFixed64($input, $value); - $this->assertEquals(Uint64::newValue(0x78563412, 0x78563412), $value); + if (PHP_INT_SIZE == 4) { + $this->assertSame("8671175386481439762", $value); + } else { + $this->assertSame(0x7856341278563412, $value); + } } public function testReadSfixed32() @@ -193,7 +193,11 @@ class ImplementationTest extends TestBase $value = null; $input = new InputStream(hex2bin("1234567812345678")); GPBWire::readSfixed64($input, $value); - $this->assertEquals(Int64::newValue(0x78563412, 0x78563412), $value); + if (PHP_INT_SIZE == 4) { + $this->assertSame("8671175386481439762", $value); + } else { + $this->assertSame(0x7856341278563412, $value); + } } public function testZigZagEncodeDecode() @@ -214,43 +218,65 @@ class ImplementationTest extends TestBase $this->assertSame(0x3FFFFFFF, GPBWire::zigZagDecode32(0x7FFFFFFE)); $this->assertSame(-1073741824, GPBWire::zigZagDecode32(0x7FFFFFFF)); $this->assertSame(0x7FFFFFFF, GPBWire::zigZagDecode32(0xFFFFFFFE)); - $this->assertSame(-2147483648, GPBWire::zigZagDecode32(0xFFFFFFFF)); - - $this->assertEquals(GPBUtil::Uint64(0), - GPBWire::zigZagEncode64(GPBUtil::Int64(0))); - $this->assertEquals(GPBUtil::Uint64(1), - GPBWire::zigZagEncode64(GPBUtil::Int64(-1))); - $this->assertEquals(GPBUtil::Uint64(2), - GPBWire::zigZagEncode64(GPBUtil::Int64(1))); - $this->assertEquals(GPBUtil::Uint64(3), - GPBWire::zigZagEncode64(GPBUtil::Int64(-2))); - $this->assertEquals( - GPBUtil::Uint64(0x000000007FFFFFFE), - GPBWire::zigZagEncode64(GPBUtil::Int64(0x000000003FFFFFFF))); - $this->assertEquals( - GPBUtil::Uint64(0x000000007FFFFFFF), - GPBWire::zigZagEncode64(GPBUtil::Int64(0xFFFFFFFFC0000000))); - $this->assertEquals( - GPBUtil::Uint64(0x00000000FFFFFFFE), - GPBWire::zigZagEncode64(GPBUtil::Int64(0x000000007FFFFFFF))); - $this->assertEquals( - GPBUtil::Uint64(0x00000000FFFFFFFF), - GPBWire::zigZagEncode64(GPBUtil::Int64(0xFFFFFFFF80000000))); - $this->assertEquals( - Uint64::newValue(4294967295, 4294967294), - GPBWire::zigZagEncode64(GPBUtil::Int64(0x7FFFFFFFFFFFFFFF))); - $this->assertEquals( - Uint64::newValue(4294967295, 4294967295), - GPBWire::zigZagEncode64(GPBUtil::Int64(0x8000000000000000))); - - $this->assertEquals(GPBUtil::Int64(0), - GPBWire::zigZagDecode64(GPBUtil::Uint64(0))); - $this->assertEquals(GPBUtil::Int64(-1), - GPBWire::zigZagDecode64(GPBUtil::Uint64(1))); - $this->assertEquals(GPBUtil::Int64(1), - GPBWire::zigZagDecode64(GPBUtil::Uint64(2))); - $this->assertEquals(GPBUtil::Int64(-2), - GPBWire::zigZagDecode64(GPBUtil::Uint64(3))); + $this->assertSame((int)-2147483648,GPBWire::zigZagDecode32(0xFFFFFFFF)); + + if (PHP_INT_SIZE == 4) { + $this->assertSame('0', GPBWire::zigZagEncode64(0)); + $this->assertSame('1', GPBWire::zigZagEncode64(-1)); + $this->assertSame('2', GPBWire::zigZagEncode64(1)); + $this->assertSame('3', GPBWire::zigZagEncode64(-2)); + $this->assertSame( + '2147483646', // 0x7FFFFFE + GPBWire::zigZagEncode64(0x3FFFFFFF)); + $this->assertSame( + '2147483647', // 0x7FFFFFF + GPBWire::zigZagEncode64(-1073741824)); // 0xFFFFFFFFC0000000 + $this->assertSame( + '4294967294', // 0xFFFFFFFE + GPBWire::zigZagEncode64(2147483647)); // 0x7FFFFFFF + $this->assertSame( + '4294967295', // 0xFFFFFFFF + GPBWire::zigZagEncode64(-2147483648)); // 0xFFFFFFFF80000000 + $this->assertSame( + '18446744073709551614', // 0xFFFFFFFFFFFFFFFE + // 0x7FFFFFFFFFFFFFFF + GPBWire::zigZagEncode64("9223372036854775807")); + $this->assertSame( + '18446744073709551615', // 0xFFFFFFFFFFFFFFFF + // 0x8000000000000000 + GPBWire::zigZagEncode64("-9223372036854775808")); + + $this->assertSame('0', GPBWire::zigZagDecode64(0)); + $this->assertSame('-1', GPBWire::zigZagDecode64(1)); + $this->assertSame('1', GPBWire::zigZagDecode64(2)); + $this->assertSame('-2', GPBWire::zigZagDecode64(3)); + } else { + $this->assertSame(0, GPBWire::zigZagEncode64(0)); + $this->assertSame(1, GPBWire::zigZagEncode64(-1)); + $this->assertSame(2, GPBWire::zigZagEncode64(1)); + $this->assertSame(3, GPBWire::zigZagEncode64(-2)); + $this->assertSame(0x7FFFFFFE, GPBWire::zigZagEncode64(0x3FFFFFFF)); + $this->assertSame( + 0x7FFFFFFF, + GPBWire::zigZagEncode64(0xFFFFFFFFC0000000)); + $this->assertSame( + 0xFFFFFFFE, + GPBWire::zigZagEncode64(0x7FFFFFFF)); + $this->assertSame( + 0xFFFFFFFF, + GPBWire::zigZagEncode64(0xFFFFFFFF80000000)); + $this->assertSame( + -2, // 0xFFFFFFFFFFFFFFFE + GPBWire::zigZagEncode64(0x7FFFFFFFFFFFFFFF)); + $this->assertSame( + -1, // 0xFFFFFFFFFFFFFFFF + GPBWire::zigZagEncode64(0x8000000000000000)); + + $this->assertSame(0, GPBWire::zigZagDecode64(0)); + $this->assertSame(-1, GPBWire::zigZagDecode64(1)); + $this->assertSame(1, GPBWire::zigZagDecode64(2)); + $this->assertSame(-2, GPBWire::zigZagDecode64(3)); + } // Round trip $this->assertSame(0, GPBWire::zigZagDecode32(GPBWire::zigZagEncode32(0))); @@ -319,15 +345,27 @@ class ImplementationTest extends TestBase // Normal case. $input = new InputStream(hex2bin('808001')); $this->assertTrue($input->readVarint64($var)); - $this->assertSame(16384, $var->toInteger()); + if (PHP_INT_SIZE == 4) { + $this->assertSame('16384', $var); + } else { + $this->assertSame(16384, $var); + } $this->assertFalse($input->readVarint64($var)); // Read two varint. $input = new InputStream(hex2bin('808001808002')); $this->assertTrue($input->readVarint64($var)); - $this->assertSame(16384, $var->toInteger()); + if (PHP_INT_SIZE == 4) { + $this->assertSame('16384', $var); + } else { + $this->assertSame(16384, $var); + } $this->assertTrue($input->readVarint64($var)); - $this->assertSame(32768, $var->toInteger()); + if (PHP_INT_SIZE == 4) { + $this->assertSame('32768', $var); + } else { + $this->assertSame(32768, $var); + } $this->assertFalse($input->readVarint64($var)); } diff --git a/php/tests/test.sh b/php/tests/test.sh index 888e93eb..a6ca89b9 100755 --- a/php/tests/test.sh +++ b/php/tests/test.sh @@ -7,10 +7,11 @@ pushd ../ext/google/protobuf/ make clean set -e -phpize && ./configure --enable-debug CFLAGS='-g -O0' && make +# Add following in configure for debug: --enable-debug CFLAGS='-g -O0' +phpize && ./configure && make popd -tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php ) +tests=( array_test.php encode_decode_test.php generated_class_test.php map_field_test.php well_known_test.php ) for t in "${tests[@]}" do diff --git a/php/tests/test_base.php b/php/tests/test_base.php index 25f18f74..d461f0f7 100644 --- a/php/tests/test_base.php +++ b/php/tests/test_base.php @@ -13,22 +13,28 @@ class TestBase extends PHPUnit_Framework_TestCase public function expectFields(TestMessage $m) { - $this->assertSame(-42, $m->getOptionalInt32()); - $this->assertSame(42, $m->getOptionalUint32()); - $this->assertSame(-43, $m->getOptionalInt64()); - $this->assertSame(43, $m->getOptionalUint64()); $this->assertSame(-44, $m->getOptionalSint32()); - $this->assertSame(-45, $m->getOptionalSint64()); $this->assertSame(46, $m->getOptionalFixed32()); - $this->assertSame(47, $m->getOptionalFixed64()); $this->assertSame(-46, $m->getOptionalSfixed32()); - $this->assertSame(-47, $m->getOptionalSfixed64()); $this->assertSame(1.5, $m->getOptionalFloat()); $this->assertSame(1.6, $m->getOptionalDouble()); $this->assertSame(true, $m->getOptionalBool()); $this->assertSame('a', $m->getOptionalString()); $this->assertSame('b', $m->getOptionalBytes()); $this->assertSame(33, $m->getOptionalMessage()->getA()); + if (PHP_INT_SIZE == 4) { + $this->assertSame('-43', $m->getOptionalInt64()); + $this->assertSame('43', $m->getOptionalUint64()); + $this->assertSame('-45', $m->getOptionalSint64()); + $this->assertSame('47', $m->getOptionalFixed64()); + $this->assertSame('-47', $m->getOptionalSfixed64()); + } else { + $this->assertSame(-43, $m->getOptionalInt64()); + $this->assertSame(43, $m->getOptionalUint64()); + $this->assertSame(-45, $m->getOptionalSint64()); + $this->assertSame(47, $m->getOptionalFixed64()); + $this->assertSame(-47, $m->getOptionalSfixed64()); + } $this->assertEquals(-42, $m->getRepeatedInt32()[0]); $this->assertEquals(42, $m->getRepeatedUint32()[0]); @@ -69,20 +75,28 @@ class TestBase extends PHPUnit_Framework_TestCase { $this->assertSame(0, $m->getOptionalInt32()); $this->assertSame(0, $m->getOptionalUint32()); - $this->assertSame(0, $m->getOptionalInt64()); - $this->assertSame(0, $m->getOptionalUint64()); $this->assertSame(0, $m->getOptionalSint32()); - $this->assertSame(0, $m->getOptionalSint64()); $this->assertSame(0, $m->getOptionalFixed32()); - $this->assertSame(0, $m->getOptionalFixed64()); $this->assertSame(0, $m->getOptionalSfixed32()); - $this->assertSame(0, $m->getOptionalSfixed64()); $this->assertSame(0.0, $m->getOptionalFloat()); $this->assertSame(0.0, $m->getOptionalDouble()); $this->assertSame(false, $m->getOptionalBool()); $this->assertSame('', $m->getOptionalString()); $this->assertSame('', $m->getOptionalBytes()); $this->assertNull($m->getOptionalMessage()); + if (PHP_INT_SIZE == 4) { + $this->assertSame("0", $m->getOptionalInt64()); + $this->assertSame("0", $m->getOptionalUint64()); + $this->assertSame("0", $m->getOptionalSint64()); + $this->assertSame("0", $m->getOptionalFixed64()); + $this->assertSame("0", $m->getOptionalSfixed64()); + } else { + $this->assertSame(0, $m->getOptionalInt64()); + $this->assertSame(0, $m->getOptionalUint64()); + $this->assertSame(0, $m->getOptionalSint64()); + $this->assertSame(0, $m->getOptionalFixed64()); + $this->assertSame(0, $m->getOptionalSfixed64()); + } } // This test is to avoid the warning of no test by php unit. diff --git a/php/tests/test_no_namespace.pb.php b/php/tests/test_no_namespace.pb.php new file mode 100644 index 00000000..2f92c955 --- /dev/null +++ b/php/tests/test_no_namespace.pb.php @@ -0,0 +1,34 @@ +<?php +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: test_no_namespace.proto + +use Google\Protobuf\Internal\DescriptorPool; +use Google\Protobuf\Internal\GPBType; +use Google\Protobuf\Internal\RepeatedField; +use Google\Protobuf\Internal\GPBUtil; + +class NoNameSpace extends \Google\Protobuf\Internal\Message +{ + private $a = 0; + + public function getA() + { + return $this->a; + } + + public function setA($var) + { + GPBUtil::checkInt32($var); + $this->a = $var; + } + +} + +$pool = DescriptorPool::getGeneratedPool(); + +$pool->internalAddGeneratedFile(hex2bin( + "0a3b0a17746573745f6e6f5f6e616d6573706163652e70726f746f22180a" . + "0b4e6f4e616d65537061636512090a0161180120012805620670726f746f" . + "33" +)); + diff --git a/php/tests/test_no_namespace.proto b/php/tests/test_no_namespace.proto new file mode 100644 index 00000000..4331aeab --- /dev/null +++ b/php/tests/test_no_namespace.proto @@ -0,0 +1,5 @@ +syntax = "proto3"; + +message NoNameSpace { + int32 a = 1; +} diff --git a/php/tests/test_util.php b/php/tests/test_util.php index 2f6e4dd8..7f2aae15 100644 --- a/php/tests/test_util.php +++ b/php/tests/test_util.php @@ -20,7 +20,7 @@ define('MAX_INT32', 2147483647); define('MAX_INT32_FLOAT', 2147483647.0); define('MAX_INT32_STRING', '2147483647'); -define('MIN_INT32', -2147483648); +define('MIN_INT32', (int)-2147483648); define('MIN_INT32_FLOAT', -2147483648.0); define('MIN_INT32_STRING', '-2147483648'); @@ -28,23 +28,24 @@ define('MAX_UINT32', 4294967295); define('MAX_UINT32_FLOAT', 4294967295.0); define('MAX_UINT32_STRING', '4294967295'); -define('MIN_UINT32', -2147483648); +define('MIN_UINT32', (int)-2147483648); define('MIN_UINT32_FLOAT', -2147483648.0); define('MIN_UINT32_STRING', '-2147483648'); -define('MAX_INT64', 9223372036854775807); -define('MAX_INT64_STRING', '9223372036854775807'); +define('MAX_INT64_STRING', '9223372036854775807'); +define('MIN_INT64_STRING', '-9223372036854775808'); +define('MAX_UINT64_STRING', '-9223372036854775808'); -define('MIN_INT64_STRING', '-9223372036854775808'); if (PHP_INT_SIZE === 8) { - define('MIN_INT64', -9223372036854775808); + define('MAX_INT64', (int)9223372036854775807); + define('MIN_INT64', (int)-9223372036854775808); + define('MAX_UINT64', (int)-9223372036854775808); } else { + define('MAX_INT64', MAX_INT64_STRING); define('MIN_INT64', MIN_INT64_STRING); + define('MAX_UINT64', MAX_UINT64_STRING); } -define('MAX_UINT64_STRING', '-9223372036854775808'); -define('MAX_UINT64', MAX_UINT64_STRING); - class TestUtil { @@ -129,16 +130,24 @@ class TestUtil public static function assertTestMessage(TestMessage $m) { + if (PHP_INT_SIZE == 4) { + assert('-43' === $m->getOptionalInt64()); + assert('43' === $m->getOptionalUint64()); + assert('-45' === $m->getOptionalSint64()); + assert('47' === $m->getOptionalFixed64()); + assert('-47' === $m->getOptionalSfixed64()); + } else { + assert(-43 === $m->getOptionalInt64()); + assert(43 === $m->getOptionalUint64()); + assert(-45 === $m->getOptionalSint64()); + assert(47 === $m->getOptionalFixed64()); + assert(-47 === $m->getOptionalSfixed64()); + } assert(-42 === $m->getOptionalInt32()); assert(42 === $m->getOptionalUint32()); - assert(-43 === $m->getOptionalInt64()); - assert(43 === $m->getOptionalUint64()); assert(-44 === $m->getOptionalSint32()); - assert(-45 === $m->getOptionalSint64()); assert(46 === $m->getOptionalFixed32()); - assert(47 === $m->getOptionalFixed64()); assert(-46 === $m->getOptionalSfixed32()); - assert(-47 === $m->getOptionalSfixed64()); assert(1.5 === $m->getOptionalFloat()); assert(1.6 === $m->getOptionalDouble()); assert(true=== $m->getOptionalBool()); @@ -147,16 +156,24 @@ class TestUtil assert(TestEnum::ONE === $m->getOptionalEnum()); assert(33 === $m->getOptionalMessage()->getA()); + if (PHP_INT_SIZE == 4) { + assert('-43' === $m->getRepeatedInt64()[0]); + assert('43' === $m->getRepeatedUint64()[0]); + assert('-45' === $m->getRepeatedSint64()[0]); + assert('47' === $m->getRepeatedFixed64()[0]); + assert('-47' === $m->getRepeatedSfixed64()[0]); + } else { + assert(-43 === $m->getRepeatedInt64()[0]); + assert(43 === $m->getRepeatedUint64()[0]); + assert(-45 === $m->getRepeatedSint64()[0]); + assert(47 === $m->getRepeatedFixed64()[0]); + assert(-47 === $m->getRepeatedSfixed64()[0]); + } assert(-42 === $m->getRepeatedInt32()[0]); assert(42 === $m->getRepeatedUint32()[0]); - assert(-43 === $m->getRepeatedInt64()[0]); - assert(43 === $m->getRepeatedUint64()[0]); assert(-44 === $m->getRepeatedSint32()[0]); - assert(-45 === $m->getRepeatedSint64()[0]); assert(46 === $m->getRepeatedFixed32()[0]); - assert(47 === $m->getRepeatedFixed64()[0]); assert(-46 === $m->getRepeatedSfixed32()[0]); - assert(-47 === $m->getRepeatedSfixed64()[0]); assert(1.5 === $m->getRepeatedFloat()[0]); assert(1.6 === $m->getRepeatedDouble()[0]); assert(true=== $m->getRepeatedBool()[0]); @@ -165,16 +182,24 @@ class TestUtil assert(TestEnum::ZERO === $m->getRepeatedEnum()[0]); assert(34 === $m->getRepeatedMessage()[0]->getA()); + if (PHP_INT_SIZE == 4) { + assert('-53' === $m->getRepeatedInt64()[1]); + assert('53' === $m->getRepeatedUint64()[1]); + assert('-55' === $m->getRepeatedSint64()[1]); + assert('57' === $m->getRepeatedFixed64()[1]); + assert('-57' === $m->getRepeatedSfixed64()[1]); + } else { + assert(-53 === $m->getRepeatedInt64()[1]); + assert(53 === $m->getRepeatedUint64()[1]); + assert(-55 === $m->getRepeatedSint64()[1]); + assert(57 === $m->getRepeatedFixed64()[1]); + assert(-57 === $m->getRepeatedSfixed64()[1]); + } assert(-52 === $m->getRepeatedInt32()[1]); assert(52 === $m->getRepeatedUint32()[1]); - assert(-53 === $m->getRepeatedInt64()[1]); - assert(53 === $m->getRepeatedUint64()[1]); assert(-54 === $m->getRepeatedSint32()[1]); - assert(-55 === $m->getRepeatedSint64()[1]); assert(56 === $m->getRepeatedFixed32()[1]); - assert(57 === $m->getRepeatedFixed64()[1]); assert(-56 === $m->getRepeatedSfixed32()[1]); - assert(-57 === $m->getRepeatedSfixed64()[1]); assert(2.5 === $m->getRepeatedFloat()[1]); assert(2.6 === $m->getRepeatedDouble()[1]); assert(false === $m->getRepeatedBool()[1]); @@ -183,14 +208,21 @@ class TestUtil assert(TestEnum::ONE === $m->getRepeatedEnum()[1]); assert(35 === $m->getRepeatedMessage()[1]->getA()); + if (PHP_INT_SIZE == 4) { + assert('-63' === $m->getMapInt64Int64()['-63']); + assert('63' === $m->getMapUint64Uint64()['63']); + assert('-65' === $m->getMapSint64Sint64()['-65']); + assert('67' === $m->getMapFixed64Fixed64()['67']); + } else { + assert(-63 === $m->getMapInt64Int64()[-63]); + assert(63 === $m->getMapUint64Uint64()[63]); + assert(-65 === $m->getMapSint64Sint64()[-65]); + assert(67 === $m->getMapFixed64Fixed64()[67]); + } assert(-62 === $m->getMapInt32Int32()[-62]); - assert(-63 === $m->getMapInt64Int64()[-63]); assert(62 === $m->getMapUint32Uint32()[62]); - assert(63 === $m->getMapUint64Uint64()[63]); assert(-64 === $m->getMapSint32Sint32()[-64]); - assert(-65 === $m->getMapSint64Sint64()[-65]); assert(66 === $m->getMapFixed32Fixed32()[66]); - assert(67 === $m->getMapFixed64Fixed64()[67]); assert(3.5 === $m->getMapInt32Float()[1]); assert(3.6 === $m->getMapInt32Double()[1]); assert(true === $m->getMapBoolBool()[true]); @@ -325,24 +357,14 @@ class TestUtil assert(-42 === $m->getRepeatedInt32()[0]); assert(-52 === $m->getRepeatedInt32()[1]); - assert(-43 === $m->getRepeatedInt64()[0]); - assert(-53 === $m->getRepeatedInt64()[1]); assert(42 === $m->getRepeatedUint32()[0]); assert(52 === $m->getRepeatedUint32()[1]); - assert(43 === $m->getRepeatedUint64()[0]); - assert(53 === $m->getRepeatedUint64()[1]); assert(-44 === $m->getRepeatedSint32()[0]); assert(-54 === $m->getRepeatedSint32()[1]); - assert(-45 === $m->getRepeatedSint64()[0]); - assert(-55 === $m->getRepeatedSint64()[1]); assert(46 === $m->getRepeatedFixed32()[0]); assert(56 === $m->getRepeatedFixed32()[1]); - assert(47 === $m->getRepeatedFixed64()[0]); - assert(57 === $m->getRepeatedFixed64()[1]); assert(-46 === $m->getRepeatedSfixed32()[0]); assert(-56 === $m->getRepeatedSfixed32()[1]); - assert(-47 === $m->getRepeatedSfixed64()[0]); - assert(-57 === $m->getRepeatedSfixed64()[1]); assert(1.5 === $m->getRepeatedFloat()[0]); assert(2.5 === $m->getRepeatedFloat()[1]); assert(1.6 === $m->getRepeatedDouble()[0]); @@ -351,6 +373,29 @@ class TestUtil assert(false === $m->getRepeatedBool()[1]); assert(TestEnum::ONE === $m->getRepeatedEnum()[0]); assert(TestEnum::ZERO === $m->getRepeatedEnum()[1]); + if (PHP_INT_SIZE == 4) { + assert('-43' === $m->getRepeatedInt64()[0]); + assert('-53' === $m->getRepeatedInt64()[1]); + assert('43' === $m->getRepeatedUint64()[0]); + assert('53' === $m->getRepeatedUint64()[1]); + assert('-45' === $m->getRepeatedSint64()[0]); + assert('-55' === $m->getRepeatedSint64()[1]); + assert('47' === $m->getRepeatedFixed64()[0]); + assert('57' === $m->getRepeatedFixed64()[1]); + assert('-47' === $m->getRepeatedSfixed64()[0]); + assert('-57' === $m->getRepeatedSfixed64()[1]); + } else { + assert(-43 === $m->getRepeatedInt64()[0]); + assert(-53 === $m->getRepeatedInt64()[1]); + assert(43 === $m->getRepeatedUint64()[0]); + assert(53 === $m->getRepeatedUint64()[1]); + assert(-45 === $m->getRepeatedSint64()[0]); + assert(-55 === $m->getRepeatedSint64()[1]); + assert(47 === $m->getRepeatedFixed64()[0]); + assert(57 === $m->getRepeatedFixed64()[1]); + assert(-47 === $m->getRepeatedSfixed64()[0]); + assert(-57 === $m->getRepeatedSfixed64()[1]); + } } public static function getGoldenTestPackedMessage() diff --git a/php/tests/well_known_test.php b/php/tests/well_known_test.php new file mode 100644 index 00000000..30715ba9 --- /dev/null +++ b/php/tests/well_known_test.php @@ -0,0 +1,13 @@ +<?php + +require_once("google/protobuf/empty.pb.php"); + +use Google\Protobuf\GPBEmpty; + +class WellKnownTest extends PHPUnit_Framework_TestCase { + + public function testNone() { + $msg = new GPBEmpty(); + } + +} |