]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Added uni_utf8_partial_strlen_n()
authorTimo Sirainen <tss@iki.fi>
Sat, 10 Jan 2015 02:30:40 +0000 (04:30 +0200)
committerTimo Sirainen <tss@iki.fi>
Sat, 10 Jan 2015 02:30:40 +0000 (04:30 +0200)
src/lib/test-unichar.c
src/lib/unichar.c
src/lib/unichar.h

index 3221e19a094f838c1d43015e6d5afaf0f1317dda..6607809616322f3153ef13c7057f8f2833d514ac 100644 (file)
@@ -5,6 +5,20 @@
 #include "buffer.h"
 #include "unichar.h"
 
+static void test_unichar_uni_utf8_partial_strlen_n(void)
+{
+       static const char input[] = "\xC3\xA4\xC3\xA4";
+       size_t pos;
+
+       test_begin("uni_utf8_partial_strlen_n()");
+       test_assert(uni_utf8_partial_strlen_n(input, 1, &pos) == 0 && pos == 0);
+       test_assert(uni_utf8_partial_strlen_n(input, 2, &pos) == 1 && pos == 2);
+       test_assert(uni_utf8_partial_strlen_n(input, 3, &pos) == 1 && pos == 2);
+       test_assert(uni_utf8_partial_strlen_n(input, 4, &pos) == 2 && pos == 4);
+       test_assert(uni_utf8_partial_strlen_n(input, (size_t)-1, &pos) == 2 && pos == 4);
+       test_end();
+}
+
 void test_unichar(void)
 {
        static const char overlong_utf8[] = "\xf8\x80\x95\x81\xa1";
@@ -32,4 +46,6 @@ void test_unichar(void)
        test_assert(!uni_utf8_str_is_valid(overlong_utf8));
        test_assert(uni_utf8_get_char(overlong_utf8, &chr2) < 0);
        test_end();
+
+       test_unichar_uni_utf8_partial_strlen_n();
 }
index ed1c28c9e204398cf40f35016e68d09ca55bb71f..e0f5f25a9f590c23346d3a82d71f3ed4811a3d08 100644 (file)
@@ -192,18 +192,28 @@ unsigned int uni_utf8_strlen(const char *input)
        return uni_utf8_strlen_n(input, (size_t)-1);
 }
 
-unsigned int uni_utf8_strlen_n(const void *_input, size_t size)
+unsigned int uni_utf8_strlen_n(const void *input, size_t size)
+{
+       size_t partial_pos;
+
+       return uni_utf8_partial_strlen_n(input, size, &partial_pos);
+}
+
+unsigned int uni_utf8_partial_strlen_n(const void *_input, size_t size,
+                                      size_t *partial_pos_r)
 {
        const unsigned char *input = _input;
-       unsigned int len = 0;
+       unsigned int count, len = 0;
        size_t i;
 
        for (i = 0; i < size && input[i] != '\0'; ) {
-               i += uni_utf8_char_bytes(input[i]);
-               if (i > size)
+               count = uni_utf8_char_bytes(input[i]);
+               if (i + count > size)
                        break;
+               i += count;
                len++;
        }
+       *partial_pos_r = i;
        return len;
 }
 
index a5466b2dcbf0f6dbba98f9f52c587b5a169d2024..dbc3bd8d45d15fecec96373e904b7533fe08be05 100644 (file)
@@ -55,6 +55,12 @@ int uni_utf8_get_char_n(const void *input, size_t max_len, unichar_t *chr_r);
 unsigned int uni_utf8_strlen(const char *input) ATTR_PURE;
 /* Returns UTF-8 string length with maximum input size. */
 unsigned int uni_utf8_strlen_n(const void *input, size_t size) ATTR_PURE;
+/* Same as uni_utf8_strlen_n(), but if input ends with a partial UTF-8
+   character, don't include it in the return value and set partial_pos_r to
+   where the character begins. Otherwise partial_pos_r is set to the end
+   of the input. */
+unsigned int uni_utf8_partial_strlen_n(const void *input, size_t size,
+                                      size_t *partial_pos_r);
 
 /* Returns the number of bytes belonging to this UTF-8 character. The given
    parameter is the first byte of the UTF-8 sequence. Invalid input is