%% options copyright owner = Dirk Krause copyright year = 2011-2014 license = bsd %% header #include "dk3conf.h" #include "dk3types.h" #ifdef __cplusplus extern "C" { #endif /** Convert long number from net to host representation. @param x Number to convert. @return Conversion result. */ unsigned long dk3enc_ntohl(unsigned long x); /** Convert long number from host to net representation. @param x Number to convert. @return Conversion result. */ unsigned long dk3enc_htonl(unsigned long x); /** Convert short number from net to host representation. @param x Number to convert. @return Conversion result. */ unsigned short dk3enc_ntohs(unsigned short x); /** Convert short number from host to net representation. @param x Number to convert. @return Conversion result. */ unsigned short dk3enc_htons(unsigned short x); /** Convert 32-bit character to UTF-8. @param c 32-bit character to convert. @param u8p Pointer to result buffer. @param u8l Size of result buffer, should be 8 at least. @return Number of bytes used in result buffer. */ size_t dk3enc_uc2utf8(dk3_c32_t c, unsigned char *u8p, size_t u8l); /** Convert UTF-8 encoded text to 32-bit character. @param ucp Pointer to variable for result. @param u8p Buffer containing UTF-8 encoded text. @param u8l Number of bytes in buffer. @param u8u Pointer to variable to receive number of bytes used. @return 1 on success, 0 on error. */ int dk3enc_utf82uc(dk3_c32_t *ucp, unsigned char const *u8p,size_t u8l,size_t *u8u); /** Convert IP address from 8-bit text string to long number in host representation. @param str Text string containing the IP address. @param ul Pointer to result variable. @param app Application structure for diagnostics, may be NULL. @return 1 on success, 0 on error. */ int dk3enc_c8_ipaddr_to_ul_app(char const *str, unsigned long *ul, dk3_app_t *app); /** Convert IP address from string to long number in host representation. @param str Text string containing the IP address. @param ul Pointer to result variable. @param app Application structure for diagnostics, may be NULL. @return 1 on success, 0 on error. */ int dk3enc_ipaddr_to_ul_app(dkChar const *str, unsigned long *ul, dk3_app_t *app); /** Find size for result buffer needed to convert binary data to text using ASCII-85 encoding. @param s Size of binary data. @return The required buffer length (includeing finalizing 0x00 byte). */ size_t dk3enc_size_bin_to_a85(size_t s); /** Convert binary data to text using reverse ASCII-85 encoding. @param dp Destination buffer pointer. @param ds Size of \a dp. @param sp Binary (source) data. @param ss Number of bytes in \a sp. @param app Application structure, for diagnostics, may be NULL. */ int dk3enc_bin_to_ra85_app( char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app ); /** Find size for result buffer needed to convert ASCII-85 encoded data back to binary data. @param s Number of ASCII-85 text characters. @return Length of resulting binary data. */ size_t dk3enc_size_a85_to_bin(size_t s); /** Convert reverse ASCII-85 encoded data back to binary. @param dp Destination buffer pointer. @param ds Destination buffer size in bytes. @param sp Source buffer pointer. @param ss Source buffer length. @param app Application structure for diagnostics, may be NULL. @return Number of binary bytes decoded. */ size_t dk3enc_ra85_to_bin_app( char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app ); #if 0 /** Convert reverse ASCII-85 encoded data back to binary. @param dp Destination buffer pointer. @param ds Destination buffer size in bytes. @param sp Source buffer pointer. @param ss Source buffer length. @return Number of binary bytes decoded. */ size_t dk3enc_ra85_to_bin(char *dp, size_t ds, char const *sp, size_t ss); #endif /** Convert reverse ASCII-85 encoded data string back to binary. @param dp Destination buffer pointer. @param ds Destination buffer size in bytes. @param sp Source buffer pointer. @param app Application structure for diagnostics, may be NULL. @return Number of binary bytes decoded. */ size_t dk3enc_ra85string_to_bin_app( char *dp, size_t ds, char const *sp, dk3_app_t *app ); /** Apply ASCII-85 encoding to binary data. @param dp Destination buffer pointer. @param ds Destination buffer size. @param sp Source buffer pointer. @param ss Source buffer size. @param app Application structure for diagnostics, may be NULL. */ int dk3enc_bin_to_a85_app( char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app ); /** Decode ASCII-85 encoded data back to binary. @param dp Destination buffer pointer. @param ds Destination buffer size. @param sp Source buffer pointer. @param ss Source buffer size. @param app Application structure for diagnostics, may be NULL. */ size_t dk3enc_a85_to_bin_app( char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app ); /** Decode ASCII-85 encoded data string back to binary. @param dp Destination buffer pointer. @param ds Destination buffer size. @param sp Source buffer pointer. @param app Application structure for diagnostics, may be NULL. */ size_t dk3enc_a85string_to_bin_app(char *dp, size_t ds, char const *sp, dk3_app_t *app); /** Calculate size for binary to hexadecimal conversion. @param s Size of binary data. @return Size of hexadecimal encoding. */ size_t dk3enc_size_bin_to_hex(size_t s); /** Calculate size for hexadecimal to binary conversion. @param s Size of hexadecimal data. @return Size of binary data. */ size_t dk3enc_size_hex_to_bin(size_t s); /** Apply hexadecimal encoding to binary data. @param dp Destination buffer pointer. @param ds Destination buffer size. @param sp Source buffer pointer. @param ss Source buffer size. @param app Application structure for diagnostics, may be NULL. */ int dk3enc_bin_to_hex_app( char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app ); /** Convert hexadecimal encoded data back to binary. @param dp Destination buffer pointer. @param ds Destination buffer size. @param sp Source buffer pointer. @param ss Source buffer size. @param app Application structure for diagnostics, may be NULL. */ size_t dk3enc_hex_to_bin_app( char *dp, size_t ds, char const *sp, size_t ss, dk3_app_t *app ); /** Convert hexadecimal encoded data string back to binary. @param dp Destination buffer pointer. @param ds Destination buffer size. @param sp Source buffer pointer. @param app Application structure for diagnostics, may be NULL. */ size_t dk3enc_hexstring_to_bin_app( char *dp, size_t ds, char const *sp, dk3_app_t *app ); /** Calculate size for hex decoding to binary. @param s String containing hexadecimal data. @return Size of binary data. */ size_t dk3enc_size_hexstring_to_bin(char const *s); /** Find size for conversion from ASCII-85 encoded data to binary. * @param s ASCII-85 encoded string. * @return Size of binary data. */ size_t dk3enc_size_a85string_to_bin(char const *s); /** Convert 32-bit character to UTF-16. If the value is 0xFFFF and below, the 16 bits are used ``as is''. For values \a c > 0xFFFF we have to build a surrogate pair. We substract 0x00010000, the result is a new character with 20 significant bits. These 20 bits are splitted into two blocks of 10 bits each. The high surrogate is built using the prefix bits 110110 and the higher 10-bits block. The low surrogate is built using the prefix bits 110111 and the lower 10-bits block. Order of surrogates in a surrogate pair is flexible, this function writes the high surrogate first. @param c The 32-bit character. @param u16p Buffer to receive UTF-16 encoded result. @param u16l Length of \a u16l in elements. @return The number of dk3_c16_t characters produced. */ size_t dk3enc_uc2utf16(dk3_c32_t c, dk3_c16_t *u16p, size_t u16l); /** Convert UTF-16 encoded characters to 32-bit character @param ucp Pointer to result variable. @param u16p Buffer containing UTF-16 encoded text. @param u16l Number of elements available in \a u16p. @param u16u Pointer to variable to receive number of dk3_c16_t used. @return 1 on success, 0 on error. */ int dk3enc_utf162uc(dk3_c32_t *ucp, dk3_c16_t const *u16p, size_t u16l, size_t *u16u); /** Get data encoding type for name. @param n Data encoding name. @param app Application structure for diagnostics, may be NULL. @return Integer representation of data encoding on success, -1 on error. */ int dk3enc_get_type_app(dkChar const *n, dk3_app_t *app); /** Get name for data encoding type. @param t Numeric type. @return Name for type on success, NULL on error. */ dkChar const * dk3enc_get_data_encoding_name(int t); /** Get numeric value for text encoding. @param en Encoding name. @param app Application structure, may be NULL. @return Numeric representation of text encoding on success, -1 on error. */ int dk3enc_get_text_encoding_app(dkChar const *en, dk3_app_t *app); /** Get the used encoding. @param app Application structure, may be NULL. @return The encoding used for characters in memory. */ int dk3enc_get_encoding(dk3_app_t *app); #ifdef __cplusplus } #endif %% module #include "dk3all.h" $(trace-include) /** 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"), NULL }; /** Encoding names for UTF-8 encoding. */ static char const * const dk3enc_utf8_names[] = { $!string-table utf-8 utf8 $!end }; /** 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. */ $? "+ dk3enc_uc2utf8_rfc2279 0x%lx=%lu %lu", (unsigned long)c, (unsigned long)c, (unsigned long)u8l 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); } } } } $? "- dk3enc_uc2utf8_rfc2279 %lu", (unsigned long)back 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. */ $? "+ dk3enc_utf82uc" 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; } $? "- dk3enc_utf82uc %d", back 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; $? "+ dk3enc_uc2utf8 (RFC 2279) 0x%lx=%lu", c, c back = dk3enc_uc2utf8_rfc2279(c, u8p, u8l); $? "- dk3enc_uc2utf8 (RFC 2279) %u", (unsigned)back 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; $? "+ dk3enc_uc2utf8 (RFC 3629) %lu=0x%lx", c, c if(c <= (dk3_c32_t)0x0010FFFFUL) { back = dk3enc_uc2utf8_rfc2279(c, u8p, u8l); } $? "- dk3enc_uc2utf8 (RFC 3629) %u", (unsigned)back 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((c & 0x0000DC00UL) != 0x0000DC00UL) { if((c & 0x0000DC00UL) != 0x0000D800UL) { *u16p = (dk3_c16_t)c; back = 1; } } } } 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; $? "+ dk3enc_ipaddr_to_ul_app \"%s\"", TR_STR(str) if((str) && (ul)) { if(dk3str_string_to_c8_simple_app(bu, sizeof(bu), str, app)) { $? ". bu=\"%s\"", bu back = dk3enc_c8_ipaddr_to_ul_app(bu, ul, app); } else { /* ERROR: Conversion failed! */ } } $? "- dk3enc_ipaddr_to_ul_app %d %lx", back, ((ul) ? (*ul) : 0UL) 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. */ $? "+ dk3enc_c8_ipaddr_to_ul %s", TR_STR(str) 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! */ } } } $? "- dk3enc_c8_ipaddr_to_ul %d %lx", back , ((ul) ? (*ul) : 0UL) 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. */ $? "+ dk3enc_size_bin_to_a85 %lu", (unsigned long)s 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; $? "- dk3enc_size_bin_to_a85 %lu", (unsigned long)back return back; #else size_t back = 0; size_t rem = 0; /* Division remainder */ size_t res = 0; /* Division result */ int ec = 0; /* Error code */ $? "+ dk3enc_size_bin_to_a85 %lu", (unsigned long)s 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; } $? "- dk3enc_size_bin_to_a85 %lu", (unsigned long)back 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. */ $? "+ dk3enc_do_bin_to_ra85" 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'; $? "- dk3enc_do_bin_to_ra85" } 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. */ $? "+ dk3enc_bin_to_ra85 %lu %lu", (unsigned long)ds, (unsigned long)ss 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); } } } } $? "- dk3enc_bin_to_ra85 %d", back 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. */ $? "+ dk3enc_size_a85_to_bin %lu", (unsigned long)s ul1 = (unsigned long)s; ul2 = ul1 % 5UL; ul3 = ul1 / 5UL; ul1 = 4UL * ul3 + ul2; back = (size_t)ul1; $? "- dk3enc_size_a85_to_bin %lu", (unsigned long)back 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. */ $? "+ dk3enc_do_ra85_to_bin %lu %lu", (unsigned long)ds, (unsigned long)ss 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; } } $? "- dk3enc_do_ra85_to_bin %lu", (unsigned long)back 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. */ $? "+ dk3enc_ra85_to_bin %lu %lu", (unsigned long)ds, (unsigned long)ss 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); } } } } $? "- dk3enc_ra85_to_bin %lu", (unsigned long)back 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; $? "+ dk3enc_ra85string_to_bin %lu %s", (unsigned long)ds, TR_STR(sp) 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. */ $? "+ dk3enc_do_bin_to_a85 %lu %lu", (unsigned long)ds, (unsigned long)ss 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'; $? "- dk3enc_do_bin_to_a85" } 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. */ $? "+ dk3enc_bin_to_a85 %lu %lu", (unsigned long)ds, (unsigned long)ss 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); } } } } $? "- dk3enc_bin_to_a85 %d", back 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; $? "+ dk3enc_do_a85_to_bin %lu %lu", (unsigned long)ds, (unsigned long)ss 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; } } $? "- dk3enc_do_a85_to_bin %lu", (unsigned long)back 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. */ $? "+ dk3enc_a85_to_bin %lu %lu", (unsigned long)ds, (unsigned long)ss 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); } } } } $? "- dk3enc_a85_to_bin %lu", (unsigned long)back 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; $? "+ dk3enc_a85string_to_bin %lu %s", (unsigned long)ds, TR_STR(sp) if(sp) { back = dk3enc_a85_to_bin_app(dp, ds, sp, dk3str_c8_len(sp), app); } $? "- dk3enc_a85string_to_bin %lu", (unsigned long)back 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. */ $? "+ dk3enc_size_bin_to_hex %lu", (unsigned long)s 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; $? "- dk3enc_size_bin_to_hex %lu", (unsigned long)back return back; #else size_t back = 0; int ec = 0; /* Error code */ $? "+ dk3enc_size_bin_to_hex %lu", (unsigned long)s back = dk3mem_add_size_t(1, dk3mem_mul_size_t(2, s, &ec), &ec); if (ec) { back = 0; } $? "- dk3enc_size_bin_to_hex %lu", (unsigned long)back return back; #endif } size_t dk3enc_size_hex_to_bin(size_t s) { size_t back; $? "+ dk3enc_size_hex_to_bin %lu", (unsigned long)s back = s / 2; back++; $? "- dk3enc_size_hex_to_bin %lu", (unsigned long)back 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. */ $? "+ dk3enc_do_bin_to_hex %lu %lu", (unsigned long)ds, (unsigned long)ss 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'; $? "- dk3enc_do_bin_to_hex" } 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. */ $? "+ dk3enc_bin_to_hex %lu %lu", (unsigned long)ds, (unsigned long)ss 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); } } } } $? "- dk3enc_bin_to_hex %d", back 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. */ $? "+ dk3enc_do_hex_to_bin %lu %lu", (unsigned long)ds, (unsigned long)ss 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++; } $? "- dk3enc_do_hex_to_bin %lu", (unsigned long)back 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. */ $? "+ dk3enc_hex_to_bin %lu %lu", (unsigned long)ds, (unsigned long)ss 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); } } } } $? "- dk3enc_hex_to_bin %lu", (unsigned long)back 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; $? "+ dk3enc_hexstring_to_bin %lu %s", (unsigned long)ds, TR_STR(sp) if(sp) { back = dk3enc_hex_to_bin_app(dp, ds, sp, dk3str_c8_len(sp), app); } $? "- dk3enc_hexstring_to_bin %lu", (unsigned long)back return back; } size_t dk3enc_size_hexstring_to_bin(char const *s) { size_t back = 0; $? "+ dk3enc_size_hexstring_to_bin %s", TR_STR(s) if(s) { back = dk3str_c8_len(s); back = dk3enc_size_hex_to_bin(back); } $? "- dk3enc_size_hexstring_to_bin %lu", (unsigned long)back return back; } size_t dk3enc_size_a85string_to_bin(char const *s) { size_t back = 0; $? "+ dk3enc_size_a85string_to_bin %s", TR_STR(s) if(s) { back = dk3str_c8_len(s); back = dk3enc_size_a85_to_bin(back); } $? "- dk3enc_size_a85string_to_bin %lu", (unsigned long)back 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; $? "+ dk3enc_get_text_encoding_app \"%s\"", TR_STR(en) if(app) { back = dk3app_get_output_encoding(app); } if(en) { i = dk3str_array_index(dk3enc_text_encoding_names, en, 0); $? ". i=%d", i switch(i) { case 0: case 8: case 9: { back = DK3_FILE_ENCODING_ASCII; } break; case 1: { back = DK3_FILE_ENCODING_UTF8; } break; case 2: { #if DK3_HAVE_BIGENDIAN back = DK3_FILE_ENCODING_UTF16_MSB_FIRST; #else back = DK3_FILE_ENCODING_UTF16_LSB_FIRST; #endif } break; case 3: { back = DK3_FILE_ENCODING_UTF16_MSB_FIRST; } break; case 4: { back = DK3_FILE_ENCODING_UTF16_LSB_FIRST; } break; case 5: { #if DK3_HAVE_BIGENDIAN back = DK3_FILE_ENCODING_UNICODE_MSB_FIRST; #else back = DK3_FILE_ENCODING_UNICODE_LSB_FIRST; #endif } break; case 6: { back = DK3_FILE_ENCODING_UNICODE_MSB_FIRST; } break; case 7: { 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; } } $? "- dk3enc_get_text_encoding_app %d", back 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 : */