| 378 | |
| 379 | template <class FieldType> |
| 380 | bool parseField(Arena& arena, Optional<FieldType>& out, const rapidjson::Document& d, const char* fieldName) { |
| 381 | auto fieldItr = d.FindMember(fieldName); |
| 382 | if (fieldItr == d.MemberEnd()) |
| 383 | return true; |
| 384 | auto const& field = fieldItr->value; |
| 385 | static_assert(std::is_same_v<StringRef, FieldType> || std::is_same_v<FieldType, uint64_t> || |
| 386 | std::is_same_v<FieldType, VectorRef<StringRef>>); |
| 387 | if constexpr (std::is_same_v<FieldType, StringRef>) { |
| 388 | if (!field.IsString()) |
| 389 | return false; |
| 390 | out = StringRef(arena, reinterpret_cast<const uint8_t*>(field.GetString()), field.GetStringLength()); |
| 391 | } else if constexpr (std::is_same_v<FieldType, uint64_t>) { |
| 392 | if (!field.IsNumber()) |
| 393 | return false; |
| 394 | out = static_cast<uint64_t>(field.GetDouble()); |
| 395 | } else { |
| 396 | if (!field.IsArray()) |
| 397 | return false; |
| 398 | if (field.Size() > 0) { |
| 399 | auto vector = new (arena) StringRef[field.Size()]; |
| 400 | for (auto i = 0; i < field.Size(); i++) { |
| 401 | if (!field[i].IsString()) |
| 402 | return false; |
| 403 | vector[i] = StringRef( |
| 404 | arena, reinterpret_cast<const uint8_t*>(field[i].GetString()), field[i].GetStringLength()); |
| 405 | } |
| 406 | out = VectorRef<StringRef>(vector, field.Size()); |
| 407 | } else { |
| 408 | out = VectorRef<StringRef>(); |
| 409 | } |
| 410 | } |
| 411 | return true; |
| 412 | } |
| 413 | |
| 414 | bool parsePayloadPart(Arena& arena, TokenRef& token, StringRef b64urlPayload) { |
| 415 | auto tmpArena = Arena(); |
no test coverage detected