From 1916e6c4985f143d1d2e85cde31953e08de99d6b Mon Sep 17 00:00:00 2001 From: Li-Xiang-Ideal <54926635+Li-Xiang-Ideal@users.noreply.github.com> Date: Fri, 30 Jan 2026 11:49:57 +0800 Subject: [PATCH] Add in-place data construction for Encoder Add functions to append new data directly to the end of the buffer, improving efficiency by avoiding intermediate copies. CHANGES - Add `generate_back_ustr()` for constructing data directly at the end of buffer using indices - Add `transform_back_ustr()` for transforming source data and inserting at buffer end - Add common buffer management functions: `size()`, `reserve()`, `resize()` --- wxf_parser.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/wxf_parser.h b/wxf_parser.h index fc3a544..c072212 100644 --- a/wxf_parser.h +++ b/wxf_parser.h @@ -179,6 +179,11 @@ namespace WXF_PARSER { // move from existing buffer Encoder(std::vector&& buf) : buffer(std::move(buf)) {} + const size_t size() const { return buffer.size(); } + void reserve(const size_t new_size) { buffer.reserve(new_size); } + void resize(const size_t new_size) { buffer.resize(new_size); } + void resize(const size_t new_size, const uint8_t val) { buffer.resize(new_size, val); } + // push ustr directly Encoder& push_ustr(const std::vector& str) { buffer.insert(buffer.end(), str.begin(), str.end()); return *this; } Encoder& push_ustr(const std::string_view str) { @@ -193,6 +198,30 @@ namespace WXF_PARSER { buffer.insert(buffer.end(), (uint8_t*)start, (uint8_t*)end); return *this; } + // generate data as ustr in the back + template + Encoder& generate_back_ustr(const size_t len, F&& func) { + static_assert(std::is_invocable_r_v, "func should be callable with size_t and return T"); + size_t old_size = buffer.size(); + buffer.resize(old_size + len * sizeof(T)); + T* data_ptr = (T*)(buffer.data() + old_size); + for (size_t i = 0; i < len; i++) { + data_ptr[i] = func(i); + } + return *this; + } + + // generate transformed data as ustr in the back + template + Encoder& transform_back_ustr(const T2* src_ptr, const size_t len, F&& func) { + static_assert(std::is_invocable_r_v, "func should be callable with T2 and return T1"); + size_t old_size = buffer.size(); + buffer.resize(old_size + len * sizeof(T1)); + T1* data_ptr = (T1*)(buffer.data() + old_size); + std::transform(src_ptr, src_ptr + len, data_ptr, func); + return *this; + } + Encoder& push_integer(const int64_t val) { auto num_type = minimal_signed_bits(val); switch (num_type) {