James Kuszmaul | 4ed5fb1 | 2022-03-22 15:20:04 -0700 | [diff] [blame] | 1 | #ifndef AOS_UTIL_MCAP_LOGGER_H_ |
| 2 | #define AOS_UTIL_MCAP_LOGGER_H_ |
| 3 | |
| 4 | #include "aos/configuration_generated.h" |
| 5 | #include "aos/events/event_loop.h" |
| 6 | #include "aos/fast_string_builder.h" |
| 7 | #include "aos/flatbuffer_utils.h" |
| 8 | #include "single_include/nlohmann/json.hpp" |
| 9 | |
| 10 | namespace aos { |
| 11 | |
| 12 | // Produces a JSON Schema (https://json-schema.org/) for a given flatbuffer |
| 13 | // type. If recursion_level is set, will include a $schema attribute indicating |
| 14 | // the schema definition being used (this is used to allow for recursion). |
| 15 | // |
| 16 | // Note that this is pretty bare-bones, so, e.g., we don't distinguish between |
| 17 | // structs and tables when generating the JSON schema, so we don't bother to |
| 18 | // mark struct fields as required. |
| 19 | enum class JsonSchemaRecursion { |
| 20 | kTopLevel, |
| 21 | kNested, |
| 22 | }; |
| 23 | nlohmann::json JsonSchemaForFlatbuffer( |
| 24 | const FlatbufferType &type, |
| 25 | JsonSchemaRecursion recursion_level = JsonSchemaRecursion::kTopLevel); |
| 26 | |
| 27 | // Generates an MCAP file, per the specification at |
| 28 | // https://github.com/foxglove/mcap/tree/main/docs/specification |
| 29 | class McapLogger { |
| 30 | public: |
| 31 | McapLogger(EventLoop *event_loop, const std::string &output_path); |
| 32 | ~McapLogger(); |
| 33 | |
| 34 | private: |
| 35 | enum class OpCode { |
| 36 | kHeader = 0x01, |
| 37 | kFooter = 0x02, |
| 38 | kSchema = 0x03, |
| 39 | kChannel = 0x04, |
| 40 | kMessage = 0x05, |
| 41 | kDataEnd = 0x0F, |
| 42 | }; |
| 43 | // Helpers to write each type of relevant record. |
| 44 | void WriteMagic(); |
| 45 | void WriteHeader(); |
| 46 | void WriteFooter(); |
| 47 | void WriteDataEnd(); |
| 48 | void WriteSchema(const uint16_t id, const aos::Channel *channel); |
| 49 | void WriteChannel(const uint16_t id, const uint16_t schema_id, |
| 50 | const aos::Channel *channel); |
| 51 | void WriteMessage(uint16_t channel_id, const Channel *channel, |
| 52 | const Context &context); |
| 53 | void WriteConfig(); |
| 54 | |
| 55 | // Writes an MCAP record to the output file. |
| 56 | void WriteRecord(OpCode op, std::string_view record); |
| 57 | // Adds an MCAP-spec string/fixed-size integer to a buffer. |
| 58 | static void AppendString(FastStringBuilder *builder, std::string_view string); |
| 59 | static void AppendInt16(FastStringBuilder *builder, uint16_t val); |
| 60 | static void AppendInt32(FastStringBuilder *builder, uint32_t val); |
| 61 | static void AppendInt64(FastStringBuilder *builder, uint64_t val); |
| 62 | |
| 63 | std::ofstream output_; |
| 64 | FastStringBuilder string_builder_; |
| 65 | }; |
| 66 | } // namespace aos |
| 67 | #endif // AOS_UTIL_MCAP_LOGGER_H_ |