bool operator()(StringData v1, const char* v1_upper, const char* v1_lower, StringData v2, bool = false, bool = false) const
    {
        if (v1.is_null() != v2.is_null())
            return false;

        return v1.size() == v2.size() && equal_case_fold(v2, v1_upper, v1_lower);
    }
    bool operator()(StringData v1, const char* v1_upper, const char* v1_lower, StringData v2, bool = false, bool = false) const
    {
        if (v2.is_null() && !v1.is_null())
            return false;

        if (v1.size() == 0 && !v2.is_null())
            return true;

        return search_case_fold(v2, v1_upper, v1_lower, v1.size()) != v2.size();
    }
    // Slow version, used if caller hasn't stored an upper and lower case version
    bool operator()(StringData v1, StringData v2, bool = false, bool = false) const
    {
        if (v2.is_null() && !v1.is_null())
            return false;

        if (v1.size() > v2.size())
            return false;
        std::string v1_upper = case_map(v1, true, IgnoreErrors);
        std::string v1_lower = case_map(v1, false, IgnoreErrors);
        return equal_case_fold(v2.suffix(v1.size()), v1_upper.c_str(), v1_lower.c_str());
    }
    // Slow version, used if caller hasn't stored an upper and lower case version
    bool operator()(StringData v1, StringData v2, bool = false, bool = false) const
    {
        if (v1.is_null() != v2.is_null())
            return true;

        if (v1.size() != v2.size())
            return true;        
        std::string v1_upper = case_map(v1, true);
        std::string v1_lower = case_map(v1, false);
        return !equal_case_fold(v2, v1_upper.c_str(), v1_lower.c_str());
    }
    // Slow version, used if caller hasn't stored an upper and lower case version
    bool operator()(StringData v1, StringData v2, bool = false, bool = false) const
    {
        if (v2.is_null() && !v1.is_null())
            return false;

        if (v1.size() == 0 && !v2.is_null())
            return true;

        std::string v1_upper = case_map(v1, true, IgnoreErrors);
        std::string v1_lower = case_map(v1, false, IgnoreErrors);
        return search_case_fold(v2, v1_upper.c_str(), v1_lower.c_str(), v1.size()) != v2.size();
    }
Exemple #6
0
util::Optional<std::string> SyncFileActionMetadata::new_name() const
{
    REALM_ASSERT(m_realm);
    m_realm->verify_thread();
    StringData result = m_row.get_string(m_schema.idx_new_name);
    return result.is_null() ? util::none : util::make_optional(std::string(result));
}
inline void StringEnumColumn::add(StringData value)
{
    REALM_ASSERT_DEBUG(!(!m_nullable && value.is_null()));
    size_t row_ndx = realm::npos;
    size_t num_rows = 1;
    do_insert(row_ndx, value, num_rows); // Throws
}
Exemple #8
0
string concat_stringdata(const char* message, StringData strData)
{
    if (strData.is_null()) {
        return std::string(message);
    }
    return std::string(message) + std::string(strData.data(), strData.size());
}
Exemple #9
0
util::Optional<std::string> SyncUserMetadata::get_optional_string_field(size_t col_idx) const
{
    REALM_ASSERT(m_realm);
    m_realm->verify_thread();
    StringData result = m_row.get_string(col_idx);
    return result.is_null() ? util::none : util::make_optional(std::string(result));
}
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 void StringEnumColumn::insert(size_t row_ndx, StringData value)
{
    REALM_ASSERT_DEBUG(!(!m_nullable && value.is_null()));
    size_t column_size = this->size();
    REALM_ASSERT_3(row_ndx, <=, column_size);
    size_t num_rows = 1;
    bool is_append = row_ndx == column_size;
    do_insert(row_ndx, value, num_rows, is_append); // Throws
}
Exemple #12
0
inline void BinaryColumn::set_string(size_t ndx, StringData value)
{
    if (value.is_null() && !m_nullable)
        throw LogicError(LogicError::column_not_nullable);

    BinaryData bin(value.data(), value.size());
    bool add_zero_term = true;
    set(ndx, bin, add_zero_term);
}
Exemple #13
0
REALM_EXPORT size_t table_get_string(const Table* table_ptr, size_t column_ndx, size_t row_ndx, uint16_t * datatochsarp, size_t bufsize, bool* is_null)
{
    return handle_errors([&]() -> size_t {
        StringData fielddata = table_ptr->get_string(column_ndx, row_ndx);
        if ((*is_null = fielddata.is_null()))
            return 0;
        
        return stringdata_to_csharpstringbuffer(fielddata, datatochsarp, bufsize);
    });
}
Exemple #14
0
 REALM_EXPORT size_t object_get_string(const Object& object, size_t property_ndx, uint16_t * datatochsarp, size_t bufsize, bool* is_null, NativeException::Marshallable& ex)
 {
     return handle_errors(ex, [&]() -> size_t {
         verify_can_get(object);
         
         const size_t column_ndx = get_column_index(object, property_ndx);
         const StringData fielddata(object.row().get_string(column_ndx));
         if ((*is_null = fielddata.is_null()))
             return 0;
         
         return stringdata_to_csharpstringbuffer(fielddata, datatochsarp, bufsize);
     });
 }
