1 /*************************************************************************
6 * [2011] - [2017] Realm Inc
9 * NOTICE: All information contained herein is, and remains
10 * the property of Realm Incorporated and its suppliers,
11 * if any. The intellectual and technical concepts contained
12 * herein are proprietary to Realm Incorporated
13 * and its suppliers and may be covered by U.S. and Foreign Patents,
14 * patents in process, and are protected by trade secret or copyright law.
15 * Dissemination of this information or reproduction of this material
16 * is strictly forbidden unless prior written permission is obtained
17 * from Realm Incorporated.
19 **************************************************************************/
21 #ifndef REALM_SYNC_CHANGESET_ENCODER_HPP
22 #define REALM_SYNC_CHANGESET_ENCODER_HPP
24 #include <realm/sync/changeset.hpp>
29 struct ChangesetEncoder: InstructionHandler {
30 util::AppendBuffer<char> release() noexcept;
31 void reset() noexcept;
32 const util::AppendBuffer<char>& buffer() const noexcept;
33 InternString intern_string(StringData);
35 void set_intern_string(uint32_t index, StringBufferRange) override;
36 // FIXME: This doesn't copy the input, but the drawback is that there can
37 // only be a single StringBufferRange per instruction. Luckily, no
38 // instructions exist that require two or more.
39 StringBufferRange add_string_range(StringData) override;
40 void operator()(const Instruction&) override;
42 #define REALM_DEFINE_INSTRUCTION_HANDLER(X) void operator()(const Instruction::X&);
43 REALM_FOR_EACH_INSTRUCTION_TYPE(REALM_DEFINE_INSTRUCTION_HANDLER)
44 #undef REALM_DEFINE_INSTRUCTION_HANDLER
47 template<class E> static void encode(E& encoder, const Instruction&);
49 StringData get_string(StringBufferRange) const noexcept;
52 template<class... Args>
53 void append(Instruction::Type t, Args&&...);
54 void append_string(StringBufferRange); // does not intern the string
55 void append_bytes(const void*, size_t);
57 template<class T> void append_int(T);
58 template<class T> char* encode_int(char* buffer, T value);
59 void append_payload(const Instruction::Payload&);
60 void append_value(DataType);
61 void append_value(bool);
62 void append_value(uint8_t);
63 void append_value(int64_t);
64 void append_value(uint32_t);
65 void append_value(uint64_t);
66 void append_value(float);
67 void append_value(double);
68 void append_value(InternString);
69 void append_value(sync::ObjectID);
70 void append_value(Timestamp);
72 util::AppendBuffer<char> m_buffer;
73 std::unordered_map<std::string, uint32_t> m_intern_strings_rev;
74 StringData m_string_range;
77 void encode_changeset(const Changeset&, util::AppendBuffer<char>& out_buffer);
84 inline const util::AppendBuffer<char>& ChangesetEncoder::buffer() const noexcept
89 inline void ChangesetEncoder::operator()(const Instruction& instr)
91 encode(*this, instr); // Throws
94 template<class E> inline void ChangesetEncoder::encode(E& encoder, const Instruction& instr)
96 instr.visit(encoder); // Throws
99 inline StringData ChangesetEncoder::get_string(StringBufferRange range) const noexcept
101 const char* data = m_string_range.data() + range.offset;
102 std::size_t size = std::size_t(range.size);
103 return StringData{data, size};
109 #endif // REALM_SYNC_CHANGESET_ENCODER_HPP