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