]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
ply-utils: Add a utf-8 string iterator API
authorRay Strode <rstrode@redhat.com>
Sat, 2 Dec 2023 17:36:54 +0000 (12:36 -0500)
committerRay Strode <rstrode@redhat.com>
Sat, 2 Dec 2023 23:14:42 +0000 (18:14 -0500)
This will make it easier to walk through a string and extract
each character.

src/libply/ply-utils.c
src/libply/ply-utils.h

index fb77e74b009aa1a0e32bd9e305758ee167ec3824..2de5f401d998eafbb3f3a6358e997cad7261a093 100644 (file)
@@ -776,6 +776,64 @@ ply_utf8_string_get_length (const char *string,
         return count;
 }
 
+size_t
+ply_utf8_string_get_byte_offset_from_character_offset (const char *string,
+                                                       size_t      character_offset)
+{
+        size_t byte_offset = 0;
+        size_t i;
+
+        for (i = 0; i < character_offset && string[byte_offset] != '\0'; i++) {
+                byte_offset += ply_utf8_character_get_size (string + byte_offset, PLY_UTF8_CHARACTER_SIZE_MAX);
+        }
+
+        return byte_offset;
+}
+
+void
+ply_utf8_string_iterator_init (ply_utf8_string_iterator_t *iterator,
+                               const char                 *string,
+                               ssize_t                     starting_offset,
+                               ssize_t                     range)
+{
+        size_t byte_offset;
+
+        iterator->character_range = range;
+        iterator->string = string;
+
+        byte_offset = ply_utf8_string_get_byte_offset_from_character_offset (string, starting_offset);
+        iterator->current_byte_offset = byte_offset;
+        iterator->number_characters_iterated = 0;
+}
+
+bool
+ply_utf8_string_iterator_next (ply_utf8_string_iterator_t *iterator,
+                               const char                **character,
+                               size_t                     *size)
+{
+        size_t size_of_current_character;
+
+        if (iterator->number_characters_iterated >= iterator->character_range)
+                return false;
+
+        if (iterator->string[iterator->current_byte_offset] == '\0')
+                return false;
+
+        size_of_current_character = ply_utf8_character_get_size (iterator->string + iterator->current_byte_offset,
+                                                                 PLY_UTF8_CHARACTER_SIZE_MAX);
+
+        if (size_of_current_character == 0)
+                return false;
+
+        *character = &iterator->string[iterator->current_byte_offset];
+        *size = size_of_current_character;
+
+        iterator->current_byte_offset += size_of_current_character;
+        iterator->number_characters_iterated++;
+
+        return true;
+}
+
 char *
 ply_get_process_command_line (pid_t pid)
 {
index 3893a6f641f291ddce12f37129534f6e8a955cf1..89bb37fd1ace7892e06016b85d8be10b853bf7d4 100644 (file)
@@ -55,6 +55,14 @@ typedef enum
         PLY_UNIX_SOCKET_TYPE_TRIMMED_ABSTRACT
 } ply_unix_socket_type_t;
 
+typedef struct
+{
+        const char *string;
+        ssize_t     character_range;
+        ssize_t     current_byte_offset;
+        ssize_t     number_characters_iterated;
+} ply_utf8_string_iterator_t;
+
 #ifndef PLY_HIDE_FUNCTION_DECLARATIONS
 
 #define ply_round_to_multiple(n, m) (((n) + (((m) - 1))) & ~((m) - 1))
@@ -117,6 +125,16 @@ int ply_utf8_character_get_size (const char *string,
 int ply_utf8_string_get_length (const char *string,
                                 size_t      n);
 
+size_t ply_utf8_string_get_byte_offset_from_character_offset (const char *string,
+                                                              size_t      character_offset);
+void ply_utf8_string_iterator_init (ply_utf8_string_iterator_t *iterator,
+                                    const char                 *string,
+                                    ssize_t                     starting_offset,
+                                    ssize_t                     range);
+bool ply_utf8_string_iterator_next (ply_utf8_string_iterator_t *iterator,
+                                    const char                **character,
+                                    size_t                     *size);
+
 char *ply_get_process_command_line (pid_t pid);
 pid_t ply_get_process_parent_pid (pid_t pid);