]> git.sur5r.net Git - i3/i3/blob - libi3/string.c
Added tests for #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 };
24
25 /*
26  * Build an i3String from an UTF-8 encoded string.
27  * Returns the newly-allocated i3String.
28  *
29  */
30 i3String *i3string_from_utf8(const char *from_utf8) {
31     i3String *str = scalloc(sizeof(i3String));
32
33     /* Get the text */
34     str->utf8 = sstrdup(from_utf8);
35
36     /* Compute and store the length */
37     str->num_bytes = strlen(str->utf8);
38
39     return str;
40 }
41
42 /*
43  * Build an i3String from an UTF-8 encoded string with fixed length.
44  * To be used when no proper NUL-terminaison is available.
45  * Returns the newly-allocated i3String.
46  *
47  */
48 i3String *i3string_from_utf8_with_length(const char *from_utf8, size_t num_bytes) {
49     i3String *str = scalloc(sizeof(i3String));
50
51     /* Copy the actual text to our i3String */
52     str->utf8 = scalloc(sizeof(char) * (num_bytes + 1));
53     strncpy(str->utf8, from_utf8, num_bytes);
54     str->utf8[num_bytes] = '\0';
55
56     /* Store the length */
57     str->num_bytes = num_bytes;
58
59     return str;
60 }
61
62 /*
63  * Build an i3String from an UCS-2 encoded string.
64  * Returns the newly-allocated i3String.
65  *
66  */
67 i3String *i3string_from_ucs2(const xcb_char2b_t *from_ucs2, size_t num_glyphs) {
68     i3String *str = scalloc(sizeof(i3String));
69
70     /* Copy the actual text to our i3String */
71     size_t num_bytes = num_glyphs * sizeof(xcb_char2b_t);
72     str->ucs2 = scalloc(num_bytes);
73     memcpy(str->ucs2, from_ucs2, num_bytes);
74
75     /* Store the length */
76     str->num_glyphs = num_glyphs;
77
78     str->utf8 = NULL;
79     str->num_bytes = 0;
80
81     return str;
82 }
83
84 /*
85  * Free an i3String.
86  *
87  */
88 void i3string_free(i3String *str) {
89     if (str == NULL)
90         return;
91     free(str->utf8);
92     free(str->ucs2);
93     free(str);
94 }
95
96 static void i3string_ensure_utf8(i3String *str) {
97     if (str->utf8 != NULL)
98         return;
99     if ((str->utf8 = convert_ucs2_to_utf8(str->ucs2, str->num_glyphs)) != NULL)
100         str->num_bytes = strlen(str->utf8);
101 }
102
103 static void i3string_ensure_ucs2(i3String *str) {
104     if (str->ucs2 != NULL)
105         return;
106     str->ucs2 = convert_utf8_to_ucs2(str->utf8, &str->num_glyphs);
107 }
108
109 /*
110  * Returns the UTF-8 encoded version of the i3String.
111  *
112  */
113 const char *i3string_as_utf8(i3String *str) {
114     i3string_ensure_utf8(str);
115     return str->utf8;
116 }
117
118 /*
119  * Returns the UCS-2 encoded version of the i3String.
120  *
121  */
122 const xcb_char2b_t *i3string_as_ucs2(i3String *str) {
123     i3string_ensure_ucs2(str);
124     return str->ucs2;
125 }
126
127 /*
128  * Returns the number of bytes (UTF-8 encoded) in an i3String.
129  *
130  */
131 size_t i3string_get_num_bytes(i3String *str) {
132     i3string_ensure_utf8(str);
133     return str->num_bytes;
134 }
135
136 /*
137  * Returns the number of glyphs in an i3String.
138  *
139  */
140 size_t i3string_get_num_glyphs(i3String *str) {
141     i3string_ensure_ucs2(str);
142     return str->num_glyphs;
143 }