| 11 | namespace PJ { |
| 12 | |
| 13 | Expected<sdk::ObjectRecord, ParserObjectError> parseObjectRecordAs( |
| 14 | MessageParserPluginBase& parser, const std::shared_ptr<std::mutex>& parser_mutex, Timestamp timestamp_ns, |
| 15 | sdk::PayloadView payload, sdk::BuiltinObjectType expected_type) { |
| 16 | // MessageParser plugins aren't thread-safe (fastcdr et al. keep stateful |
| 17 | // scratch). Consumers sharing a parser singleton must share the same mutex and |
| 18 | // hold it only across parseObject; any_cast/decode work happens after unlock. |
| 19 | auto invoke_parser = [&] { |
| 20 | if (parser_mutex) { |
| 21 | std::lock_guard<std::mutex> lock(*parser_mutex); |
| 22 | return parser.parseObject(timestamp_ns, payload); |
| 23 | } |
| 24 | return parser.parseObject(timestamp_ns, payload); |
| 25 | }; |
| 26 | |
| 27 | auto object_or = invoke_parser(); |
| 28 | if (!object_or.has_value()) { |
| 29 | return unexpected( |
| 30 | ParserObjectError{ |
| 31 | ParserObjectErrorKind::kParseFailed, |
| 32 | "parseObject failed: " + object_or.error(), |
| 33 | sdk::BuiltinObjectType::kNone, |
| 34 | }); |
| 35 | } |
| 36 | |
| 37 | const sdk::BuiltinObjectType actual_type = sdk::typeOf(object_or->object); |
| 38 | if (actual_type != expected_type) { |
| 39 | return unexpected( |
| 40 | ParserObjectError{ |
| 41 | ParserObjectErrorKind::kWrongObjectKind, |
| 42 | "parseObject returned wrong object_kind (expected " + std::string(sdk::name(expected_type)) + ")", |
| 43 | actual_type, |
| 44 | }); |
| 45 | } |
| 46 | |
| 47 | return std::move(*object_or); |
| 48 | } |
| 49 | |
| 50 | } // namespace PJ |