1 /*
2 Copyright (C) 2011-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: dk3enc.ctr
12 */
13
14 /** @file dk3enc.c The dk3enc module.
15 */
16
17
18 #include <libdk3c/dk3all.h>
19
20
21
22
23
24
25
26 /** Binary to text encoding names.
27 Order here must match order of DK3_DATA_ENCODING_xxx in dk3const.h.
28 */
29 static dkChar const * const dk3enc_data_encoding_names[] = {
30 /* 0 */ dkT("HEX"),
31 /* 1 */ dkT("ASCII-85"),
32 /* 2 */ dkT("R-ASCII-85"),
33 /* 3 */ dkT("H"),
34 /* 4 */ dkT("A"),
35 /* 5 */ dkT("R"),
36 /* 6 */ dkT("A85"),
37 /* 7 */ dkT("RA85"),
38 NULL
39 };
40
41
42
43 /** Encoding names for file contents encodings.
44 */
45 static dkChar const * const dk3enc_text_encoding_names[] = {
46 /* 0 */ dkT("PLAIN"),
47 /* 1 */ dkT("UTF-8"),
48 /* 2 */ dkT("UTF-16"),
49 /* 3 */ dkT("UTF-16.MSB"),
50 /* 4 */ dkT("UTF-16.LSB"),
51 /* 5 */ dkT("UC32"),
52 /* 6 */ dkT("UC32.MSB"),
53 /* 7 */ dkT("UC32.LSB"),
54 /* 8 */ dkT("ASCII"),
55 /* 9 */ dkT("ISO-LATIN-1"),
56 /* 10 */ dkT("UTF8"),
57 /* 11 */ dkT("UTF16"),
58 /* 12 */ dkT("UTF-16-LE"),
59 /* 13 */ dkT("UTF-16LE"),
60 /* 14 */ dkT("UTF16LE"),
61 /* 15 */ dkT("UTF-16-LSB"),
62 /* 16 */ dkT("UTF-16LSB"),
63 /* 17 */ dkT("UTF16LSB"),
64 /* 18 */ dkT("UTF-16-BE"),
65 /* 19 */ dkT("UTF-16BE"),
66 /* 20 */ dkT("UTF16BE"),
67 /* 21 */ dkT("UTF-16-MSB"),
68 /* 22 */ dkT("UTF-16MSB"),
69 /* 23 */ dkT("UTF16MSB"),
70 /* 24 */ dkT("C32"),
71 /* 25 */ dkT("C32-LE"),
72 /* 26 */ dkT("C32LE"),
73 /* 27 */ dkT("C32-LSB"),
74 /* 28 */ dkT("C32LSB"),
75 /* 29 */ dkT("C32-BE"),
76 /* 30 */ dkT("C32BE"),
77 /* 31 */ dkT("C32-MSB"),
78 /* 32 */ dkT("C32MSB"),
79 NULL
80 };
81
82
83
84 /** Encoding names for UTF-8 encoding.
85 */
86 static char const * const dk3enc_utf8_names[] = {
87 /* 0 */
88 "utf-8",
89
90 /* 1 */
91 "utf8",
92
93 NULL
94
95 };
96
97
98 /** Digits used to show hexadecimal characters.
99 */
100 static char const dk3enc_hex_digits[] = {
101 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '\0'
102 };
103
104
105 /** Bit mask to obtain last byte of a double word.
106 */
107 static unsigned long const dk3enc_last_byte = 0x000000FFUL;
108
109
110
111 /** Factors for ASCII85 and reverse ASCII85 encoding.
112 */
113 static unsigned long const dk3enc_f2[] = {
114 1UL,
115 85UL,
116 (85UL * 85UL),
117 (85UL * 85UL * 85UL),
118 (85UL * 85UL * 85UL * 85UL)
119 };
120
121
122
123 /** Swap byte order for unsigned long.
124 @param ul Original value.
125 @return Value in swapped byte order.
126 */
127 static
128 unsigned long
dk3enc_swap_ul(unsigned long ul)129 dk3enc_swap_ul(unsigned long ul)
130 {
131 unsigned long back = 0UL;
132 back = ((ul >> 24) & 0x000000FFUL);
133 back |= ((ul >> 8) & 0x0000FF00UL);
134 back |= ((ul << 8) & 0x00FF0000UL);
135 back |= ((ul << 24) & 0xFF000000UL);
136 return back;
137 }
138
139
140
141 /** Swap byte order for unsigned short.
142 @param us Original value.
143 @return Value in swapped byte order.
144 */
145 static
146 unsigned short
dk3enc_swap_us(unsigned short us)147 dk3enc_swap_us(unsigned short us)
148 {
149 unsigned short back = 0U;
150 back = (unsigned short)((us >> 8) & 0x00FFU);
151 back = (unsigned short)(back | (((unsigned)us << 8) & 0xFF00U));
152 return back;
153 }
154
155
156 unsigned long
dk3enc_ntohl(unsigned long x)157 dk3enc_ntohl(unsigned long x)
158 {
159 unsigned long back;
160 #if DK3_WORDS_BIGENDIAN
161 back = x;
162 #else
163 back = dk3enc_swap_ul(x);
164 #endif
165 return back;
166 }
167
168
169 unsigned long
dk3enc_htonl(unsigned long x)170 dk3enc_htonl(unsigned long x)
171 {
172 unsigned long back;
173 #if DK3_WORDS_BIGENDIAN
174 back = x;
175 #else
176 back = dk3enc_swap_ul(x);
177 #endif
178 return back;
179 }
180
181
182
183 unsigned short
dk3enc_ntohs(unsigned short x)184 dk3enc_ntohs(unsigned short x)
185 {
186 unsigned short back;
187 #if DK3_WORDS_BIGENDIAN
188 back = x;
189 #else
190 back = dk3enc_swap_us(x);
191 #endif
192 return back;
193 }
194
195
196
197 unsigned short
dk3enc_htons(unsigned short x)198 dk3enc_htons(unsigned short x)
199 {
200 unsigned short back;
201 #if DK3_WORDS_BIGENDIAN
202 back = x;
203 #else
204 back = dk3enc_swap_us(x);
205 #endif
206 return back;
207 }
208
209
210
211 unsigned long
dk3enc_uc_to_ul(unsigned long c)212 dk3enc_uc_to_ul(unsigned long c)
213 {
214 c &= 0xFFFFFFFFUL;
215 return c;
216 }
217
218
219
220 unsigned long
dk3enc_dk_to_ul(unsigned long c)221 dk3enc_dk_to_ul(unsigned long c)
222 {
223 #if DK3_CHAR_SIZE > 1
224 #if DK3_CHAR_SIZE > 2
225 c &= 0xFFFFFFFFUL;
226 #else
227 c &= 0x0000FFFFUL;
228 #endif
229 #else
230 c &= 0x000000FFUL;
231 #endif
232 return c;
233 }
234
235
236 /** Convert 32-bit character to UTF-8 following RFC2279.
237 @param c 32-bit character to convert.
238 @param u8p Destination buffer.
239 @param u8l Length of @a u8p (number of bytes).
240 @return Number of bytes written to @a u8p.
241 */
242 static
243 size_t
dk3enc_uc2utf8_rfc2279(dk3_c32_t c,unsigned char * u8p,size_t u8l)244 dk3enc_uc2utf8_rfc2279(dk3_c32_t c, unsigned char *u8p, size_t u8l)
245 {
246 size_t back = 0;
247 dk3_c32_t x = 0UL; /* Variable for temporary results. */
248
249 if(u8p) {
250 if(u8l > 0) {
251 if(c > (dk3_c32_t)0x7FUL) {
252 if(c > (dk3_c32_t)0x000007FFUL) {
253 if(c > (dk3_c32_t)0x0000FFFFUL) {
254 if(c > (dk3_c32_t)0x001FFFFFUL) {
255 if(c > (dk3_c32_t)0x03FFFFFFUL) {
256 if(c < (dk3_c32_t)0x80000000UL) { /* 6 Byte */
257 if(u8l >= 6) {
258 back = 6;
259 x = c >> 30;
260 x &= 0x00000001UL;
261 x |= 0x000000FCUL;
262 u8p[0] = (unsigned char)x;
263 x = c >> 24; x &= 0x0000003FUL; x |= 0x00000080UL;
264 u8p[1] = (unsigned char)x;
265 x = c >> 18; x &= 0x0000003FUL; x |= 0x00000080UL;
266 u8p[2] = (unsigned char)x;
267 x = c >> 12; x &= 0x0000003FUL; x |= 0x00000080UL;
268 u8p[3] = (unsigned char)x;
269 x = c >> 6; x &= 0x0000003FUL; x |= 0x00000080UL;
270 u8p[4] = (unsigned char)x;
271 x = c & 0x0000003FUL; x |= 0x00000080UL;
272 u8p[5] = (unsigned char)x;
273 }
274 }
275 } else { /* 5 Byte */
276 if(u8l >= 5) {
277 back = 5;
278 x = c >> 24;
279 x &= 0x00000003UL;
280 x |= 0x000000F8UL;
281 u8p[0] = (unsigned char)x;
282 x = c >> 18; x &= 0x0000003FUL; x |= 0x00000080UL;
283 u8p[1] = (unsigned char)x;
284 x = c >> 12; x &= 0x0000003FUL; x |= 0x00000080UL;
285 u8p[2] = (unsigned char)x;
286 x = c >> 6; x &= 0x0000003FUL; x |= 0x00000080UL;
287 u8p[3] = (unsigned char)x;
288 x = c & 0x0000003FUL; x |= 0x00000080UL;
289 u8p[4] = (unsigned char)x;
290 }
291 }
292 } else { /* 4 Byte */
293 if(u8l >= 4) {
294 back = 4;
295 x = c >> 18;
296 x &= 0x00000007UL;
297 x |= 0x000000F0UL;
298 u8p[0] = (unsigned char)x;
299 x = c >> 12;
300 x &= 0x0000003FUL;
301 x |= 0x00000080UL;
302 u8p[1] = (unsigned char)x;
303 x = c >> 6;
304 x &= 0x0000003FUL;
305 x |= 0x00000080UL;
306 u8p[2] = (unsigned char)x;
307 x = c & 0x0000003FUL;
308 x |= 0x00000080UL;
309 u8p[3] = (unsigned char)x;
310 }
311 }
312 } else { /* 3 Byte */
313 if(u8l >= 3) {
314 back = 3;
315 x = c >> 12;
316 x &= 0x0000000FUL;
317 x |= 0x000000E0UL;
318 u8p[0] = (unsigned char)x;
319 x = c >> 6;
320 x &= 0x0000003FUL;
321 x |= 0x00000080UL;
322 u8p[1] = (unsigned char)x;
323 x = c & 0x0000003FUL;
324 x |= 0x00000080UL;
325 u8p[2] = (unsigned char)x;
326 }
327 }
328 } else { /* 2 Byte */
329 if(u8l >= 2) {
330 back = 2;
331 x = c >> 6;
332 x &= 0x0000001FUL;
333 x |= 0x000000C0UL;
334 u8p[0] = (unsigned char)x;
335 x = c & 0x0000003FUL;
336 x |= 0x00000080UL;
337 u8p[1] = (unsigned char)x;
338 }
339 }
340 } else { /* 1 Byte */
341 if(u8l >= 1) {
342 back = 1;
343 u8p[0] = (unsigned char)(c & 0x0000007FUL);
344 }
345 }
346 }
347 }
348 return back;
349 }
350
351
352
353 /** Get one 32-bit character from UTF-8 encoded string or buffer.
354 @param ucp Pointer to destination variable.
355 @param u8p Buffer containing UTF-8 encoded data.
356 @param u8l Length of @a u8p (number of bytes).
357 @param u8u Pointer to variable for used bytes from @a u8p.
358 @return 1 on success, 0 on error.
359 */
360 static
361 int
dk3enc_utf82uc_rfc2279(dk3_c32_t * ucp,unsigned char const * u8p,size_t u8l,size_t * u8u)362 dk3enc_utf82uc_rfc2279(
363 dk3_c32_t *ucp, unsigned char const *u8p,size_t u8l,size_t *u8u
364 )
365 {
366 int back = 0;
367 unsigned char u1 = 0x00; /* Character to process. */
368 dk3_c32_t res = 0UL; /* Result. */
369 dk3_c32_t x1 = 0UL; /* Result component from 1st byte. */
370 dk3_c32_t x2 = 0UL; /* Result component from 2nd byte. */
371 dk3_c32_t x3 = 0UL; /* Result component from 3rd byte. */
372 dk3_c32_t x4 = 0UL; /* Result component from 4th byte. */
373 dk3_c32_t x5 = 0UL; /* Result component from 5th byte. */
374 dk3_c32_t x6 = 0UL; /* Result component from 6th byte. */
375 size_t needed_length = 0; /* Number of btes needed. */
376
377 needed_length = 0;
378 if(ucp) {
379 if(u8p) {
380 if(u8l) {
381 if(u8u) {
382 if((u8l) > 0) {
383 u1 = *u8p; needed_length = 1;
384 if(u1 > 0x7F) { /* > 1 Byte */
385 if((u1 & 0xE0) == 0xC0) { /* 2 Byte */
386 needed_length = 2;
387 if(u8l >= needed_length) {
388 if((u8p[1] & 0xC0) == 0x80) {
389 x1 = u1;
390 x1 = x1 << 6;
391 x1 = x1 & 0x000007C0UL;
392 x2 = u8p[1];
393 x2 = x2 & 0x0000003FUL;
394 res = (x1 | x2); back = 1;
395 }
396 }
397 } else {
398 if((u1 & 0xF0) == 0xE0) { /* 3 Byte */
399 needed_length = 3;
400 if(u8l >= needed_length) {
401 if((u8p[1] & 0xC0) == 0x80) {
402 if((u8p[2] & 0xC0) == 0x80) {
403 x1 = u1;
404 x1 = x1 << 12;
405 x1 = x1 & 0x0000F000UL;
406 x2 = u8p[1];
407 x2 = x2 << 6;
408 x2 = x2 & 0x00000FC0UL;
409 x3 = u8p[2];
410 x3 = x3 & 0x0000003FUL;
411 res = (x1 | x2 | x3); back = 1;
412 }
413 }
414 }
415 } else {
416 if((u1 & 0xF8) == 0xF0) { /* 4 Byte */
417 needed_length = 4;
418 if(u8l >= needed_length) {
419 if((u8p[1] & 0xC0) == 0x80) {
420 if((u8p[2] & 0xC0) == 0x80) {
421 if((u8p[3] & 0xC0) == 0x80) {
422 x1 = u1;
423 x2 = u8p[1];
424 x3 = u8p[2];
425 x4 = u8p[3];
426 x1 = x1 << 18;
427 x1 = x1 & 0x001C0000UL;
428 x2 = x2 << 12;
429 x2 = x2 & 0x0003F000UL;
430 x3 = x3 << 6;
431 x3 = x3 & 0x00000FC0UL;
432 x4 = x4 & 0x0000003FUL;
433 res = (x1 | x2 | x3 | x4); back = 1;
434 }
435 }
436 }
437 }
438 } else {
439 if((u1 & 0xFC) == 0xF8) { /* 5 Byte */
440 needed_length = 5;
441 if(u8l >= needed_length) {
442 if((u8p[1] & 0xC0) == 0x80) {
443 if((u8p[2] & 0xC0) == 0x80) {
444 if((u8p[3] & 0xC0) == 0x80) {
445 if((u8p[4] & 0xC0) == 0x80) {
446 x1 = u1;
447 x2 = u8p[1];
448 x3 = u8p[2];
449 x4 = u8p[3];
450 x5 = u8p[4];
451 x1 = x1 << 24;
452 x1 = x1 & 0x03000000UL;
453 x2 = x2 << 18;
454 x2 = x2 & 0x00FC0000UL;
455 x3 = x3 << 12;
456 x3 = x3 & 0x0003F000UL;
457 x4 = x4 << 6;
458 x4 = x4 & 0x00000FC0UL;
459 x5 = x5 & 0x0000003FUL;
460 res = (x1 | x2 | x3 | x4 | x5); back = 1;
461 }
462 }
463 }
464 }
465 }
466 } else {
467 if((u1 & 0xFE) == 0xFC) { /* 6 Byte */
468 needed_length = 6;
469 if(u8l >= needed_length) {
470 if((u8p[1] & 0xC0) == 0x80) {
471 if((u8p[2] & 0xC0) == 0x80) {
472 if((u8p[3] & 0xC0) == 0x80) {
473 if((u8p[4] & 0xC0) == 0x80) {
474 if((u8p[5] & 0xC0) == 0x80) {
475 x1 = 0x40000000UL;
476 x2 = u8p[1]; x3 = u8p[2]; x4 = u8p[3];
477 x5 = u8p[4]; x6 = u8p[5];
478 x2 = x2 << 24;
479 x3 = x3 << 18;
480 x4 = x4 << 12;
481 x5 = x5 << 6;
482 x2 = x2 & 0x3F000000UL;
483 x3 = x3 & 0x00FC0000UL;
484 x4 = x4 & 0x0003F000UL;
485 x5 = x5 & 0x00000FC0UL;
486 x6 = x6 & 0x0000003FUL;
487 res = (x1 | x2 | x3 | x4 | x5 | x6);
488 back = 1;
489 }
490 }
491 }
492 }
493 }
494 }
495 }
496 }
497 }
498 }
499 }
500 } else { /* 1 Byte */
501 res = u1;
502 back = 1;
503 }
504 }
505 }
506 }
507 }
508 }
509 if(back) {
510 *u8u = needed_length;
511 *ucp = res;
512 }
513 return back;
514 }
515
516
517
518 #if DK3_HAVE_RFC_2279
519
520 /*
521 RFC 2279 allowed UTF-8 encoding for 32-bit characters in the
522 range 0 ... 0x7FFFFFFF.
523 */
524
525 size_t
dk3enc_uc2utf8(dk3_c32_t c,unsigned char * u8p,size_t u8l)526 dk3enc_uc2utf8(dk3_c32_t c, unsigned char *u8p, size_t u8l)
527 {
528 size_t back;
529
530 back = dk3enc_uc2utf8_rfc2279(c, u8p, u8l);
531
532 return back;
533 }
534
535 int
dk3enc_utf82uc(dk3_c32_t * ucp,unsigned char const * u8p,size_t u8l,size_t * u8u)536 dk3enc_utf82uc(dk3_c32_t *ucp, unsigned char const *u8p,size_t u8l,size_t *u8u)
537 {
538 int back;
539 back = dk3enc_utf82uc_rfc2279(ucp, u8p, u8l, u8u);
540 return back;
541 }
542
543
544 #else
545
546 /*
547 RFC 3629 replaces (obsoletes) RFC 2279.
548 32-bit characters are now allowed in the range
549 0 ... 0x0010FFFF only.
550 */
551
552 size_t
dk3enc_uc2utf8(dk3_c32_t c,unsigned char * u8p,size_t u8l)553 dk3enc_uc2utf8(dk3_c32_t c, unsigned char *u8p, size_t u8l)
554 {
555 size_t back = 0;
556
557 if(c <= (dk3_c32_t)0x0010FFFFUL) {
558 back = dk3enc_uc2utf8_rfc2279(c, u8p, u8l);
559 }
560 return back;
561 }
562
563 int
dk3enc_utf82uc(dk3_c32_t * ucp,unsigned char const * u8p,size_t u8l,size_t * u8u)564 dk3enc_utf82uc(dk3_c32_t *ucp, unsigned char const *u8p,size_t u8l,size_t *u8u)
565 {
566 int back = 0;
567 back = dk3enc_utf82uc_rfc2279(ucp, u8p, u8l, u8u);
568 if(back) {
569 if((*ucp) > (dk3_c32_t)0x0010FFFFUL) {
570 back = 0;
571 }
572 }
573 return back;
574 }
575
576 #endif
577
578
579
580 size_t
dk3enc_uc2utf16(dk3_c32_t c,dk3_c16_t * u16p,size_t u16l)581 dk3enc_uc2utf16(dk3_c32_t c, dk3_c16_t *u16p, size_t u16l)
582 {
583 size_t back = 0;
584 dk3_c32_t ul = 0UL; /* Low surrogate. */
585 dk3_c32_t um = 0UL; /* Hight surrogate. */
586 if((u16p) && (u16l)) {
587 if(c >= (dk3_c32_t)0x00010000UL) {
588 if(c <= (dk3_c32_t)0x0010FFFFUL) {
589 if(u16l >= 2) {
590 ul = (dk3_c32_t)((unsigned long)c - 0x00010000UL);
591 um = ((ul >> 10) & 0x000003FFUL);
592 um |= 0x0000D800UL;
593 u16p[0] = (dk3_c16_t)um;
594 um = (ul & 0x000003FFUL);
595 um |= 0x0000DC00UL;
596 u16p[1] = (dk3_c16_t)um;
597 back = 2;
598 }
599 }
600 } else {
601 #if VERSION_BEFORE_20141125
602 if((c & 0x0000DC00UL) != 0x0000DC00UL) {
603 if((c & 0x0000DC00UL) != 0x0000D800UL) {
604 *u16p = (dk3_c16_t)c; back = 1;
605 }
606 }
607 #else
608 if ((0x0000D800UL > (0xFFFFFFFFUL & ((unsigned long)c)))
609 || (0x0000DFFFUL < (0xFFFFFFFFUL & ((unsigned long)c)))
610 ) {
611 *u16p = (dk3_c16_t)c; back = 1;
612 }
613 #endif
614 }
615 }
616 return back;
617 }
618
619
620
621 int
dk3enc_utf162uc(dk3_c32_t * ucp,dk3_c16_t const * u16p,size_t u16l,size_t * u16u)622 dk3enc_utf162uc(dk3_c32_t *ucp, dk3_c16_t const *u16p, size_t u16l, size_t *u16u)
623 {
624 int back = 0;
625 dk3_c32_t result = 0UL; /* Result 32-bit character. */
626 dk3_c32_t ul1 = 0UL; /* First UC16 used. */
627 dk3_c32_t ul2 = 0UL; /* Second UC16 used (if any). */
628
629 if((ucp) && (u16p) && (u16l) && (u16u)) {
630 *u16u = 0;
631 ul1 = (((dk3_c32_t)(u16p[0])) & 0x0000FFFFUL);
632 ul2 = 0UL;
633 if(u16l > 1) {
634 ul2 = (((dk3_c32_t)(u16p[1])) & 0x0000FFFFUL);
635 }
636 if((ul1 & 0x0000DC00UL) == 0x0000DC00UL) {
637 if(u16l > 1) {
638 if((ul2 & 0x0000DC00UL) == 0x0000D800UL) {
639 ul2 = ((ul2 << 10) & 0x000FFC00UL);
640 ul1 = (ul1 & 0x000003FFUL);
641 result = ul1 | ul2;
642 result = (dk3_c32_t)((unsigned long)result + 0x00010000UL);
643 *ucp = result; *u16u = 2; back = 1;
644 }
645 }
646 } else {
647 if((ul1 & 0x0000DC00UL) == 0x0000D800UL) {
648 if(u16l > 1) {
649 if((ul2 & 0x0000DC00UL) == 0x0000DC00UL) {
650 ul1 = ((ul1 << 10) & 0x000FFC00UL);
651 ul2 = (ul2 & 0x000003FFUL);
652 result = ul1 | ul2;
653 result = (dk3_c32_t)((unsigned long)result + 0x00010000UL);
654 *ucp = result; *u16u = 2; back = 1;
655 }
656 }
657 } else {
658 ul1 &= 0x0000FFFFUL;
659 *ucp = ul1; *u16u = 1; back = 1;
660 }
661 }
662 }
663 return back;
664 }
665
666
667
668 /** Check whether a character is a digit.
669 @param c Character to check.
670 @return 1 on success, 0 on error.
671 */
672 static int
dk3enc_c8_is_digit(char c)673 dk3enc_c8_is_digit(char c)
674 {
675 int back = 0;
676 switch(c) {
677 case '0': case '1': case '2': case '3': case '4':
678 case '5': case '6': case '7': case '8': case '9':
679 {
680 back = 1;
681 }
682 break;
683 }
684 return back;
685 }
686
687
688
689 /** Convert digit to corresponding unsigned long.
690 @param c Digit.
691 @return Unsigned long for the digit.
692 */
693 static
694 unsigned long
dk3enc_c8_to_ul(char c)695 dk3enc_c8_to_ul(char c)
696 {
697 unsigned long back = 0UL;
698 if(c == '1') back = 1UL;
699 if(c == '2') back = 2UL;
700 if(c == '3') back = 3UL;
701 if(c == '4') back = 4UL;
702 if(c == '5') back = 5UL;
703 if(c == '6') back = 6UL;
704 if(c == '7') back = 7UL;
705 if(c == '8') back = 8UL;
706 if(c == '9') back = 9UL;
707 return back;
708 }
709
710
711
712 int
dk3enc_ipaddr_to_ul_app(dkChar const * str,unsigned long * ul,dk3_app_t * app)713 dk3enc_ipaddr_to_ul_app(dkChar const *str, unsigned long *ul, dk3_app_t *app)
714 {
715 char bu[512];
716 int back = 0;
717
718 if((str) && (ul)) {
719 if(dk3str_string_to_c8_simple_app(bu, sizeof(bu), str, app)) {
720 back = dk3enc_c8_ipaddr_to_ul_app(bu, ul, app);
721 } else {
722 /* ERROR: Conversion failed! */
723 }
724 }
725 return back;
726 }
727
728
729
730 int
dk3enc_c8_ipaddr_to_ul_app(char const * str,unsigned long * ul,dk3_app_t * app)731 dk3enc_c8_ipaddr_to_ul_app(char const *str, unsigned long *ul, dk3_app_t *app)
732 {
733 int back = 0;
734 int state = 0; /* Current state. */
735 char const *ptr = NULL; /* Used to traverse string. */
736 unsigned long ul1 = 0UL; /* First part of IP address. */
737 unsigned long ul2 = 0UL; /* Second part of IP address. */
738 unsigned long ul3 = 0UL; /* Third part of IP address. */
739 unsigned long ulval = 0UL; /* Resulting IP address. */
740
741 if(str && ul) {
742 state = 0; ptr = str; back = 1;
743 ul1 = ul2 = ul3 = ulval = 0UL;
744 while(back && (*ptr)) {
745 if(dk3enc_c8_is_digit(*ptr)) {
746 switch(state) {
747 case 0:
748 case 1:
749 case 2:
750 case 4:
751 case 5:
752 case 6:
753 case 8:
754 case 9:
755 case 10:
756 case 12:
757 case 13:
758 case 14: {
759 ulval = 10UL * ulval + dk3enc_c8_to_ul(*ptr); state++;
760 } break;
761 default: {
762 back = 0;
763 } break;
764 }
765 } else {
766 if(*ptr == '.') {
767 switch(state) {
768 case 0:
769 case 1:
770 case 2:
771 case 3: {
772 ul1 = ulval; ulval = 0UL; state = 4;
773 } break;
774 case 4:
775 case 5:
776 case 6:
777 case 7: {
778 ul2 = ulval; ulval = 0UL; state = 8;
779 } break;
780 case 8:
781 case 9:
782 case 10:
783 case 11: {
784 ul3 = ulval; ulval = 0UL; state = 12;
785 } break;
786 }
787 } else {
788 back = 0;
789 }
790 }
791 ptr++;
792 }
793 if((state < 12) || (state > 15)) {
794 back = 0;
795 }
796 if(back) {
797 if(ul1 > 255UL) back = 1;
798 if(ul2 > 255UL) back = 1;
799 if(ul3 > 255UL) back = 1;
800 if(ulval > 255UL) back = 1;
801 }
802 if(back) {
803 ul1 = ul1 << 24;
804 ul1 &= 0xFF000000UL;
805 ul2 = ul2 << 16;
806 ul2 &= 0x00FF0000UL;
807 ul3 = ul3 << 8;
808 ul3 &= 0x0000FF00UL;
809 ulval &= 0x000000FFUL;
810 ulval = ulval | ul1 | ul2 | ul3;
811 *ul = ulval;
812 } else {
813 if(app) {
814 /* Not an IP address! */
815 }
816 }
817 }
818
819 return back;
820 }
821
822
823
824 size_t
dk3enc_size_bin_to_a85(size_t s)825 dk3enc_size_bin_to_a85(size_t s)
826 {
827 #if VERSION_BEFORE_20140809
828 size_t back = 0;
829 int ec = 0; /* Error code. */
830 unsigned long ul1 = 0UL; /* Original size converted to unsigned long. */
831 unsigned long ul2 = 0UL; /* Remainder of division by 4. */
832 unsigned long ul3 = 0UL; /* Result division by 4. */
833
834 ul1 = (unsigned long)s;
835 ul2 = ul1 % 4UL;
836 ul3 = ul1 / 4UL;
837 if(ul2) ul2++; /* for last incomplete block */
838 ul1 = dk3ma_ul_add_ok(
839 dk3ma_ul_mul_ok(ul3, 5UL, &ec),
840 ul2,
841 &ec
842 ); /* add 25 percent */
843 ul1++; /* final 0x00 byte for string */
844 back = (size_t)ul1;
845 if(ec) back = 0; /* error checking */
846 if((unsigned long)back != ul1) back = 0;
847
848 return back;
849 #else
850 size_t back = 0;
851 size_t rem = 0; /* Division remainder */
852 size_t res = 0; /* Division result */
853 int ec = 0; /* Error code */
854
855 rem = s % 4;
856 res = s / 4;
857 if (rem) { rem++; }
858 /* back = 5 * res + rem + 1 */
859 rem++;
860 back = dk3mem_add_size_t(rem, dk3mem_mul_size_t(5, res, &ec), &ec);
861 if (ec) { back = 0; }
862
863 return back;
864 #endif
865 }
866
867
868
869 /** Convert binary data to ASCII-85 encoded string.
870 @param dp Destination pointer.
871 @param sp Source pointer.
872 @param ss Source size.
873 */
874 static
875 void
dk3enc_do_bin_to_ra85(char * dp,char const * sp,size_t ss)876 dk3enc_do_bin_to_ra85(char *dp, char const *sp, size_t ss)
877 {
878 register char const *mysp = NULL; /* Source pointer. */
879 register unsigned char *mydp = NULL; /* Destination pointer. */
880 register unsigned long v = 0UL; /* Output value. */
881 register size_t i = 0; /* Current byte index. */
882 register short vused = 0; /* Flag: v is used. */
883
884 mydp = (unsigned char *)dp; mysp = sp; v = 0UL; vused = 0;
885 for(i = 0; i < ss; i++) {
886 switch(vused++) {
887 case 3: {
888 v |=
889 ((((unsigned long)((unsigned char)(*(mysp++)))) << 24) & 0xFF000000UL);
890 } break;
891 case 2: {
892 v |=
893 ((((unsigned long)((unsigned char)(*(mysp++)))) << 16) & 0x00FF0000UL);
894 } break;
895 case 1: {
896 v |=
897 ((((unsigned long)((unsigned char)(*(mysp++)))) << 8) & 0x0000FF00UL);
898 } break;
899 default: {
900 v |=
901 ((((unsigned long)((unsigned char)(*(mysp++)))) ) & dk3enc_last_byte);
902 } break;
903 }
904 if(vused >= 4) {
905 *(mydp++) = (unsigned char)((v % 85UL) + 33UL);
906 v = v / 85UL;
907 *(mydp++) = (unsigned char)((v % 85UL) + 33UL);
908 v = v / 85UL;
909 *(mydp++) = (unsigned char)((v % 85UL) + 33UL);
910 v = v / 85UL;
911 *(mydp++) = (unsigned char)((v % 85UL) + 33UL);
912 v = v / 85UL;
913 *(mydp++) = (unsigned char)((v % 85UL) + 33UL);
914 vused = 0; v = 0UL;
915 }
916 }
917 if(vused) {
918 vused++;
919 while(vused--) {
920 *(mydp++) = (unsigned char)((v % 85UL) + 33UL);
921 v = v / 85UL;
922 }
923 }
924 *mydp = '\0';
925 }
926
927
928
929 int
dk3enc_bin_to_ra85_app(char * dp,size_t ds,char const * sp,size_t ss,dk3_app_t * app)930 dk3enc_bin_to_ra85_app(
931 char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
932 )
933 {
934 int back = 0;
935 size_t needed_size = 0; /* Destination buffer minimum size. */
936
937 if((dp) && (sp) && (ds) && (ss)) {
938 needed_size = dk3enc_size_bin_to_a85(ss);
939 if(needed_size) {
940 if(ds >= needed_size) {
941 dk3enc_do_bin_to_ra85(dp, sp, ss);
942 back = 1;
943 } else {
944 if(app) {
945 /* Destination buffer too small! */
946 dk3app_log_i1(app, DK3_LL_ERROR, 38);
947 }
948 }
949 }
950 }
951 return back;
952 }
953
954
955
956 size_t
dk3enc_size_a85_to_bin(size_t s)957 dk3enc_size_a85_to_bin(size_t s)
958 {
959 size_t back = 0;
960 unsigned long ul1 = 0UL; /* Original size converted to unsigned long. */
961 unsigned long ul2 = 0UL; /* Remainder of division by 5. */
962 unsigned long ul3 = 0UL; /* Result of division by 5. */
963
964 ul1 = (unsigned long)s;
965 ul2 = ul1 % 5UL;
966 ul3 = ul1 / 5UL;
967 ul1 = 4UL * ul3 + ul2;
968 back = (size_t)ul1;
969
970 return back;
971 }
972
973
974
975 /** Check whether a character is from the ASCII-85 charset.
976 @param c Character to check.
977 @return 1 on success, 0 on error.
978 */
979 static
980 int
dk3enc_c8_is_a85(char c)981 dk3enc_c8_is_a85(char c)
982 {
983 int back = 1;
984 if((int)c < 33) {
985 back = 0;
986 } else {
987 if((int)c > 117) {
988 back = 0;
989 }
990 }
991 return back;
992 }
993
994
995
996 /** Convert reverse ASCII-85 encoded data to binary data.
997 @param dp Destination pointer.
998 @param sp Source pointer.
999 @param ss Source size.
1000 @param app Application structure for diagnostics, may be NULL.
1001 @return Number of binary bytes produced.
1002 */
1003 static
1004 size_t
dk3enc_do_ra85_to_bin(char * dp,char const * sp,size_t ss,dk3_app_t * app)1005 dk3enc_do_ra85_to_bin(char *dp, char const *sp, size_t ss, dk3_app_t *app)
1006 {
1007 size_t back = 0;
1008 unsigned char *mydp = NULL; /* Destination pointer. */
1009 char const *mysp = NULL; /* Source pointer. */
1010 unsigned long v = 0UL; /* Double-word. */
1011 short vused = 0; /* Flag: v is used. */
1012 size_t i = 0; /* Index of current source byte. */
1013 int reported_illegal_char = 0; /* Flag: Error already reported. */
1014
1015 mydp = (unsigned char *)dp; mysp = sp; v = 0UL; vused = 0;
1016 for(i = 0; i < ss; i++) {
1017 if(dk3enc_c8_is_a85(*mysp)) {
1018 v += dk3enc_f2[vused++] * ((((unsigned long)((unsigned char)(*mysp))) & dk3enc_last_byte) - 33UL);
1019 if(vused >= 5) {
1020 *(mydp++) = (unsigned char)(v & dk3enc_last_byte);
1021 *(mydp++) = (unsigned char)((v >> 8) & dk3enc_last_byte);
1022 *(mydp++) = (unsigned char)((v >> 16) & dk3enc_last_byte);
1023 *(mydp++) = (unsigned char)((v >> 24) & dk3enc_last_byte);
1024 back += 4;
1025 v = 0UL; vused = 0;
1026 }
1027 } else {
1028 if(app) {
1029 if(!reported_illegal_char) {
1030 reported_illegal_char = 1;
1031 /* Illegal character(s) in source string! */
1032 dk3app_log_i1(app, DK3_LL_ERROR, 67);
1033 }
1034 }
1035 }
1036 mysp++;
1037 }
1038 if(vused) {
1039 vused--;
1040 while(vused--) {
1041 *(mydp++) = (unsigned char)(v & dk3enc_last_byte);
1042 back++;
1043 v = v >> 8;
1044 }
1045 }
1046 return back;
1047 }
1048
1049
1050
1051 size_t
dk3enc_ra85_to_bin_app(char * dp,size_t ds,char const * sp,size_t ss,dk3_app_t * app)1052 dk3enc_ra85_to_bin_app(
1053 char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
1054 )
1055 {
1056 size_t back = 0;
1057 size_t needed_size = 0; /* Minimum output buffer size. */
1058
1059 if((dp) && (sp) && (ds) && (ss)) {
1060 needed_size = dk3enc_size_a85_to_bin(ss);
1061 if(needed_size) {
1062 if(ds >= needed_size) {
1063 back = dk3enc_do_ra85_to_bin(dp, sp, ss, app);
1064 } else {
1065 if(app) {
1066 /* Destination buffer too small! */
1067 dk3app_log_i1(app, DK3_LL_ERROR, 38);
1068 }
1069 }
1070 }
1071 }
1072 return back;
1073 }
1074
1075
1076
1077 size_t
dk3enc_ra85string_to_bin_app(char * dp,size_t ds,char const * sp,dk3_app_t * app)1078 dk3enc_ra85string_to_bin_app(
1079 char *dp, size_t ds, char const *sp, dk3_app_t *app
1080 )
1081 {
1082 size_t back = 0;
1083
1084 if(sp) {
1085 back = dk3enc_ra85_to_bin_app(dp, ds, sp, dk3str_c8_len(sp), app);
1086 }
1087 return back;
1088 }
1089
1090
1091
1092 /** Convert binary data to ASCII-85 string.
1093 @param dp Destination pointer.
1094 @param sp Source pointer.
1095 @param ss Source size.
1096 */
1097 static
1098 void
dk3enc_do_bin_to_a85(char * dp,char const * sp,size_t ss)1099 dk3enc_do_bin_to_a85(char *dp, char const *sp, size_t ss)
1100 {
1101 register unsigned char *mydp = NULL; /* Destination pointer. */
1102 register unsigned char *mysp = NULL; /* Source pointer. */
1103 register unsigned long v = 0UL; /* Double-word. */
1104 register short vused = 0; /* Flag: v used. */
1105 register short addval = 0; /* Value to add. */
1106 register size_t i = 0; /* Index of current source byte. */
1107
1108 mydp = (unsigned char *)dp;
1109 mysp = (unsigned char *)sp;
1110 v = 0UL;
1111 vused = 0;
1112 for(i = 0; i < ss; i++) {
1113 switch(vused) {
1114 case 3: {
1115 v |= ( ((unsigned long)(*(mysp++))) & 0x000000FFUL);
1116 } break;
1117 case 2: {
1118 v |= ((((unsigned long)(*(mysp++))) << 8) & 0x0000FF00UL);
1119 } break;
1120 case 1: {
1121 v |= ((((unsigned long)(*(mysp++))) << 16) & 0x00FF0000UL);
1122 } break;
1123 default: {
1124 v |= ((((unsigned long)(*(mysp++))) << 24) & 0xFF000000UL);
1125 } break;
1126 }
1127 if(++vused >= 4) {
1128 vused = 5;
1129 while(vused--) {
1130 *(mydp++) = (unsigned char)(33UL + v / dk3enc_f2[vused]);
1131 v = v % dk3enc_f2[vused];
1132 }
1133 v = 0UL; vused = 0;
1134 }
1135 }
1136 if(vused) {
1137 vused++; addval = (short)(5 - vused);
1138 while(vused--) {
1139 *(mydp++) = (unsigned char)(33UL + v / dk3enc_f2[vused + addval]);
1140 v = v % dk3enc_f2[vused + addval];
1141 }
1142 }
1143 *mydp = '\0';
1144 }
1145
1146
1147
1148 int
dk3enc_bin_to_a85_app(char * dp,size_t ds,char const * sp,size_t ss,dk3_app_t * app)1149 dk3enc_bin_to_a85_app(
1150 char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
1151 )
1152 {
1153 int back = 0;
1154 size_t needed_size = 0; /* Minimum output buffer size. */
1155
1156 if((dp) && (sp) && (ds) && (ss)) {
1157 needed_size = dk3enc_size_bin_to_a85(ss);
1158 if(needed_size) {
1159 if(ds >= needed_size) {
1160 dk3enc_do_bin_to_a85(dp, sp, ss);
1161 back = 1;
1162 } else {
1163 if(app) {
1164 /* Destination buffer too small! */
1165 dk3app_log_i1(app, DK3_LL_ERROR, 38);
1166 }
1167 }
1168 }
1169 }
1170 return back;
1171 }
1172
1173
1174
1175 /** Convert ASCII-85 encoded data to binary data.
1176 @param dp Destination pointer.
1177 @param sp Source pointer.
1178 @param ss Source size.
1179 @param app Application structure for diagnostics, may be NULL.
1180 @return Number of binary bytes produced.
1181 */
1182 static
1183 size_t
dk3enc_do_a85_to_bin(char * dp,char const * sp,size_t ss,dk3_app_t * app)1184 dk3enc_do_a85_to_bin(char *dp, char const *sp, size_t ss, dk3_app_t *app)
1185 {
1186 register size_t back = 0;
1187 register unsigned char *mydp = NULL; /* Destination pointer. */
1188 register unsigned char const *mysp = NULL; /* Source pointer. */
1189 register unsigned long v = 0UL; /* Double-word. */
1190 register short vused = 0; /* Flag: v used. */
1191 register size_t i = 0; /* Current source byte index. */
1192 unsigned long u1 = 0UL; /* Temporary value. */
1193 unsigned long u2 = 0UL; /* Temporary value. */
1194 unsigned long u3 = 0UL; /* Temporary value. */
1195 int reported_illegal_character = 0;
1196
1197 mydp = (unsigned char *)dp; mysp = (unsigned char *)sp;
1198 v = 0UL; vused = 0;
1199 for(i = 0; i < ss; i++) {
1200 if(*mysp) {
1201 if(dk3enc_c8_is_a85((char)(*mysp))) {
1202 v += dk3enc_f2[4 - vused] *
1203 ((((unsigned long)(*mysp)) & 0x000000FFUL) - 33UL);
1204 } else {
1205 if(!reported_illegal_character) {
1206 reported_illegal_character = 1;
1207 if(app) {
1208 /* Illegal character in source data! */
1209 dk3app_log_i1(app, DK3_LL_ERROR, 67);
1210 }
1211 }
1212 }
1213 vused++;
1214 if(vused >= 5) {
1215 *(mydp++) = (unsigned char)((v >> 24) & 0x000000FFUL); back++;
1216 *(mydp++) = (unsigned char)((v >> 16) & 0x000000FFUL); back++;
1217 *(mydp++) = (unsigned char)((v >> 8) & 0x000000FFUL); back++;
1218 *(mydp++) = (unsigned char)( v & 0x000000FFUL); back++;
1219 v = 0UL; vused = 0;
1220 }
1221 }
1222 mysp++;
1223 }
1224 if(vused) {
1225 u1 = (v >> 24) & 0x000000FFUL;
1226 u2 = (v >> 16) & 0x000000FFUL;
1227 u3 = (v >> 8) & 0x000000FFUL;
1228 switch(vused) {
1229 case 2: {
1230 if(v & 0x00FFFFFFUL) {
1231 u1++; if(u1 >= 256UL) u1 = 0UL;
1232 }
1233 *(mydp++) = (unsigned char)(u1 & 0x000000FFUL); back++;
1234 } break;
1235 case 3: {
1236 if(v & 0x0000FFFFUL) {
1237 u2++;
1238 if(u2 >= 256UL) {
1239 u2 = 0UL;
1240 u1++; if(u1 >= 256UL) u1 = 0UL;
1241 }
1242 }
1243 *(mydp++) = (unsigned char)(u1 & 0x000000FFUL); back++;
1244 *(mydp++) = (unsigned char)(u2 & 0x000000FFUL); back++;
1245 } break;
1246 case 4: {
1247 if(v & 0x000000FFUL) {
1248 u3++;
1249 if(u3 >= 256UL) {
1250 u3 = 0UL;
1251 u2++;
1252 if(u2 >= 256UL) {
1253 u2 = 0UL;
1254 u1++; if(u1 >= 256UL) u1 = 0UL;
1255 }
1256 }
1257 }
1258 *(mydp++) = (unsigned char)(u1 & 0x000000FFUL); back++;
1259 *(mydp++) = (unsigned char)(u2 & 0x000000FFUL); back++;
1260 *(mydp++) = (unsigned char)(u3 & 0x000000FFUL); back++;
1261 } break;
1262 }
1263 }
1264 return back;
1265 }
1266
1267
1268
1269 size_t
dk3enc_a85_to_bin_app(char * dp,size_t ds,char const * sp,size_t ss,dk3_app_t * app)1270 dk3enc_a85_to_bin_app(
1271 char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
1272 )
1273 {
1274 size_t back = 0;
1275 size_t needed_size = 0; /* Minimum output buffer size. */
1276
1277 if((dp) && (sp) && (ds) && (ss)) {
1278 needed_size = dk3enc_size_a85_to_bin(ss);
1279 if(needed_size) {
1280 if(ds >= needed_size) {
1281 back = dk3enc_do_a85_to_bin(dp, sp, ss, app);
1282 } else {
1283 if(app) {
1284 /* Destination buffer too small! */
1285 dk3app_log_i1(app, DK3_LL_ERROR, 38);
1286 }
1287 }
1288 }
1289 }
1290 return back;
1291 }
1292
1293
1294
1295 size_t
dk3enc_a85string_to_bin_app(char * dp,size_t ds,char const * sp,dk3_app_t * app)1296 dk3enc_a85string_to_bin_app(char *dp, size_t ds, char const *sp, dk3_app_t *app)
1297 {
1298 size_t back = 0;
1299
1300 if(sp) {
1301 back = dk3enc_a85_to_bin_app(dp, ds, sp, dk3str_c8_len(sp), app);
1302 }
1303 return back;
1304 }
1305
1306
1307
1308 size_t
dk3enc_size_bin_to_hex(size_t s)1309 dk3enc_size_bin_to_hex(size_t s)
1310 {
1311 #if VERSION_BEFORE_20140809
1312 size_t back = 0;
1313 int ec = 0; /* Error code. */
1314 unsigned long ul1 = 0UL; /* Temporary value for calculation. */
1315
1316 ul1 = (unsigned long)s;
1317 ul1 = dk3ma_ul_mul_ok(ul1, 2UL, &ec);
1318 ul1 = dk3ma_ul_add_ok(ul1, 1UL, &ec);
1319 back = (size_t)ul1;
1320 if(ec) back = 0;
1321 if((unsigned long)back != ul1) back = 0;
1322
1323 return back;
1324 #else
1325 size_t back = 0;
1326 int ec = 0; /* Error code */
1327
1328 back = dk3mem_add_size_t(1, dk3mem_mul_size_t(2, s, &ec), &ec);
1329 if (ec) { back = 0; }
1330
1331 return back;
1332 #endif
1333 }
1334
1335
1336
1337 size_t
dk3enc_size_hex_to_bin(size_t s)1338 dk3enc_size_hex_to_bin(size_t s)
1339 {
1340 size_t back;
1341
1342 back = s / 2;
1343 back++;
1344 return back;
1345 }
1346
1347
1348
1349 /** Get higher half-byte from character.
1350 @param c Source character.
1351 @return Higher half-byte of \a c.
1352 */
1353 static
1354 char
dk3enc_c8_high_nibble_hex(char c)1355 dk3enc_c8_high_nibble_hex(char c)
1356 {
1357 char back;
1358 back = dk3enc_hex_digits[ (((unsigned short)c) >> 4) & 0x000FU ];
1359 return back;
1360 }
1361
1362
1363
1364 /** Get lower half-byte from character.
1365 @param c Source character.
1366 @return Lower half-byte of \a c.
1367 */
1368 static
1369 char
dk3enc_c8_low_nibble_hex(char c)1370 dk3enc_c8_low_nibble_hex(char c)
1371 {
1372 char back;
1373 back = dk3enc_hex_digits[ ((unsigned short)c) & 0x000FU ];
1374 return back;
1375 }
1376
1377
1378
1379 /** Convert binary data to hexadecimal string.
1380 @param dp Destination pointer.
1381 @param sp Source pointer.
1382 @param ss Source size.
1383 */
1384 static
1385 void
dk3enc_do_bin_to_hex(char * dp,char const * sp,size_t ss)1386 dk3enc_do_bin_to_hex(char *dp, char const *sp, size_t ss)
1387 {
1388 register char *mydp = NULL; /* Destination pointer. */
1389 register char const *mysp = NULL; /* Source pointer. */
1390 register size_t i = 0; /* Current source byte index. */
1391
1392 mydp = dp; mysp = sp;
1393 for(i = 0; i < ss; i++) {
1394 *(mydp++) = dk3enc_c8_high_nibble_hex(*mysp);
1395 *(mydp++) = dk3enc_c8_low_nibble_hex(*(mysp++));
1396 }
1397 *mydp = '\0';
1398 }
1399
1400
1401
1402 int
dk3enc_bin_to_hex_app(char * dp,size_t ds,char const * sp,size_t ss,dk3_app_t * app)1403 dk3enc_bin_to_hex_app(
1404 char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
1405 )
1406 {
1407 int back = 0;
1408 size_t needed_bytes = 0; /* Minimum output buffer size. */
1409
1410 if((dp) && (ds) && (sp) && (ss)) {
1411 needed_bytes = dk3enc_size_bin_to_hex(ss);
1412 if(needed_bytes) {
1413 if(ds >= needed_bytes) {
1414 dk3enc_do_bin_to_hex(dp, sp, ss); back = 1;
1415 } else {
1416 if(app) {
1417 /* Destination buffer too small1 */
1418 dk3app_log_i1(app, DK3_LL_ERROR, 38);
1419 }
1420 }
1421 }
1422 }
1423 return back;
1424 }
1425
1426
1427
1428 /** Convert hexadecimal data to binary data.
1429 @param dp Destination pointer.
1430 @param sp Source pointer.
1431 @param ss Source size.
1432 @param app Application structure for diagnostics, may be NULL.
1433 @return Number of bytes created in destination.
1434 */
1435 static
1436 size_t
dk3enc_do_hex_to_bin(char * dp,char const * sp,size_t ss,dk3_app_t * app)1437 dk3enc_do_hex_to_bin(char *dp, char const *sp, size_t ss, dk3_app_t *app)
1438 {
1439 register size_t back = 0;
1440 register char const *mysp = NULL; /* Source pointer. */
1441 register unsigned char *mydp = NULL; /* Destination pointer. */
1442 register unsigned char v = 0x00; /* Current byte to process. */
1443 register short int vused = 0; /* Flag: v used. */
1444 register size_t i = 0; /* Current source byte index. */
1445 int reported_illegal_character = 0; /* Flag: Error already reported. */
1446
1447 mydp = (unsigned char *)dp;
1448 mysp = sp; v = 0x00; vused = 0U;
1449 for(i = 0; i < ss; i++) {
1450 switch(*mysp) {
1451 case '0':
1452 case '1':
1453 case '2':
1454 case '3':
1455 case '4':
1456 case '5':
1457 case '6':
1458 case '7':
1459 case '8':
1460 case '9':
1461 case 'a':
1462 case 'A':
1463 case 'b':
1464 case 'B':
1465 case 'c':
1466 case 'C':
1467 case 'd':
1468 case 'D':
1469 case 'e':
1470 case 'E':
1471 case 'f':
1472 case 'F':
1473 {
1474 if(vused) {
1475 switch(*mysp) {
1476 case '0': { v |= 0x00; } break;
1477 case '1': { v |= 0x01; } break;
1478 case '2': { v |= 0x02; } break;
1479 case '3': { v |= 0x03; } break;
1480 case '4': { v |= 0x04; } break;
1481 case '5': { v |= 0x05; } break;
1482 case '6': { v |= 0x06; } break;
1483 case '7': { v |= 0x07; } break;
1484 case '8': { v |= 0x08; } break;
1485 case '9': { v |= 0x09; } break;
1486 case 'a': { v |= 0x0A; } break;
1487 case 'A': { v |= 0x0A; } break;
1488 case 'b': { v |= 0x0B; } break;
1489 case 'B': { v |= 0x0B; } break;
1490 case 'c': { v |= 0x0C; } break;
1491 case 'C': { v |= 0x0C; } break;
1492 case 'd': { v |= 0x0D; } break;
1493 case 'D': { v |= 0x0D; } break;
1494 case 'e': { v |= 0x0E; } break;
1495 case 'E': { v |= 0x0E; } break;
1496 case 'f': { v |= 0x0F; } break;
1497 case 'F': { v |= 0x0F; } break;
1498 }
1499 *(mydp++) = v; back++; v = 0; vused = 0U;
1500 } else {
1501 switch(*mysp) {
1502 case '0': { v = 0x00; } break;
1503 case '1': { v = 0x10; } break;
1504 case '2': { v = 0x20; } break;
1505 case '3': { v = 0x30; } break;
1506 case '4': { v = 0x40; } break;
1507 case '5': { v = 0x50; } break;
1508 case '6': { v = 0x60; } break;
1509 case '7': { v = 0x70; } break;
1510 case '8': { v = 0x80; } break;
1511 case '9': { v = 0x90; } break;
1512 case 'a': { v = 0xA0; } break;
1513 case 'A': { v = 0xA0; } break;
1514 case 'b': { v = 0xB0; } break;
1515 case 'B': { v = 0xB0; } break;
1516 case 'c': { v = 0xC0; } break;
1517 case 'C': { v = 0xC0; } break;
1518 case 'd': { v = 0xD0; } break;
1519 case 'D': { v = 0xD0; } break;
1520 case 'e': { v = 0xE0; } break;
1521 case 'E': { v = 0xE0; } break;
1522 case 'f': { v = 0xF0; } break;
1523 case 'F': { v = 0xF0; } break;
1524 }
1525 vused = 1U;
1526 }
1527 } break;
1528 default: {
1529 if(!reported_illegal_character) {
1530 reported_illegal_character = 1;
1531 if(app) {
1532 /* Illegal character(s) in source! */
1533 dk3app_log_i1(app, DK3_LL_ERROR, 67);
1534 }
1535 }
1536 } break;
1537 }
1538 mysp++;
1539 }
1540 if(vused) {
1541 *mydp = v; back++;
1542 }
1543 return back;
1544 }
1545
1546
1547
1548 size_t
dk3enc_hex_to_bin_app(char * dp,size_t ds,char const * sp,size_t ss,dk3_app_t * app)1549 dk3enc_hex_to_bin_app(
1550 char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app
1551 )
1552 {
1553 size_t back = 0;
1554 size_t needed_bytes = 0; /* Minimum output buffer size. */
1555
1556 if((dp) && (ds) && (sp) && (ss)) {
1557 needed_bytes = dk3enc_size_hex_to_bin(ss);
1558 if(needed_bytes) {
1559 if(ds >= needed_bytes) {
1560 back = dk3enc_do_hex_to_bin(dp, sp, ss, app);
1561 } else {
1562 if(app) {
1563 /* Destination buffer too small! */
1564 dk3app_log_i1(app, DK3_LL_ERROR, 38);
1565 }
1566 }
1567 }
1568 }
1569 return back;
1570 }
1571
1572
1573
1574 size_t
dk3enc_hexstring_to_bin_app(char * dp,size_t ds,char const * sp,dk3_app_t * app)1575 dk3enc_hexstring_to_bin_app(
1576 char *dp, size_t ds, char const *sp, dk3_app_t *app
1577 )
1578 {
1579 size_t back = 0;
1580
1581 if(sp) {
1582 back = dk3enc_hex_to_bin_app(dp, ds, sp, dk3str_c8_len(sp), app);
1583 }
1584 return back;
1585 }
1586
1587
1588
1589 size_t
dk3enc_size_hexstring_to_bin(char const * s)1590 dk3enc_size_hexstring_to_bin(char const *s)
1591 {
1592 size_t back = 0;
1593
1594 if(s) {
1595 back = dk3str_c8_len(s);
1596 back = dk3enc_size_hex_to_bin(back);
1597 }
1598 return back;
1599 }
1600
1601
1602
1603 size_t
dk3enc_size_a85string_to_bin(char const * s)1604 dk3enc_size_a85string_to_bin(char const *s)
1605 {
1606 size_t back = 0;
1607
1608 if(s) {
1609 back = dk3str_c8_len(s);
1610 back = dk3enc_size_a85_to_bin(back);
1611 }
1612 return back;
1613 }
1614
1615
1616
1617 int
dk3enc_get_type_app(dkChar const * n,dk3_app_t * app)1618 dk3enc_get_type_app(dkChar const *n, dk3_app_t *app)
1619 {
1620 int back = -1;
1621 if(n) {
1622 back = dk3str_array_index(dk3enc_data_encoding_names, n, 0);
1623 if(back >= 0) {
1624 switch(back) {
1625 case 0: case 3: {
1626 back = DK3_DATA_ENCODING_HEX;
1627 } break;
1628 case 1: case 4: case 6: {
1629 back = DK3_DATA_ENCODING_ASCII85;
1630 } break;
1631 case 2: case 5: case 7: {
1632 back = DK3_DATA_ENCODING_REVERSE_ASCII85;
1633 } break;
1634 }
1635 } else {
1636 if(app) {
1637 dk3app_log_i3(app, DK3_LL_ERROR, 129, 130, n);
1638 }
1639 }
1640 }
1641 return back;
1642 }
1643
1644
1645 dkChar const *
dk3enc_get_data_encoding_name(int t)1646 dk3enc_get_data_encoding_name(int t)
1647 {
1648 dkChar const *back = NULL;
1649 if((t >= 0) && (t <= 2)) {
1650 back = dk3enc_data_encoding_names[t];
1651 }
1652 return back;
1653 }
1654
1655
1656
1657 int
dk3enc_get_text_encoding_app(dkChar const * en,dk3_app_t * app)1658 dk3enc_get_text_encoding_app(dkChar const *en, dk3_app_t *app)
1659 {
1660 int back = -1;
1661 int i;
1662
1663 if(app) { back = dk3app_get_output_encoding(app); }
1664 if(en) {
1665 i = dk3str_array_index(dk3enc_text_encoding_names, en, 0);
1666 switch(i) {
1667 case 0: case 8: case 9: {
1668 back = DK3_FILE_ENCODING_ASCII;
1669 } break;
1670 case 1: case 10: {
1671 back = DK3_FILE_ENCODING_UTF8;
1672 } break;
1673 case 2: case 11: {
1674 #if DK3_HAVE_BIGENDIAN
1675 back = DK3_FILE_ENCODING_UTF16_MSB_FIRST;
1676 #else
1677 back = DK3_FILE_ENCODING_UTF16_LSB_FIRST;
1678 #endif
1679 } break;
1680 case 3: case 18: case 19: case 20: case 21: case 22: case 23: {
1681 back = DK3_FILE_ENCODING_UTF16_MSB_FIRST;
1682 } break;
1683 case 4: case 12: case 13: case 14: case 15: case 16: case 17: {
1684 back = DK3_FILE_ENCODING_UTF16_LSB_FIRST;
1685 } break;
1686 case 5: case 24: {
1687 #if DK3_HAVE_BIGENDIAN
1688 back = DK3_FILE_ENCODING_UNICODE_MSB_FIRST;
1689 #else
1690 back = DK3_FILE_ENCODING_UNICODE_LSB_FIRST;
1691 #endif
1692 } break;
1693 case 6: case 29: case 30: case 31: case 32: {
1694 back = DK3_FILE_ENCODING_UNICODE_MSB_FIRST;
1695 } break;
1696 case 7: case 25: case 26: case 27: case 28: {
1697 back = DK3_FILE_ENCODING_UNICODE_LSB_FIRST;
1698 } break;
1699 default: {
1700 if(app) {
1701 /* ERROR: Unknown text encoding name! */
1702 dk3app_log_i3(app, DK3_LL_ERROR, 129, 130, en);
1703 }
1704 } break;
1705 }
1706 }
1707 return back;
1708 }
1709
1710
1711
1712 int
dk3enc_get_encoding(dk3_app_t * app)1713 dk3enc_get_encoding(dk3_app_t *app)
1714 {
1715 int back = 0;
1716 #if DK3_CHAR_SIZE == 1
1717 char *ptr;
1718 #endif
1719 if(app) {
1720 back = dk3app_get_encoding(app);
1721 } else {
1722 #if DK3_CHAR_SIZE > 1
1723 #if DK3_CHAR_SIZE > 2
1724 back = DK3_ENCODING_UNICODE;
1725 #else
1726 back = DK3_ENCODING_UTF16;
1727 #endif
1728 #else
1729 back = DK3_ENCODING_PLAIN;
1730 ptr = getenv("LANG");
1731 if(ptr) {
1732 ptr = dk3str_c8_chr(ptr, '.');
1733 if(ptr) {
1734 ptr++;
1735 switch(dk3str_c8_array_index(dk3enc_utf8_names, ptr, 0)) {
1736 case 0: case 1: {
1737 back = DK3_ENCODING_UTF8;
1738 } break;
1739 }
1740 }
1741 }
1742 #endif
1743 }
1744 return back;
1745 }
1746
1747
1748
1749 /* vim: set ai sw=2 : */
1750
1751