| 306 | |
| 307 | template <typename T> |
| 308 | absl::StatusOr<SourcePtr> NewSourceImpl(std::string description, const T& text, |
| 309 | const size_t text_size) { |
| 310 | if (ABSL_PREDICT_FALSE( |
| 311 | text_size > |
| 312 | static_cast<size_t>(std::numeric_limits<int32_t>::max()))) { |
| 313 | return absl::InvalidArgumentError("expression larger than 2GiB limit"); |
| 314 | } |
| 315 | using Traits = SourceTextTraits<T>; |
| 316 | size_t index = 0; |
| 317 | typename Traits::iterator_type it = Traits::Begin(text); |
| 318 | SourcePosition offset = 0; |
| 319 | char32_t code_point; |
| 320 | size_t code_units; |
| 321 | std::vector<uint8_t> data8; |
| 322 | std::vector<char16_t> data16; |
| 323 | std::vector<char32_t> data32; |
| 324 | absl::InlinedVector<SourcePosition, 1> line_offsets; |
| 325 | while (index < text_size) { |
| 326 | std::tie(code_point, code_units) = cel::internal::Utf8Decode(it); |
| 327 | if (ABSL_PREDICT_FALSE(code_point == |
| 328 | cel::internal::kUnicodeReplacementCharacter && |
| 329 | code_units == 1)) { |
| 330 | // Thats an invalid UTF-8 encoding. |
| 331 | return absl::InvalidArgumentError("cannot parse malformed UTF-8 input"); |
| 332 | } |
| 333 | if (code_point == '\n') { |
| 334 | line_offsets.push_back(offset + 1); |
| 335 | } |
| 336 | if (code_point <= 0x7f) { |
| 337 | Traits::Advance(it, code_units); |
| 338 | index += code_units; |
| 339 | ++offset; |
| 340 | continue; |
| 341 | } |
| 342 | if (code_point <= 0xff) { |
| 343 | data8.reserve(text_size); |
| 344 | Traits::AppendTo(data8, text, index); |
| 345 | data8.push_back(static_cast<uint8_t>(code_point)); |
| 346 | Traits::Advance(it, code_units); |
| 347 | index += code_units; |
| 348 | ++offset; |
| 349 | goto latin1; |
| 350 | } |
| 351 | if (code_point <= 0xffff) { |
| 352 | data16.reserve(text_size); |
| 353 | for (size_t offset = 0; offset < index; offset++) { |
| 354 | data16.push_back(static_cast<uint8_t>(text[offset])); |
| 355 | } |
| 356 | data16.push_back(static_cast<char16_t>(code_point)); |
| 357 | Traits::Advance(it, code_units); |
| 358 | index += code_units; |
| 359 | ++offset; |
| 360 | goto basic; |
| 361 | } |
| 362 | data32.reserve(text_size); |
| 363 | for (size_t offset = 0; offset < index; offset++) { |
| 364 | data32.push_back(static_cast<char32_t>(text[offset])); |
| 365 | } |
no test coverage detected