1 /*************************************************************************
3 * Copyright 2016 Realm Inc.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 **************************************************************************/
19 #ifndef REALM_ARRAY_BIG_BLOBS_HPP
20 #define REALM_ARRAY_BIG_BLOBS_HPP
22 #include <realm/array_blob.hpp>
27 class ArrayBigBlobs : public Array {
29 typedef BinaryData value_type;
31 explicit ArrayBigBlobs(Allocator&, bool nullable) noexcept;
33 // Disable copying, this is not allowed.
34 ArrayBigBlobs& operator=(const ArrayBigBlobs&) = delete;
35 ArrayBigBlobs(const ArrayBigBlobs&) = delete;
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);
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);
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
56 static BinaryData get(const char* header, size_t ndx, Allocator&) noexcept;
58 ref_type bptree_leaf_insert(size_t ndx, BinaryData, bool add_zero_term, TreeInsertBase& state);
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);
72 /// Create a new empty big blobs array and attach this accessor to
73 /// it. This does not modify the parent reference information of
76 /// Note that the caller assumes ownership of the allocated
77 /// underlying node. It is not owned by the accessor.
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;
86 void to_dot(std::ostream&, bool is_strings, StringData title = StringData()) const;
96 inline ArrayBigBlobs::ArrayBigBlobs(Allocator& allocator, bool nullable) noexcept
98 , m_nullable(nullable)
102 inline BinaryData ArrayBigBlobs::get(size_t ndx) const noexcept
104 ref_type ref = get_as_ref(ndx);
106 return {}; // realm::null();
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);
117 inline BinaryData ArrayBigBlobs::get(const char* header, size_t ndx, Allocator& alloc) noexcept
119 ref_type blob_ref = to_ref(Array::get(header, ndx));
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);
132 inline void ArrayBigBlobs::erase(size_t ndx)
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
141 inline void ArrayBigBlobs::truncate(size_t new_size)
143 Array::truncate_and_destroy_children(new_size);
146 inline void ArrayBigBlobs::clear()
148 Array::clear_and_destroy_children();
151 inline void ArrayBigBlobs::destroy()
153 Array::destroy_deep();
156 inline StringData ArrayBigBlobs::get_string(size_t ndx) const noexcept
158 BinaryData bin = get(ndx);
160 return realm::null();
162 return StringData(bin.data(), bin.size() - 1); // Do not include terminating zero
165 inline void ArrayBigBlobs::set_string(size_t ndx, StringData value)
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);
173 inline void ArrayBigBlobs::add_string(StringData value)
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);
181 inline void ArrayBigBlobs::insert_string(size_t ndx, StringData value)
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);
189 inline StringData ArrayBigBlobs::get_string(const char* header, size_t ndx, Allocator& alloc, bool nullable) noexcept
191 static_cast<void>(nullable);
192 BinaryData bin = get(header, ndx, alloc);
193 REALM_ASSERT_DEBUG(!(!nullable && bin.is_null()));
195 return realm::null();
197 return StringData(bin.data(), bin.size() - 1); // Do not include terminating zero
200 inline ref_type ArrayBigBlobs::bptree_leaf_insert_string(size_t ndx, StringData value, TreeInsertBase& state)
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);
208 inline void ArrayBigBlobs::create()
210 bool context_flag = true;
211 Array::create(type_HasRefs, context_flag); // Throws
214 inline MemRef ArrayBigBlobs::slice(size_t offset, size_t slice_size, Allocator& target_alloc) const
216 return slice_and_clone_children(offset, slice_size, target_alloc);
222 #endif // REALM_ARRAY_BIG_BLOBS_HPP