1 /*
2 Copyright (C) 2015-2021, Dirk Krause
3 SPDX-License-Identifier: BSD-3-Clause
4 */
5
6 /*
7 WARNING: This file was generated by the dkct program (see
8 http://dktools.sourceforge.net/ for details).
9 Changes you make here will be lost if dkct is run again!
10 You should modify the original source and run dkct on it.
11 Original source: dk4wxstt.cpt
12 */
13
14 /** @file dk4wxstt.cpp The dk4wxstt module.
15 */
16
17
18 #include "dk4conf.h"
19
20 #ifndef DK4_SIZEOF_WXCHAR
21 #ifndef DK4WXCS_H_INCLUDED
22 #include "dk4wxcs.h"
23 #endif
24 #endif
25
26 #include <libdk4base/dk4mem.h>
27 #include <libdk4c/dk4enc.h>
28 #include <libdk4base/dk4strd.h>
29 #include <libdk4wx/dk4wxtypes.h>
30 #include <libdk4wx/dk4strx.h>
31 #include <libdk4wx/dk4wxstt.h>
32 #include <libdk4wx/dk4tspwx.h>
33
34 #if DK4_HAVE_ASSERT_H
35 #ifndef ASSERT_H_INCLUDED
36 #include <assert.h>
37 #define ASSERT_H_INCLUDED 1
38 #endif
39 #endif
40
41
42
43
44
45
46 void
dk4wxstt_shutdown(dk4_wx_string_table_t * ptr)47 dk4wxstt_shutdown(dk4_wx_string_table_t *ptr)
48 {
49 wxChar **stptr;
50 size_t nstrings;
51
52 #if DK4_USE_ASSERT
53 assert(NULL != ptr);
54 #endif
55 if (NULL != ptr) {
56 if (NULL != ptr->strings) {
57 stptr = ptr->strings;
58 nstrings = ptr->nstrings;
59 while (0 < nstrings--) {
60 dk4mem_release(*stptr);
61 stptr++;
62 }
63 dk4mem_release(ptr->strings);
64 }
65 }
66
67 }
68
69
70 void
dk4wxstt_close(dk4_wx_string_table_t * ptr)71 dk4wxstt_close(dk4_wx_string_table_t *ptr)
72 {
73
74 #if DK4_USE_ASSERT
75 assert(NULL != ptr);
76 #endif
77 if (NULL != ptr) {
78 dk4wxstt_shutdown(ptr);
79 dk4mem_release(ptr->shrtfn);
80 ptr->nstrings = 0;
81 dk4mem_free(ptr);
82 }
83
84 }
85
86
87
88 dk4_wx_string_table_t *
dk4wxstt_open(const dkChar * fn,size_t sz,dk4_er_t * erp)89 dk4wxstt_open(const dkChar *fn, size_t sz, dk4_er_t *erp)
90 {
91 dk4_wx_string_table_t *back = NULL;
92 wxChar **stptr = NULL;
93 int ok = 0;
94
95 #if DK4_USE_ASSERT
96 assert(NULL != fn);
97 assert(0 < sz);
98 #endif
99 if ((NULL != fn) && (0 < sz)) {
100 back = dk4mem_new(dk4_wx_string_table_t,1,erp);
101 if (NULL != back) {
102 back->strings = NULL;
103 back->nstrings = 0;
104 back->shrtfn = dk4str_dup(fn, erp);
105 if (NULL != back->shrtfn) {
106 back->nstrings = sz;
107 back->strings = dk4mem_new(DK4_PWXCHAR,sz,erp);
108 if (NULL != back->strings) {
109 stptr = back->strings;
110 while (0 < sz--) { *(stptr++) = NULL; }
111 ok = 1;
112 }
113 }
114 if (1 > ok) {
115 dk4wxstt_close(back);
116 back = NULL;
117 }
118 }
119 } else {
120 dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
121 }
122
123 return back;
124 }
125
126
127
128 int
dk4wxstt_compare(const void * l,const void * r,int cr)129 dk4wxstt_compare(const void *l, const void *r, int cr)
130 {
131 const dk4_wx_string_table_t *lptr;
132 const dk4_wx_string_table_t *rptr;
133 int back = 0;
134 if (NULL != l) {
135 if (NULL != r) {
136 lptr = (const dk4_wx_string_table_t *)l;
137 switch (cr) {
138 case 1: {
139 if (NULL != lptr->shrtfn) {
140 back = dk4str_pathcmp(lptr->shrtfn, (const dkChar *)r);
141 } else {
142 back = -1;
143 }
144 } break;
145 default : {
146 rptr = (const dk4_wx_string_table_t *)r;
147 if (NULL != lptr->shrtfn) {
148 if (NULL != rptr->shrtfn) {
149 back = dk4str_pathcmp(lptr->shrtfn, rptr->shrtfn);
150 } else { back = 1; }
151 } else {
152 if (NULL != rptr->shrtfn) { back = -1; }
153 }
154 } break;
155 }
156 } else { back = 1; }
157 } else {
158 if (NULL != r) { back = -1; }
159 }
160 return back;
161 }
162
163
164
165 /** Support structure for reading string table from stream.
166 */
167 typedef struct {
168 dk4_wx_string_table_t *dptr; /**< String table to set up. */
169 size_t curpos; /**< Current string number. */
170 } dk4_wx_string_table_reader_t;
171
172
173
174 #if DK4_SIZEOF_WXCHAR > 1
175 #if DK4_SIZEOF_WXCHAR > 2
176 #define TO_SIZED_CHAR(x) ((dk4_c32_t)(x))
177 #else
178 #define TO_SIZED_CHAR(x) ((dk4_c16_t)(x))
179 #endif
180 #else
181 #define TO_SIZED_CHAR(x) ((char)(x))
182 #endif
183
184 /** Handler function for text lines.
185 @param obj Object to modify while processing the character.
186 @param line Text line to process.
187 @param lineno Current line number.
188 @param erp Error report, may be NULL.
189 @return DK4_TSP_RES_OK if the character was processed
190 successfully,
191 DK4_TSP_RES_ERROR if there was an error but we can
192 continue,
193 DK4_TSP_RES_FATAL if there was a fatal error so we
194 should abort processing.
195 */
196 static
197 int
dk4wxstt_line_handler(void * obj,dk4_c32_t * line,dk4_um_t WXUNUSED (lineno),dk4_er_t * WXUNUSED (erp))198 dk4wxstt_line_handler(
199 void *obj,
200 #if DK4_SIZEOF_WXCHAR > 1
201 #if DK4_SIZEOF_WXCHAR > 2
202 dk4_c32_t *line,
203 #else
204 dk4_c16_t *line,
205 #endif
206 #else
207 char *line,
208 #endif
209 dk4_um_t WXUNUSED(lineno),
210 dk4_er_t * WXUNUSED(erp)
211 )
212 {
213 dk4_wx_string_table_reader_t *reader;
214 wxChar *linecp;
215 int back = DK4_TSP_RES_ERROR;
216
217 reader = (dk4_wx_string_table_reader_t *)obj;
218 if (wxT('#') != (wxChar)(*line)) {
219 if (reader->curpos < reader->dptr->nstrings) {
220 linecp = dk4strx_dup((wxChar *)line, NULL);
221 if (NULL != linecp) {
222 (reader->dptr->strings)[reader->curpos] = linecp;
223 reader->curpos += 1;
224 back = DK4_TSP_RES_OK;
225 while (wxT('\0') != (wxChar)(*linecp)) {
226 if (wxT('\\') == (wxChar)(*linecp)) {
227 if (wxT('r') == (wxChar)(linecp[1])) {
228 *linecp = TO_SIZED_CHAR(wxT('\r'));
229 dk4strx_cpy_to_left(
230 (wxChar *)(&(linecp[1])), (wxChar *)(&(linecp[2]))
231 );
232 } else {
233 if (wxT('n') == wxChar(linecp[1])) {
234 *linecp = TO_SIZED_CHAR(wxT('\n'));
235 dk4strx_cpy_to_left(
236 (wxChar *)(&(linecp[1])), (wxChar *)(&(linecp[2]))
237 );
238 } else {
239 if (wxT('t') == (wxChar)(linecp[1])) {
240 *linecp = TO_SIZED_CHAR(wxT('\t'));
241 dk4strx_cpy_to_left(
242 (wxChar *)(&(linecp[1])), (wxChar *)(&(linecp[2]))
243 );
244 } else {
245 dk4strx_cpy_to_left(
246 (wxChar *)(linecp), (wxChar *)(&(linecp[1]))
247 );
248 if (wxT('\0') == (wxChar)(*linecp)) { linecp--; }
249 }
250 }
251 }
252 } else {
253 if (wxT('\n') == (wxChar)(*linecp)) {
254 *linecp = TO_SIZED_CHAR(wxT('\0'));
255 linecp--;
256 } else {
257 if ((wxT('\r') == (wxChar)(*linecp))
258 && (wxT('\n') == (wxChar)(linecp[1])))
259 {
260 *linecp = TO_SIZED_CHAR(wxT('\0'));
261 linecp--;
262 }
263 }
264 }
265 linecp++;
266 }
267 } else {
268 back = DK4_TSP_RES_FATAL;
269 }
270 } else {
271 back = DK4_TSP_RES_OK;
272 }
273 } else {
274 back = DK4_TSP_RES_OK;
275 }
276 return back;
277 }
278
279
280
281 bool
dk4wxstt_apply_stream(dk4_wx_string_table_t * tptr,dk4_stream_t * strm,int pre,dk4_er_t * WXUNUSED (erp1),dk4_er_t * erp2)282 dk4wxstt_apply_stream(
283 dk4_wx_string_table_t *tptr,
284 dk4_stream_t *strm,
285 int pre,
286 dk4_er_t * WXUNUSED(erp1),
287 dk4_er_t *erp2
288 )
289 {
290 wxChar line[1024]; /* Line buffer */
291 char buf[4096]; /* Input bytes from stream */
292 dk4_wx_string_table_reader_t reader; /* Reader structure */
293 dk4_tspwx_t tspwx; /* Text stream processor */
294 dk4_er_t e1; /* Error report decoding */
295 dk4_er_t e2; /* Error report processing */
296 size_t rdb; /* Number of bytes read */
297 int cc; /* Flag: Can continue */
298 bool back = false; /* Function result */
299
300 #if DK4_USE_ASSERT
301 assert(NULL != tptr);
302 assert(NULL != strm);
303 #endif
304 if ((NULL != tptr) && (NULL != strm)) {
305 dk4error_init(&e1);
306 dk4error_init(&e2);
307 reader.dptr = tptr;
308 reader.curpos = 0;
309 cc = dk4tspwx_setup_line(
310 &tspwx, (void *)(&reader), dk4wxstt_line_handler,
311 line, DK4_SIZEOF(line,wxChar),
312 pre, DK4_FILE_ENCODING_UTF8, &e2
313 ); back = ((cc != 0) ? true : false);
314 if (back) {
315 #if VERSION_BEFORE_20150821
316 cc = 1;
317 #endif
318 do {
319 cc = 0;
320 rdb = sizeof(buf);
321 if (0 < dk4stream_read(buf, &rdb, strm, NULL)) {
322 if (0 < rdb) {
323 switch (dk4tspwx_add_bytes(&tspwx, (unsigned char *)buf, rdb)) {
324 case DK4_TSP_RES_OK: {
325 cc = 1;
326 } break;
327 case DK4_TSP_RES_ERROR: {
328 cc = 1;
329 } break;
330 default: {
331 back = false;
332 } break;
333 }
334 }
335 }
336 } while (0 != cc);
337 if (back) {
338 if (DK4_TSP_RES_FATAL == dk4tspwx_finish(&tspwx)) {
339 back = false;
340 }
341 if (back) {
342 if (reader.curpos < (reader.dptr)->nstrings) {
343 back = false;
344 }
345 }
346 }
347 } else {
348 }
349 } else {
350 dk4error_set_simple_error_code(erp2, DK4_E_INVALID_ARGUMENTS);
351 }
352
353 return back;
354 }
355
356
357