Skip to content

PHPC-459: BSON objects should implement JsonSerializable #454

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 16, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/BSON/Binary.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
/* PHP Core stuff */
#include <php.h>
#include <php_ini.h>
#include <ext/json/php_json.h>
#include <ext/standard/base64.h>
#include <ext/standard/info.h>
#include <Zend/zend_interfaces.h>
#include <ext/spl/spl_iterators.h>
Expand Down Expand Up @@ -187,6 +189,42 @@ PHP_METHOD(Binary, getType)
}
/* }}} */

/* {{{ proto array Binary::jsonSerialize()
*/
PHP_METHOD(Binary, jsonSerialize)
{
php_phongo_binary_t *intern;
char type[3];
int type_len;

if (zend_parse_parameters_none() == FAILURE) {
return;
}

intern = Z_BINARY_OBJ_P(getThis());

array_init_size(return_value, 2);

#if PHP_VERSION_ID >= 70000
{
zend_string *data = php_base64_encode((unsigned char *)intern->data, intern->data_len);
ADD_ASSOC_STRINGL(return_value, "$binary", ZSTR_VAL(data), ZSTR_LEN(data));
zend_string_free(data);
}
#else
{
int data_len = 0;
unsigned char *data = php_base64_encode((unsigned char *)intern->data, intern->data_len, &data_len);
ADD_ASSOC_STRINGL(return_value, "$binary", (char *)data, data_len);
efree(data);
}
#endif

type_len = snprintf(type, sizeof(type), "%02x", intern->type);
ADD_ASSOC_STRINGL(return_value, "$type", type, type_len);
}
/* }}} */

