Пример #1
0
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();
}
Пример #2
0
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
}
Пример #3
0
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
}
Пример #4
0
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();
}
Пример #5
0
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;
}
Пример #6
0
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
}
Пример #7
0
 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
 }
Пример #8
0
// 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
}
Пример #9
0
// 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;
}
Пример #10
0
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
}
Пример #11
0
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();
}
Пример #12
0
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);
}
Пример #13
0
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);
}
Пример #14
0
    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();
        }
    }
Пример #15
0
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;
}
Пример #16
0
        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;
            }
        }
Пример #17
0
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();
}
Пример #18
0
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();
    }
}
Пример #19
0
inline bool Descriptor::operator==(const Descriptor& d) const noexcept
{
    REALM_ASSERT(is_attached());
    REALM_ASSERT(d.is_attached());
    return *m_spec == *d.m_spec;
}
Пример #20
0
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);
}
Пример #21
0
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);
}
Пример #22
0
inline size_t Descriptor::get_column_index(StringData name) const noexcept
{
    REALM_ASSERT(is_attached());
    return m_spec->get_column_index(name);
}
Пример #23
0
inline bool Descriptor::is_nullable(size_t ndx) const noexcept
{
    REALM_ASSERT(is_attached());
    return m_spec->get_column_attr(ndx) & col_attr_Nullable;
}
Пример #24
0
inline DataType Descriptor::get_column_type(size_t ndx) const noexcept
{
    REALM_ASSERT(is_attached());
    return m_spec->get_public_column_type(ndx);
}
Пример #25
0
inline StringData Descriptor::get_column_name(size_t ndx) const noexcept
{
    REALM_ASSERT(is_attached());
    return m_spec->get_column_name(ndx);
}
Пример #26
0
inline size_t Descriptor::get_column_count() const noexcept
{
    REALM_ASSERT(is_attached());
    return m_spec->get_public_column_count();
}
Пример #27
0
 template <class T> T& get_as()
 {
     REALM_ASSERT(type == GetInstructionType<T>::value);
     return *reinterpret_cast<T*>(&m_storage);
 }
Пример #28
0
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;
}
Пример #29
0
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;
}
Пример #30
0
template <class A, class B, class C, class D> bool operator()(A, B, C, D) const { REALM_ASSERT(false); return false; }