Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
protobuf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
protobuf
Commits
1f2dbc89
Commit
1f2dbc89
authored
Nov 08, 2016
by
Paul Yang
Committed by
GitHub
Nov 08, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement RepeatedFieldIter for c extension. (#2333)
parent
0d7199ed
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
155 additions
and
3 deletions
+155
-3
array.c
php/ext/google/protobuf/array.c
+125
-2
protobuf.c
php/ext/google/protobuf/protobuf.c
+1
-0
protobuf.h
php/ext/google/protobuf/protobuf.h
+16
-0
array_test.php
php/tests/array_test.php
+11
-0
tests.sh
tests.sh
+2
-1
No files found.
php/ext/google/protobuf/array.c
View file @
1f2dbc89
...
...
@@ -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
);
}
php/ext/google/protobuf/protobuf.c
View file @
1f2dbc89
...
...
@@ -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
);
...
...
php/ext/google/protobuf/protobuf.h
View file @
1f2dbc89
...
...
@@ -51,6 +51,7 @@ struct MessageField;
struct
MessageHeader
;
struct
MessageLayout
;
struct
RepeatedField
;
struct
RepeatedFieldIter
;
struct
MapField
;
typedef
struct
DescriptorPool
DescriptorPool
;
...
...
@@ -61,6 +62,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 +79,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 +369,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 +392,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.
...
...
php/tests/array_test.php
View file @
1f2dbc89
...
...
@@ -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
);
}
/**
...
...
tests.sh
View file @
1f2dbc89
...
...
@@ -408,7 +408,8 @@ build_php5.6_c() {
build_php5.6_mac
()
{
# Install PHP
curl
-s
https://php-osx.liip.ch/install.sh | bash
-s
5.6
export
PATH
=
"/usr/local/php5-5.6.25-20160831-101628/bin:
$PATH
"
PHP_FOLDER
=
`
find /usr/local
-type
d
-name
"php5-5.6*"
`
# The folder name may change upon time
export
PATH
=
"
$PHP_FOLDER
/bin:
$PATH
"
# Install phpunit
curl https://phar.phpunit.de/phpunit.phar
-L
-o
phpunit.phar
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment