added iOS source code
[wl-app.git] / iOS / Pods / Realm / include / core / realm / array_string_long.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_STRING_LONG_HPP
20 #define REALM_ARRAY_STRING_LONG_HPP
21
22 #include <realm/array_blob.hpp>
23 #include <realm/array_integer.hpp>
24
25 namespace realm {
26
27
28 class ArrayStringLong : public Array {
29 public:
30     typedef StringData value_type;
31
32     explicit ArrayStringLong(Allocator&, bool nullable) noexcept;
33     ~ArrayStringLong() noexcept override
34     {
35     }
36
37     // Disable copying, this is not allowed.
38     ArrayStringLong& operator=(const ArrayStringLong&) = delete;
39     ArrayStringLong(const ArrayStringLong&) = delete;
40
41     /// Create a new empty long string array and attach this accessor to
42     /// it. This does not modify the parent reference information of
43     /// this accessor.
44     ///
45     /// Note that the caller assumes ownership of the allocated
46     /// underlying node. It is not owned by the accessor.
47     void create();
48
49     //@{
50     /// Overriding functions of Array
51     void init_from_ref(ref_type) noexcept;
52     void init_from_mem(MemRef) noexcept;
53     void init_from_parent() noexcept;
54     //@}
55
56     bool is_empty() const noexcept;
57     size_t size() const noexcept;
58
59     StringData get(size_t ndx) const noexcept;
60
61
62     void add(StringData value);
63     void set(size_t ndx, StringData value);
64     void insert(size_t ndx, StringData value);
65     void erase(size_t ndx);
66     void truncate(size_t size);
67     void clear();
68     void destroy();
69
70     bool is_null(size_t ndx) const;
71     void set_null(size_t ndx);
72
73     size_t count(StringData value, size_t begin = 0, size_t end = npos) const noexcept;
74     size_t find_first(StringData value, size_t begin = 0, size_t end = npos) const noexcept;
75     void find_all(IntegerColumn& result, StringData value, size_t add_offset = 0, size_t begin = 0,
76                   size_t end = npos) const;
77
78     /// Get the specified element without the cost of constructing an
79     /// array instance. If an array instance is already available, or
80     /// you need to get multiple values, then this method will be
81     /// slower.
82     static StringData get(const char* header, size_t ndx, Allocator&, bool nullable) noexcept;
83
84     ref_type bptree_leaf_insert(size_t ndx, StringData, TreeInsertBase&);
85
86     static size_t get_size_from_header(const char*, Allocator&) noexcept;
87
88     /// Construct a long string array of the specified size and return
89     /// just the reference to the underlying memory. All elements will
90     /// be initialized to zero size blobs.
91     static MemRef create_array(size_t size, Allocator&, bool nullable);
92
93     /// Construct a copy of the specified slice of this long string
94     /// array using the specified target allocator.
95     MemRef slice(size_t offset, size_t slice_size, Allocator& target_alloc) const;
96
97 #ifdef REALM_DEBUG
98     void to_dot(std::ostream&, StringData title = StringData()) const;
99 #endif
100
101     bool update_from_parent(size_t old_baseline) noexcept;
102
103 private:
104     ArrayInteger m_offsets;
105     ArrayBlob m_blob;
106     Array m_nulls;
107     bool m_nullable;
108 };
109
110
111 // Implementation:
112 inline ArrayStringLong::ArrayStringLong(Allocator& allocator, bool nullable) noexcept
113     : Array(allocator)
114     , m_offsets(allocator)
115     , m_blob(allocator)
116     , m_nulls(nullable ? allocator : Allocator::get_default())
117     , m_nullable(nullable)
118 {
119     m_offsets.set_parent(this, 0);
120     m_blob.set_parent(this, 1);
121     if (nullable)
122         m_nulls.set_parent(this, 2);
123 }
124
125 inline void ArrayStringLong::create()
126 {
127     size_t init_size = 0;
128     MemRef mem = create_array(init_size, get_alloc(), m_nullable); // Throws
129     init_from_mem(mem);
130 }
131
132 inline void ArrayStringLong::init_from_ref(ref_type ref) noexcept
133 {
134     REALM_ASSERT(ref);
135     char* header = get_alloc().translate(ref);
136     init_from_mem(MemRef(header, ref, m_alloc));
137     m_nullable = (Array::size() == 3);
138 }
139
140 inline void ArrayStringLong::init_from_parent() noexcept
141 {
142     ref_type ref = get_ref_from_parent();
143     init_from_ref(ref);
144 }
145
146 inline bool ArrayStringLong::is_empty() const noexcept
147 {
148     return m_offsets.is_empty();
149 }
150
151 inline size_t ArrayStringLong::size() const noexcept
152 {
153     return m_offsets.size();
154 }
155
156 inline StringData ArrayStringLong::get(size_t ndx) const noexcept
157 {
158     REALM_ASSERT_3(ndx, <, m_offsets.size());
159
160     if (m_nullable && m_nulls.get(ndx) == 0)
161         return realm::null();
162
163     size_t begin, end;
164     if (0 < ndx) {
165         begin = to_size_t(m_offsets.get(ndx - 1));
166         end = to_size_t(m_offsets.get(ndx));
167     }
168     else {
169         begin = 0;
170         end = to_size_t(m_offsets.get(0));
171     }
172     --end; // Discount the terminating zero
173
174     return StringData(m_blob.get(begin), end - begin);
175 }
176
177 inline void ArrayStringLong::truncate(size_t new_size)
178 {
179     REALM_ASSERT_3(new_size, <, m_offsets.size());
180
181     size_t blob_size = new_size ? to_size_t(m_offsets.get(new_size - 1)) : 0;
182
183     m_offsets.truncate(new_size);
184     m_blob.truncate(blob_size);
185     if (m_nullable)
186         m_nulls.truncate(new_size);
187 }
188
189 inline void ArrayStringLong::clear()
190 {
191     m_blob.clear();
192     m_offsets.clear();
193     if (m_nullable)
194         m_nulls.clear();
195 }
196
197 inline void ArrayStringLong::destroy()
198 {
199     m_blob.destroy();
200     m_offsets.destroy();
201     if (m_nullable)
202         m_nulls.destroy();
203     Array::destroy();
204 }
205
206 inline bool ArrayStringLong::update_from_parent(size_t old_baseline) noexcept
207 {
208     bool res = Array::update_from_parent(old_baseline);
209     if (res) {
210         m_blob.update_from_parent(old_baseline);
211         m_offsets.update_from_parent(old_baseline);
212         if (m_nullable)
213             m_nulls.update_from_parent(old_baseline);
214     }
215     return res;
216 }
217
218 inline size_t ArrayStringLong::get_size_from_header(const char* header, Allocator& alloc) noexcept
219 {
220     ref_type offsets_ref = to_ref(Array::get(header, 0));
221     const char* offsets_header = alloc.translate(offsets_ref);
222     return Array::get_size_from_header(offsets_header);
223 }
224
225
226 } // namespace realm
227
228 #endif // REALM_ARRAY_STRING_LONG_HPP