php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
PTR_CHECK(obj);
- zval *ref;
- ZEND_PARSE_PARAMETERS_START(1, 2)
- Z_PARAM_ZVAL(ref)
+ ZEND_PARSE_PARAMETERS_START(0, 1)
Z_PARAM_OPTIONAL
Z_PARAM_OBJ_OF_CLASS_OR_NULL(obj->opt, ce_Writer_Options)
ZEND_PARSE_PARAMETERS_END();
obj->type = BUFFER_WRITER;
- ZVAL_COPY(&obj->buffer.val, ref);
- zval_dtor(Z_REFVAL_P(ref));
-
php_ion_writer_ctor(obj);
}
static ZEND_METHOD(ion_Writer_Buffer_Writer, getBuffer)
ZEND_PARSE_PARAMETERS_NONE();
- RETVAL_STR(zend_string_dup(obj->buffer.str.s, 0));
+ RETVAL_STR_COPY(obj->buffer.str.s);
+}
+static ZEND_METHOD(ion_Writer_Buffer_Writer, resetBuffer)
+{
+ php_ion_writer *obj = php_ion_obj(writer, Z_OBJ_P(ZEND_THIS));
+ OBJ_CHECK(obj);
+
+ ZEND_PARSE_PARAMETERS_NONE();
+
+ php_ion_writer_buffer_reset(obj);
}
static ZEND_METHOD(ion_Writer_Stream_Writer, __construct)
{
namespace ion\Writer;
interface Buffer extends \ion\Writer {
public function getBuffer() : string;
+ public function resetBuffer() : void;
}
namespace ion\Writer\Buffer;
class Writer extends \ion\Writer\Writer implements \ion\Writer\Buffer {
- /** @param ref $buffer */
public function __construct(
- ?string &$buffer,
?\ion\Writer\Options $options = null,
) {}
- /**
- * @return string a _copy_ of $buffer passed to the constructor
- */
public function getBuffer() : string {}
+ public function resetBuffer() : void {}
}
namespace ion\Writer;
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 8cd99962a32b5321624d6cb043fb60ff13f93738 */
+ * Stub hash: aafe212ff9dd7fd15753fa5b6a3c127a51073241 */
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_ion_Symbol_Table_PHP, 0, 0, ion\\Symbol\\Table, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_ion_Writer_Buffer_getBuffer arginfo_class_ion_Symbol_Enum_toString
-ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ion_Writer_Buffer_Writer___construct, 0, 0, 1)
- ZEND_ARG_TYPE_INFO(1, buffer, IS_STRING, 1)
+#define arginfo_class_ion_Writer_Buffer_resetBuffer arginfo_class_ion_Reader_Reader_rewind
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ion_Writer_Buffer_Writer___construct, 0, 0, 0)
ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, options, ion\\Writer\\Options, 1, "null")
ZEND_END_ARG_INFO()
#define arginfo_class_ion_Writer_Buffer_Writer_getBuffer arginfo_class_ion_Symbol_Enum_toString
+#define arginfo_class_ion_Writer_Buffer_Writer_resetBuffer arginfo_class_ion_Reader_Reader_rewind
+
#define arginfo_class_ion_Writer_Stream_getStream arginfo_class_ion_Symbol_Table_Local___construct
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ion_Writer_Stream_Writer___construct, 0, 0, 1)
static ZEND_METHOD(ion_Writer_Writer, writeAll);
static ZEND_METHOD(ion_Writer_Buffer_Writer, __construct);
static ZEND_METHOD(ion_Writer_Buffer_Writer, getBuffer);
+static ZEND_METHOD(ion_Writer_Buffer_Writer, resetBuffer);
static ZEND_METHOD(ion_Writer_Stream_Writer, __construct);
static ZEND_METHOD(ion_Writer_Stream_Writer, getStream);
static ZEND_METHOD(ion_Serializer_PHP, __construct);
static const zend_function_entry class_ion_Writer_Buffer_methods[] = {
ZEND_ABSTRACT_ME_WITH_FLAGS(ion_Writer_Buffer, getBuffer, arginfo_class_ion_Writer_Buffer_getBuffer, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT)
+ ZEND_ABSTRACT_ME_WITH_FLAGS(ion_Writer_Buffer, resetBuffer, arginfo_class_ion_Writer_Buffer_resetBuffer, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT)
ZEND_FE_END
};
static const zend_function_entry class_ion_Writer_Buffer_Writer_methods[] = {
ZEND_ME(ion_Writer_Buffer_Writer, __construct, arginfo_class_ion_Writer_Buffer_Writer___construct, ZEND_ACC_PUBLIC)
ZEND_ME(ion_Writer_Buffer_Writer, getBuffer, arginfo_class_ion_Writer_Buffer_Writer_getBuffer, ZEND_ACC_PUBLIC)
+ ZEND_ME(ion_Writer_Buffer_Writer, resetBuffer, arginfo_class_ion_Writer_Buffer_Writer_resetBuffer, ZEND_ACC_PUBLIC)
ZEND_FE_END
};
*/
#include "php.h"
+#include "ext/standard/php_var.h"
#include "ext/date/php_date.h"
#if PHP_DEBUG
} type;
union {
struct {
- zval val;
smart_str str;
} buffer;
struct {
return IERR_OK;
}
-#define REF_STR() do { \
- ZVAL_NEW_STR(ref, obj->buffer.str.s); \
- GC_ADDREF(obj->buffer.str.s); \
-} while (0)
-
-#define NEW_REF_STR() do {\
- if (Z_STR_P(ref) != obj->buffer.str.s) { \
- zval_ptr_dtor(ref); \
- REF_STR(); \
- } \
-} while(0)
-
LOCAL void php_ion_writer_stream_init(php_ion_writer *obj, php_ion_writer_options *opt)
{
PTR_CHECK(obj->stream.ptr);
obj->stream.buf.length = opt ? opt->opt.allocation_page_size : 0x1000;
obj->stream.buf.value = emalloc(obj->stream.buf.length);
}
+
LOCAL void php_ion_writer_buffer_init(php_ion_writer *obj)
{
- zval *ref = &obj->buffer.val;
- ZVAL_DEREF(ref);
+ smart_str_alloc(&obj->buffer.str, 0, 0);
+ smart_str_0(&obj->buffer.str);
+}
+LOCAL void php_ion_writer_buffer_reset(php_ion_writer *obj)
+{
+ smart_str_free(&obj->buffer.str);
+ memset(&obj->buffer.str, 0, sizeof(obj->buffer.str));
smart_str_alloc(&obj->buffer.str, 0, 0);
smart_str_0(&obj->buffer.str);
- REF_STR();
}
LOCAL void php_ion_writer_buffer_grow(php_ion_writer *obj)
{
- zval *ref = &obj->buffer.val;
- ZVAL_DEREF(ref);
-
- switch (GC_REFCOUNT(obj->buffer.str.s)) {
- case 2:
- // nothing to do
- break;
- case 1:
- // we've been separated
- GC_ADDREF(obj->buffer.str.s);
- break;
- default:
- // we have to separate
- fprintf(stderr, "SEPARATE\n");
- obj->buffer.str.s = zend_string_dup(obj->buffer.str.s, 0);
- break;
- }
-
- zend_string *old = obj->buffer.str.s;
- GC_DELREF(old);
- smart_str_erealloc(&obj->buffer.str, obj->buffer.str.a << 1);
- if (old == obj->buffer.str.s) {
- GC_ADDREF(old);
- } else if(old == Z_STR_P(ref)) {
- ZVAL_NULL(ref);
+ if (GC_REFCOUNT(obj->buffer.str.s) > 1) {
+ zend_string *keep = obj->buffer.str.s;
+ obj->buffer.str.s = NULL;
+ smart_str_alloc(&obj->buffer.str, obj->buffer.str.a << 1, 0);
+ memcpy(obj->buffer.str.s->val, keep->val, keep->len + 1);
+ obj->buffer.str.s->len = keep->len;
+ smart_str_0(&obj->buffer.str);
+ zend_string_release(keep);
+ } else {
+ smart_str_erealloc(&obj->buffer.str, obj->buffer.str.a << 1);
}
-
- NEW_REF_STR();
}
LOCAL iERR php_ion_writer_buffer_handler(struct _ion_user_stream *user)
smart_str_0(&obj->buffer.str);
zend_string_release(obj->buffer.str.s);
}
- zval_ptr_dtor(&obj->buffer.val);
}
}
TEST
<?php
-$w = new ion\Writer\Buffer\Writer($buf,
- new ion\Writer\Options(outputBinary: true));
+$w = new ion\Writer\Buffer\Writer(new ion\Writer\Options(outputBinary: true));
$w->writeSymbol("local1");
$w->writeSymbol("local1");
$w->finish();
-foreach (str_split($buf, 8) as $line) {
+foreach (str_split($w->getBuffer(), 8) as $line) {
printf("%-26s", chunk_split(bin2hex($line), 2, " "));
foreach (str_split($line) as $byte) {
echo $byte >= ' ' && $byte <= '~' ? $byte : ".";
echo "\n";
$u = new ion\Unserializer\PHP(multiSequence: true);
-var_dump($u->unserialize($buf));
+var_dump($u->unserialize($w->getBuffer()));
?>
DONE
$c = new ion\Catalog;
$c->add(new ion\Symbol\Table\Shared("shared", 1, ["shared1", "shared2"]));
-$w = new ion\Writer\Buffer\Writer($buf,
- new ion\Writer\Options(catalog: $c, outputBinary: true));
+$w = new ion\Writer\Buffer\Writer(new ion\Writer\Options(catalog: $c, outputBinary: true));
$w->writeSymbol("shared1");
$w->writeSymbol("shared1");
$w->finish();
-foreach (str_split($buf, 8) as $line) {
+foreach (str_split($w->getBuffer(), 8) as $line) {
printf("%-26s", chunk_split(bin2hex($line), 2, " "));
foreach (str_split($line) as $byte) {
echo $byte >= ' ' && $byte <= '~' ? $byte : ".";
echo "\n";
$u = new ion\Unserializer\PHP(multiSequence: true);
-var_dump($s = $u->unserialize($buf));
+var_dump($s = $u->unserialize($w->getBuffer()));
foreach ($s as $sym) {
/** @var ion\Symbol $sym */
readerOptions: new ion\Reader\Options(
catalog: $c,
onContextChange: fn(ion\Reader $r) => print("on_context_change\n")));
-var_dump($u->unserialize($buf));
+var_dump($u->unserialize($w->getBuffer()));
?>
DONE
TEST
<?php
-$w = new ion\Writer\Buffer\Writer($buf);
-for ($i = 0; $i < 100; ++$i) $w->writeTypedNull(ion\Type::Int);
-var_dump($buf === $w->getBuffer());
+$w = new ion\Writer\Buffer\Writer;
+for ($i = 0; $i < 100; ++$i)
+ $w->writeTypedNull(ion\Type::Int);
+$w->flush();
+echo $w->getBuffer(),"\n";
+$w->resetBuffer();
+var_dump($w->getBuffer());
+$w->writeSymbol("bar");
$w->finish();
-echo $buf;
+var_dump($w->getBuffer());
?>
-
DONE
--EXPECTF--
TEST
-bool(true)
null.int%r( null.int)*%r
+string(0) ""
+string(3) "bar"
DONE