/* Copyright (C) 2011-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk3enc.ctr */ /** @file dk3enc.c The dk3enc module. */ #line 326 "dk3enc.ctr" #include "dk3all.h" #line 331 "dk3enc.ctr" /** Binary to text encoding names. Order here must match order of DK3_DATA_ENCODING_xxx in dk3const.h. */ static dkChar const * const dk3enc_data_encoding_names[] = { /* 0 */ dkT("HEX"), /* 1 */ dkT("ASCII-85"), /* 2 */ dkT("R-ASCII-85"), /* 3 */ dkT("H"), /* 4 */ dkT("A"), /* 5 */ dkT("R"), /* 6 */ dkT("A85"), /* 7 */ dkT("RA85"), NULL }; /** Encoding names for file contents encodings. */ static dkChar const * const dk3enc_text_encoding_names[] = { /* 0 */ dkT("PLAIN"), /* 1 */ dkT("UTF-8"), /* 2 */ dkT("UTF-16"), /* 3 */ dkT("UTF-16.MSB"), /* 4 */ dkT("UTF-16.LSB"), /* 5 */ dkT("UC32"), /* 6 */ dkT("UC32.MSB"), /* 7 */ dkT("UC32.LSB"), /* 8 */ dkT("ASCII"), /* 9 */ dkT("ISO-LATIN-1"), /* 10 */ dkT("UTF8"), /* 11 */ dkT("UTF16"), /* 12 */ dkT("UTF-16-LE"), /* 13 */ dkT("UTF-16LE"), /* 14 */ dkT("UTF16LE"), /* 15 */ dkT("UTF-16-LSB"), /* 16 */ dkT("UTF-16LSB"), /* 17 */ dkT("UTF16LSB"), /* 18 */ dkT("UTF-16-BE"), /* 19 */ dkT("UTF-16BE"), /* 20 */ dkT("UTF16BE"), /* 21 */ dkT("UTF-16-MSB"), /* 22 */ dkT("UTF-16MSB"), /* 23 */ dkT("UTF16MSB"), /* 24 */ dkT("C32"), /* 25 */ dkT("C32-LE"), /* 26 */ dkT("C32LE"), /* 27 */ dkT("C32-LSB"), /* 28 */ dkT("C32LSB"), /* 29 */ dkT("C32-BE"), /* 30 */ dkT("C32BE"), /* 31 */ dkT("C32-MSB"), /* 32 */ dkT("C32MSB"), NULL }; /** Encoding names for UTF-8 encoding. */ static char const * const dk3enc_utf8_names[] = { /* 0 */ "utf-8", /* 1 */ "utf8", NULL #line 399 "dk3enc.ctr" }; /** Digits used to show hexadecimal characters. */ static char const dk3enc_hex_digits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '\0' }; /** Bit mask to obtain last byte of a double word. */ static unsigned long const dk3enc_last_byte = 0x000000FFUL; /** Factors for ASCII85 and reverse ASCII85 encoding. */ static unsigned long const dk3enc_f2[] = { 1UL, 85UL, (85UL * 85UL), (85UL * 85UL * 85UL), (85UL * 85UL * 85UL * 85UL) }; /** Swap byte order for unsigned long. @param ul Original value. @return Value in swapped byte order. */ static unsigned long dk3enc_swap_ul(unsigned long ul) { unsigned long back = 0UL; back = ((ul >> 24) & 0x000000FFUL); back |= ((ul >> 8) & 0x0000FF00UL); back |= ((ul << 8) & 0x00FF0000UL); back |= ((ul << 24) & 0xFF000000UL); return back; } /** Swap byte order for unsigned short. @param us Original value. @return Value in swapped byte order. */ static unsigned short dk3enc_swap_us(unsigned short us) { unsigned short back = 0U; back = ((us >> 8) & 0x00FFU); back |= ((us << 8) & 0xFF00U); return back; } unsigned long dk3enc_ntohl(unsigned long x) { unsigned long back; #if DK3_WORDS_BIGENDIAN back = x; #else back = dk3enc_swap_ul(x); #endif return back; } unsigned long dk3enc_htonl(unsigned long x) { unsigned long back; #if DK3_WORDS_BIGENDIAN back = x; #else back = dk3enc_swap_ul(x); #endif return back; } unsigned short dk3enc_ntohs(unsigned short x) { unsigned short back; #if DK3_WORDS_BIGENDIAN back = x; #else back = dk3enc_swap_us(x); #endif return back; } unsigned short dk3enc_htons(unsigned short x) { unsigned short back; #if DK3_WORDS_BIGENDIAN back = x; #else back = dk3enc_swap_us(x); #endif return back; } unsigned long dk3enc_uc_to_ul(unsigned long c) { c &= 0xFFFFFFFFUL; return c; } unsigned long dk3enc_dk_to_ul(unsigned long c) { #if DK3_CHAR_SIZE > 1 #if DK3_CHAR_SIZE > 2 c &= 0xFFFFFFFFUL; #else c &= 0x0000FFFFUL; #endif #else c &= 0x000000FFUL; #endif return c; } /** Convert 32-bit character to UTF-8 following RFC2279. @param c 32-bit character to convert. @param u8p Destination buffer. @param u8l Length of @a u8p (number of bytes). @return Number of bytes written to @a u8p. */ static size_t dk3enc_uc2utf8_rfc2279(dk3_c32_t c, unsigned char *u8p, size_t u8l) { size_t back = 0; dk3_c32_t x = 0UL; /* Variable for temporary results. */ #line 553 "dk3enc.ctr" if(u8p) { if(u8l > 0) { if(c > (dk3_c32_t)0x7FUL) { if(c > (dk3_c32_t)0x000007FFUL) { if(c > (dk3_c32_t)0x0000FFFFUL) { if(c > (dk3_c32_t)0x001FFFFFUL) { if(c > (dk3_c32_t)0x03FFFFFFUL) { if(c < (dk3_c32_t)0x80000000UL) { /* 6 Byte */ if(u8l >= 6) { back = 6; x = c >> 30; x &= 0x00000001UL; x |= 0x000000FCUL; u8p[0] = (unsigned char)x; x = c >> 24; x &= 0x0000003FUL; x |= 0x00000080UL; u8p[1] = (unsigned char)x; x = c >> 18; x &= 0x0000003FUL; x |= 0x00000080UL; u8p[2] = (unsigned char)x; x = c >> 12; x &= 0x0000003FUL; x |= 0x00000080UL; u8p[3] = (unsigned char)x; x = c >> 6; x &= 0x0000003FUL; x |= 0x00000080UL; u8p[4] = (unsigned char)x; x = c & 0x0000003FUL; x |= 0x00000080UL; u8p[5] = (unsigned char)x; } } } else { /* 5 Byte */ if(u8l >= 5) { back = 5; x = c >> 24; x &= 0x00000003UL; x |= 0x000000F8UL; u8p[0] = (unsigned char)x; x = c >> 18; x &= 0x0000003FUL; x |= 0x00000080UL; u8p[1] = (unsigned char)x; x = c >> 12; x &= 0x0000003FUL; x |= 0x00000080UL; u8p[2] = (unsigned char)x; x = c >> 6; x &= 0x0000003FUL; x |= 0x00000080UL; u8p[3] = (unsigned char)x; x = c & 0x0000003FUL; x |= 0x00000080UL; u8p[4] = (unsigned char)x; } } } else { /* 4 Byte */ if(u8l >= 4) { back = 4; x = c >> 18; x &= 0x00000007UL; x |= 0x000000F0UL; u8p[0] = (unsigned char)x; x = c >> 12; x &= 0x0000003FUL; x |= 0x00000080UL; u8p[1] = (unsigned char)x; x = c >> 6; x &= 0x0000003FUL; x |= 0x00000080UL; u8p[2] = (unsigned char)x; x = c & 0x0000003FUL; x |= 0x00000080UL; u8p[3] = (unsigned char)x; } } } else { /* 3 Byte */ if(u8l >= 3) { back = 3; x = c >> 12; x &= 0x0000000FUL; x |= 0x000000E0UL; u8p[0] = (unsigned char)x; x = c >> 6; x &= 0x0000003FUL; x |= 0x00000080UL; u8p[1] = (unsigned char)x; x = c & 0x0000003FUL; x |= 0x00000080UL; u8p[2] = (unsigned char)x; } } } else { /* 2 Byte */ if(u8l >= 2) { back = 2; x = c >> 6; x &= 0x0000001FUL; x |= 0x000000C0UL; u8p[0] = (unsigned char)x; x = c & 0x0000003FUL; x |= 0x00000080UL; u8p[1] = (unsigned char)x; } } } else { /* 1 Byte */ if(u8l >= 1) { back = 1; u8p[0] = (unsigned char)(c & 0x0000007FUL); } } } } #line 652 "dk3enc.ctr" return back; } /** Get one 32-bit character from UTF-8 encoded string or buffer. @param ucp Pointer to destination variable. @param u8p Buffer containing UTF-8 encoded data. @param u8l Length of @a u8p (number of bytes). @param u8u Pointer to variable for used bytes from @a u8p. @return 1 on success, 0 on error. */ static int dk3enc_utf82uc_rfc2279( dk3_c32_t *ucp, unsigned char const *u8p,size_t u8l,size_t *u8u ) { int back = 0; unsigned char u1 = 0x00; /* Character to process. */ dk3_c32_t res = 0UL; /* Result. */ dk3_c32_t x1 = 0UL; /* Result component from 1st byte. */ dk3_c32_t x2 = 0UL; /* Result component from 2nd byte. */ dk3_c32_t x3 = 0UL; /* Result component from 3rd byte. */ dk3_c32_t x4 = 0UL; /* Result component from 4th byte. */ dk3_c32_t x5 = 0UL; /* Result component from 5th byte. */ dk3_c32_t x6 = 0UL; /* Result component from 6th byte. */ size_t needed_length = 0; /* Number of btes needed. */ #line 681 "dk3enc.ctr" needed_length = 0; if(ucp) { if(u8p) { if(u8l) { if(u8u) { if((u8l) > 0) { u1 = *u8p; needed_length = 1; if(u1 > 0x7F) { /* > 1 Byte */ if((u1 & 0xE0) == 0xC0) { /* 2 Byte */ needed_length = 2; if(u8l >= needed_length) { if((u8p[1] & 0xC0) == 0x80) { x1 = u1; x1 = x1 << 6; x1 = x1 & 0x000007C0UL; x2 = u8p[1]; x2 = x2 & 0x0000003FUL; res = (x1 | x2); back = 1; } } } else { if((u1 & 0xF0) == 0xE0) { /* 3 Byte */ needed_length = 3; if(u8l >= needed_length) { if((u8p[1] & 0xC0) == 0x80) { if((u8p[2] & 0xC0) == 0x80) { x1 = u1; x1 = x1 << 12; x1 = x1 & 0x0000F000UL; x2 = u8p[1]; x2 = x2 << 6; x2 = x2 & 0x00000FC0UL; x3 = u8p[2]; x3 = x3 & 0x0000003FUL; res = (x1 | x2 | x3); back = 1; } } } } else { if((u1 & 0xF8) == 0xF0) { /* 4 Byte */ needed_length = 4; if(u8l >= needed_length) { if((u8p[1] & 0xC0) == 0x80) { if((u8p[2] & 0xC0) == 0x80) { if((u8p[3] & 0xC0) == 0x80) { x1 = u1; x2 = u8p[1]; x3 = u8p[2]; x4 = u8p[3]; x1 = x1 << 18; x1 = x1 & 0x001C0000UL; x2 = x2 << 12; x2 = x2 & 0x0003F000UL; x3 = x3 << 6; x3 = x3 & 0x00000FC0UL; x4 = x4 & 0x0000003FUL; res = (x1 | x2 | x3 | x4); back = 1; } } } } } else { if((u1 & 0xFC) == 0xF8) { /* 5 Byte */ needed_length = 5; if(u8l >= needed_length) { if((u8p[1] & 0xC0) == 0x80) { if((u8p[2] & 0xC0) == 0x80) { if((u8p[3] & 0xC0) == 0x80) { if((u8p[4] & 0xC0) == 0x80) { x1 = u1; x2 = u8p[1]; x3 = u8p[2]; x4 = u8p[3]; x5 = u8p[4]; x1 = x1 << 24; x1 = x1 & 0x03000000UL; x2 = x2 << 18; x2 = x2 & 0x00FC0000UL; x3 = x3 << 12; x3 = x3 & 0x0003F000UL; x4 = x4 << 6; x4 = x4 & 0x00000FC0UL; x5 = x5 & 0x0000003FUL; res = (x1 | x2 | x3 | x4 | x5); back = 1; } } } } } } else { if((u1 & 0xFE) == 0xFC) { /* 6 Byte */ needed_length = 6; if(u8l >= needed_length) { if((u8p[1] & 0xC0) == 0x80) { if((u8p[2] & 0xC0) == 0x80) { if((u8p[3] & 0xC0) == 0x80) { if((u8p[4] & 0xC0) == 0x80) { if((u8p[5] & 0xC0) == 0x80) { x1 = 0x40000000UL; x2 = u8p[1]; x3 = u8p[2]; x4 = u8p[3]; x5 = u8p[4]; x6 = u8p[5]; x2 = x2 << 24; x3 = x3 << 18; x4 = x4 << 12; x5 = x5 << 6; x2 = x2 & 0x3F000000UL; x3 = x3 & 0x00FC0000UL; x4 = x4 & 0x0003F000UL; x5 = x5 & 0x00000FC0UL; x6 = x6 & 0x0000003FUL; res = (x1 | x2 | x3 | x4 | x5 | x6); back = 1; } } } } } } } } } } } } else { /* 1 Byte */ res = u1; back = 1; } } } } } } if(back) { *u8u = needed_length; *ucp = res; } #line 817 "dk3enc.ctr" return back; } #if DK3_HAVE_RFC_2279 /* RFC 2279 allowed UTF-8 encoding for 32-bit characters in the range 0 ... 0x7FFFFFFF. */ size_t dk3enc_uc2utf8(dk3_c32_t c, unsigned char *u8p, size_t u8l) { size_t back; #line 834 "dk3enc.ctr" back = dk3enc_uc2utf8_rfc2279(c, u8p, u8l); #line 836 "dk3enc.ctr" return back; } int dk3enc_utf82uc(dk3_c32_t *ucp, unsigned char const *u8p,size_t u8l,size_t *u8u) { int back; back = dk3enc_utf82uc_rfc2279(ucp, u8p, u8l, u8u); return back; } #else /* RFC 3629 replaces (obsoletes) RFC 2279. 32-bit characters are now allowed in the range 0 ... 0x0010FFFF only. */ size_t dk3enc_uc2utf8(dk3_c32_t c, unsigned char *u8p, size_t u8l) { size_t back = 0; #line 861 "dk3enc.ctr" if(c <= (dk3_c32_t)0x0010FFFFUL) { back = dk3enc_uc2utf8_rfc2279(c, u8p, u8l); } #line 864 "dk3enc.ctr" return back; } int dk3enc_utf82uc(dk3_c32_t *ucp, unsigned char const *u8p,size_t u8l,size_t *u8u) { int back = 0; back = dk3enc_utf82uc_rfc2279(ucp, u8p, u8l, u8u); if(back) { if((*ucp) > (dk3_c32_t)0x0010FFFFUL) { back = 0; } } return back; } #endif size_t dk3enc_uc2utf16(dk3_c32_t c, dk3_c16_t *u16p, size_t u16l) { size_t back = 0; dk3_c32_t ul = 0UL; /* Low surrogate. */ dk3_c32_t um = 0UL; /* Hight surrogate. */ if((u16p) && (u16l)) { if(c >= (dk3_c32_t)0x00010000UL) { if(c <= (dk3_c32_t)0x0010FFFFUL) { if(u16l >= 2) { ul = c - 0x00010000UL; um = ((ul >> 10) & 0x000003FFUL); um |= 0x0000D800UL; u16p[0] = (dk3_c16_t)um; um = (ul & 0x000003FFUL); um |= 0x0000DC00UL; u16p[1] = (dk3_c16_t)um; back = 2; } } } else { #if VERSION_BEFORE_20141125 if((c & 0x0000DC00UL) != 0x0000DC00UL) { if((c & 0x0000DC00UL) != 0x0000D800UL) { *u16p = (dk3_c16_t)c; back = 1; } } #else if ((0x0000D800UL > (0xFFFFFFFFUL & ((unsigned long)c))) || (0x0000DFFFUL < (0xFFFFFFFFUL & ((unsigned long)c))) ) { *u16p = (dk3_c16_t)c; back = 1; } #endif } } return back; } int dk3enc_utf162uc(dk3_c32_t *ucp, dk3_c16_t const *u16p, size_t u16l, size_t *u16u) { int back = 0; dk3_c32_t result = 0UL; /* Result 32-bit character. */ dk3_c32_t ul1 = 0UL; /* First UC16 used. */ dk3_c32_t ul2 = 0UL; /* Second UC16 used (if any). */ if((ucp) && (u16p) && (u16l) && (u16u)) { *u16u = 0; ul1 = (((dk3_c32_t)(u16p[0])) & 0x0000FFFFUL); ul2 = 0UL; if(u16l > 1) { ul2 = (((dk3_c32_t)(u16p[1])) & 0x0000FFFFUL); } if((ul1 & 0x0000DC00UL) == 0x0000DC00UL) { if(u16l > 1) { if((ul2 & 0x0000DC00UL) == 0x0000D800UL) { ul2 = ((ul2 << 10) & 0x000FFC00UL); ul1 = (ul1 & 0x000003FFUL); result = ul1 | ul2; result = result + 0x00010000UL; *ucp = result; *u16u = 2; back = 1; } } } else { if((ul1 & 0x0000DC00UL) == 0x0000D800UL) { if(u16l > 1) { if((ul2 & 0x0000DC00UL) == 0x0000DC00UL) { ul1 = ((ul1 << 10) & 0x000FFC00UL); ul2 = (ul2 & 0x000003FFUL); result = ul1 | ul2; result = result + 0x00010000UL; *ucp = result; *u16u = 2; back = 1; } } } else { ul1 &= 0x0000FFFFUL; *ucp = ul1; *u16u = 1; back = 1; } } } return back; } /** Check whether a character is a digit. @param c Character to check. @return 1 on success, 0 on error. */ static int dk3enc_c8_is_digit(char c) { int back = 0; switch(c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { back = 1; } break; } return back; } /** Convert digit to corresponding unsigned long. @param c Digit. @return Unsigned long for the digit. */ static unsigned long dk3enc_c8_to_ul(char c) { unsigned long back = 0UL; if(c == '1') back = 1UL; if(c == '2') back = 2UL; if(c == '3') back = 3UL; if(c == '4') back = 4UL; if(c == '5') back = 5UL; if(c == '6') back = 6UL; if(c == '7') back = 7UL; if(c == '8') back = 8UL; if(c == '9') back = 9UL; return back; } int dk3enc_ipaddr_to_ul_app(dkChar const *str, unsigned long *ul, dk3_app_t *app) { char bu[512]; int back = 0; #line 1022 "dk3enc.ctr" if((str) && (ul)) { if(dk3str_string_to_c8_simple_app(bu, sizeof(bu), str, app)) { #line 1024 "dk3enc.ctr" back = dk3enc_c8_ipaddr_to_ul_app(bu, ul, app); } else { /* ERROR: Conversion failed! */ } } #line 1029 "dk3enc.ctr" return back; } int dk3enc_c8_ipaddr_to_ul_app(char const *str, unsigned long *ul, dk3_app_t *app) { int back = 0; int state = 0; /* Current state. */ char const *ptr = NULL; /* Used to traverse string. */ unsigned long ul1 = 0UL; /* First part of IP address. */ unsigned long ul2 = 0UL; /* Second part of IP address. */ unsigned long ul3 = 0UL; /* Third part of IP address. */ unsigned long ulval = 0UL; /* Resulting IP address. */ #line 1045 "dk3enc.ctr" if(str && ul) { state = 0; ptr = str; back = 1; ul1 = ul2 = ul3 = ulval = 0UL; while(back && (*ptr)) { if(dk3enc_c8_is_digit(*ptr)) { switch(state) { case 0: case 1: case 2: case 4: case 5: case 6: case 8: case 9: case 10: case 12: case 13: case 14: { ulval = 10UL * ulval + dk3enc_c8_to_ul(*ptr); state++; } break; default: { back = 0; } break; } } else { if(*ptr == '.') { switch(state) { case 0: case 1: case 2: case 3: { ul1 = ulval; ulval = 0UL; state = 4; } break; case 4: case 5: case 6: case 7: { ul2 = ulval; ulval = 0UL; state = 8; } break; case 8: case 9: case 10: case 11: { ul3 = ulval; ulval = 0UL; state = 12; } break; } } else { back = 0; } } ptr++; } if((state < 12) || (state > 15)) { back = 0; } if(back) { if(ul1 > 255UL) back = 1; if(ul2 > 255UL) back = 1; if(ul3 > 255UL) back = 1; if(ulval > 255UL) back = 1; } if(back) { ul1 = ul1 << 24; ul1 &= 0xFF000000UL; ul2 = ul2 << 16; ul2 &= 0x00FF0000UL; ul3 = ul3 << 8; ul3 &= 0x0000FF00UL; ulval &= 0x000000FFUL; ulval = ulval | ul1 | ul2 | ul3; *ul = ulval; } else { if(app) { /* Not an IP address! */ } } } #line 1123 "dk3enc.ctr" return back; } size_t dk3enc_size_bin_to_a85(size_t s) { #if VERSION_BEFORE_20140809 size_t back = 0; int ec = 0; /* Error code. */ unsigned long ul1 = 0UL; /* Original size converted to unsigned long. */ unsigned long ul2 = 0UL; /* Remainder of division by 4. */ unsigned long ul3 = 0UL; /* Result division by 4. */ #line 1138 "dk3enc.ctr" ul1 = (unsigned long)s; ul2 = ul1 % 4UL; ul3 = ul1 / 4UL; if(ul2) ul2++; /* for last incomplete block */ ul1 = dk3ma_ul_add_ok( dk3ma_ul_mul_ok(ul3, 5UL, &ec), ul2, &ec ); /* add 25 percent */ ul1++; /* final 0x00 byte for string */ back = (size_t)ul1; if(ec) back = 0; /* error checking */ if((unsigned long)back != ul1) back = 0; #line 1152 "dk3enc.ctr" return back; #else size_t back = 0; size_t rem = 0; /* Division remainder */ size_t res = 0; /* Division result */ int ec = 0; /* Error code */ #line 1159 "dk3enc.ctr" rem = s % 4; res = s / 4; if (rem) { rem++; } /* back = 5 * res + rem + 1 */ rem++; back = dk3mem_add_size_t(rem, dk3mem_mul_size_t(5, res, &ec), &ec); if (ec) { back = 0; } #line 1167 "dk3enc.ctr" return back; #endif } /** Convert binary data to ASCII-85 encoded string. @param dp Destination pointer. @param sp Source pointer. @param ss Source size. */ static void dk3enc_do_bin_to_ra85(char *dp, char const *sp, size_t ss) { register char const *mysp = NULL; /* Source pointer. */ register unsigned char *mydp = NULL; /* Destination pointer. */ register unsigned long v = 0UL; /* Output value. */ register size_t i = 0; /* Current byte index. */ register short vused = 0; /* Flag: v is used. */ #line 1188 "dk3enc.ctr" mydp = (unsigned char *)dp; mysp = sp; v = 0UL; vused = 0; for(i = 0; i < ss; i++) { switch(vused++) { case 3: { v |= ((((unsigned long)((unsigned char)(*(mysp++)))) << 24) & 0xFF000000UL); } break; case 2: { v |= ((((unsigned long)((unsigned char)(*(mysp++)))) << 16) & 0x00FF0000UL); } break; case 1: { v |= ((((unsigned long)((unsigned char)(*(mysp++)))) << 8) & 0x0000FF00UL); } break; default: { v |= ((((unsigned long)((unsigned char)(*(mysp++)))) ) & dk3enc_last_byte); } break; } if(vused >= 4) { *(mydp++) = (unsigned char)((v % 85UL) + 33UL); v = v / 85UL; *(mydp++) = (unsigned char)((v % 85UL) + 33UL); v = v / 85UL; *(mydp++) = (unsigned char)((v % 85UL) + 33UL); v = v / 85UL; *(mydp++) = (unsigned char)((v % 85UL) + 33UL); v = v / 85UL; *(mydp++) = (unsigned char)((v % 85UL) + 33UL); vused = 0; v = 0UL; } } if(vused) { vused++; while(vused--) { *(mydp++) = (unsigned char)((v % 85UL) + 33UL); v = v / 85UL; } } *mydp = '\0'; #line 1229 "dk3enc.ctr" } int dk3enc_bin_to_ra85_app( char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app ) { int back = 0; size_t needed_size = 0; /* Destination buffer minimum size. */ #line 1241 "dk3enc.ctr" if((dp) && (sp) && (ds) && (ss)) { needed_size = dk3enc_size_bin_to_a85(ss); if(needed_size) { if(ds >= needed_size) { dk3enc_do_bin_to_ra85(dp, sp, ss); back = 1; } else { if(app) { /* Destination buffer too small! */ dk3app_log_i1(app, DK3_LL_ERROR, 38); } } } } #line 1255 "dk3enc.ctr" return back; } size_t dk3enc_size_a85_to_bin(size_t s) { size_t back = 0; unsigned long ul1 = 0UL; /* Original size converted to unsigned long. */ unsigned long ul2 = 0UL; /* Remainder of division by 5. */ unsigned long ul3 = 0UL; /* Result of division by 5. */ #line 1268 "dk3enc.ctr" ul1 = (unsigned long)s; ul2 = ul1 % 5UL; ul3 = ul1 / 5UL; ul1 = 4UL * ul3 + ul2; back = (size_t)ul1; #line 1274 "dk3enc.ctr" return back; } /** Check whether a character is from the ASCII-85 charset. @param c Character to check. @return 1 on success, 0 on error. */ static int dk3enc_c8_is_a85(char c) { int back = 1; if((int)c < 33) { back = 0; } else { if((int)c > 117) { back = 0; } } return back; } /** Convert reverse ASCII-85 encoded data to binary data. @param dp Destination pointer. @param sp Source pointer. @param ss Source size. @param app Application structure for diagnostics, may be NULL. @return Number of binary bytes produced. */ static size_t dk3enc_do_ra85_to_bin(char *dp, char const *sp, size_t ss, dk3_app_t *app) { size_t back = 0; unsigned char *mydp = NULL; /* Destination pointer. */ char const *mysp = NULL; /* Source pointer. */ unsigned long v = 0UL; /* Double-word. */ short vused = 0; /* Flag: v is used. */ size_t i = 0; /* Index of current source byte. */ int reported_illegal_char = 0; /* Flag: Error already reported. */ #line 1319 "dk3enc.ctr" mydp = (unsigned char *)dp; mysp = sp; v = 0UL; vused = 0; for(i = 0; i < ss; i++) { if(dk3enc_c8_is_a85(*mysp)) { v += dk3enc_f2[vused++] * ((((unsigned long)((unsigned char)(*mysp))) & dk3enc_last_byte) - 33UL); if(vused >= 5) { *(mydp++) = (unsigned char)(v & dk3enc_last_byte); *(mydp++) = (unsigned char)((v >> 8) & dk3enc_last_byte); *(mydp++) = (unsigned char)((v >> 16) & dk3enc_last_byte); *(mydp++) = (unsigned char)((v >> 24) & dk3enc_last_byte); back += 4; v = 0UL; vused = 0; } } else { if(app) { if(!reported_illegal_char) { reported_illegal_char = 1; /* Illegal character(s) in source string! */ dk3app_log_i1(app, DK3_LL_ERROR, 67); } } } mysp++; } if(vused) { vused--; while(vused--) { *(mydp++) = (unsigned char)(v & dk3enc_last_byte); back++; v = v >> 8; } } #line 1350 "dk3enc.ctr" return back; } size_t dk3enc_ra85_to_bin_app( char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app ) { size_t back = 0; size_t needed_size = 0; /* Minimum output buffer size. */ #line 1363 "dk3enc.ctr" if((dp) && (sp) && (ds) && (ss)) { needed_size = dk3enc_size_a85_to_bin(ss); if(needed_size) { if(ds >= needed_size) { back = dk3enc_do_ra85_to_bin(dp, sp, ss, app); } else { if(app) { /* Destination buffer too small! */ dk3app_log_i1(app, DK3_LL_ERROR, 38); } } } } #line 1376 "dk3enc.ctr" return back; } size_t dk3enc_ra85string_to_bin_app( char *dp, size_t ds, char const *sp, dk3_app_t *app ) { size_t back = 0; #line 1388 "dk3enc.ctr" if(sp) { back = dk3enc_ra85_to_bin_app(dp, ds, sp, dk3str_c8_len(sp), app); } return back; } /** Convert binary data to ASCII-85 string. @param dp Destination pointer. @param sp Source pointer. @param ss Source size. */ static void dk3enc_do_bin_to_a85(char *dp, char const *sp, size_t ss) { register unsigned char *mydp = NULL; /* Destination pointer. */ register unsigned char *mysp = NULL; /* Source pointer. */ register unsigned long v = 0UL; /* Double-word. */ register short vused = 0; /* Flag: v used. */ register short addval = 0; /* Value to add. */ register size_t i = 0; /* Index of current source byte. */ #line 1412 "dk3enc.ctr" mydp = (unsigned char *)dp; mysp = (unsigned char *)sp; v = 0UL; vused = 0; for(i = 0; i < ss; i++) { switch(vused) { case 3: { v |= ( ((unsigned long)(*(mysp++))) & 0x000000FFUL); } break; case 2: { v |= ((((unsigned long)(*(mysp++))) << 8) & 0x0000FF00UL); } break; case 1: { v |= ((((unsigned long)(*(mysp++))) << 16) & 0x00FF0000UL); } break; default: { v |= ((((unsigned long)(*(mysp++))) << 24) & 0xFF000000UL); } break; } if(++vused >= 4) { vused = 5; while(vused--) { *(mydp++) = (unsigned char)(33UL + v / dk3enc_f2[vused]); v = v % dk3enc_f2[vused]; } v = 0UL; vused = 0; } } if(vused) { vused++; addval = 5 - vused; while(vused--) { *(mydp++) = (unsigned char)(33UL + v / dk3enc_f2[vused + addval]); v = v % dk3enc_f2[vused + addval]; } } *mydp = '\0'; #line 1448 "dk3enc.ctr" } int dk3enc_bin_to_a85_app( char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app ) { int back = 0; size_t needed_size = 0; /* Minimum output buffer size. */ #line 1460 "dk3enc.ctr" if((dp) && (sp) && (ds) && (ss)) { needed_size = dk3enc_size_bin_to_a85(ss); if(needed_size) { if(ds >= needed_size) { dk3enc_do_bin_to_a85(dp, sp, ss); back = 1; } else { if(app) { /* Destination buffer too small! */ dk3app_log_i1(app, DK3_LL_ERROR, 38); } } } } #line 1474 "dk3enc.ctr" return back; } /** Convert ASCII-85 encoded data to binary data. @param dp Destination pointer. @param sp Source pointer. @param ss Source size. @param app Application structure for diagnostics, may be NULL. @return Number of binary bytes produced. */ static size_t dk3enc_do_a85_to_bin(char *dp, char const *sp, size_t ss, dk3_app_t *app) { register size_t back = 0; register unsigned char *mydp = NULL; /* Destination pointer. */ register unsigned char const *mysp = NULL; /* Source pointer. */ register unsigned long v = 0UL; /* Double-word. */ register short vused = 0; /* Flag: v used. */ register size_t i = 0; /* Current source byte index. */ unsigned long u1 = 0UL; /* Temporary value. */ unsigned long u2 = 0UL; /* Temporary value. */ unsigned long u3 = 0UL; /* Temporary value. */ int reported_illegal_character = 0; #line 1501 "dk3enc.ctr" mydp = (unsigned char *)dp; mysp = (unsigned char *)sp; v = 0UL; vused = 0; for(i = 0; i < ss; i++) { if(*mysp) { if(dk3enc_c8_is_a85(*mysp)) { v += dk3enc_f2[4 - vused] * ((((unsigned long)(*mysp)) & 0x000000FFUL) - 33UL); } else { if(!reported_illegal_character) { reported_illegal_character = 1; if(app) { /* Illegal character in source data! */ dk3app_log_i1(app, DK3_LL_ERROR, 67); } } } vused++; if(vused >= 5) { *(mydp++) = (unsigned char)((v >> 24) & 0x000000FFUL); back++; *(mydp++) = (unsigned char)((v >> 16) & 0x000000FFUL); back++; *(mydp++) = (unsigned char)((v >> 8) & 0x000000FFUL); back++; *(mydp++) = (unsigned char)( v & 0x000000FFUL); back++; v = 0UL; vused = 0; } } mysp++; } if(vused) { u1 = (v >> 24) & 0x000000FFUL; u2 = (v >> 16) & 0x000000FFUL; u3 = (v >> 8) & 0x000000FFUL; switch(vused) { case 2: { if(v & 0x00FFFFFFUL) { u1++; if(u1 >= 256UL) u1 = 0UL; } *(mydp++) = (unsigned char)(u1 & 0x000000FFUL); back++; } break; case 3: { if(v & 0x0000FFFFUL) { u2++; if(u2 >= 256UL) { u2 = 0UL; u1++; if(u1 >= 256UL) u1 = 0UL; } } *(mydp++) = (unsigned char)(u1 & 0x000000FFUL); back++; *(mydp++) = (unsigned char)(u2 & 0x000000FFUL); back++; } break; case 4: { if(v & 0x000000FFUL) { u3++; if(u3 >= 256UL) { u3 = 0UL; u2++; if(u2 >= 256UL) { u2 = 0UL; u1++; if(u1 >= 256UL) u1 = 0UL; } } } *(mydp++) = (unsigned char)(u1 & 0x000000FFUL); back++; *(mydp++) = (unsigned char)(u2 & 0x000000FFUL); back++; *(mydp++) = (unsigned char)(u3 & 0x000000FFUL); back++; } break; } } #line 1568 "dk3enc.ctr" return back; } size_t dk3enc_a85_to_bin_app( char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app ) { size_t back = 0; size_t needed_size = 0; /* Minimum output buffer size. */ #line 1581 "dk3enc.ctr" if((dp) && (sp) && (ds) && (ss)) { needed_size = dk3enc_size_a85_to_bin(ss); if(needed_size) { if(ds >= needed_size) { back = dk3enc_do_a85_to_bin(dp, sp, ss, app); } else { if(app) { /* Destination buffer too small! */ dk3app_log_i1(app, DK3_LL_ERROR, 38); } } } } #line 1594 "dk3enc.ctr" return back; } size_t dk3enc_a85string_to_bin_app(char *dp, size_t ds, char const *sp, dk3_app_t *app) { size_t back = 0; #line 1604 "dk3enc.ctr" if(sp) { back = dk3enc_a85_to_bin_app(dp, ds, sp, dk3str_c8_len(sp), app); } #line 1607 "dk3enc.ctr" return back; } size_t dk3enc_size_bin_to_hex(size_t s) { #if VERSION_BEFORE_20140809 size_t back = 0; int ec = 0; /* Error code. */ unsigned long ul1 = 0UL; /* Temporary value for calculation. */ #line 1620 "dk3enc.ctr" ul1 = (unsigned long)s; ul1 = dk3ma_ul_mul_ok(ul1, 2UL, &ec); ul1 = dk3ma_ul_add_ok(ul1, 1UL, &ec); back = (size_t)ul1; if(ec) back = 0; if((unsigned long)back != ul1) back = 0; #line 1627 "dk3enc.ctr" return back; #else size_t back = 0; int ec = 0; /* Error code */ #line 1632 "dk3enc.ctr" back = dk3mem_add_size_t(1, dk3mem_mul_size_t(2, s, &ec), &ec); if (ec) { back = 0; } #line 1635 "dk3enc.ctr" return back; #endif } size_t dk3enc_size_hex_to_bin(size_t s) { size_t back; #line 1646 "dk3enc.ctr" back = s / 2; back++; #line 1648 "dk3enc.ctr" return back; } /** Get higher half-byte from character. @param c Source character. @return Higher half-byte of \a c. */ static char dk3enc_c8_high_nibble_hex(char c) { char back; back = dk3enc_hex_digits[ (((unsigned short)c) >> 4) & 0x000FU ]; return back; } /** Get lower half-byte from character. @param c Source character. @return Lower half-byte of \a c. */ static char dk3enc_c8_low_nibble_hex(char c) { char back; back = dk3enc_hex_digits[ ((unsigned short)c) & 0x000FU ]; return back; } /** Convert binary data to hexadecimal string. @param dp Destination pointer. @param sp Source pointer. @param ss Source size. */ static void dk3enc_do_bin_to_hex(char *dp, char const *sp, size_t ss) { register char *mydp = NULL; /* Destination pointer. */ register char const *mysp = NULL; /* Source pointer. */ register size_t i = 0; /* Current source byte index. */ #line 1696 "dk3enc.ctr" mydp = dp; mysp = sp; for(i = 0; i < ss; i++) { *(mydp++) = dk3enc_c8_high_nibble_hex(*mysp); *(mydp++) = dk3enc_c8_low_nibble_hex(*(mysp++)); } *mydp = '\0'; #line 1702 "dk3enc.ctr" } int dk3enc_bin_to_hex_app( char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app ) { int back = 0; size_t needed_bytes = 0; /* Minimum output buffer size. */ #line 1714 "dk3enc.ctr" if((dp) && (ds) && (sp) && (ss)) { needed_bytes = dk3enc_size_bin_to_hex(ss); if(needed_bytes) { if(ds >= needed_bytes) { dk3enc_do_bin_to_hex(dp, sp, ss); back = 1; } else { if(app) { /* Destination buffer too small1 */ dk3app_log_i1(app, DK3_LL_ERROR, 38); } } } } #line 1727 "dk3enc.ctr" return back; } /** Convert hexadecimal data to binary data. @param dp Destination pointer. @param sp Source pointer. @param ss Source size. @param app Application structure for diagnostics, may be NULL. @return Number of bytes created in destination. */ static size_t dk3enc_do_hex_to_bin(char *dp, char const *sp, size_t ss, dk3_app_t *app) { register size_t back = 0; register char const *mysp = NULL; /* Source pointer. */ register unsigned char *mydp = NULL; /* Destination pointer. */ register unsigned char v = 0x00; /* Current byte to process. */ register short int vused = 0; /* Flag: v used. */ register size_t i = 0; /* Current source byte index. */ int reported_illegal_character = 0; /* Flag: Error already reported. */ #line 1751 "dk3enc.ctr" mydp = (unsigned char *)dp; mysp = sp; v = 0x00; vused = 0U; for(i = 0; i < ss; i++) { switch(*mysp) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'a': case 'A': case 'b': case 'B': case 'c': case 'C': case 'd': case 'D': case 'e': case 'E': case 'f': case 'F': { if(vused) { switch(*mysp) { case '0': { v |= 0x00; } break; case '1': { v |= 0x01; } break; case '2': { v |= 0x02; } break; case '3': { v |= 0x03; } break; case '4': { v |= 0x04; } break; case '5': { v |= 0x05; } break; case '6': { v |= 0x06; } break; case '7': { v |= 0x07; } break; case '8': { v |= 0x08; } break; case '9': { v |= 0x09; } break; case 'a': { v |= 0x0A; } break; case 'A': { v |= 0x0A; } break; case 'b': { v |= 0x0B; } break; case 'B': { v |= 0x0B; } break; case 'c': { v |= 0x0C; } break; case 'C': { v |= 0x0C; } break; case 'd': { v |= 0x0D; } break; case 'D': { v |= 0x0D; } break; case 'e': { v |= 0x0E; } break; case 'E': { v |= 0x0E; } break; case 'f': { v |= 0x0F; } break; case 'F': { v |= 0x0F; } break; } *(mydp++) = v; back++; v = 0; vused = 0U; } else { switch(*mysp) { case '0': { v = 0x00; } break; case '1': { v = 0x10; } break; case '2': { v = 0x20; } break; case '3': { v = 0x30; } break; case '4': { v = 0x40; } break; case '5': { v = 0x50; } break; case '6': { v = 0x60; } break; case '7': { v = 0x70; } break; case '8': { v = 0x80; } break; case '9': { v = 0x90; } break; case 'a': { v = 0xA0; } break; case 'A': { v = 0xA0; } break; case 'b': { v = 0xB0; } break; case 'B': { v = 0xB0; } break; case 'c': { v = 0xC0; } break; case 'C': { v = 0xC0; } break; case 'd': { v = 0xD0; } break; case 'D': { v = 0xD0; } break; case 'e': { v = 0xE0; } break; case 'E': { v = 0xE0; } break; case 'f': { v = 0xF0; } break; case 'F': { v = 0xF0; } break; } vused = 1U; } } break; default: { if(!reported_illegal_character) { reported_illegal_character = 1; if(app) { /* Illegal character(s) in source! */ dk3app_log_i1(app, DK3_LL_ERROR, 67); } } } break; } mysp++; } if(vused) { *mydp = v; back++; } #line 1847 "dk3enc.ctr" return back; } size_t dk3enc_hex_to_bin_app( char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app ) { size_t back = 0; size_t needed_bytes = 0; /* Minimum output buffer size. */ #line 1860 "dk3enc.ctr" if((dp) && (ds) && (sp) && (ss)) { needed_bytes = dk3enc_size_hex_to_bin(ss); if(needed_bytes) { if(ds >= needed_bytes) { back = dk3enc_do_hex_to_bin(dp, sp, ss, app); } else { if(app) { /* Destination buffer too small! */ dk3app_log_i1(app, DK3_LL_ERROR, 38); } } } } #line 1873 "dk3enc.ctr" return back; } size_t dk3enc_hexstring_to_bin_app( char *dp, size_t ds, char const *sp, dk3_app_t *app ) { size_t back = 0; #line 1885 "dk3enc.ctr" if(sp) { back = dk3enc_hex_to_bin_app(dp, ds, sp, dk3str_c8_len(sp), app); } #line 1888 "dk3enc.ctr" return back; } size_t dk3enc_size_hexstring_to_bin(char const *s) { size_t back = 0; #line 1898 "dk3enc.ctr" if(s) { back = dk3str_c8_len(s); back = dk3enc_size_hex_to_bin(back); } #line 1902 "dk3enc.ctr" return back; } size_t dk3enc_size_a85string_to_bin(char const *s) { size_t back = 0; #line 1912 "dk3enc.ctr" if(s) { back = dk3str_c8_len(s); back = dk3enc_size_a85_to_bin(back); } #line 1916 "dk3enc.ctr" return back; } int dk3enc_get_type_app(dkChar const *n, dk3_app_t *app) { int back = -1; if(n) { back = dk3str_array_index(dk3enc_data_encoding_names, n, 0); if(back >= 0) { switch(back) { case 0: case 3: { back = DK3_DATA_ENCODING_HEX; } break; case 1: case 4: case 6: { back = DK3_DATA_ENCODING_ASCII85; } break; case 2: case 5: case 7: { back = DK3_DATA_ENCODING_REVERSE_ASCII85; } break; } } else { if(app) { dk3app_log_i3(app, DK3_LL_ERROR, 129, 130, n); } } } return back; } dkChar const * dk3enc_get_data_encoding_name(int t) { dkChar const *back = NULL; if((t >= 0) && (t <= 2)) { back = dk3enc_data_encoding_names[t]; } return back; } int dk3enc_get_text_encoding_app(dkChar const *en, dk3_app_t *app) { int back = -1; int i; #line 1967 "dk3enc.ctr" if(app) { back = dk3app_get_output_encoding(app); } if(en) { i = dk3str_array_index(dk3enc_text_encoding_names, en, 0); #line 1970 "dk3enc.ctr" switch(i) { case 0: case 8: case 9: { back = DK3_FILE_ENCODING_ASCII; } break; case 1: case 10: { back = DK3_FILE_ENCODING_UTF8; } break; case 2: case 11: { #if DK3_HAVE_BIGENDIAN back = DK3_FILE_ENCODING_UTF16_MSB_FIRST; #else back = DK3_FILE_ENCODING_UTF16_LSB_FIRST; #endif } break; case 3: case 18: case 19: case 20: case 21: case 22: case 23: { back = DK3_FILE_ENCODING_UTF16_MSB_FIRST; } break; case 4: case 12: case 13: case 14: case 15: case 16: case 17: { back = DK3_FILE_ENCODING_UTF16_LSB_FIRST; } break; case 5: case 24: { #if DK3_HAVE_BIGENDIAN back = DK3_FILE_ENCODING_UNICODE_MSB_FIRST; #else back = DK3_FILE_ENCODING_UNICODE_LSB_FIRST; #endif } break; case 6: case 29: case 30: case 31: case 32: { back = DK3_FILE_ENCODING_UNICODE_MSB_FIRST; } break; case 7: case 25: case 26: case 27: case 28: { back = DK3_FILE_ENCODING_UNICODE_LSB_FIRST; } break; default: { if(app) { /* ERROR: Unknown text encoding name! */ dk3app_log_i3(app, DK3_LL_ERROR, 129, 130, en); } } break; } } #line 2011 "dk3enc.ctr" return back; } int dk3enc_get_encoding(dk3_app_t *app) { int back = 0; #if DK3_CHAR_SIZE == 1 char *ptr; #endif if(app) { back = dk3app_get_encoding(app); } else { #if DK3_CHAR_SIZE > 1 #if DK3_CHAR_SIZE > 2 back = DK3_ENCODING_UNICODE; #else back = DK3_ENCODING_UTF16; #endif #else back = DK3_ENCODING_PLAIN; ptr = getenv("LANG"); if(ptr) { ptr = dk3str_c8_chr(ptr, '.'); if(ptr) { ptr++; switch(dk3str_c8_array_index(dk3enc_utf8_names, ptr, 0)) { case 0: case 1: { back = DK3_ENCODING_UTF8; } break; } } } #endif } return back; } /* vim: set ai sw=2 : */