Add +m_string_it_set_ref
This commit is contained in:
1 parent
ecfa4a9152
commit
2628536d20
3 files changed
+105
No files matched your search
@@ -5709,6 +5709,14 @@ It returns -1 in case of error in decoding the UTF8 string.
|
|||||||
|
|
||||||
Return the position in the stream of the iterator 'it'.
|
Return the position in the stream of the iterator 'it'.
|
||||||
|
|
||||||
|
##### void string\_it\_set\_ref(string\_it\_t it, string\_t str, string\_unicode\_t u)
|
||||||
|
|
||||||
|
Replace the unicode code point referenced by 'it' to the unicode code point 'u'
|
||||||
|
in the string 'str'.
|
||||||
|
If 'u' is 0, then it will resize the string to the size of the referenced iterator
|
||||||
|
only keeping the unicode code points before the iterator.
|
||||||
|
'it' shall be a valid iterator of 'str'.
|
||||||
|
|
||||||
##### bool string\_it\_equal\_p (const string\_it\_t it1, const string\_it\_t it2)
|
##### bool string\_it\_equal\_p (const string\_it\_t it1, const string\_it\_t it2)
|
||||||
|
|
||||||
Return true if both iterators reference the same position, false otherwise.
|
Return true if both iterators reference the same position, false otherwise.
|
||||||
|
|||||||
+51
@@ -1863,6 +1863,56 @@ m_string_cref (m_string_it_t it)
|
|||||||
return &it->u;
|
return &it->u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update the value referenced by the iterator to the given value */
|
||||||
|
static inline void
|
||||||
|
m_string_it_set_ref(m_string_it_t it, m_string_t s, m_string_unicode_t new_u)
|
||||||
|
{
|
||||||
|
M_STR1NG_IT_CONTRACT(it);
|
||||||
|
M_STR1NG_CONTRACT(s);
|
||||||
|
M_ASSERT(s == it->string);
|
||||||
|
char *ptr = m_str1ng_get_cstr(s);
|
||||||
|
M_ASSUME( it->ptr >= ptr);
|
||||||
|
size_t offset = (size_t) (it->ptr - ptr);
|
||||||
|
// Special case if the unicode codepoint is 0
|
||||||
|
if (new_u == 0) {
|
||||||
|
// Null the string
|
||||||
|
m_str1ng_set_size(s, offset);
|
||||||
|
ptr[offset] = 0;
|
||||||
|
M_STR1NG_IT_CONTRACT(it);
|
||||||
|
M_STR1NG_CONTRACT(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Encode the new unicode code point & compute its size
|
||||||
|
char buffer[4+1];
|
||||||
|
m_str1ng_utf8_encode(buffer, new_u);
|
||||||
|
size_t new_u_size = strlen(buffer);
|
||||||
|
// Compute the size of the old unicode code point
|
||||||
|
m_str1ng_utf8_state_e state = M_STR1NG_UTF8_STARTING;
|
||||||
|
m_string_unicode_t old_u = 0;
|
||||||
|
const char *str = it->ptr;
|
||||||
|
do {
|
||||||
|
m_str1ng_utf8_decode(*str, &state, &old_u);
|
||||||
|
str++;
|
||||||
|
} while (state != M_STR1NG_UTF8_STARTING && state != M_STR1NG_UTF8_ERROR && *str != 0);
|
||||||
|
M_ASSUME( str > it->ptr);
|
||||||
|
size_t old_u_size = (size_t) (str - it->ptr);
|
||||||
|
// We need to replace old_u by new_u. Both are variable length
|
||||||
|
size_t str_size = m_string_size(s);
|
||||||
|
m_str1ng_fit2size(s, str_size + new_u_size - old_u_size + 1);
|
||||||
|
ptr = m_str1ng_get_cstr(s); // ptr may be reallocated!
|
||||||
|
if (new_u_size != old_u_size) {
|
||||||
|
M_ASSUME( str_size+1 > (offset + old_u_size) );
|
||||||
|
memmove(&ptr[offset+new_u_size], &ptr[offset + old_u_size],
|
||||||
|
str_size+1 - offset - old_u_size);
|
||||||
|
}
|
||||||
|
memcpy(&ptr[offset], &buffer[0], new_u_size);
|
||||||
|
m_str1ng_set_size(s, str_size + new_u_size - old_u_size);
|
||||||
|
it->ptr = &ptr[offset];
|
||||||
|
M_STR1NG_IT_CONTRACT(it);
|
||||||
|
M_STR1NG_CONTRACT(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Push unicode code point into string, encoding it in UTF8 */
|
/* Push unicode code point into string, encoding it in UTF8 */
|
||||||
static inline void
|
static inline void
|
||||||
m_string_push_u (m_string_t str, m_string_unicode_t u)
|
m_string_push_u (m_string_t str, m_string_unicode_t u)
|
||||||
@@ -2714,6 +2764,7 @@ namespace m_lib {
|
|||||||
#define string_it_pos m_string_it_pos
|
#define string_it_pos m_string_it_pos
|
||||||
#define string_it_get_pos m_string_it_get_pos
|
#define string_it_get_pos m_string_it_get_pos
|
||||||
#define string_previous m_string_previous
|
#define string_previous m_string_previous
|
||||||
|
#define string_it_set_ref m_string_it_set_ref
|
||||||
|
|
||||||
#define STRING_CTE M_STRING_CTE
|
#define STRING_CTE M_STRING_CTE
|
||||||
#define STRING_DECL_INIT M_STRING_DECL_INIT
|
#define STRING_DECL_INIT M_STRING_DECL_INIT
|
||||||
|
|||||||
@@ -172,6 +172,52 @@ static void test_utf8_it(void)
|
|||||||
assert(!string_it_equal_p(it, it2));
|
assert(!string_it_equal_p(it, it2));
|
||||||
|
|
||||||
string_clear(s);
|
string_clear(s);
|
||||||
|
|
||||||
|
/* Test replacing of unicode */
|
||||||
|
string_init(s);
|
||||||
|
for (string_unicode_t u = 1; u < 0x10ffff; u+=3) {
|
||||||
|
if (u < 0xD800U || u > 0xDFFFU) {
|
||||||
|
for(int c1 = 0 ; c1 <= 3; c1+=2) {
|
||||||
|
for(int c2 = 0 ; c2 <= 20; c2+=5) {
|
||||||
|
const string_unicode_t u_tab[] = { 0, 'B', 300, 45215, 0x10fffe};
|
||||||
|
for(int c3 = 0 ; c3 < 5; c3++) {
|
||||||
|
// Generate string
|
||||||
|
string_reset(s);
|
||||||
|
for(int j = 0; j < c1; j++)
|
||||||
|
string_push_back(s, 'A');
|
||||||
|
string_push_u(s, u);
|
||||||
|
for(int j = 0; j < c2; j++)
|
||||||
|
string_push_back(s, 'C');
|
||||||
|
// Replace iterator in string
|
||||||
|
string_it(it, s);
|
||||||
|
for(int j = 0; j < c1; j++)
|
||||||
|
string_next(it);
|
||||||
|
assert( string_get_cref(it) == u);
|
||||||
|
string_it_set_ref(it, s, u_tab[c3]);
|
||||||
|
if (u_tab[c3] != 0) {
|
||||||
|
assert( string_get_cref(it) == u_tab[c3]);
|
||||||
|
}
|
||||||
|
// Check constructed string
|
||||||
|
string_it(it, s);
|
||||||
|
for(int j = 0; j < c1; j++) {
|
||||||
|
assert( string_get_cref(it) == 'A');
|
||||||
|
string_next(it);
|
||||||
|
}
|
||||||
|
if (u_tab[c3] != 0) {
|
||||||
|
assert( *string_cref(it) == u_tab[c3]);
|
||||||
|
string_next(it);
|
||||||
|
for(int j = 0; j < c2; j++) {
|
||||||
|
assert( string_get_cref(it) == 'C');
|
||||||
|
string_next(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(string_end_p(it));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
string_clear(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void call_string_cat_vprintf(string_t s, const char format[], ...)
|
static void call_string_cat_vprintf(string_t s, const char format[], ...)
|
||||||
|
|||||||
Reference in new issue
Block a user