Navigation Menu

Skip to content
This repository has been archived by the owner on Jan 12, 2021. It is now read-only.

Commit

Permalink
Fixed setting field value (#93)
Browse files Browse the repository at this point in the history
  • Loading branch information
hjagodzinski committed Aug 25, 2016
1 parent 3a62bfa commit 3ab9e6a
Show file tree
Hide file tree
Showing 13 changed files with 364 additions and 29 deletions.
30 changes: 12 additions & 18 deletions protobuf.c
Expand Up @@ -571,8 +571,8 @@ PHP_METHOD(ProtobufMessage, serializeToString)

PHP_METHOD(ProtobufMessage, set)
{
long field_number = -1;
zval *prepared_value, **old_value, *value, **values, *val;
long field_number;
zval *prepared_value, *value, **values;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz", &field_number, &value) == FAILURE) {
RETURN_THIS();
Expand All @@ -583,14 +583,8 @@ PHP_METHOD(ProtobufMessage, set)

if (Z_TYPE_P(value) == IS_NULL) {
// null value means 'no value', therefore should not be converted
if ((old_value = pb_get_value(getThis(), values, field_number)) == NULL) {
RETURN_THIS();
}
if (Z_TYPE_PP(old_value) != IS_NULL) {
if ((prepared_value = pb_prepare_value(getThis(), field_number, value)) != NULL) {
add_index_zval(*values, field_number, prepared_value);
}
}
Z_ADDREF_P(value);
add_index_zval(*values, field_number, value);
} else {
if ((prepared_value = pb_prepare_value(getThis(), field_number, value)) != NULL) {
add_index_zval(*values, field_number, prepared_value);
Expand Down Expand Up @@ -741,19 +735,19 @@ static zval *pb_prepare_value(zval *this, uint32_t field_number, zval *value)
PB_COMPILE_ERROR_EX(this, "unexpected '%s' field type %d in field descriptor", pb_get_field_name(this, field_number), zend_get_type_by_const(Z_LVAL_PP(type)));
goto fail;
}

if (Z_TYPE_P(value) != expected_type) {
ALLOC_ZVAL(converted_value);
INIT_PZVAL_COPY(converted_value, value);
zval_copy_ctor(converted_value);
convert_to_explicit_type(converted_value, expected_type);
return converted_value;
}
} else if (Z_TYPE_PP(type) != IS_STRING) {
PB_COMPILE_ERROR_EX(this, "unexpected %s type of '%s' field type in field descriptor", zend_get_type_by_const(Z_TYPE_PP(type)), pb_get_field_name(this, field_number));
goto fail;
}

if (Z_TYPE_P(value) != expected_type) {
ALLOC_ZVAL(converted_value);
INIT_PZVAL_COPY(converted_value, value);
zval_copy_ctor(converted_value);
convert_to_explicit_type(converted_value, expected_type);
return converted_value;
}

Z_ADDREF_P(value);
return value;
fail:
Expand Down
2 changes: 1 addition & 1 deletion tests/Bar.php
@@ -1,6 +1,6 @@
<?php
/**
* Auto generated from test.proto at 2016-08-15 23:40:08
* Auto generated from test.proto at 2016-08-24 20:32:21
*/

namespace {
Expand Down
2 changes: 1 addition & 1 deletion tests/Baz.php
@@ -1,6 +1,6 @@
<?php
/**
* Auto generated from test.proto at 2016-08-16 02:35:04
* Auto generated from test.proto at 2016-08-24 20:32:21
*/

namespace {
Expand Down
144 changes: 143 additions & 1 deletion tests/Foo.php
@@ -1,6 +1,6 @@
<?php
/**
* Auto generated from test.proto at 2016-08-15 23:40:08
* Auto generated from test.proto at 2016-08-24 20:32:21
*/

namespace {
Expand Down Expand Up @@ -35,6 +35,8 @@ class Foo extends \ProtobufMessage
const SINT32_PACKED_FIELD = 23;
const BOOL_PACKED_FIELD = 24;
const OPTIONAL_EMBEDDED_FIELD = 25;
const REPEATED_OBJ_FIELD = 26;
const REPEATED_STRING_FIELD = 27;

/* @var array Field descriptors */
protected static $fields = array(
Expand Down Expand Up @@ -170,6 +172,16 @@ class Foo extends \ProtobufMessage
'required' => false,
'type' => '\Baz'
),
self::REPEATED_OBJ_FIELD => array(
'name' => 'repeated_obj_field',
'repeated' => true,
'type' => '\Bar'
),
self::REPEATED_STRING_FIELD => array(
'name' => 'repeated_string_field',
'repeated' => true,
'type' => \ProtobufMessage::PB_TYPE_STRING,
),
);

/**
Expand Down Expand Up @@ -212,6 +224,8 @@ public function reset()
$this->values[self::SINT32_PACKED_FIELD] = array();
$this->values[self::BOOL_PACKED_FIELD] = array();
$this->values[self::OPTIONAL_EMBEDDED_FIELD] = null;
$this->values[self::REPEATED_OBJ_FIELD] = array();
$this->values[self::REPEATED_STRING_FIELD] = array();
}

/**
Expand Down Expand Up @@ -1109,5 +1123,133 @@ public function getOptionalEmbeddedField()
{
return $this->get(self::OPTIONAL_EMBEDDED_FIELD);
}

/**
* Appends value to 'repeated_obj_field' list
*
* @param \Bar $value Value to append
*
* @return null
*/
public function appendRepeatedObjField(\Bar $value)
{
return $this->append(self::REPEATED_OBJ_FIELD, $value);
}

/**
* Clears 'repeated_obj_field' list
*
* @return null
*/
public function clearRepeatedObjField()
{
return $this->clear(self::REPEATED_OBJ_FIELD);
}

/**
* Returns 'repeated_obj_field' list
*
* @return \Bar[]
*/
public function getRepeatedObjField()
{
return $this->get(self::REPEATED_OBJ_FIELD);
}

/**
* Returns 'repeated_obj_field' iterator
*
* @return \ArrayIterator
*/
public function getRepeatedObjFieldIterator()
{
return new \ArrayIterator($this->get(self::REPEATED_OBJ_FIELD));
}

/**
* Returns element from 'repeated_obj_field' list at given offset
*
* @param int $offset Position in list
*
* @return \Bar
*/
public function getRepeatedObjFieldAt($offset)
{
return $this->get(self::REPEATED_OBJ_FIELD, $offset);
}

/**
* Returns count of 'repeated_obj_field' list
*
* @return int
*/
public function getRepeatedObjFieldCount()
{
return $this->count(self::REPEATED_OBJ_FIELD);
}

/**
* Appends value to 'repeated_string_field' list
*
* @param string $value Value to append
*
* @return null
*/
public function appendRepeatedStringField($value)
{
return $this->append(self::REPEATED_STRING_FIELD, $value);
}

/**
* Clears 'repeated_string_field' list
*
* @return null
*/
public function clearRepeatedStringField()
{
return $this->clear(self::REPEATED_STRING_FIELD);
}

/**
* Returns 'repeated_string_field' list
*
* @return string[]
*/
public function getRepeatedStringField()
{
return $this->get(self::REPEATED_STRING_FIELD);
}

/**
* Returns 'repeated_string_field' iterator
*
* @return \ArrayIterator
*/
public function getRepeatedStringFieldIterator()
{
return new \ArrayIterator($this->get(self::REPEATED_STRING_FIELD));
}

/**
* Returns element from 'repeated_string_field' list at given offset
*
* @param int $offset Position in list
*
* @return string
*/
public function getRepeatedStringFieldAt($offset)
{
return $this->get(self::REPEATED_STRING_FIELD, $offset);
}

/**
* Returns count of 'repeated_string_field' list
*
* @return int
*/
public function getRepeatedStringFieldCount()
{
return $this->count(self::REPEATED_STRING_FIELD);
}
}
}
40 changes: 40 additions & 0 deletions tests/append_float_value.phpt
@@ -0,0 +1,40 @@
--TEST--
Protocol Buffers appending floating-point value
--SKIPIF--
<?php require 'skipif.inc' ?>
--FILE--
<?php
require 'Foo.php';

$foo = new Foo();

/* from float type */
$foo->appendFloatPackedField(2.0);

/* from int type */
$intValue = 3;
$foo->appendFloatPackedField($intValue);
var_dump($intValue);

/* from string type */
$stringValue = '4';
$foo->appendFloatPackedField($stringValue);
var_dump($stringValue);

/* from null */
$nullValue = null;
$foo->appendFloatPackedField($nullValue);

$values = $foo->getFloatPackedField();
var_dump(count($values));
var_dump($values[0]);
var_dump($values[1]);
var_dump($values[2]);
?>
--EXPECT--
int(3)
string(1) "4"
int(3)
float(2)
float(3)
float(4)
40 changes: 40 additions & 0 deletions tests/append_int_value.phpt
@@ -0,0 +1,40 @@
--TEST--
Protocol Buffers appending integer value
--SKIPIF--
<?php require 'skipif.inc' ?>
--FILE--
<?php
require 'Foo.php';

$foo = new Foo();

/* from int type */
$foo->appendInt32PackedField(2);

/* from float type */
$floatValue = 3.0;
$foo->appendInt32PackedField($floatValue);
var_dump($floatValue);

/* from string type */
$stringValue = '4';
$foo->appendInt32PackedField($stringValue);
var_dump($stringValue);

/* from null */
$nullValue = null;
$foo->appendInt32PackedField($nullValue);

$values = $foo->getInt32PackedField();
var_dump(count($values));
var_dump($values[0]);
var_dump($values[1]);
var_dump($values[2]);
?>
--EXPECT--
float(3)
string(1) "4"
int(3)
int(2)
int(3)
int(4)
40 changes: 40 additions & 0 deletions tests/append_object_value.phpt
@@ -0,0 +1,40 @@
--TEST--
Protocol Buffers appending object value
--SKIPIF--
<?php require 'skipif.inc' ?>
--FILE--
<?php
require 'Foo.php';
require 'Bar.php';

$barDestructed = false;

class SpiedBar extends Bar {
public function __destruct() {
global $barDestructed;
$barDestructed = true;
}
}

$bar = new SpiedBar();
$bar->setDoubleField(1.0);

$foo = new Foo();
$foo->appendRepeatedObjField($bar);

$values = $foo->getRepeatedObjField();
var_dump(count($values));
var_dump($values[0] === $bar);
$values = null;

$foo->clearRepeatedObjField();
var_dump($barDestructed);

$bar = null;
var_dump($barDestructed);
?>
--EXPECT--
int(1)
bool(true)
bool(false)
bool(true)

0 comments on commit 3ab9e6a

Please sign in to comment.