| 41 | }; |
| 42 | |
| 43 | FileLogger2::FileLogger2(const BT::Tree& tree, std::filesystem::path const& filepath) |
| 44 | : StatusChangeLogger() // Deferred subscription |
| 45 | , _p(std::make_unique<Pimpl>()) |
| 46 | { |
| 47 | if(filepath.filename().extension() != ".btlog") |
| 48 | { |
| 49 | throw RuntimeError("FileLogger2: the file extension must be [.btlog]"); |
| 50 | } |
| 51 | |
| 52 | enableTransitionToIdle(true); |
| 53 | |
| 54 | //------------------------------------- |
| 55 | _p->file_stream.open(filepath, std::ofstream::binary | std::ofstream::out); |
| 56 | |
| 57 | if(!_p->file_stream.is_open()) |
| 58 | { |
| 59 | throw RuntimeError("problem opening file in FileLogger2"); |
| 60 | } |
| 61 | |
| 62 | _p->file_stream << "BTCPP4-FileLogger2"; |
| 63 | |
| 64 | const uint8_t protocol = 1; |
| 65 | |
| 66 | _p->file_stream << protocol; |
| 67 | |
| 68 | std::string const xml = WriteTreeToXML(tree, true, true); |
| 69 | |
| 70 | // serialize the length of the buffer in the first 4 bytes |
| 71 | std::array<char, 8> write_buffer{}; |
| 72 | flatbuffers::WriteScalar(write_buffer.data(), static_cast<int32_t>(xml.size())); |
| 73 | _p->file_stream.write(write_buffer.data(), 4); |
| 74 | |
| 75 | // write the XML definition |
| 76 | _p->file_stream.write(xml.data(), static_cast<std::streamsize>(xml.size())); |
| 77 | |
| 78 | _p->first_timestamp = std::chrono::system_clock::now().time_since_epoch(); |
| 79 | |
| 80 | // save the first timestamp in the next 8 bytes (microseconds) |
| 81 | const int64_t timestamp_usec = ToUsec(_p->first_timestamp); |
| 82 | flatbuffers::WriteScalar(write_buffer.data(), timestamp_usec); |
| 83 | _p->file_stream.write(write_buffer.data(), 8); |
| 84 | |
| 85 | _p->writer_thread = std::thread(&FileLogger2::writerLoop, this); |
| 86 | |
| 87 | // Wait for writer thread to signal readiness (under mutex for proper synchronization) |
| 88 | { |
| 89 | std::unique_lock lock(_p->queue_mutex); |
| 90 | _p->queue_cv.wait(lock, [this]() { return _p->writer_ready.load(); }); |
| 91 | } |
| 92 | subscribeToTreeChanges(tree.rootNode()); |
| 93 | } |
| 94 | |
| 95 | FileLogger2::~FileLogger2() |
| 96 | { |
nothing calls this directly
no test coverage detected