/* {{{ proto string Binary::serialize()
*/
PHP_METHOD(Binary, serialize)
Expand Down Expand Up @@ -299,6 +337,7 @@ static zend_function_entry php_phongo_binary_me[] = {
PHP_ME(Binary, __construct, ai_Binary___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Binary, __set_state, ai_Binary___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(Binary, __toString, ai_Binary_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Binary, jsonSerialize, ai_Binary_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Binary, serialize, ai_Binary_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Binary, unserialize, ai_Binary_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Binary, getData, ai_Binary_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
Expand Down Expand Up @@ -399,6 +438,7 @@ PHP_MINIT_FUNCTION(Binary)
php_phongo_binary_ce->create_object = php_phongo_binary_create_object;
PHONGO_CE_FINAL(php_phongo_binary_ce);

zend_class_implements(php_phongo_binary_ce TSRMLS_CC, 1, php_json_serializable_ce);
zend_class_implements(php_phongo_binary_ce TSRMLS_CC, 1, php_phongo_type_ce);
zend_class_implements(php_phongo_binary_ce TSRMLS_CC, 1, zend_ce_serializable);

Expand Down
22 changes: 22 additions & 0 deletions src/BSON/Decimal128.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
/* PHP Core stuff */
#include <php.h>
#include <php_ini.h>
#include <ext/json/php_json.h>
#include <ext/standard/info.h>
#include <Zend/zend_interfaces.h>
#include <ext/spl/spl_iterators.h>
Expand Down Expand Up @@ -151,6 +152,25 @@ PHP_METHOD(Decimal128, __toString)
}
/* }}} */

/* {{{ proto array Decimal128::jsonSerialize()
*/
PHP_METHOD(Decimal128, jsonSerialize)
{
php_phongo_decimal128_t *intern;
char outbuf[BSON_DECIMAL128_STRING] = "";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the point of initialising this with a empty string in the code segment?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was previously done in php_phongo_decimal128_get_properties() as insurance that the string was null-terminated even if bson_decimal128_to_string() decided not to touch it. Based on my reading of bson_decimal128_to_string(), does always assign a null-terminated string to its output buffer, but it wasn't documented as doing so and I wanted to be defensive. The alternative was a memset() on the array, but I didn't think that was necessary.

__toString() and serialize() currently use char outbuf[BSON_DECIMAL128_STRING] without any assignment, but I wanted to update those later.


if (zend_parse_parameters_none() == FAILURE) {
return;
}

intern = Z_DECIMAL128_OBJ_P(getThis());

array_init_size(return_value, 1);
bson_decimal128_to_string(&intern->decimal, outbuf);
ADD_ASSOC_STRING(return_value, "$numberDecimal", outbuf);
}
/* }}} */

/* {{{ proto string Decimal128::serialize()
*/
PHP_METHOD(Decimal128, serialize)
Expand Down Expand Up @@ -262,6 +282,7 @@ static zend_function_entry php_phongo_decimal128_me[] = {
PHP_ME(Decimal128, __construct, ai_Decimal128___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Decimal128, __set_state, ai_Decimal128___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(Decimal128, __toString, ai_Decimal128_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Decimal128, jsonSerialize, ai_Decimal128_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Decimal128, serialize, ai_Decimal128_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Decimal128, unserialize, ai_Decimal128_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_FE_END
Expand Down Expand Up @@ -353,6 +374,7 @@ PHP_MINIT_FUNCTION(Decimal128)
php_phongo_decimal128_ce->create_object = php_phongo_decimal128_create_object;
PHONGO_CE_FINAL(php_phongo_decimal128_ce);

zend_class_implements(php_phongo_decimal128_ce TSRMLS_CC, 1, php_json_serializable_ce);
zend_class_implements(php_phongo_decimal128_ce TSRMLS_CC, 1, php_phongo_type_ce);
zend_class_implements(php_phongo_decimal128_ce TSRMLS_CC, 1, zend_ce_serializable);

Expand Down
36 changes: 36 additions & 0 deletions src/BSON/Javascript.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
/* PHP Core stuff */
#include <php.h>
#include <php_ini.h>
#include <ext/json/php_json.h>
#include <ext/standard/info.h>
#include <Zend/zend_interfaces.h>
#include <ext/spl/spl_iterators.h>
Expand Down Expand Up @@ -215,6 +216,39 @@ PHP_METHOD(Javascript, getScope)
}
/* }}} */

/* {{{ proto array Javascript::jsonSerialize()
*/
PHP_METHOD(Javascript, jsonSerialize)
{
php_phongo_javascript_t *intern;

if (zend_parse_parameters_none() == FAILURE) {
return;
}

intern = Z_JAVASCRIPT_OBJ_P(getThis());

array_init_size(return_value, 2);
ADD_ASSOC_STRINGL(return_value, "$code", intern->code, intern->code_len);

if (intern->scope && intern->scope->len) {
php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER;

if (phongo_bson_to_zval_ex(bson_get_data(intern->scope), intern->scope->len, &state)) {
#if PHP_VERSION_ID >= 70000
Z_ADDREF(state.zchild);
ADD_ASSOC_ZVAL_EX(return_value, "$scope", &state.zchild);
#else
Z_ADDREF_P(state.zchild);
ADD_ASSOC_ZVAL_EX(return_value, "$scope", state.zchild);
#endif
}

zval_ptr_dtor(&state.zchild);
}
}
/* }}} */

/* {{{ proto string Javascript::serialize()
*/
PHP_METHOD(Javascript, serialize)
Expand Down Expand Up @@ -351,6 +385,7 @@ static zend_function_entry php_phongo_javascript_me[] = {
PHP_ME(Javascript, __construct, ai_Javascript___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Javascript, __set_state, ai_Javascript___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(Javascript, __toString, ai_Javascript_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Javascript, jsonSerialize, ai_Javascript_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Javascript, serialize, ai_Javascript_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Javascript, unserialize, ai_Javascript_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Javascript, getCode, ai_Javascript_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
Expand Down Expand Up @@ -493,6 +528,7 @@ PHP_MINIT_FUNCTION(Javascript)
php_phongo_javascript_ce->create_object = php_phongo_javascript_create_object;
PHONGO_CE_FINAL(php_phongo_javascript_ce);

zend_class_implements(php_phongo_javascript_ce TSRMLS_CC, 1, php_json_serializable_ce);
zend_class_implements(php_phongo_javascript_ce TSRMLS_CC, 1, php_phongo_type_ce);
zend_class_implements(php_phongo_javascript_ce TSRMLS_CC, 1, zend_ce_serializable);

Expand Down
16 changes: 16 additions & 0 deletions src/BSON/MaxKey.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
/* PHP Core stuff */
#include <php.h>
#include <php_ini.h>
#include <ext/json/php_json.h>
#include <ext/standard/info.h>
#include <Zend/zend_interfaces.h>
#include <ext/spl/spl_iterators.h>
Expand Down Expand Up @@ -60,6 +61,19 @@ PHP_METHOD(MaxKey, __set_state)
}
/* }}} */

/* {{{ proto array MaxKey::jsonSerialize()
*/
PHP_METHOD(MaxKey, jsonSerialize)
{
if (zend_parse_parameters_none() == FAILURE) {
return;
}

array_init_size(return_value, 1);
ADD_ASSOC_LONG_EX(return_value, "$maxKey", 1);
}
/* }}} */

/* {{{ proto string MaxKey::serialize()
*/
PHP_METHOD(MaxKey, serialize)
Expand Down Expand Up @@ -101,6 +115,7 @@ ZEND_END_ARG_INFO()

static zend_function_entry php_phongo_maxkey_me[] = {
PHP_ME(MaxKey, __set_state, ai_MaxKey___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(MaxKey, jsonSerialize, ai_MaxKey_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(MaxKey, serialize, ai_MaxKey_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(MaxKey, unserialize, ai_MaxKey_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_FE_END
Expand Down Expand Up @@ -157,6 +172,7 @@ PHP_MINIT_FUNCTION(MaxKey)
php_phongo_maxkey_ce->create_object = php_phongo_maxkey_create_object;
PHONGO_CE_FINAL(php_phongo_maxkey_ce);

zend_class_implements(php_phongo_maxkey_ce TSRMLS_CC, 1, php_json_serializable_ce);
zend_class_implements(php_phongo_maxkey_ce TSRMLS_CC, 1, php_phongo_type_ce);
zend_class_implements(php_phongo_maxkey_ce TSRMLS_CC, 1, zend_ce_serializable);

Expand Down
16 changes: 16 additions & 0 deletions src/BSON/MinKey.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
/* PHP Core stuff */
#include <php.h>
#include <php_ini.h>
#include <ext/json/php_json.h>
#include <ext/standard/info.h>
#include <Zend/zend_interfaces.h>
#include <ext/spl/spl_iterators.h>
Expand Down Expand Up @@ -60,6 +61,19 @@ PHP_METHOD(MinKey, __set_state)
}
/* }}} */

/* {{{ proto array MinKey::jsonSerialize()
*/
PHP_METHOD(MinKey, jsonSerialize)
{
if (zend_parse_parameters_none() == FAILURE) {
return;
}

array_init_size(return_value, 1);
ADD_ASSOC_LONG_EX(return_value, "$minKey", 1);
}
/* }}} */

/* {{{ proto string MinKey::serialize()
*/
PHP_METHOD(MinKey, serialize)
Expand Down Expand Up @@ -101,6 +115,7 @@ ZEND_END_ARG_INFO()

static zend_function_entry php_phongo_minkey_me[] = {
PHP_ME(MinKey, __set_state, ai_MinKey___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(MinKey, jsonSerialize, ai_MinKey_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(MinKey, serialize, ai_MinKey_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(MinKey, unserialize, ai_MinKey_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_FE_END
Expand Down Expand Up @@ -158,6 +173,7 @@ PHP_MINIT_FUNCTION(MinKey)
php_phongo_minkey_ce->create_object = php_phongo_minkey_create_object;
PHONGO_CE_FINAL(php_phongo_minkey_ce);

zend_class_implements(php_phongo_minkey_ce TSRMLS_CC, 1, php_json_serializable_ce);
zend_class_implements(php_phongo_minkey_ce TSRMLS_CC, 1, php_phongo_type_ce);
zend_class_implements(php_phongo_minkey_ce TSRMLS_CC, 1, zend_ce_serializable);

Expand Down
20 changes: 20 additions & 0 deletions src/BSON/ObjectID.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
/* PHP Core stuff */
#include <php.h>
#include <php_ini.h>
#include <ext/json/php_json.h>
#include <ext/standard/info.h>
#include <Zend/zend_interfaces.h>
#include <ext/spl/spl_iterators.h>
Expand Down Expand Up @@ -197,6 +198,23 @@ PHP_METHOD(ObjectID, __toString)
}
/* }}} */

/* {{{ proto array ObjectID::jsonSerialize()
*/
PHP_METHOD(ObjectID, jsonSerialize)
{
php_phongo_objectid_t *intern;

if (zend_parse_parameters_none() == FAILURE) {
return;
}

intern = Z_OBJECTID_OBJ_P(getThis());

array_init_size(return_value, 1);
ADD_ASSOC_STRINGL(return_value, "$oid", intern->oid, 24);
}
/* }}} */

/* {{{ proto string ObjectID::serialize()
*/
PHP_METHOD(ObjectID, serialize)
Expand Down Expand Up @@ -306,6 +324,7 @@ static zend_function_entry php_phongo_objectid_me[] = {
PHP_ME(ObjectID, getTimestamp, ai_ObjectID_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(ObjectID, __set_state, ai_ObjectID___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(ObjectID, __toString, ai_ObjectID_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(ObjectID, jsonSerialize, ai_ObjectID_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(ObjectID, serialize, ai_ObjectID_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(ObjectID, unserialize, ai_ObjectID_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_FE_END
Expand Down Expand Up @@ -405,6 +424,7 @@ PHP_MINIT_FUNCTION(ObjectID)
php_phongo_objectid_ce->create_object = php_phongo_objectid_create_object;
PHONGO_CE_FINAL(php_phongo_objectid_ce);

zend_class_implements(php_phongo_objectid_ce TSRMLS_CC, 1, php_json_serializable_ce);
zend_class_implements(php_phongo_objectid_ce TSRMLS_CC, 1, php_phongo_type_ce);
zend_class_implements(php_phongo_objectid_ce TSRMLS_CC, 1, zend_ce_serializable);

Expand Down
21 changes: 21 additions & 0 deletions src/BSON/Regex.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
/* PHP Core stuff */
#include <php.h>
#include <php_ini.h>
#include <ext/json/php_json.h>
#include <ext/standard/info.h>
#include <Zend/zend_interfaces.h>
#include <ext/spl/spl_iterators.h>
Expand Down Expand Up @@ -206,6 +207,24 @@ PHP_METHOD(Regex, __toString)
}
/* }}} */

/* {{{ proto array Regex::jsonSerialize()
*/
PHP_METHOD(Regex, jsonSerialize)
{
php_phongo_regex_t *intern;

if (zend_parse_parameters_none() == FAILURE) {
return;
}

intern = Z_REGEX_OBJ_P(getThis());

array_init_size(return_value, 2);
ADD_ASSOC_STRINGL(return_value, "$regex", intern->pattern, intern->pattern_len);
ADD_ASSOC_STRINGL(return_value, "$options", intern->flags, intern->flags_len);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a comment in DRIVERS-331 asking whether we should alphabetically order the regex flag characters (as should be done for raw BSON to support binary comparisons). The implementation here leaves the flags as-is.

If we do start alphabetically ordering the characters in the future, we'll likely do so when the Regex object is initialized and this code shouldn't need to change.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The relevant PHPC ticket for flag ordering is PHPC-829.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And HHVM is at HHVM-264.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we should order the flags in the constructor/initialiser only. That should be all what we need to do about this I believe.

The HHVM ticket is HHVM-264.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we should order the flags in the constructor/initialiser only

I concur. Nothing to do here and we have our respective tickets.

}
/* }}} */

/* {{{ proto string Regex::serialize()
*/
PHP_METHOD(Regex, serialize)
Expand Down Expand Up @@ -317,6 +336,7 @@ static zend_function_entry php_phongo_regex_me[] = {
PHP_ME(Regex, __construct, ai_Regex___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Regex, __set_state, ai_Regex___set_state, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME(Regex, __toString, ai_Regex_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Regex, jsonSerialize, ai_Regex_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Regex, serialize, ai_Regex_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Regex, unserialize, ai_Regex_unserialize, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
PHP_ME(Regex, getPattern, ai_Regex_void, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
Expand Down Expand Up @@ -445,6 +465,7 @@ PHP_MINIT_FUNCTION(Regex)

zend_class_implements(php_phongo_regex_ce TSRMLS_CC, 1, php_phongo_type_ce);
zend_class_implements(php_phongo_regex_ce TSRMLS_CC, 1, zend_ce_serializable);
zend_class_implements(php_phongo_regex_ce TSRMLS_CC, 1, php_json_serializable_ce);

memcpy(&php_phongo_handler_regex, phongo_get_std_object_handlers(), sizeof(zend_object_handlers));
php_phongo_handler_regex.get_properties = php_phongo_regex_get_properties;
Expand Down
Loading