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: dk4rec11.ctr
12 */
13 
14 /**	@file dk4rec11.c The dk4rec11 module.
15 */
16 
17 
18 #include "dk4conf.h"
19 #include <libdk4c/dk4rec11.h>
20 #include <libdk4base/dk4mem.h>
21 #include <libdk4c/dk4utf8.h>
22 #include <libdk4c/dk4utf16.h>
23 
24 #if	DK4_HAVE_ASSERT_H
25 #ifndef	ASSERT_H_INCLUDED
26 #include <assert.h>
27 #define	ASSERT_H_INCLUDED 1
28 #endif
29 #endif
30 
31 
32 
33 
34 
35 
36 size_t
dk4recode_size_utf8_to_utf16(const char * src,dk4_er_t * erp)37 dk4recode_size_utf8_to_utf16(const char *src, dk4_er_t *erp)
38 {
39   dk4_er_t		 er;
40   dk4_utf8_decoder_t	 dec;
41   dk4_c16_t		 c16[4];
42   size_t		 rdb	= 0;
43   size_t		 back	= 0;
44   size_t		 sz;
45   dk4_c32_t		 c32;
46 
47 #if	DK4_USE_ASSERT
48   assert(NULL != src);
49 #endif
50   if (NULL != src) {
51     /*	Initialize data structures.
52     */
53     dk4error_init(&er);
54     dk4utf8_init(&dec);
55     /*	Process source string.
56     */
57     while ('\0' != *src) {
58       rdb++;
59       switch(dk4utf8_add(&dec, (unsigned char)(*(src++)))) {
60         case DK4_EDSTM_FINISHED: {
61 	  c32 = dk4utf8_get(&dec);
62 	  dk4utf8_init(&dec);
63 	  sz = DK4_SIZEOF(c16,dk4_c16_t);
64 	  if (0 != dk4utf16_encode(c16, &sz, c32, &er)) {
65 	    if ((SIZE_MAX - sz) >= back) {
66 	      back += sz;
67 	    } else {
68 	      dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
69 	    }
70 	  } else {
71 	    dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
72 	  }
73 	} break;
74 	case DK4_EDSTM_ERROR: {
75 	  dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
76 	} break;
77       }
78     }
79     if (0 == dk4utf8_is_empty(&dec)) {
80       dk4error_set_elsize_nelem(&er, DK4_E_SYNTAX, 1, rdb);
81     }
82     /*	Add one for the finalizer.
83     */
84     if (SIZE_MAX == back) {
85       dk4error_set_simple_error_code(&er, DK4_E_MATH_OVERFLOW);
86     } else {
87       back++;
88     }
89     /*	On error return 0 and pass error code.
90     */
91     if (DK4_E_NONE != er.ec) {
92       back = 0;
93       dk4error_copy(erp, &er);
94     }
95   } else {
96     dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
97   }
98   return back;
99 }
100 
101 
102 
103 int
dk4recode_utf8_to_utf16(dk4_c16_t * dstb,size_t szdstb,const char * src,dk4_er_t * erp)104 dk4recode_utf8_to_utf16(
105   dk4_c16_t *dstb, size_t szdstb, const char *src, dk4_er_t *erp
106 )
107 {
108   dk4_c16_t		 buf[8];
109   dk4_utf8_decoder_t	 dec;
110   size_t		 sz;
111   size_t		 used	=	0;
112   size_t		 rdb	=	0;
113   dk4_c32_t		 c32	=	dkC32(0);
114   int			 back	=	0;
115 
116 #if	DK4_USE_ASSERT
117   assert(NULL != dstb);
118   assert(0 < szdstb);
119   assert(NULL != src);
120 #endif
121   if ((NULL != dstb) && (NULL != src) && (0 < szdstb)) {
122     back = 1;
123     dk4utf8_init(&dec);
124     while(('\0' != *src) && (1 == back) && (used < szdstb)) {
125       switch(dk4utf8_add(&dec, (unsigned char)(*(src++)))) {
126         case DK4_EDSTM_FINISHED: {
127 	  c32 = dk4utf8_get(&dec);
128 	  dk4utf8_init(&dec);
129 	  sz = DK4_SIZEOF(buf,dk4_c16_t);
130 	  if (0 != dk4utf16_encode(buf, &sz, c32, erp)) {
131 	    if ((szdstb - used) > sz) {
132 	      DK4_MEMCPY(&(dstb[used]),buf,(2 * sz));
133 	      used += sz;
134 	    } else {
135 	      back = 0;
136 	      dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
137 	    }
138 	  } else {
139 	    back = 0;
140 	    dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
141 	  }
142 	} break;
143 	case DK4_EDSTM_ERROR: {
144 	  back = 0;
145 	  dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
146 	} break;
147       }
148       if(back) { rdb++; }
149     }
150     if (used < szdstb) {
151       dstb[used] = (dk4_c16_t)0U;
152     } else {
153       dstb[szdstb - 1] = (dk4_c16_t)0U;
154       back = 0;
155       dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL);
156     }
157     if (0 == dk4utf8_is_empty(&dec)) {
158       back = 0;
159       dk4error_set_elsize_nelem(erp, DK4_E_SYNTAX, 1, rdb);
160     }
161   } else {
162     dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
163   }
164   return back;
165 }
166 
167 
168 
169