| 314 | } |
| 315 | |
| 316 | Standalone<StringRef> Tuple::getString(size_t index) const { |
| 317 | if (index >= offsets.size()) { |
| 318 | throw invalid_tuple_index(); |
| 319 | } |
| 320 | |
| 321 | uint8_t code = data[offsets[index]]; |
| 322 | if (code != BYTES_CODE && code != STRING_CODE) { |
| 323 | throw invalid_tuple_data_type(); |
| 324 | } |
| 325 | |
| 326 | size_t b = offsets[index] + 1; |
| 327 | size_t e; |
| 328 | if (offsets.size() > index + 1) { |
| 329 | e = offsets[index + 1]; |
| 330 | } else { |
| 331 | e = data.size(); |
| 332 | } |
| 333 | |
| 334 | Standalone<StringRef> result; |
| 335 | VectorRef<uint8_t> staging; |
| 336 | |
| 337 | for (size_t i = b; i < e; ++i) { |
| 338 | if (data[i] == '\x00') { |
| 339 | staging.append(result.arena(), data.begin() + b, i - b); |
| 340 | ++i; |
| 341 | b = i + 1; |
| 342 | |
| 343 | if (i < e) { |
| 344 | staging.push_back(result.arena(), '\x00'); |
| 345 | } |
| 346 | } |
| 347 | } |
| 348 | |
| 349 | if (b < e) { |
| 350 | staging.append(result.arena(), data.begin() + b, e - b); |
| 351 | } |
| 352 | |
| 353 | result.StringRef::operator=(StringRef(staging.begin(), staging.size())); |
| 354 | return result; |
| 355 | } |
| 356 | |
| 357 | int64_t Tuple::getInt(size_t index) const { |
| 358 | if (index >= offsets.size()) { |