/* WARNING: This file was generated by dkct. 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 */ /* Copyright (C) 2011-2017, Dirk Krause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file dk3enc.c The dk3enc module. */ #line 312 "dk3enc.ctr" #include "dk3all.h" #line 317 "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 385 "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; } /** 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 514 "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 613 "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 642 "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 778 "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 795 "dk3enc.ctr" back = dk3enc_uc2utf8_rfc2279(c, u8p, u8l); #line 797 "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 822 "dk3enc.ctr" if(c <= (dk3_c32_t)0x0010FFFFUL) { back = dk3enc_uc2utf8_rfc2279(c, u8p, u8l); } #line 825 "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 > c) || (0x0000DFFF < 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 981 "dk3enc.ctr" if((str) && (ul)) { if(dk3str_string_to_c8_simple_app(bu, sizeof(bu), str, app)) { #line 983 "dk3enc.ctr" back = dk3enc_c8_ipaddr_to_ul_app(bu, ul, app); } else { /* ERROR: Conversion failed! */ } } #line 988 "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 1004 "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 1082 "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 1097 "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 1111 "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 1118 "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 1126 "dk3enc.ctr" return back; #endif } /** Convert binary data to ASCII-85 encoded string. @param dp Destination pointer. @param ds Destination size. @param sp Source pointer. @param ss Source size. */ static void dk3enc_do_bin_to_ra85(char *dp, size_t ds, 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 1148 "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 1189 "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 1201 "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, ds, sp, ss); back = 1; } else { if(app) { /* Destination buffer too small! */ dk3app_log_i1(app, DK3_LL_ERROR, 38); } } } } #line 1215 "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 1228 "dk3enc.ctr" ul1 = (unsigned long)s; ul2 = ul1 % 5UL; ul3 = ul1 / 5UL; ul1 = 4UL * ul3 + ul2; back = (size_t)ul1; #line 1234 "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 ds Destination size. @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, size_t ds, 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 1280 "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 1311 "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 1324 "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, ds, sp, ss, app); } else { if(app) { /* Destination buffer too small! */ dk3app_log_i1(app, DK3_LL_ERROR, 38); } } } } #line 1337 "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 1349 "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 ds Destination size. @param sp Source pointer. @param ss Source size. */ static void dk3enc_do_bin_to_a85(char *dp, size_t ds, 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 1374 "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 1410 "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 1422 "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, ds, sp, ss); back = 1; } else { if(app) { /* Destination buffer too small! */ dk3app_log_i1(app, DK3_LL_ERROR, 38); } } } } #line 1436 "dk3enc.ctr" return back; } /** Convert ASCII-85 encoded data to binary data. @param dp Destination pointer. @param ds Destination size. @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, size_t ds, 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 1464 "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 1531 "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 1544 "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, ds, sp, ss, app); } else { if(app) { /* Destination buffer too small! */ dk3app_log_i1(app, DK3_LL_ERROR, 38); } } } } #line 1557 "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 1567 "dk3enc.ctr" if(sp) { back = dk3enc_a85_to_bin_app(dp, ds, sp, dk3str_c8_len(sp), app); } #line 1570 "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 1583 "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 1590 "dk3enc.ctr" return back; #else size_t back = 0; int ec = 0; /* Error code */ #line 1595 "dk3enc.ctr" back = dk3mem_add_size_t(1, dk3mem_mul_size_t(2, s, &ec), &ec); if (ec) { back = 0; } #line 1598 "dk3enc.ctr" return back; #endif } size_t dk3enc_size_hex_to_bin(size_t s) { size_t back; #line 1609 "dk3enc.ctr" back = s / 2; back++; #line 1611 "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 ds Destination size. @param sp Source pointer. @param ss Source size. @param app Application structure for diagnostics, may be NULL. */ static void dk3enc_do_bin_to_hex(char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app) { register char *mydp = NULL; /* Destination pointer. */ register char const *mysp = NULL; /* Source pointer. */ register size_t i = 0; /* Current source byte index. */ #line 1661 "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 1667 "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 1679 "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, ds, sp, ss, app); back = 1; } else { if(app) { /* Destination buffer too small1 */ dk3app_log_i1(app, DK3_LL_ERROR, 38); } } } } #line 1692 "dk3enc.ctr" return back; } /** Convert hexadecimal data to binary data. @param dp Destination pointer. @param ds Destination size. @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, size_t ds, 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 1717 "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 1813 "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 1826 "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, ds, sp, ss, app); } else { if(app) { /* Destination buffer too small! */ dk3app_log_i1(app, DK3_LL_ERROR, 38); } } } } #line 1839 "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 1851 "dk3enc.ctr" if(sp) { back = dk3enc_hex_to_bin_app(dp, ds, sp, dk3str_c8_len(sp), app); } #line 1854 "dk3enc.ctr" return back; } size_t dk3enc_size_hexstring_to_bin(char const *s) { size_t back = 0; #line 1864 "dk3enc.ctr" if(s) { back = dk3str_c8_len(s); back = dk3enc_size_hex_to_bin(back); } #line 1868 "dk3enc.ctr" return back; } size_t dk3enc_size_a85string_to_bin(char const *s) { size_t back = 0; #line 1878 "dk3enc.ctr" if(s) { back = dk3str_c8_len(s); back = dk3enc_size_a85_to_bin(back); } #line 1882 "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 1933 "dk3enc.ctr" if(app) { back = dk3app_get_output_encoding(app); } if(en) { i = dk3str_array_index(dk3enc_text_encoding_names, en, 0); #line 1936 "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 1977 "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 : */