Skip to content

Commit 31df535

Browse files
committed
Drop array pack/unpack functions
Very unlikely to need these, and I think the inconvenience of being made to use a buffer for this is probably worth the trade of not maintaining an extra 50 functions. In any case, writing a large array in particular probably ought to use a reused buffer to avoid unnecessary allocations.
1 parent f1c4206 commit 31df535

File tree

1 file changed

+16
-81
lines changed

1 file changed

+16
-81
lines changed

classes/Types.cpp

Lines changed: 16 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,11 @@ ZEND_ARG_OBJ_INFO(0, buffer, pmmp\\encoding\\ByteBufferReader, 0)
3535
ZEND_ARG_TYPE_INFO(0, count, IS_LONG, 0)
3636
ZEND_END_ARG_INFO()
3737

38-
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_unpack_array, 0, 2, IS_ARRAY, 0)
39-
ZEND_ARG_TYPE_INFO(0, bytes, IS_STRING, 0)
40-
ZEND_ARG_TYPE_INFO(0, count, IS_LONG, 0)
41-
ZEND_END_ARG_INFO()
42-
4338
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_write_array, 0, 2, IS_VOID, 0)
4439
ZEND_ARG_OBJ_INFO(0, buffer, pmmp\\encoding\\ByteBufferWriter, 0)
4540
ZEND_ARG_ARRAY_INFO(0, values, 0)
4641
ZEND_END_ARG_INFO()
4742

48-
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pack_array, 0, 2, IS_STRING, 0)
49-
ZEND_ARG_ARRAY_INFO(0, values, 0)
50-
ZEND_END_ARG_INFO()
5143

