Ejemplo n.º 1
0
inline void Descriptor::insert_column_link(size_t col_ndx, DataType type, StringData name, Table& target,
                                           LinkType link_type)
{
    typedef _impl::TableFriend tf;

    if (REALM_UNLIKELY(!is_attached() || !target.is_attached()))
        throw LogicError(LogicError::detached_accessor);
    if (REALM_UNLIKELY(col_ndx > get_column_count()))
        throw LogicError(LogicError::column_index_out_of_range);
    if (REALM_UNLIKELY(!tf::is_link_type(ColumnType(type))))
        throw LogicError(LogicError::illegal_type);
    if (REALM_UNLIKELY(!is_root()))
        throw LogicError(LogicError::wrong_kind_of_descriptor);
    // Both origin and target must be group-level tables, and in the same group.
    Group* origin_group = tf::get_parent_group(*get_root_table());
    Group* target_group = tf::get_parent_group(target);
    if (!origin_group || !target_group)
        throw LogicError(LogicError::wrong_kind_of_table);
    if (origin_group != target_group)
        throw LogicError(LogicError::group_mismatch);

    LinkTargetInfo link(&target);
    tf::insert_column(*this, col_ndx, type, name, link); // Throws
    adj_insert_column(col_ndx);

    tf::set_link_type(*get_root_table(), col_ndx, link_type); // Throws
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
inline void Descriptor::rename_column(size_t col_ndx, StringData name)
{
    typedef _impl::TableFriend tf;

    if (REALM_UNLIKELY(!is_attached()))
        throw LogicError(LogicError::detached_accessor);
    if (REALM_UNLIKELY(col_ndx >= get_column_count()))
        throw LogicError(LogicError::column_index_out_of_range);

    tf::rename_column(*this, col_ndx, name); // Throws
}
Ejemplo n.º 4
0
inline void Descriptor::set_link_type(size_t col_ndx, LinkType link_type)
{
    typedef _impl::TableFriend tf;

    if (REALM_UNLIKELY(!is_attached()))
        throw LogicError(LogicError::detached_accessor);
    if (REALM_UNLIKELY(col_ndx >= get_column_count()))
        throw LogicError(LogicError::column_index_out_of_range);
    if (REALM_UNLIKELY(!tf::is_link_type(ColumnType(get_column_type(col_ndx)))))
        throw LogicError(LogicError::illegal_type);

    tf::set_link_type(*get_root_table(), col_ndx, link_type); // Throws
}
Ejemplo n.º 5
0
inline size_t Utf8x16<Char16, Traits16>::find_utf16_buf_size(const char*& in_begin,
                                                                  const char* const in_end)
{
        typedef std::char_traits<char> traits8;
    size_t num_out = 0;
    const char* in = in_begin;
    while (in != in_end) {
        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
            num_out += 1;
            in += 1;
            continue;
        }
        if (REALM_UNLIKELY(v1 < 0xC0)) {
            break; // Invalid first byte of UTF-8 sequence
        }
        if (REALM_LIKELY(v1 < 0xE0)) { // Two bytes
            if (REALM_UNLIKELY(in_end - in < 2)) {
                break; // Incomplete UTF-8 sequence
            }
            num_out += 1;
            in += 2;
            continue;
        }
        if (REALM_LIKELY(v1 < 0xF0)) { // Three bytes
            if (REALM_UNLIKELY(in_end - in < 3)) {
                break; // Incomplete UTF-8 sequence
            }
            num_out += 1;
            in += 3;
            continue;
        }
        if (REALM_LIKELY(v1 < 0xF8)) { // Four bytes
            if (REALM_UNLIKELY(in_end - in < 4)) {
                break; // Incomplete UTF-8 sequence
            }
            num_out += 2; // Surrogate pair
            in += 4;
            continue;
        }
        // Invalid first byte of UTF-8 sequence, or code point too big for UTF-16
        break;
    }

    REALM_ASSERT(in >= in_begin && in <= in_end);
    in_begin  = in;
    return num_out;
}
Ejemplo n.º 6
0
inline size_t ChangesetInputStream::next_block(const char*& begin, const char*& end)
{
    for (;;) {
        if (REALM_UNLIKELY(m_changesets_begin == m_changesets_end)) {
            if (m_begin_version == m_end_version)
                return 0; // End of input
            version_type n = sizeof m_changesets / sizeof m_changesets[0];
            version_type avail = m_end_version - m_begin_version;
            if (n > avail)
                n = avail;
            version_type end_version = m_begin_version + n;
            m_history.get_changesets(m_begin_version, end_version, m_changesets);
            m_begin_version = end_version;
            m_changesets_begin = m_changesets;
            m_changesets_end = m_changesets_begin + n;
        }

        BinaryData changeset = *m_changesets_begin++;
        if (changeset.size() > 0) {
            begin = changeset.data();
            end   = changeset.data() + changeset.size();
            return changeset.size();
        }
    }
}
Ejemplo n.º 7
0
inline void Descriptor::insert_column(size_t col_ndx, DataType type, StringData name, DescriptorRef* subdesc,
                                      bool nullable)
{
    typedef _impl::TableFriend tf;

    if (REALM_UNLIKELY(!is_attached()))
        throw LogicError(LogicError::detached_accessor);
    if (REALM_UNLIKELY(col_ndx > get_column_count()))
        throw LogicError(LogicError::column_index_out_of_range);
    if (REALM_UNLIKELY(tf::is_link_type(ColumnType(type))))
        throw LogicError(LogicError::illegal_type);

    LinkTargetInfo invalid_link;
    tf::insert_column(*this, col_ndx, type, name, invalid_link, nullable); // Throws
    adj_insert_column(col_ndx);
    if (subdesc && type == type_Table)
        *subdesc = get_subdescriptor(col_ndx);
}
Ejemplo n.º 8
0
    bool next_block(const char*& begin, const char*& end) override
    {
        while (m_valid) {
            BinaryData actual = m_changesets_begin->get_next();

            if (actual.size() > 0) {
                begin = actual.data();
                end = actual.data() + actual.size();
                return true;
            }

            m_changesets_begin++;

            if (REALM_UNLIKELY(m_changesets_begin == m_changesets_end)) {
                get_changeset();
            }
        }
        return false; // End of input
    }
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
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;
}