Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(124)

Side by Side Diff: third_party/protobuf/php/ext/google/protobuf/protobuf.h

Issue 2599263002: third_party/protobuf: Update to HEAD (f52e188fe4) (Closed)
Patch Set: Address comments Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
1 #ifndef __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__ 31 #ifndef __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__
2 #define __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__ 32 #define __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__
3 33
4 #include <php.h> 34 #include <php.h>
5 35
36 // ubp.h has to be placed after php.h. Othwise, php.h will introduce NDEBUG.
6 #include "upb.h" 37 #include "upb.h"
7 38
8 #define PHP_PROTOBUF_EXTNAME "protobuf" 39 #define PHP_PROTOBUF_EXTNAME "protobuf"
9 #define PHP_PROTOBUF_VERSION "0.01" 40 #define PHP_PROTOBUF_VERSION "3.1.0a1"
10 41
11 // Forward decls. 42 #define MAX_LENGTH_OF_INT64 20
43 #define SIZEOF_INT64 8
44
45 // -----------------------------------------------------------------------------
46 // Forward Declaration
47 // ----------------------------------------------------------------------------
48
12 struct DescriptorPool; 49 struct DescriptorPool;
13 struct Descriptor; 50 struct Descriptor;
51 struct EnumDescriptor;
14 struct FieldDescriptor; 52 struct FieldDescriptor;
15 struct EnumDescriptor;
16 struct MessageLayout;
17 struct MessageField; 53 struct MessageField;
18 struct MessageHeader; 54 struct MessageHeader;
19 struct MessageBuilderContext; 55 struct MessageLayout;
20 struct EnumBuilderContext; 56 struct RepeatedField;
57 struct RepeatedFieldIter;
58 struct MapField;
21 59
22 typedef struct DescriptorPool DescriptorPool; 60 typedef struct DescriptorPool DescriptorPool;
23 typedef struct Descriptor Descriptor; 61 typedef struct Descriptor Descriptor;
62 typedef struct EnumDescriptor EnumDescriptor;
24 typedef struct FieldDescriptor FieldDescriptor; 63 typedef struct FieldDescriptor FieldDescriptor;
25 typedef struct OneofDescriptor OneofDescriptor;
26 typedef struct EnumDescriptor EnumDescriptor;
27 typedef struct MessageLayout MessageLayout;
28 typedef struct MessageField MessageField; 64 typedef struct MessageField MessageField;
29 typedef struct MessageHeader MessageHeader; 65 typedef struct MessageHeader MessageHeader;
30 typedef struct MessageBuilderContext MessageBuilderContext; 66 typedef struct MessageLayout MessageLayout;
31 typedef struct OneofBuilderContext OneofBuilderContext; 67 typedef struct RepeatedField RepeatedField;
32 typedef struct EnumBuilderContext EnumBuilderContext; 68 typedef struct RepeatedFieldIter RepeatedFieldIter;
69 typedef struct MapField MapField;
33 70
34 extern zend_class_entry* builder_type; 71 // -----------------------------------------------------------------------------
35 extern zend_class_entry* descriptor_type; 72 // Globals.
36 extern zend_class_entry* message_builder_context_type; 73 // -----------------------------------------------------------------------------
37
38 extern DescriptorPool* generated_pool; // The actual generated pool
39 74
40 ZEND_BEGIN_MODULE_GLOBALS(protobuf) 75 ZEND_BEGIN_MODULE_GLOBALS(protobuf)
41 zval* generated_pool;
42 zend_object_handlers* message_handlers;
43 HashTable upb_def_to_php_obj_map;
44 ZEND_END_MODULE_GLOBALS(protobuf) 76 ZEND_END_MODULE_GLOBALS(protobuf)
45 77
46 ZEND_DECLARE_MODULE_GLOBALS(protobuf) 78 // Init module and PHP classes.
79 void descriptor_init(TSRMLS_D);
80 void enum_descriptor_init(TSRMLS_D);
81 void descriptor_pool_init(TSRMLS_D);
82 void gpb_type_init(TSRMLS_D);
83 void map_field_init(TSRMLS_D);
84 void repeated_field_init(TSRMLS_D);
85 void repeated_field_iter_init(TSRMLS_D);
86 void util_init(TSRMLS_D);
87 void message_init(TSRMLS_D);
47 88
48 #ifdef ZTS 89 // Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor
49 #define PROTOBUF_G(v) TSRMG(protobuf_globals_id, zend_protobuf_globals*, v) 90 // instances.
50 #else 91 void add_def_obj(const void* def, zval* value);
51 #define PROTOBUF_G(v) (protobuf_globals.v) 92 zval* get_def_obj(const void* def);
52 #endif 93
94 // Global map from PHP class entries to wrapper Descriptor/EnumDescriptor
95 // instances.
96 void add_ce_obj(const void* ce, zval* value);
97 zval* get_ce_obj(const void* ce);
98
99 extern zend_class_entry* map_field_type;
100 extern zend_class_entry* repeated_field_type;
53 101
54 // ----------------------------------------------------------------------------- 102 // -----------------------------------------------------------------------------
55 // PHP functions and global variables. 103 // Descriptor.
56 // -----------------------------------------------------------------------------
57
58 PHP_MINIT_FUNCTION(protobuf);
59
60 // -----------------------------------------------------------------------------
61 // PHP class structure.
62 // ----------------------------------------------------------------------------- 104 // -----------------------------------------------------------------------------
63 105
64 struct DescriptorPool { 106 struct DescriptorPool {
65 zend_object std; 107 zend_object std;
66 upb_symtab* symtab; 108 upb_symtab* symtab;
67 HashTable* pending_list; 109 HashTable* pending_list;
68 }; 110 };
69 111
112 PHP_METHOD(DescriptorPool, getGeneratedPool);
113 PHP_METHOD(DescriptorPool, internalAddGeneratedFile);
114
115 extern zval* generated_pool_php; // wrapper of generated pool
116 extern DescriptorPool* generated_pool; // The actual generated pool
117
70 struct Descriptor { 118 struct Descriptor {
71 zend_object std; 119 zend_object std;
72 const upb_msgdef* msgdef; 120 const upb_msgdef* msgdef;
73 MessageLayout* layout; 121 MessageLayout* layout;
74 // zval* klass; // begins as NULL 122 zend_class_entry* klass; // begins as NULL
75 // const upb_handlers* fill_handlers; 123 const upb_handlers* fill_handlers;
76 // const upb_pbdecodermethod* fill_method; 124 const upb_pbdecodermethod* fill_method;
77 const upb_handlers* pb_serialize_handlers; 125 const upb_handlers* pb_serialize_handlers;
78 // const upb_handlers* json_serialize_handlers;
79 // Handlers hold type class references for sub-message fields directly in some
80 // cases. We need to keep these rooted because they might otherwise be
81 // collected.
82 // zval_array typeclass_references;
83 }; 126 };
84 127
128 extern zend_class_entry* descriptor_type;
129
130 void descriptor_name_set(Descriptor *desc, const char *name);
131
85 struct FieldDescriptor { 132 struct FieldDescriptor {
86 zend_object std; 133 zend_object std;
87 const upb_fielddef* fielddef; 134 const upb_fielddef* fielddef;
88 }; 135 };
89 136
90 struct OneofDescriptor {
91 zend_object std;
92 const upb_oneofdef* oneofdef;
93 };
94
95 struct EnumDescriptor { 137 struct EnumDescriptor {
96 zend_object std; 138 zend_object std;
97 const upb_enumdef* enumdef; 139 const upb_enumdef* enumdef;
98 // zval* module; // begins as NULL 140 zend_class_entry* klass; // begins as NULL
141 // VALUE module; // begins as nil
99 }; 142 };
100 143
144 extern zend_class_entry* enum_descriptor_type;
145
101 // ----------------------------------------------------------------------------- 146 // -----------------------------------------------------------------------------
102 // Native slot storage abstraction. 147 // Message class creation.
103 // ----------------------------------------------------------------------------- 148 // -----------------------------------------------------------------------------
104 149
105 #define NATIVE_SLOT_MAX_SIZE sizeof(uint64_t) 150 void* message_data(void* msg);
106 151
107 size_t native_slot_size(upb_fieldtype_t type); 152 // Build PHP class for given descriptor. Instead of building from scratch, this
153 // function modifies existing class which has been partially defined in PHP
154 // code.
155 void build_class_from_descriptor(zval* php_descriptor TSRMLS_DC);
108 156
109 #define MAP_KEY_FIELD 1 157 extern zend_object_handlers* message_handlers;
110 #define MAP_VALUE_FIELD 2
111
112 // Oneof case slot value to indicate that no oneof case is set. The value `0` is
113 // safe because field numbers are used as case identifiers, and no field can
114 // have a number of 0.
115 #define ONEOF_CASE_NONE 0
116
117 // These operate on a map field (i.e., a repeated field of submessages whose
118 // submessage type is a map-entry msgdef).
119 bool is_map_field(const upb_fielddef* field);
120 const upb_fielddef* map_field_key(const upb_fielddef* field);
121 const upb_fielddef* map_field_value(const upb_fielddef* field);
122
123 // These operate on a map-entry msgdef.
124 const upb_fielddef* map_entry_key(const upb_msgdef* msgdef);
125 const upb_fielddef* map_entry_value(const upb_msgdef* msgdef);
126 158
127 // ----------------------------------------------------------------------------- 159 // -----------------------------------------------------------------------------
128 // Message layout / storage. 160 // Message layout / storage.
129 // ----------------------------------------------------------------------------- 161 // -----------------------------------------------------------------------------
130 162
163 /*
164 * In c extension, each protobuf message is a zval instance. The zval instance
165 * is like union, which can be used to store int, string, zend_object_value and
166 * etc. For protobuf message, the zval instance is used to store the
167 * zend_object_value.
168 *
169 * The zend_object_value is composed of handlers and a handle to look up the
170 * actual stored data. The handlers are pointers to functions, e.g., read,
171 * write, and etc, to access properties.
172 *
173 * The actual data of protobuf messages is stored as MessageHeader in zend
174 * engine's central repository. Each MessageHeader instance is composed of a
175 * zend_object, a Descriptor instance and the real message data.
176 *
177 * For the reason that PHP's native types may not be large enough to store
178 * protobuf message's field (e.g., int64), all message's data is stored in
179 * custom memory layout and is indexed by the Descriptor instance.
180 *
181 * The zend_object contains the zend class entry and the properties table. The
182 * zend class entry contains all information about protobuf message's
183 * corresponding PHP class. The most useful information is the offset table of
184 * properties. Because read access to properties requires returning zval
185 * instance, we need to convert data from the custom layout to zval instance.
186 * Instead of creating zval instance for every read access, we use the zval
187 * instances in the properties table in the zend_object as cache. When
188 * accessing properties, the offset is needed to find the zval property in
189 * zend_object's properties table. These properties will be updated using the
190 * data from custom memory layout only when reading these properties.
191 *
192 * zval
193 * |-zend_object_value obj
194 * |-zend_object_handlers* handlers -> |-read_property_handler
195 * | |-write_property_handler
196 * | ++++++++++++++++++++++
197 * |-zend_object_handle handle -> + central repository +
198 * ++++++++++++++++++++++
199 * MessageHeader <-----------------|
200 * |-zend_object std
201 * | |-class_entry* ce -> class_entry
202 * | | |-HashTable properties_table (name->offset)
203 * | |-zval** properties_table <------------------------------|
204 * | |------> zval* property(cache)
205 * |-Descriptor* desc (name->offset)
206 * |-void** data <-----------|
207 * |-----------------------> void* property(data)
208 *
209 */
210
131 #define MESSAGE_FIELD_NO_CASE ((size_t)-1) 211 #define MESSAGE_FIELD_NO_CASE ((size_t)-1)
132 212
133 struct MessageField { 213 struct MessageField {
134 size_t offset; 214 size_t offset;
135 size_t case_offset; // for oneofs, a uint32. Else, MESSAGE_FIELD_NO_CASE. 215 int cache_index; // Each field except oneof field has a zval cache to avoid
216 // multiple creation when being accessed.
217 size_t case_offset; // for oneofs, a uint32. Else, MESSAGE_FIELD_NO_CASE.
136 }; 218 };
137 219
138 struct MessageLayout { 220 struct MessageLayout {
139 const upb_msgdef* msgdef; 221 const upb_msgdef* msgdef;
140 MessageField* fields; 222 MessageField* fields;
141 size_t size; 223 size_t size;
142 }; 224 };
143 225
144 void layout_init(MessageLayout* layout, void* storage); 226 struct MessageHeader {
227 zend_object std; // Stores properties table and class info of PHP instance.
228 // This is needed for MessageHeader to be accessed via PHP.
229 Descriptor* descriptor; // Kept alive by self.class.descriptor reference.
230 // The real message data is appended after MessageHeader.
231 };
232
233 MessageLayout* create_layout(const upb_msgdef* msgdef);
234 void layout_init(MessageLayout* layout, void* storage,
235 zval** properties_table TSRMLS_DC);
145 zval* layout_get(MessageLayout* layout, const void* storage, 236 zval* layout_get(MessageLayout* layout, const void* storage,
146 const upb_fielddef* field TSRMLS_DC); 237 const upb_fielddef* field, zval** cache TSRMLS_DC);
147 MessageLayout* create_layout(const upb_msgdef* msgdef); 238 void layout_set(MessageLayout* layout, MessageHeader* header,
239 const upb_fielddef* field, zval* val TSRMLS_DC);
148 void free_layout(MessageLayout* layout); 240 void free_layout(MessageLayout* layout);
149 zval* native_slot_get(upb_fieldtype_t type, /*VALUE type_class,*/ 241
150 const void* memory TSRMLS_DC); 242 PHP_METHOD(Message, readOneof);
151 243 PHP_METHOD(Message, writeOneof);
152 // ----------------------------------------------------------------------------- 244 PHP_METHOD(Message, __construct);
153 // Message class creation. 245
154 // ----------------------------------------------------------------------------- 246 // -----------------------------------------------------------------------------
155 247 // Encode / Decode.
156 struct MessageHeader { 248 // -----------------------------------------------------------------------------
157 zend_object std; 249
158 Descriptor* descriptor; // kept alive by self.class.descriptor reference. 250 // Maximum depth allowed during encoding, to avoid stack overflows due to
159 // Data comes after this. 251 // cycles.
160 }; 252 #define ENCODE_MAX_NESTING 63
161 253
162 struct MessageBuilderContext { 254 // Constructs the upb decoder method for parsing messages of this type.
163 zend_object std; 255 // This is called from the message class creation code.
164 zval* descriptor; 256 const upb_pbdecodermethod *new_fillmsg_decodermethod(Descriptor *desc,
165 zval* pool; 257 const void *owner);
166 };
167
168 struct OneofBuilderContext {
169 zend_object std;
170 // VALUE descriptor;
171 // VALUE builder;
172 };
173
174 struct EnumBuilderContext {
175 zend_object std;
176 // VALUE enumdesc;
177 };
178
179 // Forward-declare all of the PHP method implementations.
180
181 DescriptorPool* php_to_descriptor_pool(zval* value TSRMLS_DC);
182 zend_object_value descriptor_pool_create(zend_class_entry *ce TSRMLS_DC);
183 void descriptor_pool_free_c(DescriptorPool* object TSRMLS_DC);
184 void descriptor_pool_free(void* object TSRMLS_DC);
185 void descriptor_pool_init_c_instance(DescriptorPool* pool TSRMLS_DC);
186 PHP_METHOD(DescriptorPool, addMessage);
187 PHP_METHOD(DescriptorPool, finalize);
188
189 Descriptor* php_to_descriptor(zval* value TSRMLS_DC);
190 zend_object_value descriptor_create(zend_class_entry *ce TSRMLS_DC);
191 void descriptor_init_c_instance(Descriptor* intern TSRMLS_DC);
192 void descriptor_free_c(Descriptor* object TSRMLS_DC);
193 void descriptor_free(void* object TSRMLS_DC);
194 void descriptor_name_set(Descriptor *desc, const char *name);
195
196 MessageBuilderContext* php_to_message_builder_context(zval* value TSRMLS_DC);
197 zend_object_value message_builder_context_create(
198 zend_class_entry* ce TSRMLS_DC);
199 void message_builder_context_init_c_instance(
200 MessageBuilderContext* intern TSRMLS_DC);
201 void message_builder_context_free_c(MessageBuilderContext* object TSRMLS_DC);
202 void message_builder_context_free(void* object TSRMLS_DC);
203 PHP_METHOD(MessageBuilderContext, optional);
204 PHP_METHOD(MessageBuilderContext, finalizeToPool);
205 258
206 PHP_METHOD(Message, encode); 259 PHP_METHOD(Message, encode);
207 const zend_class_entry* build_class_from_descriptor( 260 PHP_METHOD(Message, decode);
208 zval* php_descriptor TSRMLS_DC); 261
209 262 // -----------------------------------------------------------------------------
210 PHP_FUNCTION(get_generated_pool); 263 // Type check / conversion.
211 264 // -----------------------------------------------------------------------------
212 // ----------------------------------------------------------------------------- 265
213 // Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor 266 bool protobuf_convert_to_int32(zval* from, int32_t* to);
214 // instances. 267 bool protobuf_convert_to_uint32(zval* from, uint32_t* to);
215 // ---------------------------------------------------------------------------- 268 bool protobuf_convert_to_int64(zval* from, int64_t* to);
216 269 bool protobuf_convert_to_uint64(zval* from, uint64_t* to);
217 void add_def_obj(const void* def, zval* value); 270 bool protobuf_convert_to_float(zval* from, float* to);
218 zval* get_def_obj(const void* def); 271 bool protobuf_convert_to_double(zval* from, double* to);
272 bool protobuf_convert_to_bool(zval* from, int8_t* to);
273 bool protobuf_convert_to_string(zval* from);
274
275 PHP_METHOD(Util, checkInt32);
276 PHP_METHOD(Util, checkUint32);
277 PHP_METHOD(Util, checkInt64);
278 PHP_METHOD(Util, checkUint64);
279 PHP_METHOD(Util, checkEnum);
280 PHP_METHOD(Util, checkFloat);
281 PHP_METHOD(Util, checkDouble);
282 PHP_METHOD(Util, checkBool);
283 PHP_METHOD(Util, checkString);
284 PHP_METHOD(Util, checkBytes);
285 PHP_METHOD(Util, checkMessage);
286 PHP_METHOD(Util, checkRepeatedField);
287
288 // -----------------------------------------------------------------------------
289 // Native slot storage abstraction.
290 // -----------------------------------------------------------------------------
291
292 #define NATIVE_SLOT_MAX_SIZE sizeof(uint64_t)
293
294 size_t native_slot_size(upb_fieldtype_t type);
295 bool native_slot_set(upb_fieldtype_t type, const zend_class_entry* klass,
296 void* memory, zval* value TSRMLS_DC);
297 void native_slot_init(upb_fieldtype_t type, void* memory, zval** cache);
298 // For each property, in order to avoid conversion between the zval object and
299 // the actual data type during parsing/serialization, the containing message
300 // object use the custom memory layout to store the actual data type for each
301 // property inside of it. To access a property from php code, the property
302 // needs to be converted to a zval object. The message object is not responsible
303 // for providing such a zval object. Instead the caller needs to provide one
304 // (cache) and update it with the actual data (memory).
305 void native_slot_get(upb_fieldtype_t type, const void* memory,
306 zval** cache TSRMLS_DC);
307 void native_slot_get_default(upb_fieldtype_t type, zval** cache TSRMLS_DC);
308
309 // -----------------------------------------------------------------------------
310 // Map Field.
311 // -----------------------------------------------------------------------------
312
313 extern zend_object_handlers* map_field_handlers;
314
315 typedef struct {
316 zend_object std;
317 upb_fieldtype_t key_type;
318 upb_fieldtype_t value_type;
319 const zend_class_entry* msg_ce; // class entry for value message
320 upb_strtable table;
321 } Map;
322
323 typedef struct {
324 Map* self;
325 upb_strtable_iter it;
326 } MapIter;
327
328 void map_begin(zval* self, MapIter* iter TSRMLS_DC);
329 void map_next(MapIter* iter);
330 bool map_done(MapIter* iter);
331 const char* map_iter_key(MapIter* iter, int* len);
332 upb_value map_iter_value(MapIter* iter, int* len);
333
334 // These operate on a map-entry msgdef.
335 const upb_fielddef* map_entry_key(const upb_msgdef* msgdef);
336 const upb_fielddef* map_entry_value(const upb_msgdef* msgdef);
337
338 zend_object_value map_field_create(zend_class_entry *ce TSRMLS_DC);
339 void map_field_create_with_type(zend_class_entry *ce, const upb_fielddef *field,
340 zval **map_field TSRMLS_DC);
341 void map_field_free(void* object TSRMLS_DC);
342 void* upb_value_memory(upb_value* v);
343
344 #define MAP_KEY_FIELD 1
345 #define MAP_VALUE_FIELD 2
346
347 // These operate on a map field (i.e., a repeated field of submessages whose
348 // submessage type is a map-entry msgdef).
349 bool is_map_field(const upb_fielddef* field);
350 const upb_fielddef* map_field_key(const upb_fielddef* field);
351 const upb_fielddef* map_field_value(const upb_fielddef* field);
352
353 bool map_index_set(Map *intern, const char* keyval, int length, upb_value v);
354
355 PHP_METHOD(MapField, __construct);
356 PHP_METHOD(MapField, offsetExists);
357 PHP_METHOD(MapField, offsetGet);
358 PHP_METHOD(MapField, offsetSet);
359 PHP_METHOD(MapField, offsetUnset);
360 PHP_METHOD(MapField, count);
361
362 // -----------------------------------------------------------------------------
363 // Repeated Field.
364 // -----------------------------------------------------------------------------
365
366 extern zend_object_handlers* repeated_field_handlers;
367
368 struct RepeatedField {
369 zend_object std;
370 zval* array;
371 upb_fieldtype_t type;
372 const zend_class_entry* msg_ce; // class entry for containing message
373 // (for message field only).
374 };
375
376 struct RepeatedFieldIter {
377 zend_object std;
378 RepeatedField* repeated_field;
379 long position;
380 };
381
382 void repeated_field_create_with_type(zend_class_entry* ce,
383 const upb_fielddef* field,
384 zval** repeated_field TSRMLS_DC);
385 // Return the element at the index position from the repeated field. There is
386 // not restriction on the type of stored elements.
387 void *repeated_field_index_native(RepeatedField *intern, int index TSRMLS_DC);
388 // Add the element to the end of the repeated field. There is not restriction on
389 // the type of stored elements.
390 void repeated_field_push_native(RepeatedField *intern, void *value TSRMLS_DC);
391
392 PHP_METHOD(RepeatedField, __construct);
393 PHP_METHOD(RepeatedField, append);
394 PHP_METHOD(RepeatedField, offsetExists);
395 PHP_METHOD(RepeatedField, offsetGet);
396 PHP_METHOD(RepeatedField, offsetSet);
397 PHP_METHOD(RepeatedField, offsetUnset);
398 PHP_METHOD(RepeatedField, count);
399 PHP_METHOD(RepeatedField, getIterator);
400
401 PHP_METHOD(RepeatedFieldIter, rewind);
402 PHP_METHOD(RepeatedFieldIter, current);
403 PHP_METHOD(RepeatedFieldIter, key);
404 PHP_METHOD(RepeatedFieldIter, next);
405 PHP_METHOD(RepeatedFieldIter, valid);
406
407 // -----------------------------------------------------------------------------
408 // Oneof Field.
409 // -----------------------------------------------------------------------------
410
411 typedef struct {
412 zend_object std;
413 upb_oneofdef* oneofdef;
414 int index; // Index of field in oneof. -1 if not set.
415 char value[NATIVE_SLOT_MAX_SIZE];
416 } Oneof;
417
418 // Oneof case slot value to indicate that no oneof case is set. The value `0` is
419 // safe because field numbers are used as case identifiers, and no field can
420 // have a number of 0.
421 #define ONEOF_CASE_NONE 0
422
423 // -----------------------------------------------------------------------------
424 // Upb.
425 // -----------------------------------------------------------------------------
426
427 upb_fieldtype_t to_fieldtype(upb_descriptortype_t type);
428 const zend_class_entry *field_type_class(const upb_fielddef *field TSRMLS_DC);
219 429
220 // ----------------------------------------------------------------------------- 430 // -----------------------------------------------------------------------------
221 // Utilities. 431 // Utilities.
222 // ----------------------------------------------------------------------------- 432 // -----------------------------------------------------------------------------
223 433
224 // PHP Array utils. 434 // PHP <-> C conversion.
225 #define Z_ARRVAL_SIZE_P(zval_p) zend_hash_num_elements(Z_ARRVAL_P(zval_p)) 435 #define UNBOX(class_name, val) \
226 #define Z_ARRVAL_BEGIN_P(zval_p) Z_ARRVAL_P(zval_p)->pListHead 436 (class_name*)zend_object_store_get_object(val TSRMLS_CC);
227 #define Z_BUCKET_NEXT_PP(bucket_pp) *bucket_pp = (*bucket_pp)->pListNext 437
228 438 #define BOX(class_name, wrapper, intern, free_func) \
229 #define DEFINE_PHP_OBJECT(class_name, class_name_lower, name) \ 439 MAKE_STD_ZVAL(wrapper); \
230 do { \ 440 Z_TYPE_P(wrapper) = IS_OBJECT; \
231 zval* name; \ 441 Z_OBJVAL_P(wrapper) \
232 MAKE_STD_ZVAL(name); \ 442 .handle = \
233 object_init_ex(name, class_name_lower##_type); \ 443 zend_objects_store_put(intern, NULL, free_func, NULL TSRMLS_CC); \
234 } while (0) 444 Z_OBJVAL_P(wrapper).handlers = zend_get_std_object_handlers();
235
236 #define DEFINE_PHP_WRAPPER(class_name, class_name_lower, name, intern) \
237 zval* name; \
238 MAKE_STD_ZVAL(name); \
239 object_init_ex(name, class_name_lower##_type); \
240 Z_OBJVAL_P(name) \
241 .handle = zend_objects_store_put( \
242 intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, \
243 class_name_lower##_free, NULL TSRMLS_CC);
244
245 #define DEFINE_PHP_ZVAL(name) \
246 do { \
247 zval* name; \
248 MAKE_STD_ZVAL(name); \
249 } while (0)
250
251 #define DEFINE_PHP_STRING(name, value) \
252 do { \
253 zval* name; \
254 MAKE_STD_ZVAL(name); \
255 ZVAL_STRING(name, value, 1); \
256 } while (0)
257
258 // Upb Utilities
259
260 void check_upb_status(const upb_status* status, const char* msg);
261
262 #define CHECK_UPB(code, msg) \
263 do { \
264 upb_status status = UPB_STATUS_INIT; \
265 code; \
266 check_upb_status(&status, msg); \
267 } while (0)
268 445
269 // Memory management 446 // Memory management
270
271 #define ALLOC(class_name) (class_name*) emalloc(sizeof(class_name)) 447 #define ALLOC(class_name) (class_name*) emalloc(sizeof(class_name))
448 #define PEMALLOC(class_name) (class_name*) pemalloc(sizeof(class_name), 1)
272 #define ALLOC_N(class_name, n) (class_name*) emalloc(sizeof(class_name) * n) 449 #define ALLOC_N(class_name, n) (class_name*) emalloc(sizeof(class_name) * n)
273 #define FREE(object) efree(object) 450 #define FREE(object) efree(object)
274 451 #define PEFREE(object) pefree(object, 1)
275 // Type Checking 452
276 #define CHECK_TYPE(field, type) \ 453 // Create PHP internal instance.
277 if (Z_TYPE_P(field) != type) { \ 454 #define CREATE(class_name, intern, init_func) \
278 zend_error(E_ERROR, "Unexpected type"); \ 455 intern = ALLOC(class_name); \
279 } 456 memset(intern, 0, sizeof(class_name)); \
457 init_func(intern TSRMLS_CC);
458
459 // String argument.
460 #define STR(str) (str), strlen(str)
461
462 // Zend Value
463 #define Z_OBJ_P(zval_p) \
464 ((zend_object*)(EG(objects_store) \
465 .object_buckets[Z_OBJ_HANDLE_P(zval_p)] \
466 .bucket.obj.object))
280 467
281 #endif // __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__ 468 #endif // __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__
OLDNEW
« no previous file with comments | « third_party/protobuf/php/ext/google/protobuf/package.xml ('k') | third_party/protobuf/php/ext/google/protobuf/protobuf.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698