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
3a0382e9
Commit
3a0382e9
authored
Jul 13, 2017
by
Paul Yang
Committed by
GitHub
Jul 13, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add map iterator for c extension (#3350)
parent
d3bbf1c8
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
157 additions
and
5 deletions
+157
-5
map.c
php/ext/google/protobuf/map.c
+91
-2
protobuf.c
php/ext/google/protobuf/protobuf.c
+2
-0
protobuf.h
php/ext/google/protobuf/protobuf.h
+13
-2
storage.c
php/ext/google/protobuf/storage.c
+13
-0
MapFieldIter.php
php/src/Google/Protobuf/Internal/MapFieldIter.php
+4
-1
map_field_test.php
php/tests/map_field_test.php
+34
-0
No files found.
php/ext/google/protobuf/map.c
View file @
3a0382e9
...
...
@@ -143,6 +143,7 @@ static zend_function_entry map_field_methods[] = {
PHP_ME
(
MapField
,
offsetSet
,
arginfo_offsetSet
,
ZEND_ACC_PUBLIC
)
PHP_ME
(
MapField
,
offsetUnset
,
arginfo_offsetGet
,
ZEND_ACC_PUBLIC
)
PHP_ME
(
MapField
,
count
,
arginfo_void
,
ZEND_ACC_PUBLIC
)
PHP_ME
(
MapField
,
getIterator
,
arginfo_void
,
ZEND_ACC_PUBLIC
)
ZEND_FE_END
};
...
...
@@ -156,7 +157,10 @@ static void map_field_write_dimension(zval *object, zval *key,
// -----------------------------------------------------------------------------
zend_class_entry
*
map_field_type
;
zend_class_entry
*
map_field_iter_type
;
zend_object_handlers
*
map_field_handlers
;
zend_object_handlers
*
map_field_iter_handlers
;
static
void
map_begin_internal
(
Map
*
map
,
MapIter
*
iter
)
{
iter
->
self
=
map
;
...
...
@@ -231,8 +235,8 @@ PHP_PROTO_OBJECT_CREATE_END(Map, map_field)
// Init class entry.
PHP_PROTO_INIT_CLASS_START
(
"Google
\\
Protobuf
\\
Internal
\\
MapField"
,
Map
,
map_field
)
zend_class_implements
(
map_field_type
TSRMLS_CC
,
2
,
spl_ce_ArrayAccess
,
spl_ce_Countable
);
zend_class_implements
(
map_field_type
TSRMLS_CC
,
3
,
spl_ce_ArrayAccess
,
zend_ce_aggregate
,
spl_ce_Countable
);
map_field_handlers
->
write_dimension
=
map_field_write_dimension
;
map_field_handlers
->
get_gc
=
map_field_get_gc
;
PHP_PROTO_INIT_CLASS_END
...
...
@@ -444,6 +448,15 @@ PHP_METHOD(MapField, count) {
RETURN_LONG
(
upb_strtable_count
(
&
intern
->
table
));
}
PHP_METHOD
(
MapField
,
getIterator
)
{
CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR
(
return_value
,
map_field_iter_type
);
Map
*
intern
=
UNBOX
(
Map
,
getThis
());
MapIter
*
iter
=
UNBOX
(
MapIter
,
return_value
);
map_begin
(
getThis
(),
iter
TSRMLS_CC
);
}
// -----------------------------------------------------------------------------
// Map Iterator
// -----------------------------------------------------------------------------
...
...
@@ -470,3 +483,79 @@ upb_value map_iter_value(MapIter *iter, int *len) {
*
len
=
native_slot_size
(
iter
->
self
->
value_type
);
return
upb_strtable_iter_value
(
&
iter
->
it
);
}
// -----------------------------------------------------------------------------
// MapFieldIter methods
// -----------------------------------------------------------------------------
static
zend_function_entry
map_field_iter_methods
[]
=
{
PHP_ME
(
MapFieldIter
,
rewind
,
arginfo_void
,
ZEND_ACC_PUBLIC
)
PHP_ME
(
MapFieldIter
,
current
,
arginfo_void
,
ZEND_ACC_PUBLIC
)
PHP_ME
(
MapFieldIter
,
key
,
arginfo_void
,
ZEND_ACC_PUBLIC
)
PHP_ME
(
MapFieldIter
,
next
,
arginfo_void
,
ZEND_ACC_PUBLIC
)
PHP_ME
(
MapFieldIter
,
valid
,
arginfo_void
,
ZEND_ACC_PUBLIC
)
ZEND_FE_END
};
// -----------------------------------------------------------------------------
// MapFieldIter creation/desctruction
// -----------------------------------------------------------------------------
// Define object free method.
PHP_PROTO_OBJECT_FREE_START
(
MapIter
,
map_field_iter
)
PHP_PROTO_OBJECT_FREE_END
PHP_PROTO_OBJECT_DTOR_START
(
MapIter
,
map_field_iter
)
PHP_PROTO_OBJECT_DTOR_END
// Define object create method.
PHP_PROTO_OBJECT_CREATE_START
(
MapIter
,
map_field_iter
)
intern
->
self
=
NULL
;
PHP_PROTO_OBJECT_CREATE_END
(
MapIter
,
map_field_iter
)
// Init class entry.
PHP_PROTO_INIT_CLASS_START
(
"Google
\\
Protobuf
\\
Internal
\\
MapFieldIter"
,
MapIter
,
map_field_iter
)
zend_class_implements
(
map_field_iter_type
TSRMLS_CC
,
1
,
zend_ce_iterator
);
PHP_PROTO_INIT_CLASS_END
// -----------------------------------------------------------------------------
// PHP MapFieldIter Methods
// -----------------------------------------------------------------------------
PHP_METHOD
(
MapFieldIter
,
rewind
)
{
MapIter
*
intern
=
UNBOX
(
MapIter
,
getThis
());
map_begin_internal
(
intern
->
self
,
intern
);
}
PHP_METHOD
(
MapFieldIter
,
current
)
{
MapIter
*
intern
=
UNBOX
(
MapIter
,
getThis
());
Map
*
map_field
=
intern
->
self
;
int
value_length
=
0
;
upb_value
value
=
map_iter_value
(
intern
,
&
value_length
);
void
*
mem
=
upb_value_memory
(
&
value
);
native_slot_get_by_array
(
map_field
->
value_type
,
mem
,
ZVAL_PTR_TO_CACHED_PTR
(
return_value
)
TSRMLS_CC
);
}
PHP_METHOD
(
MapFieldIter
,
key
)
{
MapIter
*
intern
=
UNBOX
(
MapIter
,
getThis
());
Map
*
map_field
=
intern
->
self
;
int
key_length
=
0
;
const
char
*
key
=
map_iter_key
(
intern
,
&
key_length
);
native_slot_get_by_map_key
(
map_field
->
key_type
,
key
,
key_length
,
ZVAL_PTR_TO_CACHED_PTR
(
return_value
)
TSRMLS_CC
);
}
PHP_METHOD
(
MapFieldIter
,
next
)
{
MapIter
*
intern
=
UNBOX
(
MapIter
,
getThis
());
map_next
(
intern
);
}
PHP_METHOD
(
MapFieldIter
,
valid
)
{
MapIter
*
intern
=
UNBOX
(
MapIter
,
getThis
());
RETURN_BOOL
(
!
map_done
(
intern
));
}
php/ext/google/protobuf/protobuf.c
View file @
3a0382e9
...
...
@@ -189,6 +189,7 @@ static PHP_RSHUTDOWN_FUNCTION(protobuf) {
static
PHP_MINIT_FUNCTION
(
protobuf
)
{
map_field_init
(
TSRMLS_C
);
map_field_iter_init
(
TSRMLS_C
);
repeated_field_init
(
TSRMLS_C
);
repeated_field_iter_init
(
TSRMLS_C
);
gpb_type_init
(
TSRMLS_C
);
...
...
@@ -206,6 +207,7 @@ static PHP_MSHUTDOWN_FUNCTION(protobuf) {
PEFREE
(
repeated_field_handlers
);
PEFREE
(
repeated_field_iter_handlers
);
PEFREE
(
map_field_handlers
);
PEFREE
(
map_field_iter_handlers
);
return
0
;
}
php/ext/google/protobuf/protobuf.h
View file @
3a0382e9
...
...
@@ -373,6 +373,7 @@ struct MessageLayout;
struct
RepeatedField
;
struct
RepeatedFieldIter
;
struct
Map
;
struct
MapIter
;
struct
Oneof
;
typedef
struct
DescriptorPool
DescriptorPool
;
...
...
@@ -385,6 +386,7 @@ typedef struct MessageLayout MessageLayout;
typedef
struct
RepeatedField
RepeatedField
;
typedef
struct
RepeatedFieldIter
RepeatedFieldIter
;
typedef
struct
Map
Map
;
typedef
struct
MapIter
MapIter
;
typedef
struct
Oneof
Oneof
;
// -----------------------------------------------------------------------------
...
...
@@ -400,6 +402,7 @@ void enum_descriptor_init(TSRMLS_D);
void
descriptor_pool_init
(
TSRMLS_D
);
void
gpb_type_init
(
TSRMLS_D
);
void
map_field_init
(
TSRMLS_D
);
void
map_field_iter_init
(
TSRMLS_D
);
void
repeated_field_init
(
TSRMLS_D
);
void
repeated_field_iter_init
(
TSRMLS_D
);
void
util_init
(
TSRMLS_D
);
...
...
@@ -659,6 +662,7 @@ void native_slot_get_default(upb_fieldtype_t type,
// -----------------------------------------------------------------------------
extern
zend_object_handlers
*
map_field_handlers
;
extern
zend_object_handlers
*
map_field_iter_handlers
;
PHP_PROTO_WRAP_OBJECT_START
(
Map
)
upb_fieldtype_t
key_type
;
...
...
@@ -667,10 +671,10 @@ PHP_PROTO_WRAP_OBJECT_START(Map)
upb_strtable
table
;
PHP_PROTO_WRAP_OBJECT_END
typedef
struct
{
PHP_PROTO_WRAP_OBJECT_START
(
MapIter
)
Map
*
self
;
upb_strtable_iter
it
;
}
MapIter
;
PHP_PROTO_WRAP_OBJECT_END
void
map_begin
(
zval
*
self
,
MapIter
*
iter
TSRMLS_DC
);
void
map_next
(
MapIter
*
iter
);
...
...
@@ -709,6 +713,13 @@ PHP_METHOD(MapField, offsetGet);
PHP_METHOD
(
MapField
,
offsetSet
);
PHP_METHOD
(
MapField
,
offsetUnset
);
PHP_METHOD
(
MapField
,
count
);
PHP_METHOD
(
MapField
,
getIterator
);
PHP_METHOD
(
MapFieldIter
,
rewind
);
PHP_METHOD
(
MapFieldIter
,
current
);
PHP_METHOD
(
MapFieldIter
,
key
);
PHP_METHOD
(
MapFieldIter
,
next
);
PHP_METHOD
(
MapFieldIter
,
valid
);
// -----------------------------------------------------------------------------
// Repeated Field.
...
...
php/ext/google/protobuf/storage.c
View file @
3a0382e9
...
...
@@ -355,6 +355,19 @@ void native_slot_get_by_array(upb_fieldtype_t type, const void* memory,
}
}
void
native_slot_get_by_map_key
(
upb_fieldtype_t
type
,
const
void
*
memory
,
int
length
,
CACHED_VALUE
*
cache
TSRMLS_DC
)
{
switch
(
type
)
{
case
UPB_TYPE_STRING
:
case
UPB_TYPE_BYTES
:
{
PHP_PROTO_ZVAL_STRINGL
(
CACHED_PTR_TO_ZVAL_PTR
(
cache
),
memory
,
length
,
1
);
return
;
}
default:
native_slot_get
(
type
,
memory
,
cache
TSRMLS_CC
);
}
}
void
native_slot_get_default
(
upb_fieldtype_t
type
,
CACHED_VALUE
*
cache
TSRMLS_DC
)
{
switch
(
type
)
{
...
...
php/src/Google/Protobuf/Internal/MapFieldIter.php
View file @
3a0382e9
...
...
@@ -91,9 +91,12 @@ class MapFieldIter implements \Iterator
public
function
key
()
{
$key
=
key
(
$this
->
container
);
// PHP associative array stores bool as integer for key.
if
(
$this
->
key_type
===
GPBType
::
BOOL
)
{
// PHP associative array stores bool as integer for key.
return
boolval
(
$key
);
}
elseif
(
$this
->
key_type
===
GPBType
::
STRING
)
{
// PHP associative array stores int string as int for key.
return
strval
(
$key
);
}
else
{
return
$key
;
}
...
...
php/tests/map_field_test.php
View file @
3a0382e9
...
...
@@ -56,6 +56,23 @@ class MapFieldTest extends PHPUnit_Framework_TestCase {
unset
(
$arr
[
'3.1'
]);
unset
(
$arr
[
MAX_INT32_STRING
]);
$this
->
assertEquals
(
0
,
count
(
$arr
));
// Test foreach.
$arr
=
new
MapField
(
GPBType
::
INT32
,
GPBType
::
INT32
);
for
(
$i
=
0
;
$i
<
3
;
$i
++
)
{
$arr
[
$i
]
=
$i
;
}
$i
=
0
;
$arr_test
=
[];
foreach
(
$arr
as
$key
=>
$val
)
{
$this
->
assertSame
(
$key
,
$val
);
$arr_test
[]
=
$key
;
$i
++
;
}
$this
->
assertTrue
(
isset
(
$arr_test
[
0
]));
$this
->
assertTrue
(
isset
(
$arr_test
[
1
]));
$this
->
assertTrue
(
isset
(
$arr_test
[
2
]));
$this
->
assertSame
(
3
,
$i
);
}
#########################################################
...
...
@@ -366,6 +383,23 @@ class MapFieldTest extends PHPUnit_Framework_TestCase {
$this
->
assertEquals
(
1
,
count
(
$arr
));
unset
(
$arr
[
True
]);
$this
->
assertEquals
(
0
,
count
(
$arr
));
// Test foreach.
$arr
=
new
MapField
(
GPBType
::
STRING
,
GPBType
::
STRING
);
for
(
$i
=
0
;
$i
<
3
;
$i
++
)
{
$arr
[
$i
]
=
$i
;
}
$i
=
0
;
$arr_test
=
[];
foreach
(
$arr
as
$key
=>
$val
)
{
$this
->
assertSame
(
$key
,
$val
);
$arr_test
[]
=
$key
;
$i
++
;
}
$this
->
assertTrue
(
isset
(
$arr_test
[
'0'
]));
$this
->
assertTrue
(
isset
(
$arr_test
[
'1'
]));
$this
->
assertTrue
(
isset
(
$arr_test
[
'2'
]));
$this
->
assertSame
(
3
,
$i
);
}
#########################################################
...
...
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