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