1 //
2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 #pragma once
8
9 #include "td/utils/buffer.h"
10 #include "td/utils/common.h"
11 #include "td/utils/format.h"
12 #include "td/utils/Slice.h"
13 #include "td/utils/SliceBuilder.h"
14 #include "td/utils/Status.h"
15 #include "td/utils/Storer.h"
16 #include "td/utils/StorerBase.h"
17 #include "td/utils/StringBuilder.h"
18
19 namespace td {
20
21 struct EmptyStorerImpl {
EmptyStorerImplEmptyStorerImpl22 EmptyStorerImpl() {
23 }
24
25 template <class StorerT>
storeEmptyStorerImpl26 void store(StorerT &storer) const {
27 }
28 };
29
EmptyStorer()30 inline auto EmptyStorer() {
31 static const EmptyStorerImpl impl;
32 return create_default_storer(impl);
33 }
34
35 struct BinlogDebugInfo {
36 BinlogDebugInfo() = default;
BinlogDebugInfoBinlogDebugInfo37 BinlogDebugInfo(const char *file, int line) : file(file), line(line) {
38 }
39 const char *file{""};
40 int line{0};
41 };
42
43 inline StringBuilder &operator<<(StringBuilder &sb, const BinlogDebugInfo &info) {
44 if (info.line == 0) {
45 return sb;
46 }
47 return sb << "[" << info.file << ":" << info.line << "]";
48 }
49
50 struct BinlogEvent {
51 static constexpr size_t MAX_SIZE = 1 << 24;
52 static constexpr size_t HEADER_SIZE = 4 + 8 + 4 + 4 + 8;
53 static constexpr size_t TAIL_SIZE = 4;
54 static constexpr size_t MIN_SIZE = HEADER_SIZE + TAIL_SIZE;
55
56 int64 offset_;
57
58 uint32 size_;
59 uint64 id_;
60 int32 type_; // type can be merged with flags
61 int32 flags_;
62 uint64 extra_;
63 MutableSlice data_;
64 uint32 crc32_;
65
66 BufferSlice raw_event_;
67
68 BinlogDebugInfo debug_info_;
69
70 enum ServiceTypes { Header = -1, Empty = -2, AesCtrEncryption = -3, NoEncryption = -4 };
71 enum Flags { Rewrite = 1, Partial = 2 };
72
clearBinlogEvent73 void clear() {
74 raw_event_ = BufferSlice();
75 }
emptyBinlogEvent76 bool empty() const {
77 return raw_event_.empty();
78 }
cloneBinlogEvent79 BinlogEvent clone() const {
80 BinlogEvent result;
81 result.debug_info_ = BinlogDebugInfo{__FILE__, __LINE__};
82 result.init(raw_event_.clone()).ensure();
83 return result;
84 }
85
data_as_buffer_sliceBinlogEvent86 BufferSlice data_as_buffer_slice() const {
87 return raw_event_.from_slice(data_);
88 }
89
90 BinlogEvent() = default;
91 //explicit BinlogEvent(BufferSlice &&raw_event) {
92 //init(std::move(raw_event), false).ensure();
93 //}
BinlogEventBinlogEvent94 BinlogEvent(BufferSlice &&raw_event, BinlogDebugInfo info) {
95 debug_info_ = info;
96 init(std::move(raw_event), false).ensure();
97 }
98
99 Status init(BufferSlice &&raw_event, bool check_crc = true) TD_WARN_UNUSED_RESULT;
100
101 static BufferSlice create_raw(uint64 id, int32 type, int32 flags, const Storer &storer);
102
public_to_stringBinlogEvent103 std::string public_to_string() const {
104 return PSTRING() << "LogEvent[" << tag("id", format::as_hex(id_)) << tag("type", type_) << tag("flags", flags_)
105 << tag("data", data_.size()) << "]" << debug_info_;
106 }
107
108 Status validate() const;
109
110 void realloc();
111 };
112
113 inline StringBuilder &operator<<(StringBuilder &sb, const BinlogEvent &event) {
114 return sb << "LogEvent[" << tag("id", format::as_hex(event.id_)) << tag("type", event.type_)
115 << tag("flags", event.flags_) << tag("data", format::as_hex_dump<4>(event.data_)) << "]"
116 << event.debug_info_;
117 }
118
119 } // namespace td
120