Read string data and return as std::string
| 100 | |
| 101 | /// Read string data and return as std::string |
| 102 | inline std::string read_string_data(ReadContext &ctx) { |
| 103 | // Read size with encoding using varuint36small |
| 104 | uint64_t size_with_encoding = ctx.read_var_uint36_small(ctx.error()); |
| 105 | |
| 106 | // Extract size and encoding from lower 2 bits |
| 107 | uint64_t length = size_with_encoding >> 2; |
| 108 | StringEncoding encoding = |
| 109 | static_cast<StringEncoding>(size_with_encoding & 0x3); |
| 110 | |
| 111 | if (length == 0) { |
| 112 | return std::string(); |
| 113 | } |
| 114 | |
| 115 | if (FORY_PREDICT_FALSE(length > std::numeric_limits<uint32_t>::max())) { |
| 116 | ctx.set_error(Error::invalid_data("String length exceeds uint32 range")); |
| 117 | return std::string(); |
| 118 | } |
| 119 | const uint32_t length_u32 = static_cast<uint32_t>(length); |
| 120 | |
| 121 | if (FORY_PREDICT_FALSE( |
| 122 | !ctx.buffer().ensure_readable(length_u32, ctx.error()))) { |
| 123 | return std::string(); |
| 124 | } |
| 125 | |
| 126 | Buffer &buffer = ctx.buffer(); |
| 127 | const uint8_t *data = buffer.data() + buffer.reader_index(); |
| 128 | |
| 129 | // Handle different encodings |
| 130 | switch (encoding) { |
| 131 | case StringEncoding::LATIN1: { |
| 132 | std::string result = latin1_to_utf8(data, length_u32); |
| 133 | buffer.unsafe_increase_reader_index(length_u32); |
| 134 | return result; |
| 135 | } |
| 136 | case StringEncoding::UTF16: { |
| 137 | if (FORY_PREDICT_FALSE((length_u32 & 1) != 0)) { |
| 138 | ctx.set_error(Error::invalid_data("UTF-16 length must be even")); |
| 139 | return std::string(); |
| 140 | } |
| 141 | std::vector<uint16_t> utf16_chars(length_u32 / 2); |
| 142 | std::memcpy(utf16_chars.data(), data, length_u32); |
| 143 | buffer.unsafe_increase_reader_index(length_u32); |
| 144 | return utf16_to_utf8(utf16_chars.data(), utf16_chars.size()); |
| 145 | } |
| 146 | case StringEncoding::UTF8: { |
| 147 | std::string result(reinterpret_cast<const char *>(data), length_u32); |
| 148 | buffer.unsafe_increase_reader_index(length_u32); |
| 149 | return result; |
| 150 | } |
| 151 | default: |
| 152 | ctx.set_error( |
| 153 | Error::encoding_error("Unknown string encoding: " + |
| 154 | std::to_string(static_cast<int>(encoding)))); |
| 155 | return std::string(); |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | /// Read string data and return as std::u16string |