1 | #ifndef __GTK_ISTRING_PRIVATE_H__ |
2 | #define __GTK_ISTRING_PRIVATE_H__ |
3 | |
4 | #include <glib.h> |
5 | #include <string.h> |
6 | |
7 | typedef struct |
8 | { |
9 | guint n_bytes; |
10 | guint n_chars; |
11 | union { |
12 | char buf[24]; |
13 | char *str; |
14 | } u; |
15 | } IString; |
16 | |
17 | static inline gboolean |
18 | istring_is_inline (const IString *str) |
19 | { |
20 | return str->n_bytes <= (sizeof str->u.buf - 1); |
21 | } |
22 | |
23 | static inline char * |
24 | istring_str (IString *str) |
25 | { |
26 | if (istring_is_inline (str)) |
27 | return str->u.buf; |
28 | else |
29 | return str->u.str; |
30 | } |
31 | |
32 | static inline void |
33 | istring_clear (IString *str) |
34 | { |
35 | if (istring_is_inline (str)) |
36 | str->u.buf[0] = 0; |
37 | else |
38 | g_clear_pointer (&str->u.str, g_free); |
39 | |
40 | str->n_bytes = 0; |
41 | str->n_chars = 0; |
42 | } |
43 | |
44 | static inline void |
45 | istring_set (IString *str, |
46 | const char *text, |
47 | guint n_bytes, |
48 | guint n_chars) |
49 | { |
50 | if G_LIKELY (n_bytes <= (sizeof str->u.buf - 1)) |
51 | { |
52 | memcpy (dest: str->u.buf, src: text, n: n_bytes); |
53 | str->u.buf[n_bytes] = 0; |
54 | } |
55 | else |
56 | { |
57 | str->u.str = g_strndup (str: text, n: n_bytes); |
58 | } |
59 | |
60 | str->n_bytes = n_bytes; |
61 | str->n_chars = n_chars; |
62 | } |
63 | |
64 | static inline gboolean |
65 | istring_empty (IString *str) |
66 | { |
67 | return str->n_bytes == 0; |
68 | } |
69 | |
70 | static inline gboolean |
71 | istring_ends_with_space (IString *str) |
72 | { |
73 | return g_ascii_isspace (istring_str (str)[str->n_bytes - 1]); |
74 | } |
75 | |
76 | static inline gboolean |
77 | istring_starts_with_space (IString *str) |
78 | { |
79 | return g_unichar_isspace (c: g_utf8_get_char (p: istring_str (str))); |
80 | } |
81 | |
82 | static inline gboolean |
83 | istring_contains_unichar (IString *str, |
84 | gunichar ch) |
85 | { |
86 | return g_utf8_strchr (p: istring_str (str), len: str->n_bytes, c: ch) != NULL; |
87 | } |
88 | |
89 | static inline gboolean |
90 | istring_only_contains_space (IString *str) |
91 | { |
92 | const char *iter; |
93 | |
94 | for (iter = istring_str (str); *iter; iter = g_utf8_next_char (iter)) |
95 | { |
96 | if (!g_unichar_isspace (c: g_utf8_get_char (p: iter))) |
97 | return FALSE; |
98 | } |
99 | |
100 | return TRUE; |
101 | } |
102 | |
103 | static inline gboolean |
104 | istring_contains_space (IString *str) |
105 | { |
106 | const char *iter; |
107 | |
108 | for (iter = istring_str (str); *iter; iter = g_utf8_next_char (iter)) |
109 | { |
110 | if (g_unichar_isspace (c: g_utf8_get_char (p: iter))) |
111 | return TRUE; |
112 | } |
113 | |
114 | return FALSE; |
115 | } |
116 | |
117 | static inline void |
118 | istring_prepend (IString *str, |
119 | IString *other) |
120 | { |
121 | if G_LIKELY (str->n_bytes + other->n_bytes < sizeof str->u.buf - 1) |
122 | { |
123 | memmove (dest: str->u.buf + other->n_bytes, src: str->u.buf, n: str->n_bytes); |
124 | memcpy (dest: str->u.buf, src: other->u.buf, n: other->n_bytes); |
125 | str->n_bytes += other->n_bytes; |
126 | str->n_chars += other->n_chars; |
127 | str->u.buf[str->n_bytes] = 0; |
128 | } |
129 | else |
130 | { |
131 | char *old = NULL; |
132 | |
133 | if (!istring_is_inline (str)) |
134 | old = str->u.str; |
135 | |
136 | str->u.str = g_strconcat (string1: istring_str (str), istring_str (str: other), NULL); |
137 | str->n_bytes += other->n_bytes; |
138 | str->n_chars += other->n_chars; |
139 | |
140 | g_free (mem: old); |
141 | } |
142 | } |
143 | |
144 | static inline void |
145 | istring_append (IString *str, |
146 | IString *other) |
147 | { |
148 | const char *text = istring_str (str: other); |
149 | guint n_bytes = other->n_bytes; |
150 | guint n_chars = other->n_chars; |
151 | |
152 | if G_LIKELY (istring_is_inline (str)) |
153 | { |
154 | if G_LIKELY (str->n_bytes + n_bytes <= (sizeof str->u.buf - 1)) |
155 | memcpy (dest: str->u.buf + str->n_bytes, src: text, n: n_bytes); |
156 | else |
157 | str->u.str = g_strconcat (string1: str->u.buf, text, NULL); |
158 | } |
159 | else |
160 | { |
161 | str->u.str = g_realloc (mem: str->u.str, n_bytes: str->n_bytes + n_bytes + 1); |
162 | memcpy (dest: str->u.str + str->n_bytes, src: text, n: n_bytes); |
163 | } |
164 | |
165 | str->n_bytes += n_bytes; |
166 | str->n_chars += n_chars; |
167 | |
168 | istring_str (str)[str->n_bytes] = 0; |
169 | } |
170 | |
171 | #endif /* __GTK_ISTRING_PRIVATE_H__ */ |
172 | |