added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / sync / changeset_encoder.hpp
1 /*************************************************************************
2  *
3  * REALM CONFIDENTIAL
4  * __________________
5  *
6  *  [2011] - [2017] Realm Inc
7  *  All Rights Reserved.
8  *
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.
18  *
19  **************************************************************************/
20
21 #ifndef REALM_SYNC_CHANGESET_ENCODER_HPP
22 #define REALM_SYNC_CHANGESET_ENCODER_HPP
23
24 #include <realm/sync/changeset.hpp>
25
26 namespace realm {
27 namespace sync {
28
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);
34
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;
41
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
45
46 protected:
47     template<class E> static void encode(E& encoder, const Instruction&);
48
49     StringData get_string(StringBufferRange) const noexcept;
50
51 private:
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);
56
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);
71
72     util::AppendBuffer<char> m_buffer;
73     std::unordered_map<std::string, uint32_t> m_intern_strings_rev;
74     StringData m_string_range;
75 };
76
77 void encode_changeset(const Changeset&, util::AppendBuffer<char>& out_buffer);
78
79
80
81
82 // Implementation
83
84 inline const util::AppendBuffer<char>& ChangesetEncoder::buffer() const noexcept
85 {
86     return m_buffer;
87 }
88
89 inline void ChangesetEncoder::operator()(const Instruction& instr)
90 {
91     encode(*this, instr); // Throws
92 }
93
94 template<class E> inline void ChangesetEncoder::encode(E& encoder, const Instruction& instr)
95 {
96     instr.visit(encoder); // Throws
97 }
98
99 inline StringData ChangesetEncoder::get_string(StringBufferRange range) const noexcept
100 {
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};
104 }
105
106 } // namespace sync
107 } // namespace realm
108
109 #endif // REALM_SYNC_CHANGESET_ENCODER_HPP