1 /* Public domain */
2
3 #ifndef _AGAR_CORE_TEXT_H_
4 #define _AGAR_CORE_TEXT_H_
5 #include <agar/core/begin.h>
6
7 /* Language code (see iso639-gen.pl) */
8 enum ag_language {
9 AG_LANG_NONE, /* Undefined */
10 AG_LANG_AA, /* Afar */
11 AG_LANG_AB, /* Abkhazian */
12 AG_LANG_AF, /* Afrikaans */
13 AG_LANG_AM, /* Amharic */
14 AG_LANG_AR, /* Arabic */
15 AG_LANG_AS, /* Assamese */
16 AG_LANG_AY, /* Aymara */
17 AG_LANG_AZ, /* Azerbaijani */
18 AG_LANG_BA, /* Bashkir */
19 AG_LANG_BE, /* Byelorussian */
20 AG_LANG_BG, /* Bulgarian */
21 AG_LANG_BH, /* Bihari */
22 AG_LANG_BI, /* Bislama */
23 AG_LANG_BN, /* Bengali; Bangla */
24 AG_LANG_BO, /* Tibetan */
25 AG_LANG_BR, /* Breton */
26 AG_LANG_CA, /* Catalan */
27 AG_LANG_CO, /* Corsican */
28 AG_LANG_CS, /* Czech */
29 AG_LANG_CY, /* Welsh */
30 AG_LANG_DA, /* Danish */
31 AG_LANG_DE, /* German */
32 AG_LANG_DZ, /* Bhutani */
33 AG_LANG_EL, /* Greek */
34 AG_LANG_EN, /* English */
35 AG_LANG_EO, /* Esperanto */
36 AG_LANG_ES, /* Spanish */
37 AG_LANG_ET, /* Estonian */
38 AG_LANG_EU, /* Basque */
39 AG_LANG_FA, /* Persian */
40 AG_LANG_FI, /* Finnish */
41 AG_LANG_FJ, /* Fiji */
42 AG_LANG_FO, /* Faroese */
43 AG_LANG_FR, /* French */
44 AG_LANG_FY, /* Frisian */
45 AG_LANG_GA, /* Irish */
46 AG_LANG_GD, /* Scots Gaelic */
47 AG_LANG_GL, /* Galician */
48 AG_LANG_GN, /* Guarani */
49 AG_LANG_GU, /* Gujarati */
50 AG_LANG_HA, /* Hausa */
51 AG_LANG_HE, /* Hebrew (formerly iw) */
52 AG_LANG_HI, /* Hindi */
53 AG_LANG_HR, /* Croatian */
54 AG_LANG_HU, /* Hungarian */
55 AG_LANG_HY, /* Armenian */
56 AG_LANG_IA, /* Interlingua */
57 AG_LANG_ID, /* Indonesian (formerly in) */
58 AG_LANG_IE, /* Interlingue */
59 AG_LANG_IK, /* Inupiak */
60 AG_LANG_IS, /* Icelandic */
61 AG_LANG_IT, /* Italian */
62 AG_LANG_IU, /* Inuktitut */
63 AG_LANG_JA, /* Japanese */
64 AG_LANG_JW, /* Javanese */
65 AG_LANG_KA, /* Georgian */
66 AG_LANG_KK, /* Kazakh */
67 AG_LANG_KL, /* Greenlandic */
68 AG_LANG_KM, /* Cambodian */
69 AG_LANG_KN, /* Kannada */
70 AG_LANG_KO, /* Korean */
71 AG_LANG_KS, /* Kashmiri */
72 AG_LANG_KU, /* Kurdish */
73 AG_LANG_KY, /* Kirghiz */
74 AG_LANG_LA, /* Latin */
75 AG_LANG_LN, /* Lingala */
76 AG_LANG_LO, /* Laothian */
77 AG_LANG_LT, /* Lithuanian */
78 AG_LANG_LV, /* Latvian, Lettish */
79 AG_LANG_MG, /* Malagasy */
80 AG_LANG_MI, /* Maori */
81 AG_LANG_MK, /* Macedonian */
82 AG_LANG_ML, /* Malayalam */
83 AG_LANG_MN, /* Mongolian */
84 AG_LANG_MO, /* Moldavian */
85 AG_LANG_MR, /* Marathi */
86 AG_LANG_MS, /* Malay */
87 AG_LANG_MT, /* Maltese */
88 AG_LANG_MY, /* Burmese */
89 AG_LANG_NA, /* Nauru */
90 AG_LANG_NE, /* Nepali */
91 AG_LANG_NL, /* Dutch */
92 AG_LANG_NO, /* Norwegian */
93 AG_LANG_OC, /* Occitan */
94 AG_LANG_OM, /* (Afan) Oromo */
95 AG_LANG_OR, /* Oriya */
96 AG_LANG_PA, /* Punjabi */
97 AG_LANG_PL, /* Polish */
98 AG_LANG_PS, /* Pashto, Pushto */
99 AG_LANG_PT, /* Portuguese */
100 AG_LANG_QU, /* Quechua */
101 AG_LANG_RM, /* Rhaeto-Romance */
102 AG_LANG_RN, /* Kirundi */
103 AG_LANG_RO, /* Romanian */
104 AG_LANG_RU, /* Russian */
105 AG_LANG_RW, /* Kinyarwanda */
106 AG_LANG_SA, /* Sanskrit */
107 AG_LANG_SD, /* Sindhi */
108 AG_LANG_SG, /* Sangho */
109 AG_LANG_SH, /* Serbo-Croatian */
110 AG_LANG_SI, /* Sinhalese */
111 AG_LANG_SK, /* Slovak */
112 AG_LANG_SL, /* Slovenian */
113 AG_LANG_SM, /* Samoan */
114 AG_LANG_SN, /* Shona */
115 AG_LANG_SO, /* Somali */
116 AG_LANG_SQ, /* Albanian */
117 AG_LANG_SR, /* Serbian */
118 AG_LANG_SS, /* Siswati */
119 AG_LANG_ST, /* Sesotho */
120 AG_LANG_SU, /* Sundanese */
121 AG_LANG_SV, /* Swedish */
122 AG_LANG_SW, /* Swahili */
123 AG_LANG_TA, /* Tamil */
124 AG_LANG_TE, /* Telugu */
125 AG_LANG_TG, /* Tajik */
126 AG_LANG_TH, /* Thai */
127 AG_LANG_TI, /* Tigrinya */
128 AG_LANG_TK, /* Turkmen */
129 AG_LANG_TL, /* Tagalog */
130 AG_LANG_TN, /* Setswana */
131 AG_LANG_TO, /* Tonga */
132 AG_LANG_TR, /* Turkish */
133 AG_LANG_TS, /* Tsonga */
134 AG_LANG_TT, /* Tatar */
135 AG_LANG_TW, /* Twi */
136 AG_LANG_UG, /* Uighur */
137 AG_LANG_UK, /* Ukrainian */
138 AG_LANG_UR, /* Urdu */
139 AG_LANG_UZ, /* Uzbek */
140 AG_LANG_VI, /* Vietnamese */
141 AG_LANG_VO, /* Volapuk */
142 AG_LANG_WO, /* Wolof */
143 AG_LANG_XH, /* Xhosa */
144 AG_LANG_YI, /* Yiddish (formerly ji) */
145 AG_LANG_YO, /* Yoruba */
146 AG_LANG_ZA, /* Zhuang */
147 AG_LANG_ZH, /* Chinese */
148 AG_LANG_ZU, /* Zulu */
149 AG_LANG_LAST
150 };
151
152 /* Text entry */
153 typedef struct ag_text_ent {
154 char *buf; /* String buffer */
155 size_t maxLen; /* Length (allocated) */
156 size_t len; /* Length (chars) */
157 } AG_TextEnt;
158
159 /* Text object */
160 typedef struct ag_text {
161 AG_Mutex lock;
162 AG_TextEnt ent[AG_LANG_LAST]; /* Language entries */
163 enum ag_language lang; /* Selected language */
164 size_t maxLen; /* Maximum string length (bytes) */
165 Uint flags;
166 #define AG_TEXT_SAVED_FLAGS 0
167 } AG_Text, AG_TextElement;
168
169 #define AGTEXT(p) ((AG_Text *)(p))
170
171 __BEGIN_DECLS
172 extern const char *agLanguageCodes[];
173 extern const char *agLanguageNames[];
174
175 AG_Text *AG_TextNew(size_t);
176
177 void AG_TextInit(AG_Text *, size_t);
178 void AG_TextDestroy(AG_Text *);
179
180 void AG_TextClear(AG_Text *);
181 int AG_TextSet(AG_Text *, const char *, ...)
182 FORMAT_ATTRIBUTE(__printf__, 2, 3);
183 int AG_TextSetEnt(AG_Text *, enum ag_language, const char *, ...)
184 FORMAT_ATTRIBUTE(__printf__, 3, 4);
185 int AG_TextSetEntS(AG_Text *, enum ag_language, const char *);
186
187 int AG_TextSetLangISO(AG_Text *, const char *);
188 const char *AG_TextGetLangISO(AG_Text *);
189 AG_Text *AG_TextDup(AG_Text *);
190 int AG_TextLoad(AG_Text *, AG_DataSource *);
191 void AG_TextSave(AG_DataSource *, AG_Text *);
192
193 /* Set text of current entry from C string */
194 static __inline__ int
AG_TextSetS(AG_Text * txt,const char * s)195 AG_TextSetS(AG_Text *txt, const char *s)
196 {
197 int rv;
198 AG_MutexLock(&txt->lock);
199 rv = AG_TextSetEntS(txt, txt->lang, s);
200 AG_MutexUnlock(&txt->lock);
201 return (rv);
202 }
203
204 /* Set the size limit on strings. */
205 static __inline__ void
AG_TextSetLimit(AG_Text * txt,size_t maxLen)206 AG_TextSetLimit(AG_Text *txt, size_t maxLen)
207 {
208 AG_MutexLock(&txt->lock);
209 txt->maxLen = maxLen;
210 AG_MutexUnlock(&txt->lock);
211 }
212
213 /* Select the active language. */
214 static __inline__ void
AG_TextSetLang(AG_Text * txt,enum ag_language lang)215 AG_TextSetLang(AG_Text *txt, enum ag_language lang)
216 {
217 AG_MutexLock(&txt->lock);
218 txt->lang = lang;
219 AG_MutexUnlock(&txt->lock);
220 }
221
222 /* Get the active language. */
223 static __inline__ enum ag_language
AG_TextGetLang(AG_Text * txt)224 AG_TextGetLang(AG_Text *txt)
225 {
226 enum ag_language lang;
227 AG_MutexLock(&txt->lock);
228 lang = txt->lang;
229 AG_MutexUnlock(&txt->lock);
230 return (lang);
231 }
232
233 /* Reallocate entry's buffer to size in bytes. */
234 static __inline__ int
AG_TextRealloc(AG_TextEnt * te,size_t maxLenNew)235 AG_TextRealloc(AG_TextEnt *te, size_t maxLenNew)
236 {
237 if (maxLenNew >= te->maxLen) {
238 char *bufNew;
239 bufNew = (char *)AG_TryRealloc(te->buf, maxLenNew);
240 if (bufNew == NULL) {
241 return (-1);
242 }
243 te->buf = bufNew;
244 te->maxLen = maxLenNew;
245 }
246 return (0);
247 }
248
249 /* Append a valid C string to the current buffer. */
250 static __inline__ int
AG_TextCatS(AG_Text * txt,const char * s)251 AG_TextCatS(AG_Text *txt, const char *s)
252 {
253 AG_TextEnt *te;
254 size_t len;
255
256 len = strlen(s);
257
258 AG_MutexLock(&txt->lock);
259 te = &txt->ent[txt->lang];
260 if (AG_TextRealloc(te, te->len + len + 1) == -1) {
261 AG_MutexUnlock(&txt->lock);
262 return (-1);
263 }
264 memcpy(&te->buf[te->len], s, len+1);
265 te->len += len;
266 AG_MutexUnlock(&txt->lock);
267 return (0);
268 }
269 /* Append an arbitrary block of bytes to the current buffer. */
270 static __inline__ int
AS_StringCatBytes(AG_Text * txt,const char * s,size_t len)271 AS_StringCatBytes(AG_Text *txt, const char *s, size_t len)
272 {
273 AG_TextEnt *te;
274
275 AG_MutexLock(&txt->lock);
276 te = &txt->ent[txt->lang];
277 if (AG_TextRealloc(te, te->len + len + 1) == -1) {
278 AG_MutexUnlock(&txt->lock);
279 return (-1);
280 }
281 memcpy(&te->buf[te->len], s, len);
282 te->len += len;
283 AG_MutexUnlock(&txt->lock);
284 return (0);
285 }
286
287 /* Free an autoallocated AG_Text element. */
288 static __inline__ void
AG_TextFree(AG_Text * txt)289 AG_TextFree(AG_Text *txt)
290 {
291 if (txt == NULL) {
292 return;
293 }
294 AG_TextDestroy(txt);
295 AG_Free(txt);
296 }
297 __END_DECLS
298
299 #include <agar/core/close.h>
300 #endif /* _AGAR_CORE_TEXT_H_ */
301