added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / array_blobs_big.hpp
1 /*************************************************************************
2  *
3  * Copyright 2016 Realm Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  **************************************************************************/
18
19 #ifndef REALM_ARRAY_BIG_BLOBS_HPP
20 #define REALM_ARRAY_BIG_BLOBS_HPP
21
22 #include <realm/array_blob.hpp>
23
24 namespace realm {
25
26
27 class ArrayBigBlobs : public Array {
28 public:
29     typedef BinaryData value_type;
30
31     explicit ArrayBigBlobs(Allocator&, bool nullable) noexcept;
32
33     // Disable copying, this is not allowed.
34     ArrayBigBlobs& operator=(const ArrayBigBlobs&) = delete;
35     ArrayBigBlobs(const ArrayBigBlobs&) = delete;
36
37     BinaryData get(size_t ndx) const noexcept;
38     BinaryData get_at(size_t ndx, size_t& pos) const noexcept;
39     void set(size_t ndx, BinaryData value, bool add_zero_term = false);
40     void add(BinaryData value, bool add_zero_term = false);
41     void insert(size_t ndx, BinaryData value, bool add_zero_term = false);
42     void erase(size_t ndx);
43     void truncate(size_t new_size);
44     void clear();
45     void destroy();
46
47     size_t count(BinaryData value, bool is_string = false, size_t begin = 0, size_t end = npos) const noexcept;
48     size_t find_first(BinaryData value, bool is_string = false, size_t begin = 0, size_t end = npos) const noexcept;
49     void find_all(IntegerColumn& result, BinaryData value, bool is_string = false, size_t add_offset = 0,
50                   size_t begin = 0, size_t end = npos);
51
52     /// Get the specified element without the cost of constructing an
53     /// array instance. If an array instance is already available, or
54     /// you need to get multiple values, then this method will be
55     /// slower.
56     static BinaryData get(const char* header, size_t ndx, Allocator&) noexcept;
57
58     ref_type bptree_leaf_insert(size_t ndx, BinaryData, bool add_zero_term, TreeInsertBase& state);
59
60     //@{
61     /// Those that return a string, discard the terminating zero from
62     /// the stored value. Those that accept a string argument, add a
63     /// terminating zero before storing the value.
64     StringData get_string(size_t ndx) const noexcept;
65     void add_string(StringData value);
66     void set_string(size_t ndx, StringData value);
67     void insert_string(size_t ndx, StringData value);
68     static StringData get_string(const char* header, size_t ndx, Allocator&, bool nullable) noexcept;
69     ref_type bptree_leaf_insert_string(size_t ndx, StringData, TreeInsertBase& state);
70     //@}
71
72     /// Create a new empty big blobs array and attach this accessor to
73     /// it. This does not modify the parent reference information of
74     /// this accessor.
75     ///
76     /// Note that the caller assumes ownership of the allocated
77     /// underlying node. It is not owned by the accessor.
78     void create();
79
80     /// Construct a copy of the specified slice of this big blobs
81     /// array using the specified target allocator.
82     MemRef slice(size_t offset, size_t slice_size, Allocator& target_alloc) const;
83
84 #ifdef REALM_DEBUG
85     void verify() const;
86     void to_dot(std::ostream&, bool is_strings, StringData title = StringData()) const;
87 #endif
88
89 private:
90     bool m_nullable;
91 };
92
93
94 // Implementation:
95
96 inline ArrayBigBlobs::ArrayBigBlobs(Allocator& allocator, bool nullable) noexcept
97     : Array(allocator)
98     , m_nullable(nullable)
99 {
100 }
101
102 inline BinaryData ArrayBigBlobs::get(size_t ndx) const noexcept
103 {
104     ref_type ref = get_as_ref(ndx);
105     if (ref == 0)
106         return {}; // realm::null();
107
108     const char* blob_header = get_alloc().translate(ref);
109     if (!get_context_flag_from_header(blob_header)) {
110         const char* value = ArrayBlob::get(blob_header, 0);
111         size_t blob_size = get_size_from_header(blob_header);
112         return BinaryData(value, blob_size);
113     }
114     return {};
115 }
116
117 inline BinaryData ArrayBigBlobs::get(const char* header, size_t ndx, Allocator& alloc) noexcept
118 {
119     ref_type blob_ref = to_ref(Array::get(header, ndx));
120     if (blob_ref == 0)
121         return {};
122
123     const char* blob_header = alloc.translate(blob_ref);
124     if (!get_context_flag_from_header(blob_header)) {
125         const char* blob_data = Array::get_data_from_header(blob_header);
126         size_t blob_size = Array::get_size_from_header(blob_header);
127         return BinaryData(blob_data, blob_size);
128     }
129     return {};
130 }
131
132 inline void ArrayBigBlobs::erase(size_t ndx)
133 {
134     ref_type blob_ref = Array::get_as_ref(ndx);
135     if (blob_ref != 0) {                       // nothing to destroy if null
136         Array::destroy_deep(blob_ref, get_alloc()); // Deep
137     }
138     Array::erase(ndx);
139 }
140
141 inline void ArrayBigBlobs::truncate(size_t new_size)
142 {
143     Array::truncate_and_destroy_children(new_size);
144 }
145
146 inline void ArrayBigBlobs::clear()
147 {
148     Array::clear_and_destroy_children();
149 }
150
151 inline void ArrayBigBlobs::destroy()
152 {
153     Array::destroy_deep();
154 }
155
156 inline StringData ArrayBigBlobs::get_string(size_t ndx) const noexcept
157 {
158     BinaryData bin = get(ndx);
159     if (bin.is_null())
160         return realm::null();
161     else
162         return StringData(bin.data(), bin.size() - 1); // Do not include terminating zero
163 }
164
165 inline void ArrayBigBlobs::set_string(size_t ndx, StringData value)
166 {
167     REALM_ASSERT_DEBUG(!(!m_nullable && value.is_null()));
168     BinaryData bin(value.data(), value.size());
169     bool add_zero_term = true;
170     set(ndx, bin, add_zero_term);
171 }
172
173 inline void ArrayBigBlobs::add_string(StringData value)
174 {
175     REALM_ASSERT_DEBUG(!(!m_nullable && value.is_null()));
176     BinaryData bin(value.data(), value.size());
177     bool add_zero_term = true;
178     add(bin, add_zero_term);
179 }
180
181 inline void ArrayBigBlobs::insert_string(size_t ndx, StringData value)
182 {
183     REALM_ASSERT_DEBUG(!(!m_nullable && value.is_null()));
184     BinaryData bin(value.data(), value.size());
185     bool add_zero_term = true;
186     insert(ndx, bin, add_zero_term);
187 }
188
189 inline StringData ArrayBigBlobs::get_string(const char* header, size_t ndx, Allocator& alloc, bool nullable) noexcept
190 {
191     static_cast<void>(nullable);
192     BinaryData bin = get(header, ndx, alloc);
193     REALM_ASSERT_DEBUG(!(!nullable && bin.is_null()));
194     if (bin.is_null())
195         return realm::null();
196     else
197         return StringData(bin.data(), bin.size() - 1); // Do not include terminating zero
198 }
199
200 inline ref_type ArrayBigBlobs::bptree_leaf_insert_string(size_t ndx, StringData value, TreeInsertBase& state)
201 {
202     REALM_ASSERT_DEBUG(!(!m_nullable && value.is_null()));
203     BinaryData bin(value.data(), value.size());
204     bool add_zero_term = true;
205     return bptree_leaf_insert(ndx, bin, add_zero_term, state);
206 }
207
208 inline void ArrayBigBlobs::create()
209 {
210     bool context_flag = true;
211     Array::create(type_HasRefs, context_flag); // Throws
212 }
213
214 inline MemRef ArrayBigBlobs::slice(size_t offset, size_t slice_size, Allocator& target_alloc) const
215 {
216     return slice_and_clone_children(offset, slice_size, target_alloc);
217 }
218
219
220 } // namespace realm
221
222 #endif // REALM_ARRAY_BIG_BLOBS_HPP