1#ifndef __GTK_ISTRING_PRIVATE_H__
2#define __GTK_ISTRING_PRIVATE_H__
3
4#include <glib.h>
5#include <string.h>
6
7typedef struct
8{
9 guint n_bytes;
10 guint n_chars;
11 union {
12 char buf[24];
13 char *str;
14 } u;
15} IString;
16
17static inline gboolean
18istring_is_inline (const IString *str)
19{
20 return str->n_bytes <= (sizeof str->u.buf - 1);
21}
22
23static inline char *
24istring_str (IString *str)
25{
26 if (istring_is_inline (str))
27 return str->u.buf;
28 else
29 return str->u.str;
30}
31
32static inline void
33istring_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
44static inline void
45istring_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
64static inline gboolean
65istring_empty (IString *str)
66{
67 return str->n_bytes == 0;
68}
69
70static inline gboolean
71istring_ends_with_space (IString *str)
72{
73 return g_ascii_isspace (istring_str (str)[str->n_bytes - 1]);
74}
75
76static inline gboolean
77istring_starts_with_space (IString *str)
78{
79 return g_unichar_isspace (c: g_utf8_get_char (p: istring_str (str)));
80}
81
82static inline gboolean
83istring_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
89static inline gboolean
90istring_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
103static inline gboolean
104istring_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
117static inline void
118istring_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
144static inline void
145istring_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

source code of gtk/gtk/gtkistringprivate.h