diff options
author | 董菲 <feidong@anjuke.com> | 2016-11-16 10:32:52 +0800 |
---|---|---|
committer | James E. King, III <jking@apache.org> | 2017-10-25 08:56:40 -0400 |
commit | 1df2d9b801553a1addc1df112bedde09527dbfdd (patch) | |
tree | 4bf690a9a322ae2775b876805e849801a5ae78cc | |
parent | a39ba7f2946c08fa59dd0928e9c608a70ca52529 (diff) | |
download | thrift-1df2d9b801553a1addc1df112bedde09527dbfdd.tar.gz |
THRIFT-4353: support php ext read data after message begin
Client: php
This closes #1383
3 files changed, 90 insertions, 0 deletions
diff --git a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp index 4c9062e80..5374286f4 100644 --- a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp +++ b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp @@ -98,6 +98,7 @@ const int BAD_VERSION = 4; static zend_function_entry thrift_protocol_functions[] = { PHP_FE(thrift_protocol_write_binary, NULL) PHP_FE(thrift_protocol_read_binary, NULL) + PHP_FE(thrift_protocol_read_binary_after_message_begin, NULL) {NULL, NULL, NULL} } ; @@ -1123,4 +1124,61 @@ PHP_FUNCTION(thrift_protocol_read_binary) { } } + +// 4 params: $transport $response_Typename $strict_read $buffer_size +PHP_FUNCTION(thrift_protocol_read_binary_after_message_begin) { + int argc = ZEND_NUM_ARGS(); + + if (argc < 3) { + WRONG_PARAM_COUNT; + } + + zval ***args = (zval***) emalloc(argc * sizeof(zval**)); + zend_get_parameters_array_ex(argc, args); + + if (Z_TYPE_PP(args[0]) != IS_OBJECT) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "1st parameter is not an object (transport)"); + efree(args); + RETURN_NULL(); + } + + if (Z_TYPE_PP(args[1]) != IS_STRING) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "2nd parameter is not a string (typename of expected response struct)"); + efree(args); + RETURN_NULL(); + } + + if (argc == 4 && Z_TYPE_PP(args[3]) != IS_LONG) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "4nd parameter is not an integer (typename of expected buffer size)"); + efree(args); + RETURN_NULL(); + } + + try { + size_t buffer_size = 8192; + if (argc == 4) { + buffer_size = Z_LVAL_PP(args[3]); + } + + PHPInputTransport transport(*args[0], buffer_size); + char* obj_typename = Z_STRVAL_PP(args[1]); + convert_to_boolean(*args[2]); + bool strict_read = Z_BVAL_PP(args[2]); + efree(args); + args = NULL; + + createObject(obj_typename, return_value); + zval* spec = zend_read_static_property(zend_get_class_entry(return_value TSRMLS_CC), "_TSPEC", 6, false TSRMLS_CC); + binary_deserialize_spec(return_value, transport, Z_ARRVAL_P(spec)); + } catch (const PHPExceptionWrapper& ex) { + zend_throw_exception_object(ex TSRMLS_CC); + RETURN_NULL(); + } catch (const std::exception& ex) { + throw_zend_exception_from_std_exception(ex TSRMLS_CC); + RETURN_NULL(); + } +} + + + #endif /* PHP_VERSION_ID < 70000 && PHP_VERSION_ID > 50000 */ diff --git a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.h b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.h index 44d03ccde..04209973c 100644 --- a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.h +++ b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.h @@ -21,6 +21,7 @@ PHP_FUNCTION(thrift_protocol_write_binary); PHP_FUNCTION(thrift_protocol_read_binary); +PHP_FUNCTION(thrift_protocol_read_binary_after_message_begin); extern zend_module_entry thrift_protocol_module_entry; #define phpext_thrift_protocol_ptr &thrift_protocol_module_entry diff --git a/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp b/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp index 3c6c3db8e..dafc18501 100644 --- a/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp +++ b/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp @@ -88,6 +88,7 @@ const int BAD_VERSION = 4; static zend_function_entry thrift_protocol_functions[] = { PHP_FE(thrift_protocol_write_binary, nullptr) PHP_FE(thrift_protocol_read_binary, nullptr) + PHP_FE(thrift_protocol_read_binary_after_message_begin, nullptr) {nullptr, nullptr, nullptr} }; @@ -959,6 +960,10 @@ void binary_serialize_spec(zval* zthis, PHPOutputTransport& transport, HashTable zval rv; zval* prop = zend_read_property(Z_OBJCE_P(zthis), zthis, varname, strlen(varname), false, &rv); + + if (Z_TYPE_P(prop) == IS_REFERENCE){ + ZVAL_UNREF(prop); + } if (Z_TYPE_P(prop) != IS_NULL) { transport.writeI8(ttype); transport.writeI16(fieldno); @@ -1068,4 +1073,30 @@ PHP_FUNCTION(thrift_protocol_read_binary) { } } +// 4 params: $transport $response_Typename $strict_read $buffer_size +PHP_FUNCTION(thrift_protocol_read_binary_after_message_begin) { + zval *protocol; + zend_string *obj_typename; + zend_bool strict_read; + size_t buffer_size = 8192; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "oSb|l", &protocol, &obj_typename, &strict_read, &buffer_size) == FAILURE) { + return; + } + + try { + PHPInputTransport transport(protocol, buffer_size); + + createObject(ZSTR_VAL(obj_typename), return_value); + zval* spec = zend_read_static_property(Z_OBJCE_P(return_value), "_TSPEC", sizeof("_TSPEC")-1, false); + binary_deserialize_spec(return_value, transport, Z_ARRVAL_P(spec)); + } catch (const PHPExceptionWrapper& ex) { + zend_throw_exception_object(ex); + RETURN_NULL(); + } catch (const std::exception& ex) { + throw_zend_exception_from_std_exception(ex); + RETURN_NULL(); + } +} + #endif /* PHP_VERSION_ID >= 70000 */ |