]> git.sur5r.net Git - i3/i3/blob - libi3/string.c
e6297f9eed89b0282a2b104fab360921eb723b07
[i3/i3] / libi3 / string.c
1 /*
2  * vim:ts=4:sw=4:expandtab
3  *
4  * i3 - an improved dynamic tiling window manager
5  * © 2009-2011 Michael Stapelberg and contributors (see also: LICENSE)
6  *
7  * string.c: Define an i3String type to automagically handle UTF-8/UCS-2
8  *           conversions. Some font backends need UCS-2 (X core fonts),
9  *           others want UTF-8 (Pango).
10  *
11  */
12
13 #include <stdlib.h>
14 #include <string.h>
15
16 #include "libi3.h"
17
18 struct _i3String {
19     char *utf8;
20     xcb_char2b_t *ucs2;
21     size_t num_glyphs;
22     size_t num_bytes;
23     bool is_markup;
24 };
25
26 /*
27  * Build an i3String from an UTF-8 encoded string.
28  * Returns the newly-allocated i3String.
29  *
30  */
31 i3String *i3string_from_utf8(const char *from_utf8) {
32     i3String *str = scalloc(sizeof(i3String));
33
34     /* Get the text */
35     str->utf8 = sstrdup(from_utf8);
36
37     /* Compute and store the length */
38     str->num_bytes = strlen(str->utf8);
39
40     return str;
41 }
42
43 /*
44  * Build an i3String from an UTF-8 encoded string in Pango markup.
45  *
46  */
47 i3String *i3string_from_markup(const char *from_markup) {
48     i3String *str = i3string_from_utf8(from_markup);
49
50     /* Set the markup flag */
51     str->is_markup = true;
52
53     return str;
54 }
55
56 /*
57  * Build an i3String from an UTF-8 encoded string with fixed length.
58  * To be used when no proper NUL-terminaison is available.
59  * Returns the newly-allocated i3String.
60  *
61  */
62 i3String *i3string_from_utf8_with_length(const char *from_utf8, size_t num_bytes) {
63     i3String *str = scalloc(sizeof(i3String));
64
65     /* Copy the actual text to our i3String */
66     str->utf8 = scalloc(sizeof(char) * (num_bytes + 1));
67     strncpy(str->utf8, from_utf8, num_bytes);
68     str->utf8[num_bytes] = '\0';
69
70     /* Store the length */
71     str->num_bytes = num_bytes;
72
73     return str;
74 }
75
76 /*
77  * Build an i3String from an UTF-8 encoded string in Pango markup with fixed
78  * length.
79  *
80  */
81 i3String *i3string_from_markup_with_length(const char *from_markup, size_t num_bytes) {
82     i3String *str = i3string_from_utf8_with_length(from_markup, num_bytes);
83
84     /* set the markup flag */
85     str->is_markup = true;
86
87     return str;
88 }
89
90 /*
91  * Build an i3String from an UCS-2 encoded string.
92  * Returns the newly-allocated i3String.
93  *
94  */
95 i3String *i3string_from_ucs2(const xcb_char2b_t *from_ucs2, size_t num_glyphs) {
96     i3String *str = scalloc(sizeof(i3String));
97
98     /* Copy the actual text to our i3String */
99     size_t num_bytes = num_glyphs * sizeof(xcb_char2b_t);
100     str->ucs2 = scalloc(num_bytes);
101     memcpy(str->ucs2, from_ucs2, num_bytes);
102
103     /* Store the length */
104     str->num_glyphs = num_glyphs;
105
106     str->utf8 = NULL;
107     str->num_bytes = 0;
108
109     return str;
110 }
111
112 /**
113  * Copies the given i3string.
114  * Note that this will not free the source string.
115  */
116 i3String *i3string_copy(i3String *str) {
117     i3String *copy = i3string_from_utf8(i3string_as_utf8(str));
118     copy->is_markup = str->is_markup;
119     return copy;
120 }
121
122 /*
123  * Free an i3String.
124  *
125  */
126 void i3string_free(i3String *str) {
127     if (str == NULL)
128         return;
129     free(str->utf8);
130     free(str->ucs2);
131     free(str);
132 }
133
134 static void i3string_ensure_utf8(i3String *str) {
135     if (str->utf8 != NULL)
136         return;
137     if ((str->utf8 = convert_ucs2_to_utf8(str->ucs2, str->num_glyphs)) != NULL)
138         str->num_bytes = strlen(str->utf8);
139 }
140
141 static void i3string_ensure_ucs2(i3String *str) {
142     if (str->ucs2 != NULL)
143         return;
144     str->ucs2 = convert_utf8_to_ucs2(str->utf8, &str->num_glyphs);
145 }
146
147 /*
148  * Returns the UTF-8 encoded version of the i3String.
149  *
150  */
151 const char *i3string_as_utf8(i3String *str) {
152     i3string_ensure_utf8(str);
153     return str->utf8;
154 }
155
156 /*
157  * Returns the UCS-2 encoded version of the i3String.
158  *
159  */
160 const xcb_char2b_t *i3string_as_ucs2(i3String *str) {
161     i3string_ensure_ucs2(str);
162     return str->ucs2;
163 }
164
165 /*
166  * Returns the number of bytes (UTF-8 encoded) in an i3String.
167  *
168  */
169 size_t i3string_get_num_bytes(i3String *str) {
170     i3string_ensure_utf8(str);
171     return str->num_bytes;
172 }
173
174 /*
175  * Whether the given i3String is in Pango markup.
176  */
177 bool i3string_is_markup(i3String *str) {
178     return str->is_markup;
179 }
180
181 /*
182  * Set whether the i3String should use Pango markup.
183  */
184 void i3string_set_markup(i3String *str, bool is_markup) {
185     str->is_markup = is_markup;
186 }
187
188 /*
189  * Returns the number of glyphs in an i3String.
190  *
191  */
192 size_t i3string_get_num_glyphs(i3String *str) {
193     i3string_ensure_ucs2(str);
194     return str->num_glyphs;
195 }