5244
#if PHP_VERSION_ID >= 80400
5345
static const char* read_zend_long_array_doc_comment = "/**\n\t * @return int[]\n\t * @phpstan-return list<int>\n\t * @throws DataDecodeException\n\t */";
@@ -136,21 +128,6 @@ void ZEND_FASTCALL zif_unpackType(INTERNAL_FUNCTION_PARAMETERS) {
136128
template<typename TValue>
137129
using readTypeArrayFunc_t = bool (*) (unsigned char* bytes, size_t used, size_t& offset, size_t count, std::vector<TValue>& resultArray);
138130

139-
template<typename TValue, readTypeArrayFunc_t<TValue> readTypeArray, typename TZendValue>
140-
inline void readTypeArrayCommon(INTERNAL_FUNCTION_PARAMETERS, byte_buffer_reader_t& reader, zend_long zcount) {
141-
if (zcount < 1) {
142-
zend_value_error("Count must be at least 1");
143-
return;
144-
}
145-
size_t count = static_cast<size_t>(zcount);
146-
147-
std::vector<TValue> resultArray;
148-
auto bytes = reinterpret_cast<unsigned char*>(ZSTR_VAL(reader.buffer));
149-
if (readTypeArray(bytes, ZSTR_LEN(reader.buffer), reader.offset, count, resultArray)) {
150-
assignZvalArray(return_value, resultArray, std::type_identity<TZendValue>{});
151-
}
152-
}
153-
154131
template<typename TValue, readTypeArrayFunc_t<TValue> readTypeArray, typename TZendValue>
155132
void ZEND_FASTCALL zif_readTypeArray(INTERNAL_FUNCTION_PARAMETERS) {
156133
zval* object_zv;
@@ -164,20 +141,17 @@ void ZEND_FASTCALL zif_readTypeArray(INTERNAL_FUNCTION_PARAMETERS) {
164141

165142
object = READER_FROM_ZVAL(object_zv);
166143

167-
readTypeArrayCommon<TValue, readTypeArray, TZendValue>(INTERNAL_FUNCTION_PARAM_PASSTHRU, object->reader, zcount);
168-
}
169-
170-
template<typename TValue, readTypeArrayFunc_t<TValue> readTypeArray, typename TZendValue>
171-
void ZEND_FASTCALL zif_unpackTypeArray(INTERNAL_FUNCTION_PARAMETERS) {
172-
zend_long zcount;
173-
byte_buffer_reader_t reader = { 0 };
174-
175-
ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 2, 2)
176-
Z_PARAM_STR(reader.buffer)
177-
Z_PARAM_LONG(zcount)
178-
ZEND_PARSE_PARAMETERS_END_EX(return);
144+
if (zcount < 1) {
145+
zend_value_error("Count must be at least 1");
146+
return;
147+
}
148+
size_t count = static_cast<size_t>(zcount);
179149

180-
readTypeArrayCommon<TValue, readTypeArray, TZendValue>(INTERNAL_FUNCTION_PARAM_PASSTHRU, reader, zcount);
150+
std::vector<TValue> resultArray;
151+
auto bytes = reinterpret_cast<unsigned char*>(ZSTR_VAL(object->reader.buffer));
152+
if (readTypeArray(bytes, ZSTR_LEN(object->reader.buffer), object->reader.offset, count, resultArray)) {
153+
assignZvalArray(return_value, resultArray, std::type_identity<TZendValue>{});
154+
}
181155
}
182156

183157
//this must be reimplemented for any new zend types handled, because ZPP macros can't be easily templated
@@ -320,21 +294,6 @@ bool typeHashTableToArray(HashTable* valueArrayHt, std::vector<TValue>& valueArr
320294
template<typename TValue>
321295
using writeTypeArrayFunc_t = void (*)(zend_string*& buffer, size_t& offset, std::vector<TValue>& value);
322296

323-
template<typename TValue, writeTypeArrayFunc_t<TValue> writeTypeFunc, typename TZendValue>
324-
static inline bool writeTypeArrayCommon(INTERNAL_FUNCTION_PARAMETERS, byte_buffer_writer_t& writer, HashTable* valueArrayHt) {
325-
std::vector<TValue> valueArray;
326-
327-
if (!typeHashTableToArray(valueArrayHt, valueArray, std::type_identity<TZendValue>{})) {
328-
return false;
329-
}
330-
331-
writeTypeFunc(writer.buffer, writer.offset, valueArray);
332-
if (writer.offset > writer.used) {
333-
writer.used = writer.offset;
334-
}
335-
return true;
336-
}
337-
338297
template<typename TValue, writeTypeArrayFunc_t<TValue> writeTypeFunc, typename TZendValue>
339298
void ZEND_FASTCALL zif_writeTypeArray(INTERNAL_FUNCTION_PARAMETERS) {
340299
byte_buffer_writer_zend_object* object;
@@ -348,27 +307,16 @@ void ZEND_FASTCALL zif_writeTypeArray(INTERNAL_FUNCTION_PARAMETERS) {
348307

349308
object = WRITER_FROM_ZVAL(objectZv);
350309

351-
writeTypeArrayCommon<TValue, writeTypeFunc, TZendValue>(INTERNAL_FUNCTION_PARAM_PASSTHRU, object->writer, valueArrayHt);
352-
}
353-
354-
template<typename TValue, writeTypeArrayFunc_t<TValue> writeTypeFunc, typename TZendValue>
355-
void ZEND_FASTCALL zif_packTypeArray(INTERNAL_FUNCTION_PARAMETERS) {
356-
byte_buffer_writer_t writer = { 0 };
357-
HashTable* valueArrayHt;
358-
359-
ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_THROW, 1, 1)
360-
Z_PARAM_ARRAY_HT(valueArrayHt)
361-
ZEND_PARSE_PARAMETERS_END();
362-
363-
writer.buffer = zend_empty_string;
310+
std::vector<TValue> valueArray;
364311

365-
if (!writeTypeArrayCommon<TValue, writeTypeFunc, TZendValue>(INTERNAL_FUNCTION_PARAM_PASSTHRU, writer, valueArrayHt)) {
366-
//extracting args from the array may have failed
312+
if (!typeHashTableToArray(valueArrayHt, valueArray, std::type_identity<TZendValue>{})) {
367313
return;
368314
}
369315

370-
RETVAL_STRINGL(ZSTR_VAL(writer.buffer), writer.used);
371-
zend_string_release_ex(writer.buffer, 0);
316+
writeTypeFunc(object->writer.buffer, object->writer.offset, valueArray);
317+
if (object->writer.offset > object->writer.used) {
318+
object->writer.used = object->writer.offset;
319+
}
372320
}
373321

374322
ZEND_NAMED_FUNCTION(pmmp_encoding_private_constructor) {
@@ -424,24 +372,11 @@ ZEND_NAMED_FUNCTION(pmmp_encoding_private_constructor) {
424372
arginfo_read_array, \
425373
read_##zend_type##_array_doc_comment \
426374
) \
427-
BC_ZEND_RAW_FENTRY_WITH_DOC_COMMENT( \
428-
"unpack" zend_name "Array", \
429-
(zif_unpackTypeArray<native_type, read_complex_type, zend_type>), \
430-
arginfo_unpack_array, \
431-
read_##zend_type##_array_doc_comment \
432-
) \
433-
\
434375
BC_ZEND_RAW_FENTRY_WITH_DOC_COMMENT( \
435376
"write" zend_name "Array", \
436377
(zif_writeTypeArray<native_type, write_complex_type, zend_type>), \
437378
arginfo_write_array, \
438379
write_##zend_type##_array_doc_comment \
439-
) \
440-
BC_ZEND_RAW_FENTRY_WITH_DOC_COMMENT( \
441-
"pack" zend_name "Array", \
442-
(zif_packTypeArray<native_type, write_complex_type, zend_type>), \
443-
arginfo_pack_array, \
444-
write_##zend_type##_array_doc_comment \
445380
)
446381

447382
#define FIXED_TYPE_ARRAY_ENTRIES(zend_name, native_type, zend_type, byte_order) \

0 commit comments

Comments
 (0)