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