blob: 1eddd0035a3c0884ce7f21159a0bb95788de84f1 [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:
Austin Schuhc41603c2020-10-11 16:17:37 -070059 DummyEncoder() {}
60 DummyEncoder(const DummyEncoder &) = delete;
61 DummyEncoder(DummyEncoder &&other) = delete;
62 DummyEncoder &operator=(const DummyEncoder &) = delete;
63 DummyEncoder &operator=(DummyEncoder &&other) = delete;
Brian Silvermanf51499a2020-09-21 12:49:08 -070064 ~DummyEncoder() override = default;
65
66 // No encoding happens, the raw data is queued up as is.
67 void Encode(flatbuffers::DetachedBuffer &&in) final;
68 bool may_bypass() const final { return true; }
69 void Finish() final {}
70 void Clear(int n) final;
71 std::vector<absl::Span<const uint8_t>> queue() const final;
72 size_t queued_bytes() const final;
73 size_t total_bytes() const final { return total_bytes_; }
74 size_t queue_size() const final { return queue_.size(); }
75
76 private:
77 std::vector<flatbuffers::DetachedBuffer> queue_;
78 size_t total_bytes_ = 0;
79};
80
81// Interface to decode chunks of data. Implementations of this interface will
82// manage opening, reading, and closing the file stream.
83class DataDecoder {
84 public:
85 virtual ~DataDecoder() = default;
86
87 // Reads data into the given range. Returns the number of bytes read.
88 //
89 // Returns less than end-begin if all bytes have been read. Otherwise, this
90 // will always fill the whole range.
91 virtual size_t Read(uint8_t *begin, uint8_t *end) = 0;
92};
93
94// Simply reads the contents of the file into the target buffer.
95class DummyDecoder final : public DataDecoder {
96 public:
97 explicit DummyDecoder(std::string_view filename);
Austin Schuhc41603c2020-10-11 16:17:37 -070098 DummyDecoder(const DummyDecoder &) = delete;
99 DummyDecoder(DummyDecoder &&other) = delete;
100 DummyDecoder &operator=(const DummyDecoder &) = delete;
101 DummyDecoder &operator=(DummyDecoder &&other) = delete;
Brian Silvermanf51499a2020-09-21 12:49:08 -0700102 ~DummyDecoder() override;
103
104 size_t Read(uint8_t *begin, uint8_t *end) final;
105
106 private:
107 // File descriptor for the log file.
108 int fd_;
109
110 // Cached bit for if we have reached the end of the file. Otherwise we will
111 // hammer on the kernel asking for more data each time we send.
112 bool end_of_file_ = false;
113};
114
115} // namespace aos::logger
116
117#endif // AOS_EVENTS_LOGGING_BUFFER_ENCODER_H_