blob: cc16fea6d9591ebe2198b51d837df0d52fd2a59b [file] [log] [blame]
Brian Silvermanf51499a2020-09-21 12:49:08 -07001#ifndef AOS_EVENTS_LOGGING_BUFFER_ENCODER_H_
2#define AOS_EVENTS_LOGGING_BUFFER_ENCODER_H_
3
4#include "absl/types/span.h"
5#include "flatbuffers/flatbuffers.h"
6
7#include "aos/events/logging/logger_generated.h"
8
9namespace aos::logger {
10
11// Interface to encode DetachedBuffers as they are written to a file.
12//
13// The interface to a file is represented as a series of buffers, appropriate to
14// pass to writev(2). The backing storage for these is managed internally so
15// subclasses can handle resizing/moving as desired. Implementations must
16// enqueue as many of these backing buffers as demanded, leaving it up to the
17// caller to write them to a file when desired.
18class DetachedBufferEncoder {
19 public:
20 virtual ~DetachedBufferEncoder() = default;
21
22 // Encodes and enqueues the given DetachedBuffer.
23 //
24 // Note that in may be moved-from, or it may be left unchanged, depending on
25 // what makes the most sense for a given implementation.
26 virtual void Encode(flatbuffers::DetachedBuffer &&in) = 0;
27
28 // If this returns true, the encoder may be bypassed by writing directly to
29 // the file.
30 virtual bool may_bypass() const { return false; }
31
32 // Finalizes the encoding process. After this, queue_size() represents the
33 // full extent of data which will be written to this file.
34 //
35 // Encode may not be called after this method.
36 virtual void Finish() = 0;
37
38 // Clears the first n encoded buffers from the queue.
39 virtual void Clear(int n) = 0;
40
41 // Returns a view of the queue of encoded buffers.
42 virtual std::vector<absl::Span<const uint8_t>> queue() const = 0;
43
44 // Returns the total number of of bytes currently queued up.
45 virtual size_t queued_bytes() const = 0;
46
47 // Returns the cumulative number of bytes which have been queued. This
48 // includes data which has been removed via Clear.
49 virtual size_t total_bytes() const = 0;
50
51 // Returns the number of elements in the queue.
52 virtual size_t queue_size() const = 0;
53};
54
55// This class does not encode the data. It just claims ownership of the raw data
56// and queues it up as is.
57class DummyEncoder final : public DetachedBufferEncoder {
58 public:
59 ~DummyEncoder() override = default;
60
61 // No encoding happens, the raw data is queued up as is.
62 void Encode(flatbuffers::DetachedBuffer &&in) final;
63 bool may_bypass() const final { return true; }
64 void Finish() final {}
65 void Clear(int n) final;
66 std::vector<absl::Span<const uint8_t>> queue() const final;
67 size_t queued_bytes() const final;
68 size_t total_bytes() const final { return total_bytes_; }
69 size_t queue_size() const final { return queue_.size(); }
70
71 private:
72 std::vector<flatbuffers::DetachedBuffer> queue_;
73 size_t total_bytes_ = 0;
74};
75
76// Interface to decode chunks of data. Implementations of this interface will
77// manage opening, reading, and closing the file stream.
78class DataDecoder {
79 public:
80 virtual ~DataDecoder() = default;
81
82 // Reads data into the given range. Returns the number of bytes read.
83 //
84 // Returns less than end-begin if all bytes have been read. Otherwise, this
85 // will always fill the whole range.
86 virtual size_t Read(uint8_t *begin, uint8_t *end) = 0;
87};
88
89// Simply reads the contents of the file into the target buffer.
90class DummyDecoder final : public DataDecoder {
91 public:
92 explicit DummyDecoder(std::string_view filename);
93 ~DummyDecoder() override;
94
95 size_t Read(uint8_t *begin, uint8_t *end) final;
96
97 private:
98 // File descriptor for the log file.
99 int fd_;
100
101 // Cached bit for if we have reached the end of the file. Otherwise we will
102 // hammer on the kernel asking for more data each time we send.
103 bool end_of_file_ = false;
104};
105
106} // namespace aos::logger
107
108#endif // AOS_EVENTS_LOGGING_BUFFER_ENCODER_H_