inline std::size_t LinkView::size() const noexcept { REALM_ASSERT(is_attached()); if (!m_row_indexes.is_attached()) return 0; return m_row_indexes.size(); }
inline bool InterprocessMutex::is_valid() noexcept { #ifdef REALM_ROBUST_MUTEX_EMULATION return true; #else REALM_ASSERT(m_shared_part); return m_shared_part->is_valid(); #endif }
inline void StringColumn::insert(std::size_t row_ndx, StringData value) { REALM_ASSERT(!(value.is_null() && !m_nullable)); std::size_t size = this->size(); REALM_ASSERT_3(row_ndx, <=, size); std::size_t num_rows = 1; bool is_append = row_ndx == size; do_insert(row_ndx, value, num_rows, is_append); // Throws }
inline bool LinkView::is_empty() const noexcept { REALM_ASSERT(is_attached()); if (!m_row_indexes.is_attached()) return true; return m_row_indexes.is_empty(); }
void SyncFileActionMetadata::remove() { REALM_ASSERT(m_realm); m_realm->verify_thread(); m_realm->begin_transaction(); TableRef table = ObjectStore::table_for_object_type(m_realm->read_group(), c_sync_fileActionMetadata); table->move_last_over(m_row.get_index()); m_realm->commit_transaction(); m_realm = nullptr; }
inline void InterprocessMutex::unlock() { #ifdef REALM_ROBUST_MUTEX_EMULATION m_lock_info->m_file.unlock(); m_lock_info->m_local_mutex.unlock(); #else REALM_ASSERT(m_shared_part); m_shared_part->unlock(); #endif }
void set_null(size_t index) override { REALM_ASSERT(m_nullable); if (!m_array->is_inner_bptree_node()) { static_cast<BasicArray<T>*>(m_array.get())->set(index, null::get_null_float<T>()); // Throws return; } SetLeafElem set_leaf_elem(m_array->get_alloc(), null::get_null_float<T>()); m_array->update_bptree_elem(index, set_leaf_elem); // Throws }
// Implementing pure virtual method of ColumnBase. inline void StringColumn::insert_rows(size_t row_ndx, size_t num_rows_to_insert, size_t prior_num_rows) { REALM_ASSERT_DEBUG(prior_num_rows == size()); REALM_ASSERT(row_ndx <= prior_num_rows); StringData value = m_nullable ? realm::null() : StringData(""); bool is_append = (row_ndx == prior_num_rows); do_insert(row_ndx, value, num_rows_to_insert, is_append); // Throws }
// Old database files will not have the m_nulls array, so we need code paths for // backwards compatibility for these cases. We can test if m_nulls exists by looking // at number of references in this ArrayBinary. inline bool ArrayBinary::legacy_array_type() const noexcept { if (Array::size() == 3) return false; // New database file else if (Array::size() == 2) return true; // Old database file else REALM_ASSERT(false); // Should never happen return false; }
inline void InterprocessMutex::lock() { #ifdef REALM_ROBUST_MUTEX_EMULATION std::unique_lock<Mutex> mutex_lock(m_lock_info->m_local_mutex); m_lock_info->m_file.lock_exclusive(); mutex_lock.release(); #else REALM_ASSERT(m_shared_part); m_shared_part->lock([]() {}); #endif }
inline void Spec::set_column_attr(size_t column_ndx, ColumnAttr attr) { REALM_ASSERT(column_ndx < get_column_count()); // At this point we only allow one attr at a time // so setting it will overwrite existing. In the future // we will allow combinations. m_attr.set(column_ndx, attr); update_has_strong_link_columns(); }
inline std::size_t LinkView::find(std::size_t target_row_ndx, std::size_t start) const noexcept { REALM_ASSERT(is_attached()); REALM_ASSERT_3(target_row_ndx, <, m_origin_column.get_target_table().size()); REALM_ASSERT_3(start, <=, size()); if (!m_row_indexes.is_attached()) return not_found; return m_row_indexes.find_first(target_row_ndx, start); }
inline void BinaryColumn::update_from_parent(size_t old_baseline) noexcept { if (root_is_leaf()) { bool is_big = m_array->get_context_flag(); if (!is_big) { // Small blobs root leaf REALM_ASSERT(dynamic_cast<ArrayBinary*>(m_array.get())); ArrayBinary* leaf = static_cast<ArrayBinary*>(m_array.get()); leaf->update_from_parent(old_baseline); return; } // Big blobs root leaf REALM_ASSERT(dynamic_cast<ArrayBigBlobs*>(m_array.get())); ArrayBigBlobs* leaf = static_cast<ArrayBigBlobs*>(m_array.get()); leaf->update_from_parent(old_baseline); return; } // Non-leaf root m_array->update_from_parent(old_baseline); }
Utf16StringAccessor(const uint16_t* csbuffer, size_t csbufsize) { // For efficiency, if the incoming UTF-16 string is sufficiently // small, we will choose an UTF-8 output buffer whose size (in // bytes) is simply 4 times the number of 16-bit elements in the // input. This is guaranteed to be enough. However, to avoid // excessive over allocation, this is not done for larger input // strings. error = false; typedef realm::util::Utf8x16<uint16_t, std::char_traits<char16_t>>Xcode; //This might not work in old compilers (the std::char_traits<char16_t> ). size_t max_project_size = 48; REALM_ASSERT(max_project_size <= std::numeric_limits<size_t>::max() / 4); size_t u8buf_size; if (csbufsize <= max_project_size) { u8buf_size = csbufsize * 4; } else { const uint16_t* begin = csbuffer; const uint16_t* end = csbuffer + csbufsize; u8buf_size = Xcode::find_utf8_buf_size(begin, end); } m_data.reset(new char[u8buf_size]); { const uint16_t* in_begin = csbuffer; const uint16_t* in_end = csbuffer + csbufsize; char* out_begin = m_data.get(); char* out_end = m_data.get() + u8buf_size; if (!Xcode::to_utf8(in_begin, in_end, out_begin, out_end)) { m_size = 0; error = true; return;//calling method should handle this. We can't throw exceptions } REALM_ASSERT(in_begin == in_end); m_size = out_begin - m_data.get(); } }
inline size_t Utf8x16<Char16, Traits16>::find_utf8_buf_size(const Char16*& in_begin, const Char16* const in_end) { size_t num_out = 0; const Char16* in = in_begin; while (in != in_end) { REALM_ASSERT(&in[0] >= in_begin && &in[0] < in_end); uint_fast16_t v = uint_fast16_t(Traits16::to_int_type(in[0])); if (REALM_LIKELY(v < 0x80)) { if (REALM_UNLIKELY(int_add_with_overflow_detect(num_out, 1))) break; // Avoid overflow in += 1; } else if (REALM_LIKELY(v < 0x800)) { if (REALM_UNLIKELY(int_add_with_overflow_detect(num_out, 2))) break; // Avoid overflow in += 1; } else if (REALM_LIKELY(v < 0xD800 || 0xE000 <= v)) { if (REALM_UNLIKELY(int_add_with_overflow_detect(num_out, 3))) break; // Avoid overflow in += 1; } else { if (REALM_UNLIKELY(in + 1 == in_end)) { break; // Incomplete surrogate pair } if (REALM_UNLIKELY(int_add_with_overflow_detect(num_out, 4))) break; // Avoid overflow in += 2; } } REALM_ASSERT(in >= in_begin && in <= in_end); in_begin = in; return num_out; }
void init(RowIndexes* row_indexes) { m_columns.clear(); m_string_enum_columns.clear(); m_columns.resize(m_column_indexes.size(), 0); m_string_enum_columns.resize(m_column_indexes.size(), 0); for (size_t i = 0; i < m_column_indexes.size(); i++) { const ColumnBase& cb = row_indexes->get_column_base(m_column_indexes[i]); const ColumnTemplateBase* ctb = dynamic_cast<const ColumnTemplateBase*>(&cb); REALM_ASSERT(ctb); if (const StringEnumColumn* cse = dynamic_cast<const StringEnumColumn*>(&cb)) m_string_enum_columns[i] = cse; else m_columns[i] = ctb; } }
MemRef BasicArray<T>::slice(size_t offset, size_t size, Allocator& target_alloc) const { REALM_ASSERT(is_attached()); // FIXME: This can be optimized as a single contiguous copy // operation. BasicArray slice(target_alloc); _impl::ShallowArrayDestroyGuard dg(&slice); slice.create(); // Throws size_t begin = offset; size_t end = offset + size; for (size_t i = begin; i != end; ++i) { T value = get(i); slice.add(value); // Throws } dg.release(); return slice.get_mem(); }
ValueType Object::get_property_value_impl(ContextType& ctx, const Property &property) { verify_attached(); size_t column = property.table_column; if (is_nullable(property.type) && m_row.is_null(column)) { return ctx.null_value(); } if (is_array(property.type) && property.type != PropertyType::LinkingObjects) { REALM_ASSERT(property.type == PropertyType::Object); return ctx.box(List(m_realm, m_row.get_linklist(column))); } switch (property.type & ~PropertyType::Flags) { case PropertyType::Bool: return ctx.box(m_row.get_bool(column)); case PropertyType::Int: return ctx.box(m_row.get_int(column)); case PropertyType::Float: return ctx.box(m_row.get_float(column)); case PropertyType::Double: return ctx.box(m_row.get_double(column)); case PropertyType::String: return ctx.box(m_row.get_string(column)); case PropertyType::Data: return ctx.box(m_row.get_binary(column)); case PropertyType::Date: return ctx.box(m_row.get_timestamp(column)); case PropertyType::Any: return ctx.box(m_row.get_mixed(column)); case PropertyType::Object: { auto linkObjectSchema = m_realm->schema().find(property.object_type); TableRef table = ObjectStore::table_for_object_type(m_realm->read_group(), property.object_type); return ctx.box(Object(m_realm, *linkObjectSchema, table->get(m_row.get_link(column)))); } case PropertyType::LinkingObjects: { auto target_object_schema = m_realm->schema().find(property.object_type); auto link_property = target_object_schema->property_for_name(property.link_origin_property_name); TableRef table = ObjectStore::table_for_object_type(m_realm->read_group(), target_object_schema->name); auto tv = m_row.get_table()->get_backlink_view(m_row.get_index(), table.get(), link_property->table_column); return ctx.box(Results(m_realm, std::move(tv))); } default: REALM_UNREACHABLE(); } }
inline bool Descriptor::operator==(const Descriptor& d) const noexcept { REALM_ASSERT(is_attached()); REALM_ASSERT(d.is_attached()); return *m_spec == *d.m_spec; }
inline ConstTableRef Descriptor::get_link_target(size_t col_ndx) const noexcept { REALM_ASSERT(is_attached()); REALM_ASSERT(is_root()); return get_root_table()->get_link_target(col_ndx); }
inline size_t Descriptor::get_column_link_target(size_t column_ndx) const noexcept { REALM_ASSERT(is_attached()); return m_spec->get_opposite_link_table_ndx(column_ndx); }
inline size_t Descriptor::get_column_index(StringData name) const noexcept { REALM_ASSERT(is_attached()); return m_spec->get_column_index(name); }
inline bool Descriptor::is_nullable(size_t ndx) const noexcept { REALM_ASSERT(is_attached()); return m_spec->get_column_attr(ndx) & col_attr_Nullable; }
inline DataType Descriptor::get_column_type(size_t ndx) const noexcept { REALM_ASSERT(is_attached()); return m_spec->get_public_column_type(ndx); }
inline StringData Descriptor::get_column_name(size_t ndx) const noexcept { REALM_ASSERT(is_attached()); return m_spec->get_column_name(ndx); }
inline size_t Descriptor::get_column_count() const noexcept { REALM_ASSERT(is_attached()); return m_spec->get_public_column_count(); }
template <class T> T& get_as() { REALM_ASSERT(type == GetInstructionType<T>::value); return *reinterpret_cast<T*>(&m_storage); }
inline bool Utf8x16<Char16, Traits16>::to_utf16(const char*& in_begin, const char* const in_end, Char16*& out_begin, Char16* const out_end) { typedef std::char_traits<char> traits8; bool invalid = false; const char* in = in_begin; Char16* out = out_begin; while (in != in_end) { if (REALM_UNLIKELY(out == out_end)) { break; // Need space in output buffer } REALM_ASSERT(&in[0] >= in_begin && &in[0] < in_end); uint_fast16_t v1 = uint_fast16_t(traits8::to_int_type(in[0])); if (REALM_LIKELY(v1 < 0x80)) { // One byte // UTF-8 layout: 0xxxxxxx *out++ = Traits16::to_char_type(v1); in += 1; continue; } if (REALM_UNLIKELY(v1 < 0xC0)) { invalid = true; break; // Invalid first byte of UTF-8 sequence } if (REALM_LIKELY(v1 < 0xE0)) { // Two bytes if (REALM_UNLIKELY(in_end - in < 2)) { invalid = true; break; // Incomplete UTF-8 sequence } REALM_ASSERT(&in[1] >= in_begin && &in[1] < in_end); uint_fast16_t v2 = uint_fast16_t(traits8::to_int_type(in[1])); // UTF-8 layout: 110xxxxx 10xxxxxx if (REALM_UNLIKELY((v2 & 0xC0) != 0x80)) { invalid = true; break; // Invalid continuation byte } uint_fast16_t v = uint_fast16_t(((v1 & 0x1F) << 6) | ((v2 & 0x3F) << 0)); if (REALM_UNLIKELY(v < 0x80)) { invalid = true; break; // Overlong encoding is invalid } *out++ = Traits16::to_char_type(v); in += 2; continue; } if (REALM_LIKELY(v1 < 0xF0)) { // Three bytes if (REALM_UNLIKELY(in_end - in < 3)) { invalid = true; break; // Incomplete UTF-8 sequence } REALM_ASSERT(&in[1] >= in_begin && &in[2] < in_end); uint_fast16_t v2 = uint_fast16_t(traits8::to_int_type(in[1])); uint_fast16_t v3 = uint_fast16_t(traits8::to_int_type(in[2])); // UTF-8 layout: 1110xxxx 10xxxxxx 10xxxxxx if (REALM_UNLIKELY((v2 & 0xC0) != 0x80 || (v3 & 0xC0) != 0x80)) { invalid = true; break; // Invalid continuation byte } uint_fast16_t v = uint_fast16_t(((v1 & 0x0F) << 12) | ((v2 & 0x3F) << 6) | ((v3 & 0x3F) << 0)); if (REALM_UNLIKELY(v < 0x800)) { invalid = true; break; // Overlong encoding is invalid } if (REALM_UNLIKELY(0xD800 <= v && v < 0xE000)) { invalid = true; break; // Illegal code point range (reserved for UTF-16 surrogate pairs) } *out++ = Traits16::to_char_type(v); in += 3; continue; } if (REALM_UNLIKELY(out + 1 == out_end)) { break; // Need space in output buffer for surrogate pair } if (REALM_LIKELY(v1 < 0xF8)) { // Four bytes if (REALM_UNLIKELY(in_end - in < 4)) { invalid = true; break; // Incomplete UTF-8 sequence } uint_fast32_t w1 = uint_fast32_t(v1); // 16 bit -> 32 bit REALM_ASSERT(&in[1] >= in_begin && &in[3] < in_end); uint_fast32_t v2 = uint_fast32_t(traits8::to_int_type(in[1])); // 32 bit intended uint_fast16_t v3 = uint_fast16_t(traits8::to_int_type(in[2])); // 16 bit intended uint_fast16_t v4 = uint_fast16_t(traits8::to_int_type(in[3])); // 16 bit intended // UTF-8 layout: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx if (REALM_UNLIKELY((v2 & 0xC0) != 0x80 || (v3 & 0xC0) != 0x80 || (v4 & 0xC0) != 0x80)) { invalid = true; break; // Invalid continuation byte } uint_fast32_t v = uint_fast32_t(((w1 & 0x07) << 18) | // Parenthesis is 32 bit partial result ((v2 & 0x3F) << 12) | // Parenthesis is 32 bit partial result ((v3 & 0x3F) << 6) | // Parenthesis is 16 bit partial result ((v4 & 0x3F) << 0)); // Parenthesis is 16 bit partial result if (REALM_UNLIKELY(v < 0x10000)) { invalid = true; break; // Overlong encoding is invalid } if (REALM_UNLIKELY(0x110000 <= v)) { invalid = true; break; // Code point too big for UTF-16 } v -= 0x10000l; *out++ = Traits16::to_char_type(0xD800 + (v / 0x400)); *out++ = Traits16::to_char_type(0xDC00 + (v % 0x400)); in += 4; continue; } // Invalid first byte of UTF-8 sequence, or code point too big for UTF-16 invalid = true; break; } REALM_ASSERT(in >= in_begin && in <= in_end); REALM_ASSERT(out >= out_begin && out <= out_end); in_begin = in; out_begin = out; return !invalid; }
inline bool Utf8x16<Char16, Traits16>::to_utf8(const Char16*& in_begin, const Char16* const in_end, char*& out_begin, char* const out_end) { typedef std::char_traits<char> traits8; typedef typename traits8::int_type traits8_int_type; bool invalid = false; const Char16* in = in_begin; char* out = out_begin; while (in != in_end) { REALM_ASSERT(&in[0] >= in_begin && &in[0] < in_end); uint_fast16_t v1 = uint_fast16_t(Traits16::to_int_type(in[0])); if (REALM_LIKELY(v1 < 0x80)) { if (REALM_UNLIKELY(out == out_end)) { break; // Not enough output buffer space } // UTF-8 layout: 0xxxxxxx REALM_ASSERT(out >= out_begin && out < out_end); *out++ = traits8::to_char_type(traits8_int_type(v1)); in += 1; continue; } if (REALM_LIKELY(v1 < 0x800)) { if (REALM_UNLIKELY(out_end - out < 2)) { break; // Not enough output buffer space } // UTF-8 layout: 110xxxxx 10xxxxxx *out++ = traits8::to_char_type(traits8_int_type(0xC0 + v1 / 0x40)); REALM_ASSERT(out >= out_begin && out < out_end); *out++ = traits8::to_char_type(traits8_int_type(0x80 + v1 % 0x40)); in += 1; continue; } if (REALM_LIKELY(v1 < 0xD800 || 0xE000 <= v1)) { if (REALM_UNLIKELY(out_end - out < 3)) { break; // Not enough output buffer space } // UTF-8 layout: 1110xxxx 10xxxxxx 10xxxxxx REALM_ASSERT(out >= out_begin && out + 2 < out_end); *out++ = traits8::to_char_type(traits8_int_type(0xE0 + v1 / 0x1000)); *out++ = traits8::to_char_type(traits8_int_type(0x80 + v1 / 0x40 % 0x40)); *out++ = traits8::to_char_type(traits8_int_type(0x80 + v1 % 0x40)); in += 1; continue; } // Surrogate pair if (REALM_UNLIKELY(out_end - out < 4)) { break; // Not enough output buffer space } if (REALM_UNLIKELY(0xDC00 <= v1)) { invalid = true; break; // Invalid first half of surrogate pair } if (REALM_UNLIKELY(in + 1 == in_end)) { invalid = true; break; // Incomplete surrogate pair } REALM_ASSERT(&in[1] >= in_begin && &in[1] < in_end); uint_fast16_t v2 = uint_fast16_t(Traits16::to_int_type(in[1])); if (REALM_UNLIKELY(v2 < 0xDC00 || 0xE000 <= v2)) { invalid = true; break; // Invalid second half of surrogate pair } uint_fast32_t v = 0x10000l + (uint_fast32_t(v1 - 0xD800) * 0x400 + (v2 - 0xDC00)); // UTF-8 layout: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx REALM_ASSERT(out >= out_begin && out + 3 < out_end); *out++ = traits8::to_char_type(traits8_int_type(0xF0 + v / 0x40000)); *out++ = traits8::to_char_type(traits8_int_type(0x80 + v / 0x1000 % 0x40)); *out++ = traits8::to_char_type(traits8_int_type(0x80 + v / 0x40 % 0x40)); *out++ = traits8::to_char_type(traits8_int_type(0x80 + v % 0x40)); in += 2; } REALM_ASSERT(in >= in_begin && in <= in_end); REALM_ASSERT(out >= out_begin && out <= out_end); in_begin = in; out_begin = out; return !invalid; }
template <class A, class B, class C, class D> bool operator()(A, B, C, D) const { REALM_ASSERT(false); return false; }