| 237 | MetaStringTable::MetaStringTable() = default; |
| 238 | |
| 239 | Result<std::string, Error> |
| 240 | MetaStringTable::read_string(Buffer &buffer, const MetaStringDecoder &decoder) { |
| 241 | Error error; |
| 242 | // Header is encoded with VarUint32Small7 on Java side, but wire |
| 243 | // format is still standard varuint32. |
| 244 | uint32_t header = buffer.read_var_uint32(error); |
| 245 | if (FORY_PREDICT_FALSE(!error.ok())) { |
| 246 | return Unexpected(std::move(error)); |
| 247 | } |
| 248 | uint32_t len_or_id = header >> 1; |
| 249 | bool is_ref = (header & 0x1u) != 0; |
| 250 | |
| 251 | if (is_ref) { |
| 252 | if (len_or_id == 0 || len_or_id > entries_.size()) { |
| 253 | return Unexpected(Error::invalid_data( |
| 254 | "Invalid meta string reference id: " + std::to_string(len_or_id))); |
| 255 | } |
| 256 | return entries_[len_or_id - 1].decoded; |
| 257 | } |
| 258 | |
| 259 | constexpr uint32_t k_small_threshold = 16; |
| 260 | uint32_t len = len_or_id; |
| 261 | |
| 262 | std::vector<uint8_t> bytes; |
| 263 | MetaEncoding encoding = MetaEncoding::UTF8; |
| 264 | |
| 265 | if (len > k_small_threshold) { |
| 266 | // Big string layout in Java MetaStringResolver: |
| 267 | // header (len<<1 | flags) + hash_code(int64) + data[len] |
| 268 | // The original encoding is not transmitted explicitly. For cross-language |
| 269 | // purposes we treat the payload bytes as UTF8 and let callers handle any |
| 270 | // higher-level semantics. |
| 271 | int64_t hash_code = buffer.read_int64(error); |
| 272 | if (FORY_PREDICT_FALSE(!error.ok())) { |
| 273 | return Unexpected(std::move(error)); |
| 274 | } |
| 275 | (void)hash_code; // hash_code is only used for Java-side caching. |
| 276 | if (len > 0) { |
| 277 | if (FORY_PREDICT_FALSE(!buffer.ensure_readable(len, error))) { |
| 278 | return Unexpected(std::move(error)); |
| 279 | } |
| 280 | bytes.resize(len); |
| 281 | buffer.read_bytes(bytes.data(), len, error); |
| 282 | if (FORY_PREDICT_FALSE(!error.ok())) { |
| 283 | return Unexpected(std::move(error)); |
| 284 | } |
| 285 | } |
| 286 | encoding = MetaEncoding::UTF8; |
| 287 | } else { |
| 288 | // Small string layout: data[len] with an encoding byte when len > 0. |
| 289 | // Java omits the encoding byte for empty strings. |
| 290 | if (len == 0) { |
| 291 | encoding = MetaEncoding::UTF8; |
| 292 | } else { |
| 293 | int8_t enc_byte_res = buffer.read_int8(error); |
| 294 | if (FORY_PREDICT_FALSE(!error.ok())) { |
| 295 | return Unexpected(std::move(error)); |
| 296 | } |