Exemple #15
0
// Index works as follows: All non-NULL values are stored as if they had appended an 'X' character at the end. So
// "foo" is stored as if it was "fooX", and "" (empty string) is stored as "X". And NULLs are stored as empty strings.
inline StringIndex::key_type StringIndex::create_key(StringData str, size_t offset) noexcept
{
    if (str.is_null())
        return 0;

    if (offset > str.size())
        return 0;

    // for very short strings
    size_t tail = str.size() - offset;
    if (tail <= sizeof(key_type)-1) {
        char buf[sizeof(key_type)];
        memset(buf, 0, sizeof(key_type));
        buf[tail] = 'X';
        memcpy(buf, str.data() + offset, tail);
        return create_key(StringData(buf, tail + 1));
    }
    // else fallback
    return create_key(str.substr(offset));
}
inline int StringColumn::compare_values(std::size_t row1, std::size_t row2) const
{
    StringData a = get(row1);
    StringData b = get(row2);

    if (a.is_null() && !b.is_null())
        return 1;
    else if (b.is_null() && !a.is_null())
        return -1;
    else if (a.is_null() && b.is_null())
        return 0;

    if (a == b)
        return 0;
    return utf8_compare(a, b) ? 1 : -1;
}
Exemple #17
0
jstring to_jstring(JNIEnv* env, StringData str)
{
    if (str.is_null()) {
        return NULL;
    }

    // For efficiency, if the incoming UTF-8 string is sufficiently
    // small, we will attempt to store the UTF-16 output into a stack
    // allocated buffer of static size. Otherwise we will have to
    // dynamically allocate the output buffer after calculating its
    // size.

    const size_t stack_buf_size = 48;
    jchar stack_buf[stack_buf_size];
    std::unique_ptr<jchar[]> dyn_buf;

    const char* in_begin = str.data();
    const char* in_end = str.data() + str.size();
    jchar* out_begin = stack_buf;
    jchar* out_curr = stack_buf;
    jchar* out_end = stack_buf + stack_buf_size;

    typedef Utf8x16<jchar, JcharTraits> Xcode;

    if (str.size() <= stack_buf_size) {
        size_t retcode = Xcode::to_utf16(in_begin, in_end, out_curr, out_end);
        if (retcode != 0) {
            throw std::runtime_error(string_to_hex("Failure when converting short string to UTF-16", str, in_begin, in_end,
                                              out_curr, out_end, size_t(0), retcode));
        }
        if (in_begin == in_end) {
            goto transcode_complete;
        }
    }

    {
        const char* in_begin2 = in_begin;
        size_t error_code;
        size_t size = Xcode::find_utf16_buf_size(in_begin2, in_end, error_code);
        if (in_begin2 != in_end) {
            throw std::runtime_error(string_to_hex("Failure when computing UTF-16 size", str, in_begin, in_end, out_curr,
                                              out_end, size, error_code));
        }
        if (int_add_with_overflow_detect(size, stack_buf_size)) {
            throw std::runtime_error("String size overflow");
        }
        dyn_buf.reset(new jchar[size]);
        out_curr = copy(out_begin, out_curr, dyn_buf.get());
        out_begin = dyn_buf.get();
        out_end = dyn_buf.get() + size;
        size_t retcode = Xcode::to_utf16(in_begin, in_end, out_curr, out_end);
        if (retcode != 0) {
            throw std::runtime_error(string_to_hex("Failure when converting long string to UTF-16", str, in_begin, in_end,
                                              out_curr, out_end, size_t(0), retcode));
        }
        REALM_ASSERT(in_begin == in_end);
    }

transcode_complete : {
    jsize out_size;
    if (int_cast_with_overflow_detect(out_curr - out_begin, out_size)) {
        throw std::runtime_error("String size overflow");
    }

    return env->NewString(out_begin, out_size);
}
}
inline void StringColumn::set_string(std::size_t row_ndx, StringData value)
{
    REALM_ASSERT(!(value.is_null() && !m_nullable));
    set(row_ndx, value); // Throws
}