fix #6: compatibility with 8.2
[awesomized/ext-ion] / ion.c
1 /*
2 +--------------------------------------------------------------------+
3 | PECL :: ion |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2021, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
16
17 #include "php.h"
18 #include "ext/standard/info.h"
19
20 #include "Zend/zend_enum.h"
21 #include "Zend/zend_exceptions.h"
22 #include "Zend/zend_closures.h"
23 #include "Zend/zend_interfaces.h"
24 #include "Zend/zend_smart_str.h"
25
26 #include "ext/date/php_date.h"
27 #include "ext/spl/spl_exceptions.h"
28
29 #include "php_ion.h"
30 #include "ion_private.h"
31
32 #define Z_PARAM_OBJ_OF_CLASS_OR_NAMED_OR_NULL(obj_dest, iface_ce, impl_ce, arr_dest) \
33 Z_PARAM_PROLOGUE(0,0) \
34 if (!zend_parse_arg_obj(_arg, &(obj_dest), iface_ce, true) && !zend_parse_arg_obj(_arg, &(obj_dest), impl_ce, true)) { \
35 if (UNEXPECTED(!zend_parse_arg_array(_arg, &(arr_dest), true, 0))) { \
36 _error = (iface_ce)->name->val; \
37 _error_code = ZPP_ERROR_WRONG_CLASS_OR_NULL; \
38 break; \
39 } \
40 zval tmp; \
41 object_init_ex(&tmp, impl_ce); \
42 *(&(obj_dest)) = Z_OBJ(tmp); \
43 zend_call_known_function((impl_ce)->constructor, obj_dest, impl_ce, \
44 NULL, 0, NULL, Z_ARRVAL_P(arr_dest)); \
45 if (EG(exception)) { \
46 OBJ_RELEASE(obj_dest); \
47 return; \
48 } \
49 }
50
51 #define Z_PARAM_HASH_OR_INSTANCE_OF_NULL(za_dest, zo_inst, ce_inst) \
52 Z_PARAM_PROLOGUE(0, 0) { \
53 zval *_arr; \
54 if (zend_parse_arg_array(_arg, &(_arr), true, 0)) { \
55 za_dest = Z_ARRVAL_P(_arr); \
56 } else { \
57 zend_object *_obj = NULL; \
58 if (zend_parse_arg_obj(_arg, &_obj, ce, true)) { \
59 za_dest = _obj->handlers->get_properties(_obj); \
60 } else if (zend_parse_arg_obj(_arg, &(zo_inst), ce_inst, true)) { \
61 } else { \
62 _error = ce->name->val; \
63 _error_code = ZPP_ERROR_WRONG_CLASS_OR_NULL; \
64 break; \
65 } \
66 } \
67 }
68
69 static ZEND_METHOD(ion_Symbol_ImportLocation, __construct)
70 {
71 php_ion_symbol_iloc *obj = php_ion_obj(symbol_iloc, Z_OBJ_P(ZEND_THIS));
72 PTR_CHECK(obj);
73
74 zend_long location;
75 ZEND_PARSE_PARAMETERS_START(2, 2)
76 Z_PARAM_STR(obj->name)
77 Z_PARAM_LONG(location)
78 ZEND_PARSE_PARAMETERS_END();
79
80 obj->loc.location = (SID) location;
81 php_ion_symbol_iloc_ctor(obj);
82 }
83 static ZEND_METHOD(ion_Symbol, __construct)
84 {
85 php_ion_symbol *obj = php_ion_obj(symbol, Z_OBJ_P(ZEND_THIS));
86 PTR_CHECK(obj);
87
88 zend_long sid = -1;
89 ZEND_PARSE_PARAMETERS_START(0, 3)
90 Z_PARAM_OPTIONAL
91 Z_PARAM_STR_OR_NULL(obj->value)
92 Z_PARAM_LONG(sid)
93 Z_PARAM_OBJ_OF_CLASS_OR_NULL(obj->iloc, ce_Symbol_ImportLocation)
94 ZEND_PARSE_PARAMETERS_END();
95
96 obj->sym.sid = (SID) sid;
97 php_ion_symbol_ctor(obj);
98 }
99 static ZEND_METHOD(ion_Symbol, equals)
100 {
101 php_ion_symbol *sym = php_ion_obj(symbol, Z_OBJ_P(ZEND_THIS));
102 OBJ_CHECK(sym);
103
104 zend_object *other_obj;
105 ZEND_PARSE_PARAMETERS_START(1, 1)
106 Z_PARAM_OBJ_OF_CLASS(other_obj, ce_Symbol)
107 ZEND_PARSE_PARAMETERS_END();
108
109 BOOL eq = FALSE;
110 iERR err = ion_symbol_is_equal(
111 &sym->sym,
112 &php_ion_obj(symbol, other_obj)->sym, &eq);
113 ION_CHECK(err);
114 RETVAL_BOOL(eq);
115 }
116 static ZEND_METHOD(ion_Symbol, __toString)
117 {
118 php_ion_symbol *sym = php_ion_obj(symbol, Z_OBJ_P(ZEND_THIS));
119 OBJ_CHECK(sym);
120
121 ZEND_PARSE_PARAMETERS_NONE();
122
123 if (!sym->value) {
124 RETURN_EMPTY_STRING();
125 }
126 RETURN_STR_COPY(sym->value);
127 }
128 static ZEND_METHOD(ion_Symbol_Enum, toSymbol)
129 {
130 ZEND_PARSE_PARAMETERS_NONE();
131
132 zval *zc = zend_enum_fetch_case_name(Z_OBJ_P(ZEND_THIS));
133 PTR_CHECK(zc);
134
135 zval *zsym = php_ion_global_symbol_fetch_by_enum(Z_STR_P(zc));
136 PTR_CHECK(zsym);
137 RETVAL_ZVAL(zsym, 1, 0);
138 }
139 static ZEND_METHOD(ion_Symbol_Enum, toSID)
140 {
141 ZEND_PARSE_PARAMETERS_NONE();
142
143 zval *zc = zend_enum_fetch_case_name(Z_OBJ_P(ZEND_THIS));
144 PTR_CHECK(zc);
145
146 zval *zsym = php_ion_global_symbol_fetch_by_enum(Z_STR_P(zc));
147 PTR_CHECK(zsym);
148
149 zval tmp;
150 RETVAL_ZVAL(zend_read_property(Z_OBJCE_P(zsym), Z_OBJ_P(zsym), ZEND_STRL("sid"), 0, &tmp), 1, 0);
151 }
152 static ZEND_METHOD(ion_Symbol_Enum, toString)
153 {
154 ZEND_PARSE_PARAMETERS_NONE();
155
156 zval *zc = zend_enum_fetch_case_name(Z_OBJ_P(ZEND_THIS));
157 PTR_CHECK(zc);
158
159 zval *zsym = php_ion_global_symbol_fetch_by_enum(Z_STR_P(zc));
160 PTR_CHECK(zsym);
161
162 zval tmp;
163 RETVAL_ZVAL(zend_read_property(Z_OBJCE_P(zsym), Z_OBJ_P(zsym), ZEND_STRL("value"), 0, &tmp), 1, 0);
164 }
165 static ZEND_METHOD(ion_Symbol_System, asTable)
166 {
167 ZEND_PARSE_PARAMETERS_NONE();
168
169 object_init_ex(return_value, ce_Symbol_Table_Shared);
170 php_ion_symbol_table *obj = php_ion_obj(symbol_table, Z_OBJ_P(return_value));
171 ION_CHECK(ion_symbol_table_get_system_table(&obj->tab, 1));
172 php_ion_symbol_table_ctor(obj);
173 ion_symbol_table_lock(obj->tab);
174 }
175 static ZEND_METHOD(ion_Symbol_PHP, asTable)
176 {
177 ZEND_PARSE_PARAMETERS_NONE();
178
179 object_init_ex(return_value, ce_Symbol_Table_Shared);
180 php_ion_symbol_table *obj = php_ion_obj(symbol_table, Z_OBJ_P(return_value));
181 obj->tab = g_sym_tab_php;
182 php_ion_symbol_table_ctor(obj);
183 ion_symbol_table_lock(obj->tab);
184 }
185 static ZEND_METHOD(ion_Symbol_Table_Local, __construct)
186 {
187 php_ion_symbol_table *obj = php_ion_obj(symbol_table, Z_OBJ_P(ZEND_THIS));
188 PTR_CHECK(obj);
189
190 ZEND_PARSE_PARAMETERS_NONE();
191
192 ION_CHECK(ion_symbol_table_open_with_type(&obj->tab, NULL, ist_LOCAL));
193 obj->dtor = ion_symbol_table_close;
194 OBJ_CHECK(obj);
195 }
196 static ZEND_METHOD(ion_Symbol_Table_Local, import)
197 {
198 php_ion_symbol_table *obj = php_ion_obj(symbol_table, Z_OBJ_P(ZEND_THIS));
199 OBJ_CHECK(obj);
200
201 zend_object *zo_import;
202 ZEND_PARSE_PARAMETERS_START(1, 1)
203 Z_PARAM_OBJ_OF_CLASS(zo_import, ce_Symbol_Table);
204 ZEND_PARSE_PARAMETERS_END();
205
206 php_ion_symbol_table_import(obj, php_ion_obj(symbol_table, zo_import));
207 }
208 static ZEND_METHOD(ion_Symbol_Table_Shared, __construct)
209 {
210 php_ion_symbol_table *obj = php_ion_obj(symbol_table, Z_OBJ_P(ZEND_THIS));
211 PTR_CHECK(obj);
212
213 zend_string *zname;
214 zend_long version = 1;
215 HashTable *ht_sym = NULL;
216 ZEND_PARSE_PARAMETERS_START(1, 3)
217 Z_PARAM_STR(zname)
218 Z_PARAM_OPTIONAL
219 Z_PARAM_LONG(version)
220 Z_PARAM_ARRAY_HT_OR_NULL(ht_sym)
221 ZEND_PARSE_PARAMETERS_END();
222
223 ION_CHECK(ion_symbol_table_open_with_type(&obj->tab, NULL, ist_SHARED));
224 obj->dtor = ion_symbol_table_close;
225
226 ION_STRING is;
227 ION_CHECK(ion_symbol_table_set_name(obj->tab, ion_string_from_zend(&is, zname)));
228 ION_CHECK(ion_symbol_table_set_version(obj->tab, version));
229
230 php_ion_symbol_table_ctor(obj);
231
232 zval *zsym;
233 if (ht_sym) ZEND_HASH_FOREACH_VAL(ht_sym, zsym)
234 {
235 zend_string *str = zval_get_string(zsym);
236 if (EG(exception)) {
237 break;
238 }
239
240 ION_STRING istr;
241 ION_CHECK(ion_symbol_table_add_symbol(obj->tab, ion_string_from_zend(&istr, str), NULL), zend_string_release(str));
242 zend_string_release(str);
243 }
244 ZEND_HASH_FOREACH_END();
245 }
246 static ZEND_METHOD(ion_Symbol_Table, getMaxId)
247 {
248 php_ion_symbol_table *obj = php_ion_obj(symbol_table, Z_OBJ_P(ZEND_THIS));
249 OBJ_CHECK(obj);
250
251 ZEND_PARSE_PARAMETERS_NONE();
252
253 SID max_sid;
254 ION_CHECK(ion_symbol_table_get_max_sid(obj->tab, &max_sid));
255 RETURN_LONG(max_sid);
256 }
257 static ZEND_METHOD(ion_Symbol_Table, add)
258 {
259 php_ion_symbol_table *obj = php_ion_obj(symbol_table, Z_OBJ_P(ZEND_THIS));
260 OBJ_CHECK(obj);
261
262 zend_object *zo_sym = NULL;
263 zend_string *zs_sym = NULL;
264 ZEND_PARSE_PARAMETERS_START(1, 1)
265 Z_PARAM_OBJ_OF_CLASS_OR_STR(zo_sym, ce_Symbol, zs_sym)
266 ZEND_PARSE_PARAMETERS_END();
267
268 if (zo_sym) {
269 zval z_sym;
270 ZVAL_OBJ(&z_sym, zo_sym);
271 zs_sym = zval_get_string(&z_sym);
272 ION_CATCH();
273 }
274 SID sid;
275 ION_STRING is;
276 ION_CHECK(ion_symbol_table_add_symbol(obj->tab, ion_string_from_zend(&is, zs_sym), &sid),
277 if (zo_sym) {
278 zend_string_release(zs_sym);
279 });
280 if (zo_sym) {
281 zend_string_release(zs_sym);
282 }
283 RETURN_LONG(sid);
284 }
285 static ZEND_METHOD(ion_Symbol_Table, find)
286 {
287 php_ion_symbol_table *obj = php_ion_obj(symbol_table, Z_OBJ_P(ZEND_THIS));
288 OBJ_CHECK(obj);
289
290 zend_long zsid;
291 zend_string *zstring = NULL;
292 ZEND_PARSE_PARAMETERS_START(1, 1)
293 Z_PARAM_STR_OR_LONG(zstring, zsid)
294 ZEND_PARSE_PARAMETERS_END();
295
296 if (zstring) {
297 SID sid;
298 ION_STRING is;
299 ION_CHECK(ion_symbol_table_find_by_name(obj->tab, ion_string_from_zend(&is, zstring), &sid));
300 zsid = sid;
301 }
302 ION_SYMBOL *sym;
303 ION_CHECK(ion_symbol_table_get_symbol(obj->tab, zsid, &sym));
304 if (sym) {
305 php_ion_symbol_table_symbol_zval(obj, sym, return_value);
306 }
307 }
308 static ZEND_METHOD(ion_Symbol_Table, findLocal)
309 {
310 php_ion_symbol_table *obj = php_ion_obj(symbol_table, Z_OBJ_P(ZEND_THIS));
311 OBJ_CHECK(obj);
312
313 zend_long zsid;
314 zend_string *zstring;
315 ZEND_PARSE_PARAMETERS_START(1, 1)
316 Z_PARAM_STR_OR_LONG(zstring, zsid)
317 ZEND_PARSE_PARAMETERS_END();
318
319 if (zstring) {
320 SID sid;
321 ION_STRING is;
322 ION_CHECK(ion_symbol_table_find_by_name(obj->tab, ion_string_from_zend(&is, zstring), &sid));
323 zsid = sid;
324 }
325 ION_SYMBOL *sym;
326 ION_CHECK(ion_symbol_table_get_local_symbol(obj->tab, zsid, &sym));
327 if (sym) {
328 php_ion_symbol_table_symbol_zval(obj, sym, return_value);
329 }
330 }
331 static ZEND_METHOD(ion_Catalog, __construct)
332 {
333 php_ion_catalog *obj = php_ion_obj(catalog, Z_OBJ_P(ZEND_THIS));
334 PTR_CHECK(obj);
335
336 ZEND_PARSE_PARAMETERS_NONE();
337
338 php_ion_catalog_ctor(obj);
339 }
340 static ZEND_METHOD(ion_Catalog, count)
341 {
342 php_ion_catalog *obj = php_ion_obj(catalog, Z_OBJ_P(ZEND_THIS));
343 OBJ_CHECK(obj);
344
345 ZEND_PARSE_PARAMETERS_NONE();
346
347 int32_t c;
348 ION_CHECK(ion_catalog_get_symbol_table_count(obj->cat, &c));
349 RETURN_LONG(c);
350 }
351 static ZEND_METHOD(ion_Catalog, add)
352 {
353 php_ion_catalog *obj = php_ion_obj(catalog, Z_OBJ_P(ZEND_THIS));
354 OBJ_CHECK(obj);
355
356 zend_object *zo_symtab;
357 ZEND_PARSE_PARAMETERS_START(1, 1)
358 Z_PARAM_OBJ_OF_CLASS(zo_symtab, ce_Symbol_Table)
359 ZEND_PARSE_PARAMETERS_END();
360
361 php_ion_symbol_table *o_symtab = php_ion_obj(symbol_table, zo_symtab);
362 php_ion_catalog_add_symbol_table(obj, o_symtab);
363 }
364
365 static ZEND_METHOD(ion_Catalog, remove)
366 {
367 php_ion_catalog *obj = php_ion_obj(catalog, Z_OBJ_P(ZEND_THIS));
368 OBJ_CHECK(obj);
369
370 zend_object *zo_symtab = NULL;
371 zend_string *zs_symtab = NULL;
372 ZEND_PARSE_PARAMETERS_START(1, 1)
373 Z_PARAM_OBJ_OF_CLASS_OR_STR(zo_symtab, ce_Symbol_Table, zs_symtab)
374 ZEND_PARSE_PARAMETERS_END();
375
376 RETVAL_FALSE;
377
378 zval tmp;
379 zval *ztabs = zend_read_property(obj->std.ce, &obj->std, ZEND_STRL("symbolTables"), 0, &tmp);
380 if (ztabs) {
381 if (zo_symtab) {
382 // fast path
383 zend_ulong idx = (uintptr_t) &zo_symtab->gc;
384 RETVAL_BOOL(SUCCESS == zend_hash_index_del(Z_ARRVAL_P(ztabs), idx));
385 ION_CHECK(ion_catalog_release_symbol_table(obj->cat, php_ion_obj(symbol_table, zo_symtab)->tab));
386 } else {
387 bool deleted = false;
388 ION_SYMBOL_TABLE *tab;
389 ION_STRING is;
390 ion_string_from_zend(&is, zs_symtab);
391 do {
392 tab = NULL;
393 ION_CHECK(ion_catalog_find_best_match(obj->cat, &is, 0, &tab));
394 if (tab) {
395 ION_CHECK(ion_catalog_release_symbol_table(obj->cat, tab));
396 deleted = true;
397 }
398 } while(tab);
399 RETVAL_BOOL(deleted);
400 }
401 }
402 }
403 static ZEND_METHOD(ion_Catalog, find)
404 {
405 php_ion_catalog *obj = php_ion_obj(catalog, Z_OBJ_P(ZEND_THIS));
406 OBJ_CHECK(obj);
407
408 zend_long zversion = 0;
409 zend_string *zname;
410 ZEND_PARSE_PARAMETERS_START(1, 2)
411 Z_PARAM_STR(zname)
412 Z_PARAM_OPTIONAL
413 Z_PARAM_LONG(zversion)
414 ZEND_PARSE_PARAMETERS_END();
415
416 ION_STRING is;
417 ION_SYMBOL_TABLE *tab_ptr = NULL;
418 ION_CHECK(ion_catalog_find_symbol_table(obj->cat, ion_string_from_zend(&is, zname), zversion, &tab_ptr));
419 if (tab_ptr) {
420 php_ion_catalog_symbol_table_zval(obj, tab_ptr, return_value);
421 }
422 }
423 static ZEND_METHOD(ion_Catalog, findBest)
424 {
425 php_ion_catalog *obj = php_ion_obj(catalog, Z_OBJ_P(ZEND_THIS));
426 OBJ_CHECK(obj);
427
428 zend_long zversion = 0;
429 zend_string *zname;
430 ZEND_PARSE_PARAMETERS_START(1, 2)
431 Z_PARAM_STR(zname)
432 Z_PARAM_OPTIONAL
433 Z_PARAM_LONG(zversion)
434 ZEND_PARSE_PARAMETERS_END();
435
436 ION_STRING is;
437 ION_SYMBOL_TABLE *tab_ptr = NULL;
438 ION_CHECK(ion_catalog_find_best_match(obj->cat, ion_string_from_zend(&is, zname), zversion, &tab_ptr));
439 if (tab_ptr) {
440 php_ion_catalog_symbol_table_zval(obj, tab_ptr, return_value);
441 }
442 }
443 static ZEND_METHOD(ion_Timestamp, __construct)
444 {
445 php_ion_timestamp *obj = php_ion_obj(timestamp, Z_OBJ_P(ZEND_THIS));
446 PTR_CHECK(obj);
447
448 zend_long precision;
449 zend_object *precision_obj = NULL, *format_obj = NULL;
450 zend_string *fmt = NULL, *dt = NULL, *tz = NULL;
451 zend_object *tz_obj = NULL;
452 zval z_tz_tmp, *z_tz_ptr = NULL;
453 ZEND_PARSE_PARAMETERS_START(1, 4)
454 Z_PARAM_OBJ_OF_CLASS_OR_LONG(precision_obj, ce_Timestamp_Precision, precision)
455 Z_PARAM_OPTIONAL
456 Z_PARAM_OBJ_OF_CLASS_OR_STR_OR_NULL(format_obj, ce_Timestamp_Format, fmt)
457 Z_PARAM_STR_OR_NULL(dt)
458 Z_PARAM_OBJ_OF_CLASS_OR_STR_OR_NULL(tz_obj, php_date_get_timezone_ce(), tz)
459 ZEND_PARSE_PARAMETERS_END();
460
461 if (precision_obj) {
462 precision = Z_LVAL_P(zend_enum_fetch_case_value(precision_obj));
463 }
464 if (format_obj) {
465 fmt = Z_STR_P(zend_enum_fetch_case_value(format_obj));
466 }
467 if (tz_obj) {
468 ZVAL_OBJ(z_tz_ptr = &z_tz_tmp, tz_obj);
469 } else if (tz) {
470 // there's no public API, so call timezone_open
471 zend_function *tz_open = zend_fetch_function_str(ZEND_STRL("timezone_open"));
472 if (tz_open) {
473 zval z_arg;
474 ZVAL_STR(&z_arg, tz);
475 zend_call_known_function(tz_open, NULL, NULL, z_tz_ptr = &z_tz_tmp, 1, &z_arg, NULL);
476 }
477 }
478 php_ion_timestamp_ctor(obj, precision, fmt, dt, z_tz_ptr);
479 if (tz && z_tz_ptr) {
480 zval_ptr_dtor(z_tz_ptr);
481 }
482 }
483 static ZEND_METHOD(ion_Timestamp, __toString)
484 {
485 php_ion_timestamp *obj = php_ion_obj(timestamp, Z_OBJ_P(ZEND_THIS));
486 OBJ_CHECK(obj);
487
488 ZEND_PARSE_PARAMETERS_NONE();
489
490 zval fmt;
491 ZVAL_NULL(&fmt);
492 zend_call_method_with_1_params(&obj->std, obj->std.ce, NULL, "format", return_value,
493 zend_read_property(obj->std.ce, &obj->std, ZEND_STRL("format"), 0, &fmt));
494 }
495 static ZEND_METHOD(ion_Decimal_Context, __construct)
496 {
497 php_ion_decimal_ctx *obj = php_ion_obj(decimal_ctx, Z_OBJ_P(ZEND_THIS));
498 PTR_CHECK(obj);
499
500 zend_bool clamp;
501 zend_object *o_round = NULL;
502 zend_long digits, emax, emin, round;
503 ZEND_PARSE_PARAMETERS_START(5, 5)
504 Z_PARAM_LONG(digits)
505 Z_PARAM_LONG(emax)
506 Z_PARAM_LONG(emin)
507 Z_PARAM_OBJ_OF_CLASS_OR_LONG(o_round, ce_Decimal_Context_Rounding, round)
508 Z_PARAM_BOOL(clamp)
509 ZEND_PARSE_PARAMETERS_END();
510
511 if (o_round) {
512 round = Z_LVAL_P(zend_enum_fetch_case_value(o_round));
513 }
514 php_ion_decimal_ctx_init(&obj->ctx, digits, emax, emin, round, clamp); // NOLINT(cppcoreguidelines-narrowing-conversions)
515 php_ion_decimal_ctx_ctor(obj, o_round);
516 }
517 static inline void make_decimal_ctx(INTERNAL_FUNCTION_PARAMETERS, int kind)
518 {
519 ZEND_PARSE_PARAMETERS_NONE();
520
521 object_init_ex(return_value, ce_Decimal_Context);
522 php_ion_decimal_ctx *obj = php_ion_obj(decimal_ctx, Z_OBJ_P(return_value));
523 decContextDefault(&obj->ctx, kind);
524 php_ion_decimal_ctx_ctor(obj, NULL);
525 }
526 static ZEND_METHOD(ion_Decimal_Context, Dec32)
527 {
528 make_decimal_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, DEC_INIT_DECIMAL32);
529 }
530 static ZEND_METHOD(ion_Decimal_Context, Dec64)
531 {
532 make_decimal_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, DEC_INIT_DECIMAL64);
533 }
534 static ZEND_METHOD(ion_Decimal_Context, Dec128)
535 {
536 make_decimal_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, DEC_INIT_DECIMAL128);
537 }
538 static ZEND_METHOD(ion_Decimal_Context, DecMax)
539 {
540 zend_object *o_round = NULL;
541 zend_long round = DEC_ROUND_HALF_EVEN;
542 ZEND_PARSE_PARAMETERS_START(0, 1)
543 Z_PARAM_OPTIONAL
544 Z_PARAM_OBJ_OF_CLASS_OR_LONG(o_round, ce_Decimal_Context_Rounding, round)
545 ZEND_PARSE_PARAMETERS_END();
546
547 if (o_round) {
548 round = Z_LVAL_P(zend_enum_fetch_case_value(o_round));
549 }
550 object_init_ex(return_value, ce_Decimal_Context);
551 php_ion_decimal_ctx *obj = php_ion_obj(decimal_ctx, Z_OBJ_P(return_value));
552 php_ion_decimal_ctx_init_max(&obj->ctx, round);
553 php_ion_decimal_ctx_ctor(obj, o_round);
554 }
555 static ZEND_METHOD(ion_Decimal, __construct)
556 {
557 php_ion_decimal *obj = php_ion_obj(decimal, Z_OBJ_P(ZEND_THIS));
558 PTR_CHECK(obj);
559
560 zend_long num;
561 zend_string *zstr;
562 ZEND_PARSE_PARAMETERS_START(1, 2)
563 Z_PARAM_STR_OR_LONG(zstr, num)
564 Z_PARAM_OPTIONAL
565 Z_PARAM_OBJ_OF_CLASS_OR_NULL(obj->ctx, ce_Decimal_Context)
566 ZEND_PARSE_PARAMETERS_END();
567
568 if (obj->ctx) {
569 GC_ADDREF(obj->ctx);
570 } else {
571 zval zdc;
572 object_init_ex(&zdc, ce_Decimal_Context);
573 obj->ctx = Z_OBJ(zdc);
574 php_ion_decimal_ctx_ctor(php_ion_obj(decimal_ctx, obj->ctx), NULL);
575 }
576
577 decContext *ctx = &php_ion_obj(decimal_ctx, obj->ctx)->ctx;
578
579 if (zstr) {
580 ION_CHECK(ion_decimal_from_string(&obj->dec, zstr->val, ctx), OBJ_RELEASE(obj->ctx));
581 } else {
582 php_ion_decimal_from_zend_long(&obj->dec, ctx, num);
583 }
584
585 php_ion_decimal_ctor(obj);
586 OBJ_RELEASE(obj->ctx);
587 }
588 static ZEND_METHOD(ion_Decimal, equals)
589 {
590 php_ion_decimal *obj = php_ion_obj(decimal, Z_OBJ_P(ZEND_THIS));
591 PTR_CHECK(obj);
592
593 zend_object *dec_obj;
594 ZEND_PARSE_PARAMETERS_START(1, 1)
595 Z_PARAM_OBJ_OF_CLASS(dec_obj, ce_Decimal)
596 ZEND_PARSE_PARAMETERS_END();
597
598 BOOL is = FALSE;
599 ION_CHECK(ion_decimal_equals(&obj->dec, &php_ion_obj(decimal, dec_obj)->dec,
600 obj->ctx ? &php_ion_obj(decimal_ctx, obj->ctx)->ctx : NULL, &is));
601 RETURN_BOOL(is);
602 }
603 static ZEND_METHOD(ion_Decimal, __toString)
604 {
605 php_ion_decimal *obj = php_ion_obj(decimal, Z_OBJ_P(ZEND_THIS));
606 PTR_CHECK(obj);
607
608 ZEND_PARSE_PARAMETERS_NONE();
609
610 RETURN_STR(php_ion_decimal_to_string(&obj->dec));
611 }
612 static ZEND_METHOD(ion_Decimal, toInt)
613 {
614 php_ion_decimal *obj = php_ion_obj(decimal, Z_OBJ_P(ZEND_THIS));
615 PTR_CHECK(obj);
616
617 ZEND_PARSE_PARAMETERS_NONE();
618
619 zend_long l;
620 php_ion_decimal_to_zend_long(&obj->dec, &php_ion_obj(decimal_ctx, obj->ctx)->ctx, &l);
621 RETURN_LONG(l);
622 }
623 static ZEND_METHOD(ion_Decimal, isInt)
624 {
625 php_ion_decimal *obj = php_ion_obj(decimal, Z_OBJ_P(ZEND_THIS));
626 PTR_CHECK(obj);
627
628 ZEND_PARSE_PARAMETERS_NONE();
629
630 RETURN_BOOL(ion_decimal_is_integer(&obj->dec));
631 }
632 static ZEND_METHOD(ion_LOB, __construct)
633 {
634 zend_string *value;
635 zend_object *type = NULL;
636 ZEND_PARSE_PARAMETERS_START(1, 2)
637 Z_PARAM_STR(value)
638 Z_PARAM_OPTIONAL
639 Z_PARAM_OBJ_OF_CLASS(type, ce_Type)
640 ZEND_PARSE_PARAMETERS_END();
641
642 if (!type) {
643 type = zend_enum_get_case_cstr(ce_Type, "CLob");
644 }
645 update_property_obj(Z_OBJ_P(ZEND_THIS), ZEND_STRL("type"), type);
646 zend_update_property_str(Z_OBJCE_P(ZEND_THIS), Z_OBJ_P(ZEND_THIS), ZEND_STRL("value"), value);
647 }
648 static ZEND_METHOD(ion_Reader_Reader, __construct)
649 {
650 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
651
652 PTR_CHECK(obj);
653
654 zval *zstream = NULL;
655 zend_bool ret_sys_val = false, skip_validation = false;
656 zend_long max_depth = 10, max_ann = 10, ann_buf_siz = 0x4000, tmp_buf_siz = 0x4000;
657 ZEND_PARSE_PARAMETERS_START(1, 10)
658 Z_PARAM_PROLOGUE(0, 0)
659 if (!instanceof_function(obj->std.ce, ce_Reader_Buffer) &&
660 zend_parse_arg_resource(_arg, &zstream, 0)) {
661 obj->type = STREAM_READER;
662 php_stream_from_zval_no_verify(obj->stream.ptr, zstream);
663 PTR_CHECK(obj->stream.ptr);
664 GC_ADDREF(obj->stream.ptr->res);
665 } else if (!instanceof_function(obj->std.ce, ce_Reader_Stream) &&
666 zend_parse_arg_str(_arg, &obj->buffer, 0, _i)) {
667 obj->type = BUFFER_READER;
668 zend_string_addref(obj->buffer);
669 } else {
670 _error_code = ZPP_ERROR_WRONG_ARG;
671 _error = "of type string or resource";
672 break;
673 }
674 Z_PARAM_OPTIONAL
675 // public readonly ?\ion\Catalog $catalog = null,
676 Z_PARAM_OBJ_OF_CLASS_OR_NULL(obj->cat, ce_Catalog)
677 // public readonly ?\ion\Decimal\Context $decimalContext = null,
678 Z_PARAM_OBJ_OF_CLASS_OR_NULL(obj->dec_ctx, ce_Decimal_Context)
679 // public readonly ?\Closure $onContextChange = null,
680 Z_PARAM_OBJ_OF_CLASS_OR_NULL(obj->cb, zend_ce_closure);
681 // public readonly bool $returnSystemValues = false,
682 Z_PARAM_BOOL(ret_sys_val)
683 // public readonly int $maxContainerDepth = 10,
684 Z_PARAM_LONG(max_depth)
685 // public readonly int $maxAnnotations = 10,
686 Z_PARAM_LONG(max_ann)
687 // public readonly int $annotationBufferSize = 0x4000,
688 Z_PARAM_LONG(ann_buf_siz)
689 // public readonly int $tempBufferSize = 0x4000,
690 Z_PARAM_LONG(tmp_buf_siz)
691 // public readonly bool $skipCharacterValidation = false,
692 Z_PARAM_BOOL(skip_validation)
693 ZEND_PARSE_PARAMETERS_END();
694
695 obj->options.return_system_values = ret_sys_val;
696 obj->options.max_container_depth = (SIZE) max_depth;
697 obj->options.max_annotation_count = (SIZE) max_ann;
698 obj->options.max_annotation_buffered = (SIZE) ann_buf_siz;
699 obj->options.chunk_threshold = (SIZE) tmp_buf_siz;
700 obj->options.user_value_threshold = (SIZE) tmp_buf_siz;
701 obj->options.symbol_threshold = (SIZE) tmp_buf_siz;
702 obj->options.skip_character_validation = skip_validation;
703
704 php_ion_reader_ctor(obj);
705 }
706 static ZEND_METHOD(ion_Reader_Reader, hasChildren)
707 {
708 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
709
710 OBJ_CHECK(obj);
711 ZEND_PARSE_PARAMETERS_NONE();
712
713 ION_TYPE t;
714 ION_CHECK(ion_reader_get_type(obj->reader, &t));
715 switch (ION_TYPE_INT(t)) {
716 case tid_LIST_INT:
717 case tid_SEXP_INT:
718 case tid_STRUCT_INT:
719 RETVAL_TRUE;
720 break;
721 default:
722 RETVAL_FALSE;
723 break;
724 }
725 }
726 static ZEND_METHOD(ion_Reader_Reader, getChildren)
727 {
728 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
729 OBJ_CHECK(obj);
730
731 ZEND_PARSE_PARAMETERS_NONE();
732
733 ION_CHECK(ion_reader_step_in(obj->reader));
734
735 RETURN_ZVAL(ZEND_THIS, 1, 0);
736 }
737 static ZEND_METHOD(ion_Reader_Reader, rewind)
738 {
739 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
740 OBJ_CHECK(obj);
741
742 ZEND_PARSE_PARAMETERS_NONE();
743
744 ION_CHECK(ion_reader_next(obj->reader, &obj->state));
745 }
746 static ZEND_METHOD(ion_Reader_Reader, next)
747 {
748 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
749 OBJ_CHECK(obj);
750
751 ZEND_PARSE_PARAMETERS_NONE();
752
753 if (obj->state == tid_EOF) {
754 SIZE depth = 0;
755 ION_CHECK(ion_reader_get_depth(obj->reader, &depth));
756 if (depth) {
757 ION_CHECK(ion_reader_step_out(obj->reader));
758 }
759 }
760 ION_CHECK(ion_reader_next(obj->reader, &obj->state));
761 }
762 static ZEND_METHOD(ion_Reader_Reader, valid)
763 {
764 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
765 OBJ_CHECK(obj);
766
767 ZEND_PARSE_PARAMETERS_NONE();
768 RETURN_BOOL(obj->state != tid_none && obj->state != tid_EOF);
769 }
770 static ZEND_METHOD(ion_Reader_Reader, key)
771 {
772 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
773 OBJ_CHECK(obj);
774
775 ZEND_PARSE_PARAMETERS_NONE();
776 RETURN_IONTYPE(obj->state);
777 }
778 static ZEND_METHOD(ion_Reader_Reader, current)
779 {
780 ZEND_PARSE_PARAMETERS_NONE();
781 RETURN_ZVAL(ZEND_THIS, 1, 0);
782 }
783 static ZEND_METHOD(ion_Reader_Reader, getType)
784 {
785 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
786 OBJ_CHECK(obj);
787
788 ZEND_PARSE_PARAMETERS_NONE();
789
790 ION_TYPE typ;
791 ION_CHECK(ion_reader_get_type(obj->reader, &typ));
792 RETURN_IONTYPE(typ);
793 }
794 static ZEND_METHOD(ion_Reader_Reader, hasAnnotations)
795 {
796 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
797 OBJ_CHECK(obj);
798
799 ZEND_PARSE_PARAMETERS_NONE();
800
801 BOOL has = FALSE;
802 ION_CHECK(ion_reader_has_any_annotations(obj->reader, &has));
803 RETURN_BOOL(has);
804 }
805 static ZEND_METHOD(ion_Reader_Reader, hasAnnotation)
806 {
807 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
808 OBJ_CHECK(obj);
809
810 zend_string *ann_zstr;
811 ZEND_PARSE_PARAMETERS_START(1, 1);
812 Z_PARAM_STR(ann_zstr);
813 ZEND_PARSE_PARAMETERS_END();
814
815 ION_STRING ann_istr;
816 BOOL has = FALSE;
817 ION_CHECK(ion_reader_has_annotation(obj->reader, ion_string_from_zend(&ann_istr, ann_zstr), &has));
818 RETURN_BOOL(has);
819 }
820 static ZEND_METHOD(ion_Reader_Reader, isNull)
821 {
822 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
823 OBJ_CHECK(obj);
824
825 ZEND_PARSE_PARAMETERS_NONE();
826
827 BOOL is = FALSE;
828 ION_CHECK(ion_reader_is_null(obj->reader, &is));
829 RETURN_BOOL(is);
830 }
831 static ZEND_METHOD(ion_Reader_Reader, isInStruct)
832 {
833 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
834 OBJ_CHECK(obj);
835
836 ZEND_PARSE_PARAMETERS_NONE();
837
838 BOOL is = FALSE;
839 ION_CHECK(ion_reader_is_in_struct(obj->reader, &is));
840 RETURN_BOOL(is);
841 }
842 static ZEND_METHOD(ion_Reader_Reader, getFieldName)
843 {
844 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
845 OBJ_CHECK(obj);
846
847 ZEND_PARSE_PARAMETERS_NONE();
848
849 ION_STRING name;
850 ION_CHECK(ion_reader_get_field_name(obj->reader, &name));
851 RETURN_STRINGL((char *) name.value, name.length);
852 }
853 static ZEND_METHOD(ion_Reader_Reader, getFieldNameSymbol)
854 {
855 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
856 OBJ_CHECK(obj);
857
858 ZEND_PARSE_PARAMETERS_NONE();
859
860 ION_SYMBOL *sym_ptr;
861 ION_CHECK(ion_reader_get_field_name_symbol(obj->reader, &sym_ptr));
862
863 php_ion_symbol_zval(sym_ptr, return_value);
864 }
865 static ZEND_METHOD(ion_Reader_Reader, getAnnotations)
866 {
867 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
868 OBJ_CHECK(obj);
869
870 ZEND_PARSE_PARAMETERS_NONE();
871
872 int32_t count, max;
873 if (obj->options.max_annotation_count) {
874 max = obj->options.max_annotation_count;
875 } else {
876 max = 10;
877 }
878 ION_STRING *ptr = ecalloc(sizeof(*ptr), max);
879 iERR err = ion_reader_get_annotations(obj->reader, ptr, max, &count);
880 if (!err) {
881 array_init_size(return_value, count);
882 for (int32_t i = 0; i < count; ++i) {
883 add_next_index_str(return_value, zend_string_from_ion(&ptr[i]));
884 }
885 }
886 efree(ptr);
887 ION_CHECK(err);
888 }
889 static ZEND_METHOD(ion_Reader_Reader, getAnnotationSymbols)
890 {
891 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
892 OBJ_CHECK(obj);
893
894 ZEND_PARSE_PARAMETERS_NONE();
895
896 int32_t count, max;
897 if (obj->options.max_annotation_count) {
898 max = obj->options.max_annotation_count;
899 } else {
900 max = 10;
901 }
902 ION_SYMBOL *ptr = ecalloc(sizeof(*ptr), max);
903 iERR err = ion_reader_get_annotation_symbols(obj->reader, ptr, max, &count);
904 if (!err) {
905 array_init_size(return_value, count);
906 for (int32_t i = 0; i < count; ++i) {
907 zval zsym;
908 php_ion_symbol_zval(&ptr[i], &zsym);
909 add_next_index_zval(return_value, &zsym);
910 }
911 }
912 efree(ptr);
913 ION_CHECK(err);
914 }
915 static ZEND_METHOD(ion_Reader_Reader, countAnnotations)
916 {
917 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
918 OBJ_CHECK(obj);
919
920 ZEND_PARSE_PARAMETERS_NONE();
921
922 SIZE sz = 0;
923 ION_CHECK(ion_reader_get_annotation_count(obj->reader, &sz));
924 RETURN_LONG(sz);
925 }
926 static ZEND_METHOD(ion_Reader_Reader, getAnnotation)
927 {
928 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
929 OBJ_CHECK(obj);
930
931 zend_long idx;
932 ZEND_PARSE_PARAMETERS_START(1, 1)
933 Z_PARAM_LONG(idx);
934 ZEND_PARSE_PARAMETERS_END();
935
936 ION_STRING ann;
937 ION_CHECK(ion_reader_get_an_annotation(obj->reader, idx, &ann));
938 RETURN_STRINGL((char *) ann.value, ann.length);
939 }
940 static ZEND_METHOD(ion_Reader_Reader, getAnnotationSymbol)
941 {
942 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
943 OBJ_CHECK(obj);
944
945 zend_long idx;
946 ZEND_PARSE_PARAMETERS_START(1, 1)
947 Z_PARAM_LONG(idx);
948 ZEND_PARSE_PARAMETERS_END();
949
950 ION_SYMBOL sym;
951 ION_CHECK(ion_reader_get_an_annotation_symbol(obj->reader, idx, &sym));
952 php_ion_symbol_zval(&sym, return_value);
953 }
954 static ZEND_METHOD(ion_Reader_Reader, readNull)
955 {
956 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
957 OBJ_CHECK(obj);
958
959 ZEND_PARSE_PARAMETERS_NONE();
960
961 ION_TYPE typ;
962 ION_CHECK(ion_reader_read_null(obj->reader, &typ));
963 RETURN_IONTYPE(typ);
964 }
965 static ZEND_METHOD(ion_Reader_Reader, readBool)
966 {
967 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
968 OBJ_CHECK(obj);
969
970 ZEND_PARSE_PARAMETERS_NONE();
971
972 BOOL b;
973 ION_CHECK(ion_reader_read_bool(obj->reader, &b));
974 RETURN_BOOL(b);
975 }
976 static ZEND_METHOD(ion_Reader_Reader, readInt)
977 {
978 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
979 OBJ_CHECK(obj);
980
981 ZEND_PARSE_PARAMETERS_NONE();
982
983 php_ion_reader_read_int(obj->reader, return_value);
984 }
985 static ZEND_METHOD(ion_Reader_Reader, readFloat)
986 {
987 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
988 OBJ_CHECK(obj);
989
990 ZEND_PARSE_PARAMETERS_NONE();
991
992 double dval;
993 ION_CHECK(ion_reader_read_double(obj->reader, &dval));
994 RETURN_DOUBLE(dval);
995 }
996 static ZEND_METHOD(ion_Reader_Reader, readDecimal)
997 {
998 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
999 OBJ_CHECK(obj);
1000
1001 ZEND_PARSE_PARAMETERS_NONE();
1002
1003 object_init_ex(return_value, ce_Decimal);
1004 php_ion_decimal *dec = php_ion_obj(decimal, Z_OBJ_P(return_value));
1005 ION_CHECK(ion_reader_read_ion_decimal(obj->reader, &dec->dec));
1006 php_ion_decimal_ctor(dec);
1007 }
1008 static ZEND_METHOD(ion_Reader_Reader, readTimestamp)
1009 {
1010 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
1011 OBJ_CHECK(obj);
1012
1013 ZEND_PARSE_PARAMETERS_NONE();
1014
1015 php_ion_reader_read_timestamp(obj->reader, &obj->options, return_value);
1016 }
1017 static ZEND_METHOD(ion_Reader_Reader, readSymbol)
1018 {
1019 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
1020 OBJ_CHECK(obj);
1021
1022 ZEND_PARSE_PARAMETERS_NONE();
1023
1024 ION_SYMBOL sym;
1025 ION_CHECK(ion_reader_read_ion_symbol(obj->reader, &sym));
1026 php_ion_symbol_zval(&sym, return_value);
1027 }
1028 static ZEND_METHOD(ion_Reader_Reader, readString)
1029 {
1030 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
1031 OBJ_CHECK(obj);
1032
1033 ZEND_PARSE_PARAMETERS_NONE();
1034
1035 ION_STRING str;
1036 ION_CHECK(ion_reader_read_string(obj->reader, &str));
1037 RETURN_STRINGL((char *) str.value, str.length);
1038 }
1039
1040 typedef iERR (*read_part_fn)(ION_READER *, BYTE *, SIZE, SIZE *);
1041 static void read_part(INTERNAL_FUNCTION_PARAMETERS, read_part_fn fn)
1042 {
1043 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
1044 OBJ_CHECK(obj);
1045
1046 zval *ref;
1047 zend_string *zstr;
1048 zend_long len = 0x1000;
1049 ZEND_PARSE_PARAMETERS_START(1, 1)
1050 Z_PARAM_ZVAL(ref)
1051 Z_PARAM_OPTIONAL
1052 Z_PARAM_LONG(len)
1053 ZEND_PARSE_PARAMETERS_END();
1054
1055 ZVAL_DEREF(ref);
1056
1057 if (Z_TYPE_P(ref) == IS_STRING && Z_STRLEN_P(ref) == len) {
1058 /* reuse */
1059 zstr = Z_STR_P(ref);
1060 } else {
1061 zval_dtor(ref);
1062 zstr = zend_string_alloc(len, 0);
1063 }
1064
1065 SIZE read = 0;
1066 ION_CHECK(fn(obj->reader, (BYTE *) zstr->val, zstr->len, &read), goto fail);
1067 if (read > 0) {
1068 if (read < zstr->len) {
1069 zstr = zend_string_truncate(zstr, read, 0);
1070 }
1071 ZVAL_STR(ref, zstr);
1072 RETURN_TRUE;
1073 }
1074 fail:
1075 zend_string_release(zstr);
1076 ZVAL_EMPTY_STRING(ref);
1077 RETURN_FALSE;
1078 }
1079 static ZEND_METHOD(ion_Reader_Reader, readStringPart)
1080 {
1081 read_part(INTERNAL_FUNCTION_PARAM_PASSTHRU, ion_reader_read_partial_string);
1082 }
1083 static ZEND_METHOD(ion_Reader_Reader, readLob)
1084 {
1085 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
1086 OBJ_CHECK(obj);
1087
1088 ZEND_PARSE_PARAMETERS_NONE();
1089
1090 php_ion_reader_read_lob(obj->reader, return_value);
1091 }
1092 static ZEND_METHOD(ion_Reader_Reader, readLobPart)
1093 {
1094 read_part(INTERNAL_FUNCTION_PARAM_PASSTHRU, ion_reader_read_lob_partial_bytes);
1095 }
1096 static ZEND_METHOD(ion_Reader_Reader, getPosition)
1097 {
1098 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
1099 OBJ_CHECK(obj);
1100
1101 ZEND_PARSE_PARAMETERS_NONE();
1102
1103 int64_t bytes = 0;
1104 int32_t dummy;
1105 ION_CHECK(ion_reader_get_position(obj->reader, &bytes, &dummy, &dummy));
1106 RETURN_LONG(bytes);
1107 }
1108 static ZEND_METHOD(ion_Reader_Reader, getDepth)
1109 {
1110 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
1111 OBJ_CHECK(obj);
1112
1113 ZEND_PARSE_PARAMETERS_NONE();
1114
1115 SIZE depth = 0;
1116 ION_CHECK(ion_reader_get_depth(obj->reader, &depth));
1117 RETURN_LONG(depth);
1118 }
1119 static ZEND_METHOD(ion_Reader_Reader, seek)
1120 {
1121 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
1122 OBJ_CHECK(obj);
1123
1124 zend_long off, len = -1;
1125 ZEND_PARSE_PARAMETERS_START(1, 2)
1126 Z_PARAM_LONG(off)
1127 Z_PARAM_OPTIONAL
1128 Z_PARAM_LONG(len)
1129 ZEND_PARSE_PARAMETERS_END();
1130
1131 ION_CHECK(ion_reader_seek(obj->reader, off, len));
1132 }
1133 static ZEND_METHOD(ion_Reader_Reader, getValueOffset)
1134 {
1135 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
1136 OBJ_CHECK(obj);
1137
1138 ZEND_PARSE_PARAMETERS_NONE();
1139
1140 POSITION off = 0;
1141 ION_CHECK(ion_reader_get_value_offset(obj->reader, &off));
1142 RETURN_LONG(off);
1143 }
1144 static ZEND_METHOD(ion_Reader_Reader, getValueLength)
1145 {
1146 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
1147 OBJ_CHECK(obj);
1148
1149 ZEND_PARSE_PARAMETERS_NONE();
1150
1151 SIZE len = 0;
1152 ION_CHECK(ion_reader_get_value_length(obj->reader, &len));
1153 RETURN_LONG(len);
1154 }
1155
1156 static ZEND_METHOD(ion_Reader_Buffer_Reader, getBuffer)
1157 {
1158 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
1159 OBJ_CHECK(obj);
1160
1161 ZEND_PARSE_PARAMETERS_NONE();
1162 RETURN_STR_COPY(obj->buffer);
1163 }
1164
1165 static ZEND_METHOD(ion_Reader_Stream_Reader, getStream)
1166 {
1167 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
1168 OBJ_CHECK(obj);
1169
1170 ZEND_PARSE_PARAMETERS_NONE();
1171 PTR_CHECK(obj->stream.ptr);
1172
1173 GC_ADDREF(obj->stream.ptr->res);
1174 RETURN_RES(obj->stream.ptr->res);
1175 }
1176 static ZEND_METHOD(ion_Reader_Stream_Reader, resetStream)
1177 {
1178 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
1179 OBJ_CHECK(obj);
1180
1181 zval *zstream;
1182 ZEND_PARSE_PARAMETERS_START(1, 1);
1183 Z_PARAM_RESOURCE(zstream);
1184 ZEND_PARSE_PARAMETERS_END();
1185
1186 ION_CHECK(ion_reader_reset_stream(&obj->reader, obj, php_ion_reader_stream_handler));
1187
1188 if (obj->stream.ptr) {
1189 zend_list_delete(obj->stream.ptr->res);
1190 }
1191 php_stream_from_zval_no_verify(obj->stream.ptr, zstream);
1192 PTR_CHECK(obj->stream.ptr);
1193 Z_ADDREF_P(zstream);
1194 }
1195 static ZEND_METHOD(ion_Reader_Stream_Reader, resetStreamWithLength)
1196 {
1197 php_ion_reader *obj = php_ion_obj(reader, Z_OBJ_P(ZEND_THIS));
1198 OBJ_CHECK(obj);
1199
1200 zval *zstream;
1201 zend_long length;
1202 ZEND_PARSE_PARAMETERS_START(2, 2);
1203 Z_PARAM_RESOURCE(zstream);
1204 Z_PARAM_LONG(length)
1205 ZEND_PARSE_PARAMETERS_END();
1206
1207 ION_CHECK(ion_reader_reset_stream_with_length(&obj->reader, obj, php_ion_reader_stream_handler, length));
1208
1209 if (obj->stream.ptr) {
1210 zend_list_delete(obj->stream.ptr->res);
1211 }
1212 php_stream_from_zval_no_verify(obj->stream.ptr, zstream);
1213 PTR_CHECK(obj->stream.ptr);
1214 Z_ADDREF_P(zstream);
1215 }
1216
1217 static void _ion_Writer_Writer___construct(bool stream_writer, INTERNAL_FUNCTION_PARAMETERS)
1218 {
1219 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1220 PTR_CHECK(obj);
1221
1222 zend_bool binary = false, compact_floats = false, escape = false, pretty = false,
1223 tabs = true, flush = false;
1224 zend_long indent = 2, max_depth = 10, max_ann = 10, temp = 0x4000;
1225 ZEND_PARSE_PARAMETERS_START(0 + stream_writer, 12 + stream_writer)
1226 if (!stream_writer) {
1227 obj->type = BUFFER_WRITER;
1228 } else {
1229 Z_PARAM_PROLOGUE(0, 0)
1230 obj->type = STREAM_WRITER;
1231 zval *zstream = NULL;
1232 if (zend_parse_arg_resource(_arg, &zstream, 0)) {
1233 php_stream_from_zval_no_verify(obj->stream.ptr, zstream);
1234 PTR_CHECK(obj->stream.ptr);
1235 GC_ADDREF(obj->stream.ptr->res);
1236 } else {
1237 _error_code = Z_EXPECTED_RESOURCE;
1238 _error = "of type resource";
1239 break;
1240 }
1241 }
1242 Z_PARAM_OPTIONAL
1243 //public readonly ?\ion\Catalog $catalog = null,
1244 Z_PARAM_OBJ_OF_CLASS_OR_NULL(obj->cat, ce_Catalog)
1245 //public readonly ?\ion\Decimal\Context $decimalContext = null,
1246 Z_PARAM_OBJ_OF_CLASS_OR_NULL(obj->dec_ctx, ce_Decimal_Context)
1247 //public readonly bool $outputBinary = false,
1248 Z_PARAM_BOOL(binary)
1249 //public readonly bool $compactFloats = false,
1250 Z_PARAM_BOOL(compact_floats)
1251 //public readonly bool $escapeNonAscii = false,
1252 Z_PARAM_BOOL(escape)
1253 //public readonly bool $prettyPrint = false,
1254 Z_PARAM_BOOL(pretty)
1255 //public readonly bool $indentTabs = true,
1256 Z_PARAM_BOOL(tabs)
1257 //public readonly int $indentSize = 2,
1258 Z_PARAM_LONG(indent)
1259 //public readonly bool $flushEveryValue = false,
1260 Z_PARAM_BOOL(flush)
1261 //public readonly int $maxContainerDepth = 10,
1262 Z_PARAM_LONG(max_depth)
1263 //public readonly int $maxAnnotations = 10,
1264 Z_PARAM_LONG(max_ann)
1265 //public readonly int $tempBufferSize = 0x4000,
1266 Z_PARAM_LONG(temp)
1267 ZEND_PARSE_PARAMETERS_END();
1268
1269 obj->options.output_as_binary = binary;
1270 obj->options.compact_floats = compact_floats;
1271 obj->options.escape_all_non_ascii = escape;
1272 obj->options.pretty_print = pretty;
1273 obj->options.indent_with_tabs = tabs;
1274 obj->options.indent_size = (SIZE) indent;
1275 obj->options.flush_every_value = flush;
1276 obj->options.max_container_depth = (SIZE) max_depth;
1277 obj->options.max_annotation_count = (SIZE) max_ann;
1278 obj->options.temp_buffer_size = (SIZE) temp;
1279
1280 php_ion_writer_ctor(obj);
1281 }
1282
1283 static ZEND_METHOD(ion_Writer_Writer, __construct)
1284 {
1285 _ion_Writer_Writer___construct(false, INTERNAL_FUNCTION_PARAM_PASSTHRU);
1286 }
1287 static ZEND_METHOD(ion_Writer_Writer, writeNull)
1288 {
1289 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1290 OBJ_CHECK(obj);
1291
1292 ZEND_PARSE_PARAMETERS_NONE();
1293
1294 ION_CHECK(ion_writer_write_null(obj->writer));
1295 }
1296 static ZEND_METHOD(ion_Writer_Writer, writeTypedNull)
1297 {
1298 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1299 OBJ_CHECK(obj);
1300
1301 zend_object *typ_obj;
1302 ZEND_PARSE_PARAMETERS_START(1, 1)
1303 Z_PARAM_OBJ_OF_CLASS(typ_obj, ce_Type)
1304 ZEND_PARSE_PARAMETERS_END();
1305
1306 ION_CHECK(ion_writer_write_typed_null(obj->writer, ion_type_from_enum(typ_obj)));
1307 }
1308 static ZEND_METHOD(ion_Writer_Writer, writeBool)
1309 {
1310 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1311 OBJ_CHECK(obj);
1312
1313 zend_bool b;
1314 ZEND_PARSE_PARAMETERS_START(1, 1)
1315 Z_PARAM_BOOL(b)
1316 ZEND_PARSE_PARAMETERS_END();
1317
1318 ION_CHECK(ion_writer_write_bool(obj->writer, b));
1319 }
1320 static ZEND_METHOD(ion_Writer_Writer, writeInt)
1321 {
1322 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1323 OBJ_CHECK(obj);
1324
1325 zend_long l;
1326 zend_string *s;
1327 ZEND_PARSE_PARAMETERS_START(1, 1)
1328 Z_PARAM_STR_OR_LONG(s, l)
1329 ZEND_PARSE_PARAMETERS_END();
1330
1331 if (s) {
1332 ION_INT *i;
1333 ION_CHECK(ion_int_alloc(obj->writer, &i));
1334 ION_CHECK(ion_int_from_chars(i, s->val, s->len));
1335 ION_CHECK(ion_writer_write_ion_int(obj->writer, i));
1336 ion_int_free(i);
1337 } else {
1338 ION_CHECK(ion_writer_write_int64(obj->writer, l));
1339 }
1340 }
1341 static ZEND_METHOD(ion_Writer_Writer, writeFloat)
1342 {
1343 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1344 OBJ_CHECK(obj);
1345
1346 double d;
1347 ZEND_PARSE_PARAMETERS_START(1, 1)
1348 Z_PARAM_DOUBLE(d)
1349 ZEND_PARSE_PARAMETERS_END();
1350
1351 ION_CHECK(ion_writer_write_double(obj->writer, d));
1352 }
1353 static ZEND_METHOD(ion_Writer_Writer, writeDecimal)
1354 {
1355 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1356 OBJ_CHECK(obj);
1357
1358 zend_object *dec_obj;
1359 zend_string *dec_str;
1360 ZEND_PARSE_PARAMETERS_START(1, 1)
1361 Z_PARAM_OBJ_OF_CLASS_OR_STR(dec_obj, ce_Decimal, dec_str)
1362 ZEND_PARSE_PARAMETERS_END();
1363
1364 if (dec_str) {
1365 decContext *ctx = &php_ion_globals.decimal.ctx;
1366 ION_DECIMAL dec = {0};
1367
1368 if (obj->options.decimal_context) {
1369 ctx = obj->options.decimal_context;
1370 }
1371 ION_CHECK(ion_decimal_from_string(&dec, dec_str->val, ctx));
1372 ION_CHECK(ion_writer_write_ion_decimal(obj->writer, &dec));
1373 } else {
1374 php_ion_decimal *dec = php_ion_obj(decimal, dec_obj);
1375 ION_CHECK(ion_writer_write_ion_decimal(obj->writer, &dec->dec));
1376 }
1377 }
1378 static ZEND_METHOD(ion_Writer_Writer, writeTimestamp)
1379 {
1380 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1381 OBJ_CHECK(obj);
1382
1383 zend_object *ts_obj;
1384 zend_string *ts_str;
1385 ZEND_PARSE_PARAMETERS_START(1, 1)
1386 Z_PARAM_OBJ_OF_CLASS_OR_STR(ts_obj, ce_Timestamp, ts_str)
1387 ZEND_PARSE_PARAMETERS_END();
1388
1389 decContext *ctx = obj->options.decimal_context;
1390 ION_TIMESTAMP tmp = {0};
1391 if (ts_str) {
1392 SIZE used;
1393 ION_CHECK(ion_timestamp_parse(&tmp, ts_str->val, ts_str->len, &used, ctx));
1394 } else {
1395 php_ion_timestamp *ts = php_ion_obj(timestamp, ts_obj);
1396 OBJ_CHECK(ts);
1397 ion_timestamp_from_php(&tmp, ts, ctx);
1398 }
1399 ION_CHECK(ion_writer_write_timestamp(obj->writer, &tmp));
1400 }
1401 static ZEND_METHOD(ion_Writer_Writer, writeSymbol)
1402 {
1403 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1404 OBJ_CHECK(obj);
1405
1406 zend_object *sym_obj;
1407 zend_string *sym_str;
1408 ZEND_PARSE_PARAMETERS_START(1, 1)
1409 Z_PARAM_OBJ_OF_CLASS_OR_STR(sym_obj, ce_Symbol, sym_str);
1410 ZEND_PARSE_PARAMETERS_END();
1411
1412 if (sym_str) {
1413 ION_STRING is;
1414 ION_CHECK(ion_writer_write_symbol(obj->writer, ion_string_from_zend(&is, sym_str)));
1415 } else {
1416 php_ion_symbol *sym = php_ion_obj(symbol, sym_obj);
1417 PTR_CHECK(sym);
1418 ION_CHECK(ion_writer_write_ion_symbol(obj->writer, &sym->sym));
1419 }
1420 }
1421 static ZEND_METHOD(ion_Writer_Writer, writeString)
1422 {
1423 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1424 OBJ_CHECK(obj);
1425
1426 zend_string *str;
1427 ZEND_PARSE_PARAMETERS_START(1, 1)
1428 Z_PARAM_STR(str)
1429 ZEND_PARSE_PARAMETERS_END();
1430
1431 ION_STRING is;
1432 ION_CHECK(ion_writer_write_string(obj->writer, ion_string_from_zend(&is, str)));
1433 }
1434 static ZEND_METHOD(ion_Writer_Writer, writeCLob)
1435 {
1436 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1437 OBJ_CHECK(obj);
1438
1439 zend_string *str;
1440 ZEND_PARSE_PARAMETERS_START(1, 1)
1441 Z_PARAM_STR(str)
1442 ZEND_PARSE_PARAMETERS_END();
1443
1444 ION_CHECK(ion_writer_write_clob(obj->writer, (BYTE *) str->val, str->len));
1445 }
1446 static ZEND_METHOD(ion_Writer_Writer, writeBLob)
1447 {
1448 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1449 OBJ_CHECK(obj);
1450
1451 zend_string *str;
1452 ZEND_PARSE_PARAMETERS_START(1, 1)
1453 Z_PARAM_STR(str)
1454 ZEND_PARSE_PARAMETERS_END();
1455
1456 ION_CHECK(ion_writer_write_blob(obj->writer, (BYTE *) str->val, str->len));
1457 }
1458 static ZEND_METHOD(ion_Writer_Writer, startLob)
1459 {
1460 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1461 OBJ_CHECK(obj);
1462
1463 zend_object *typ_obj;
1464 ZEND_PARSE_PARAMETERS_START(1, 1)
1465 Z_PARAM_OBJ_OF_CLASS(typ_obj, ce_Type)
1466 ZEND_PARSE_PARAMETERS_END();
1467
1468 ION_CHECK(ion_writer_start_lob(obj->writer, ion_type_from_enum(typ_obj)));
1469 }
1470 static ZEND_METHOD(ion_Writer_Writer, appendLob)
1471 {
1472 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1473 OBJ_CHECK(obj);
1474
1475 zend_string *str;
1476 ZEND_PARSE_PARAMETERS_START(1, 1)
1477 Z_PARAM_STR(str)
1478 ZEND_PARSE_PARAMETERS_END();
1479
1480 ION_CHECK(ion_writer_append_lob(obj->writer, (BYTE *) str->val, str->len));
1481 }
1482 static ZEND_METHOD(ion_Writer_Writer, finishLob)
1483 {
1484 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1485 OBJ_CHECK(obj);
1486
1487 ZEND_PARSE_PARAMETERS_NONE();
1488
1489 ION_CHECK(ion_writer_finish_lob(obj->writer));
1490 }
1491 static ZEND_METHOD(ion_Writer_Writer, startContainer)
1492 {
1493 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1494 OBJ_CHECK(obj);
1495
1496 zend_object *typ_obj;
1497 ZEND_PARSE_PARAMETERS_START(1, 1)
1498 Z_PARAM_OBJ_OF_CLASS(typ_obj, ce_Type)
1499 ZEND_PARSE_PARAMETERS_END();
1500
1501 ION_CHECK(ion_writer_start_container(obj->writer, ion_type_from_enum(typ_obj)));
1502 }
1503 static ZEND_METHOD(ion_Writer_Writer, finishContainer)
1504 {
1505 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1506 OBJ_CHECK(obj);
1507
1508 ZEND_PARSE_PARAMETERS_NONE();
1509
1510 ION_CHECK(ion_writer_finish_container(obj->writer));
1511 }
1512 static ZEND_METHOD(ion_Writer_Writer, writeFieldName)
1513 {
1514 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1515 OBJ_CHECK(obj);
1516
1517 zend_object *sym_obj;
1518 zend_string *sym_str;
1519 ZEND_PARSE_PARAMETERS_START(1, 1)
1520 Z_PARAM_OBJ_OF_CLASS_OR_STR(sym_obj, ce_Symbol, sym_str);
1521 ZEND_PARSE_PARAMETERS_END();
1522
1523 if (sym_str) {
1524 ION_STRING is;
1525 ION_CHECK(ion_writer_write_field_name(obj->writer, ion_string_from_zend(&is, sym_str)));
1526 } else {
1527 php_ion_symbol *sym = php_ion_obj(symbol, sym_obj);
1528 PTR_CHECK(sym);
1529 ION_CHECK(ion_writer_write_field_name_symbol(obj->writer, &sym->sym));
1530 }
1531 }
1532 static ZEND_METHOD(ion_Writer_Writer, writeAnnotation)
1533 {
1534 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1535 OBJ_CHECK(obj);
1536
1537 zval *args;
1538 unsigned argc;
1539 ZEND_PARSE_PARAMETERS_START(1, -1)
1540 Z_PARAM_VARIADIC('+', args, argc);
1541 ZEND_PARSE_PARAMETERS_END();
1542
1543 for (unsigned i = 0; i < argc; ++i) {
1544 switch (Z_TYPE(args[i])) {
1545 case IS_STRING: ;
1546 ION_STRING is;
1547 ION_CHECK(ion_writer_add_annotation(obj->writer, ion_string_from_zend(&is, Z_STR(args[i]))));
1548 break;
1549
1550 case IS_OBJECT:
1551 ION_CHECK(ion_writer_add_annotation_symbol(obj->writer, &php_ion_obj(symbol, Z_OBJ(args[i]))->sym));
1552 break;
1553 }
1554 }
1555 }
1556 static ZEND_METHOD(ion_Writer_Writer, getDepth)
1557 {
1558 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1559 OBJ_CHECK(obj);
1560
1561 ZEND_PARSE_PARAMETERS_NONE();
1562
1563 SIZE depth;
1564 ION_CHECK(ion_writer_get_depth(obj->writer, &depth));
1565 RETURN_LONG(depth);
1566 }
1567 static ZEND_METHOD(ion_Writer_Writer, flush)
1568 {
1569 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1570 OBJ_CHECK(obj);
1571
1572 ZEND_PARSE_PARAMETERS_NONE();
1573
1574 SIZE flushed;
1575 ION_CHECK(ion_writer_flush(obj->writer, &flushed));
1576 RETURN_LONG(flushed);
1577 }
1578 static ZEND_METHOD(ion_Writer_Writer, finish)
1579 {
1580 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1581 OBJ_CHECK(obj);
1582
1583 ZEND_PARSE_PARAMETERS_NONE();
1584
1585 SIZE flushed;
1586 ION_CHECK(ion_writer_finish(obj->writer, &flushed));
1587 RETURN_LONG(flushed);
1588 }
1589 static ZEND_METHOD(ion_Writer_Buffer_Writer, __construct)
1590 {
1591 _ion_Writer_Writer___construct(false, INTERNAL_FUNCTION_PARAM_PASSTHRU);
1592 }
1593 static ZEND_METHOD(ion_Writer_Buffer_Writer, getBuffer)
1594 {
1595 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1596 OBJ_CHECK(obj);
1597
1598 ZEND_PARSE_PARAMETERS_NONE();
1599
1600 RETVAL_STR(php_ion_writer_buffer_copy(obj));
1601 }
1602 static ZEND_METHOD(ion_Writer_Buffer_Writer, resetBuffer)
1603 {
1604 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1605 OBJ_CHECK(obj);
1606
1607 ZEND_PARSE_PARAMETERS_NONE();
1608
1609 php_ion_writer_buffer_reset(obj);
1610 }
1611 static ZEND_METHOD(ion_Writer_Stream_Writer, __construct)
1612 {
1613 _ion_Writer_Writer___construct(true, INTERNAL_FUNCTION_PARAM_PASSTHRU);
1614 }
1615 static ZEND_METHOD(ion_Writer_Stream_Writer, getStream)
1616 {
1617 php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
1618 OBJ_CHECK(obj);
1619
1620 ZEND_PARSE_PARAMETERS_NONE();
1621 PTR_CHECK(obj->stream.ptr);
1622
1623 GC_ADDREF(obj->stream.ptr->res);
1624 RETURN_RES(obj->stream.ptr->res);
1625 }
1626
1627 static ZEND_METHOD(ion_Serializer_Serializer, __construct)
1628 {
1629 php_ion_serializer *obj = php_ion_obj(serializer, Z_OBJ_P(ZEND_THIS));
1630 PTR_CHECK(obj);
1631
1632 obj->call_magic = true;
1633
1634 ZEND_PARSE_PARAMETERS_START(0, 3)
1635 Z_PARAM_OPTIONAL
1636 Z_PARAM_BOOL(obj->multi_seq)
1637 Z_PARAM_BOOL(obj->call_magic)
1638 Z_PARAM_STR_OR_NULL(obj->call_custom)
1639 ZEND_PARSE_PARAMETERS_END();
1640
1641 php_ion_serializer_ctor(obj);
1642 }
1643 static ZEND_METHOD(ion_Serializer_Serializer, serialize)
1644 {
1645 zend_object *obj = Z_OBJ_P(ZEND_THIS);
1646
1647 zval *data;
1648 zend_object *zo_wri = NULL;
1649 zend_array *za_named = NULL;
1650 ZEND_PARSE_PARAMETERS_START(1, 2)
1651 Z_PARAM_ZVAL(data)
1652 Z_PARAM_OPTIONAL
1653 Z_PARAM_PROLOGUE(0, 0)
1654 if (!zend_parse_arg_obj(_arg, &zo_wri, ce_Writer, true)) {
1655 if (!zend_parse_arg_array_ht(_arg, &za_named, false, false, false)) {
1656 _error_code = ZPP_ERROR_WRONG_ARG;
1657 _error = "of type array or \\ion\\Writer";
1658 break;
1659 }
1660 zo_wri = create_ion_Writer_Writer(ce_Writer_Buffer_Writer);
1661 call_constructor(zo_wri, 0, NULL, za_named);
1662 ION_CATCH(OBJ_RELEASE(zo_wri));
1663 }
1664 ZEND_PARSE_PARAMETERS_END();
1665
1666 php_ion_serializer *ser = php_ion_obj(serializer, obj);
1667 ser->wri = zo_wri;
1668 php_ion_serialize(ser, data, return_value);
1669 ser->wri = NULL;
1670
1671 if (za_named) {
1672 OBJ_RELEASE(zo_wri);
1673 }
1674 }
1675 static ZEND_FUNCTION(ion_serialize)
1676 {
1677 zval *data;
1678 zend_object *zo_ser = NULL;
1679 zend_array *za_named = NULL;
1680 ZEND_PARSE_PARAMETERS_START(1, 2)
1681 Z_PARAM_ZVAL(data)
1682 Z_PARAM_OPTIONAL
1683 Z_PARAM_PROLOGUE(0, 0)
1684 if (!zend_parse_arg_obj(_arg, &zo_ser, ce_Serializer, true)) {
1685 if (!zend_parse_arg_array_ht(_arg, &za_named, false, false, false)) {
1686 _error_code = ZPP_ERROR_WRONG_ARG;
1687 _error = "of type array or \\ion\\Writer";
1688 break;
1689 }
1690 zo_ser = create_ion_Serializer_Serializer(NULL);
1691 call_constructor(zo_ser, 0, NULL, za_named);
1692 ION_CATCH(OBJ_RELEASE(zo_ser));
1693 }
1694 ZEND_PARSE_PARAMETERS_END();
1695
1696 if (!zo_ser || zo_ser->ce == ce_Serializer_Serializer) {
1697 // default, fast path
1698 php_ion_serialize(php_ion_obj(serializer, zo_ser), data, return_value);
1699 } else {
1700 zend_call_method_with_1_params(zo_ser, NULL, NULL, "serialize", return_value, data);
1701 }
1702
1703 if (za_named) {
1704 OBJ_RELEASE(zo_ser);
1705 }
1706 }
1707
1708 static ZEND_METHOD(ion_Unserializer_Unserializer, __construct)
1709 {
1710 php_ion_unserializer *obj = php_ion_obj(unserializer, Z_OBJ_P(ZEND_THIS));
1711 PTR_CHECK(obj);
1712
1713 obj->call_magic = true;
1714
1715 ZEND_PARSE_PARAMETERS_START(0, 3)
1716 Z_PARAM_OPTIONAL
1717 Z_PARAM_BOOL(obj->multi_seq)
1718 Z_PARAM_BOOL(obj->call_magic)
1719 Z_PARAM_STR_OR_NULL(obj->call_custom)
1720 ZEND_PARSE_PARAMETERS_END();
1721
1722 php_ion_unserializer_ctor(obj);
1723 }
1724 static ZEND_METHOD(ion_Unserializer_Unserializer, unserialize)
1725 {
1726 zval *data;
1727 ZEND_PARSE_PARAMETERS_START(1, 1)
1728 Z_PARAM_ZVAL(data)
1729 ZEND_PARSE_PARAMETERS_END();
1730
1731 php_ion_unserialize(php_ion_obj(unserializer, Z_OBJ_P(ZEND_THIS)), data, return_value);
1732 }
1733 static ZEND_FUNCTION(ion_unserialize)
1734 {
1735 zval *data;
1736 zend_object *zo_ser = NULL;
1737 zend_array *za_named = NULL;
1738 ZEND_PARSE_PARAMETERS_START(1, 2)
1739 Z_PARAM_ZVAL(data)
1740 Z_PARAM_OPTIONAL
1741 Z_PARAM_PROLOGUE(0, 0)
1742 if (!zend_parse_arg_obj(_arg, &zo_ser, ce_Unserializer, true)) {
1743 if (!zend_parse_arg_array_ht(_arg, &za_named, false, false, false)) {
1744 _error_code = ZPP_ERROR_WRONG_ARG;
1745 _error = "of type array of \\ion\\Unserializer";
1746 break;
1747 }
1748 zo_ser = create_ion_Unserializer_Unserializer(NULL);
1749 call_constructor(zo_ser, 0, NULL, za_named);
1750 ION_CATCH(OBJ_RELEASE(zo_ser));
1751 }
1752 ZEND_PARSE_PARAMETERS_END();
1753
1754 if (!zo_ser || zo_ser->ce == ce_Unserializer_Unserializer) {
1755 // default, fast path
1756 php_ion_unserialize(php_ion_obj(unserializer, zo_ser), data, return_value);
1757 } else {
1758 zend_call_method_with_1_params(zo_ser, NULL, NULL, "unserialize", return_value, data);
1759 }
1760
1761 if (za_named) {
1762 OBJ_RELEASE(zo_ser);
1763 }
1764 }
1765
1766 PHP_RINIT_FUNCTION(ion)
1767 {
1768 #if defined(ZTS) && defined(COMPILE_DL_ION)
1769 ZEND_TSRMLS_CACHE_UPDATE();
1770 #endif
1771
1772 php_ion_globals_symbols_init();
1773 php_ion_globals_serializer_init();
1774 php_ion_globals_unserializer_init();
1775 return SUCCESS;
1776 }
1777
1778 PHP_RSHUTDOWN_FUNCTION(ion)
1779 {
1780 php_ion_globals_unserializer_dtor();
1781 php_ion_globals_serializer_dtor();
1782 php_ion_globals_symbols_dtor();
1783 return SUCCESS;
1784 }
1785
1786 #define ZEND_ARG_VARIADIC_OBJ_TYPE_MASK(pass_by_ref, name, classname, type_mask, default_value) \
1787 { #name, ZEND_TYPE_INIT_CLASS_CONST_MASK(#classname, ((type_mask) | _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1, 0))), default_value },
1788 #include "ion_arginfo.h"
1789
1790 // spl_iterators.h includes ext/pcre/php_pcre.h which might not find pcre2.h
1791 extern PHPAPI zend_class_entry *spl_ce_RecursiveIterator;
1792
1793 PHP_MINIT_FUNCTION(ion)
1794 {
1795 // true globals
1796 if (SUCCESS != g_sym_init()) {
1797 return FAILURE;
1798 }
1799 g_intern_str_init();
1800
1801 // Catalog
1802 php_ion_register(catalog, Catalog, zend_ce_countable);
1803
1804 // Decimal
1805 php_ion_register(decimal, Decimal);
1806 php_ion_register(decimal_ctx, Decimal_Context);
1807 ce_Decimal_Context_Rounding = register_class_ion_Decimal_Context_Rounding();
1808
1809 // Exception
1810 ce_Exception = register_class_ion_Exception(zend_ce_exception);
1811
1812 // LOB
1813 ce_LOB = register_class_ion_LOB();
1814
1815 // Reader
1816 ce_Reader = register_class_ion_Reader(spl_ce_RecursiveIterator);
1817 php_ion_register(reader, Reader_Reader, ce_Reader);
1818 ce_Reader_Buffer = register_class_ion_Reader_Buffer(ce_Reader);
1819 ce_Reader_Buffer_Reader = register_class_ion_Reader_Buffer_Reader(ce_Reader_Reader, ce_Reader_Buffer);
1820 ce_Reader_Stream = register_class_ion_Reader_Stream(ce_Reader);
1821 ce_Reader_Stream_Reader = register_class_ion_Reader_Stream_Reader(ce_Reader_Reader, ce_Reader_Stream);
1822
1823 // Serializer
1824 ce_Serializer = register_class_ion_Serializer();
1825 php_ion_register(serializer, Serializer_Serializer, ce_Serializer);
1826
1827 // Symbol
1828 php_ion_register(symbol, Symbol);
1829 oh_Symbol.compare = php_ion_symbol_zval_compare;
1830 php_ion_register(symbol_iloc, Symbol_ImportLocation);
1831 php_ion_register(symbol_table, Symbol_Table);
1832 ce_Symbol_Table->create_object = NULL;
1833 ce_Symbol_Table_Local = register_class_ion_Symbol_Table_Local(ce_Symbol_Table);
1834 ce_Symbol_Table_Local->create_object = create_ion_Symbol_Table;
1835 ce_Symbol_Table_Shared = register_class_ion_Symbol_Table_Shared(ce_Symbol_Table);
1836 ce_Symbol_Table_Shared->create_object = create_ion_Symbol_Table;
1837 ce_Symbol_Enum = register_class_ion_Symbol_Enum();
1838 ce_Symbol_Table_System = register_class_ion_Symbol_System(ce_Symbol_Enum);
1839 ce_Symbol_Table_PHP = register_class_ion_Symbol_PHP(ce_Symbol_Enum);
1840
1841 // Timestamp
1842 ce_Timestamp = register_class_ion_Timestamp(php_date_get_date_ce());
1843 ce_Timestamp_Format = register_class_ion_Timestamp_Format();
1844 ce_Timestamp_Precision = register_class_ion_Timestamp_Precision();
1845
1846 // Type
1847 ce_Type = register_class_ion_Type();
1848
1849 // Writer
1850 ce_Writer = register_class_ion_Writer();
1851 php_ion_register(writer, Writer_Writer, ce_Writer);
1852 ce_Writer_Buffer = register_class_ion_Writer_Buffer(ce_Writer);
1853 ce_Writer_Buffer_Writer = register_class_ion_Writer_Buffer_Writer(ce_Writer_Writer, ce_Writer_Buffer);
1854 ce_Writer_Stream = register_class_ion_Writer_Stream(ce_Writer);
1855 ce_Writer_Stream_Writer = register_class_ion_Writer_Stream_Writer(ce_Writer_Writer, ce_Writer_Stream);
1856
1857 // Unserializer
1858 ce_Unserializer = register_class_ion_Unserializer();
1859 php_ion_register(unserializer, Unserializer_Unserializer, ce_Unserializer);
1860
1861 return SUCCESS;
1862 }
1863
1864 PHP_MSHUTDOWN_FUNCTION(ion)
1865 {
1866 g_sym_dtor();
1867 return SUCCESS;
1868 }
1869
1870 PHP_MINFO_FUNCTION(ion)
1871 {
1872 php_info_print_table_start();
1873 php_info_print_table_header(2, "ion support", "enabled");
1874 php_info_print_table_row(2, "ion version", PHP_ION_VERSION);
1875 php_info_print_table_row(2, "ion-c version", "unknown");
1876 php_info_print_table_end();
1877 }
1878
1879 PHP_GINIT_FUNCTION(ion)
1880 {
1881 memset(ion_globals, 0, sizeof(*ion_globals));
1882
1883 php_ion_decimal_ctx_init_max(&ion_globals->decimal.ctx, DEC_ROUND_HALF_EVEN);
1884 php_ion_decimal_from_zend_long(&ion_globals->decimal.zend_max, &ion_globals->decimal.ctx, ZEND_LONG_MAX);
1885 php_ion_decimal_from_zend_long(&ion_globals->decimal.zend_min, &ion_globals->decimal.ctx, ZEND_LONG_MIN);
1886 }
1887
1888 PHP_GSHUTDOWN_FUNCTION(ion)
1889 {
1890 }
1891
1892 static zend_module_dep ion_module_deps[] = {
1893 ZEND_MOD_REQUIRED("date")
1894 ZEND_MOD_REQUIRED("spl")
1895 ZEND_MOD_END
1896 };
1897
1898 zend_module_entry ion_module_entry = {
1899 STANDARD_MODULE_HEADER_EX,
1900 NULL,
1901 ion_module_deps,
1902 "ion", /* Extension name */
1903 ext_functions, /* zend_function_entry */
1904 PHP_MINIT(ion), /* PHP_MINIT - Module initialization */
1905 PHP_MSHUTDOWN(ion), /* PHP_MSHUTDOWN - Module shutdown */
1906 PHP_RINIT(ion), /* PHP_RINIT - Request initialization */
1907 PHP_RSHUTDOWN(ion), /* PHP_RSHUTDOWN - Request shutdown */
1908 PHP_MINFO(ion), /* PHP_MINFO - Module info */
1909 PHP_ION_VERSION, /* Version */
1910 ZEND_MODULE_GLOBALS(ion),
1911 PHP_GINIT(ion), /* PHP_GINIT */
1912 PHP_GSHUTDOWN(ion), /* PHP_GSHUTDOWN */
1913 NULL,
1914 STANDARD_MODULE_PROPERTIES_EX
1915 };
1916
1917 #ifdef COMPILE_DL_ION
1918 # ifdef ZTS
1919 ZEND_TSRMLS_CACHE_DEFINE()
1920 # endif
1921 ZEND_GET_MODULE(ion)
1922 #endif