浏览代码

libobs/util: Add seeking support to array serializer

derrod 1 年之前
父节点
当前提交
dc4cba7427
共有 3 个文件被更改,包括 63 次插入1 次删除
  1. 10 0
      docs/sphinx/reference-libobs-util-serializers.rst
  2. 51 1
      libobs/util/array-serializer.c
  3. 2 0
      libobs/util/array-serializer.h

+ 10 - 0
docs/sphinx/reference-libobs-util-serializers.rst

@@ -95,6 +95,9 @@ Array Output Serializer
 
 Provides an output serializer used with dynamic arrays.
 
+.. versionchanged:: 30.2
+   Array output serializer now supports seeking.
+
 .. code:: cpp
 
    #include <util/array-serializer.h>
@@ -119,6 +122,13 @@ Array Output Serializer Functions
 
 ---------------------
 
+.. function:: void array_output_serializer_reset(struct array_output_data *data)
+
+   Resets serializer without freeing data.
+
+   .. versionadded:: 30.2
+
+---------------------
 
 File Input/Output Serializers
 =============================

+ 51 - 1
libobs/util/array-serializer.c

@@ -20,7 +20,23 @@
 static size_t array_output_write(void *param, const void *data, size_t size)
 {
 	struct array_output_data *output = param;
-	da_push_back_array(output->bytes, (uint8_t *)data, size);
+
+	if (output->cur_pos < output->bytes.num) {
+		size_t new_size = output->cur_pos + size;
+
+		if (new_size > output->bytes.num) {
+			darray_ensure_capacity(sizeof(uint8_t),
+					       &output->bytes.da, new_size);
+			output->bytes.num = new_size;
+		}
+
+		memcpy(output->bytes.array + output->cur_pos, data, size);
+		output->cur_pos += size;
+	} else {
+		da_push_back_array(output->bytes, (uint8_t *)data, size);
+		output->cur_pos += size;
+	}
+
 	return size;
 }
 
@@ -30,6 +46,33 @@ static int64_t array_output_get_pos(void *param)
 	return (int64_t)data->bytes.num;
 }
 
+static int64_t array_output_seek(void *param, int64_t offset,
+				 enum serialize_seek_type seek_type)
+{
+	struct array_output_data *output = param;
+
+	size_t new_pos = 0;
+
+	switch (seek_type) {
+	case SERIALIZE_SEEK_START:
+		new_pos = offset;
+		break;
+	case SERIALIZE_SEEK_CURRENT:
+		new_pos = output->cur_pos + offset;
+		break;
+	case SERIALIZE_SEEK_END:
+		new_pos = output->bytes.num - offset;
+		break;
+	}
+
+	if (new_pos > output->bytes.num)
+		return -1;
+
+	output->cur_pos = new_pos;
+
+	return (int64_t)new_pos;
+}
+
 void array_output_serializer_init(struct serializer *s,
 				  struct array_output_data *data)
 {
@@ -38,9 +81,16 @@ void array_output_serializer_init(struct serializer *s,
 	s->data = data;
 	s->write = array_output_write;
 	s->get_pos = array_output_get_pos;
+	s->seek = array_output_seek;
 }
 
 void array_output_serializer_free(struct array_output_data *data)
 {
 	da_free(data->bytes);
 }
+
+void array_output_serializer_reset(struct array_output_data *data)
+{
+	da_clear(data->bytes);
+	data->cur_pos = 0;
+}

+ 2 - 0
libobs/util/array-serializer.h

@@ -25,11 +25,13 @@ extern "C" {
 
 struct array_output_data {
 	DARRAY(uint8_t) bytes;
+	size_t cur_pos;
 };
 
 EXPORT void array_output_serializer_init(struct serializer *s,
 					 struct array_output_data *data);
 EXPORT void array_output_serializer_free(struct array_output_data *data);
+EXPORT void array_output_serializer_reset(struct array_output_data *data);
 
 #ifdef __cplusplus
 }