]> git.sur5r.net Git - i3/i3/blob - libi3/string.c
Merge pull request #1513 from Airblader/defect-1473
[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  * Free an i3String.
114  *
115  */
116 void i3string_free(i3String *str) {
117     if (str == NULL)
118         return;
119     free(str->utf8);
120     free(str->ucs2);
121     free(str);
122 }
123
124 static void i3string_ensure_utf8(i3String *str) {
125     if (str->utf8 != NULL)
126         return;
127     if ((str->utf8 = convert_ucs2_to_utf8(str->ucs2, str->num_glyphs)) != NULL)
128         str->num_bytes = strlen(str->utf8);
129 }
130
131 static void i3string_ensure_ucs2(i3String *str) {
132     if (str->ucs2 != NULL)
133         return;
134     str->ucs2 = convert_utf8_to_ucs2(str->utf8, &str->num_glyphs);
135 }
136
137 /*
138  * Returns the UTF-8 encoded version of the i3String.
139  *
140  */
141 const char *i3string_as_utf8(i3String *str) {
142     i3string_ensure_utf8(str);
143     return str->utf8;
144 }
145
146 /*
147  * Returns the UCS-2 encoded version of the i3String.
148  *
149  */
150 const xcb_char2b_t *i3string_as_ucs2(i3String *str) {
151     i3string_ensure_ucs2(str);
152     return str->ucs2;
153 }
154
155 /*
156  * Returns the number of bytes (UTF-8 encoded) in an i3String.
157  *
158  */
159 size_t i3string_get_num_bytes(i3String *str) {
160     i3string_ensure_utf8(str);
161     return str->num_bytes;
162 }
163
164 /*
165  * Whether the given i3String is in Pango markup.
166  */
167 bool i3string_is_markup(i3String *str) {
168     return str->is_markup;
169 }
170
171 /*
172  * Returns the number of glyphs in an i3String.
173  *
174  */
175 size_t i3string_get_num_glyphs(i3String *str) {
176     i3string_ensure_ucs2(str);
177     return str->num_glyphs;
178 }