/*
	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-2013, 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 358 "dk3enc.ctr"

#include "dk3all.h"





#line 363 "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"),
NULL
};



/**	Encoding names for UTF-8 encoding.
*/
static char const * const	dk3enc_utf8_names[] = {
/* 0 */
"utf-8",

/* 1 */
"utf8",

NULL


#line 408 "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 537 "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 636 "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 665 "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 801 "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;
  back = dk3enc_uc2utf8_rfc2279(c, u8p, u8l);
  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;
  if(c <= (dk3_c32_t)0x0010FFUL) {
    back = dk3enc_uc2utf8_rfc2279(c, u8p, u8l);
  }
  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;
  

#line 995 "dk3enc.ctr"
  if((str) && (ul)) {
    if(dk3str_string_to_c8_simple_app(bu, sizeof(bu), str, app)) { 

#line 997 "dk3enc.ctr"
      back = dk3enc_c8_ipaddr_to_ul_app(bu, ul, app);
    } else {
      /* ERROR: Conversion failed! */
    }
  } 

#line 1002 "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 1018 "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 1096 "dk3enc.ctr"
  return back;
}



size_t
dk3enc_size_bin_to_a85(size_t s)
{
  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 1110 "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 1124 "dk3enc.ctr"
  return back;
}



/**	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 1145 "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 1186 "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 1198 "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 1212 "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 1225 "dk3enc.ctr"
  ul1 = (unsigned long)s;
  ul2 = ul1 % 5UL;
  ul3 = ul1 / 5UL;
  ul1 = 4UL * ul3 + ul2;
  back = (size_t)ul1;
  

#line 1231 "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 1277 "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 1308 "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 1321 "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 1334 "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 1346 "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 1371 "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 1407 "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 1419 "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 1433 "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 1461 "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 1528 "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 1541 "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 1554 "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 1564 "dk3enc.ctr"
  if(sp) {
    back = dk3enc_a85_to_bin_app(dp, ds, sp, dk3str_c8_len(sp), app);
  } 

#line 1567 "dk3enc.ctr"
  return back;
}



size_t
dk3enc_size_bin_to_hex(size_t s)
{
  size_t back = 0;
  int ec = 0;			/* Error code. */
  unsigned long ul1 = 0UL;	/* Temporary value for calculation. */
  

#line 1579 "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 1586 "dk3enc.ctr"
  return back;
}



size_t
dk3enc_size_hex_to_bin(size_t s)
{
  size_t back;
  

#line 1596 "dk3enc.ctr"
  back = s / 2;
  back++; 

#line 1598 "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 1648 "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 1654 "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 1666 "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 1679 "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 1704 "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 1800 "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 1813 "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 1826 "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 1838 "dk3enc.ctr"
  if(sp) {
    back = dk3enc_hex_to_bin_app(dp, ds, sp, dk3str_c8_len(sp), app);
  } 

#line 1841 "dk3enc.ctr"
  return back;
}



size_t
dk3enc_size_hexstring_to_bin(char const *s)
{
  size_t back = 0;
  

#line 1851 "dk3enc.ctr"
  if(s) {
    back = dk3str_c8_len(s);
    back = dk3enc_size_hex_to_bin(back);
  } 

#line 1855 "dk3enc.ctr"
  return back;
}



size_t
dk3enc_size_a85string_to_bin(char const *s)
{
  size_t back = 0;
  

#line 1865 "dk3enc.ctr"
  if(s) {
    back = dk3str_c8_len(s);
    back = dk3enc_size_a85_to_bin(back);
  } 

#line 1869 "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 1920 "dk3enc.ctr"
  if(app) { back = dk3app_get_output_encoding(app); }
  if(en) {
    i = dk3str_array_index(dk3enc_text_encoding_names, en, 0); 

#line 1923 "dk3enc.ctr"
    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;
    }
  } 

#line 1964 "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 : */

