/*
Copyright (c) 2000-2010, Dirk Krause
All rights reserved.

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 Dirk Krause 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 dkenc.h
	Encoding changes module.
	This module contains functions to change encodings.

	The dkenc_ntohl() function group is intended as replacement
	for ntohl() and friends. On Windows systems these functions
	are in winsock2.dll which is an optional DLL typically not
	installed on standalone systems.
	To change byte order for data read from file we need replacement
	functions.
*/

#ifndef DK_ENC_INCLUDED

/** Make sure to include the file only once. */
#define DK_ENC_INCLUDED 1

#if defined(EXTERN)
#undef EXTERN
#endif
#ifndef DK_ENC_C
#if !DK_HAVE_PROTOTYPES
#define EXTERN extern
#else
#define EXTERN /* nix */
#endif
#else
#define EXTERN /* nix */
#endif

#if defined(__cplusplus)
extern "C" {
#endif

/**	Convert long (32 bit integer) from network byte order to host byte
	order.
	@param	l	Long unsigned in network byte order.
	@return	The long unsigned in host byte order.
*/
EXTERN unsigned long  dkenc_ntohl DK_PR((unsigned long l));

/**	Convert long (32 bit integer) from host byte order to
	network byte order.
	@param	l	The long unsigned in host byte order.
	@return	The long unsigned in network byte order.
*/
EXTERN unsigned long  dkenc_htonl DK_PR((unsigned long l));

/**	Convert short (16 bit integer) from network byte order to
	host byte order.
	@param	s	The unsigned short number in network byte order.
	@return	The unsigned short number in host byte order.
*/
EXTERN unsigned short  dkenc_ntohs DK_PR((unsigned short s));

/**	Convert short (16 bit integer) from host byte order to network
	byte order.
	@param	s	The unsigned short in host byte order.
	@return	The unsigned short in network byte order.
*/
EXTERN unsigned short  dkenc_htons DK_PR((unsigned short s));

/**	Convert an UTF-8 encoded character into the appropriate 32 bit
	character.
	@param ucp	Pointer to a variable for conversion result.
	@param u8p	Pointer to buffer containing UTF-8 encoded data.
	@param u8l	Number of bytes available in \a u8p.
	@param u8u	Pointer to variable to store the number of bytes
			used from \a u8p.
	@return		Flag to indicate success (non-zero value) or
			error (0).
*/
EXTERN
int
dkenc_utf82uc DK_PR((dk_udword *ucp, dk_ubyte *u8p, size_t u8l, size_t *u8u));

/**	Convert 32-bit character to UTF-8.
	@param	c	The character to convert.
	@param	u8p	Buffer to receive the UTF-8 encoded result.
	@param	u8l	Length of \a u8p.
	@return	The number of bytes stored into \a u8p (0 on error).
*/
EXTERN size_t  dkenc_uc2utf8 DK_PR((dk_udword c, dk_ubyte *u8p, size_t u8l));

/**	Convert text IP address to unsigned long in host representation.
	@param	s	String containing the IP address in dotted decimal
			notation.
	@param	u	Pointer to unsigned long variable to receive the
			conversion result.
	@return	Flag to indicate success (non-zero value) or error (0).
*/
EXTERN int  dkenc_ipaddr_to_ul DK_PR((char *s, unsigned long *u));

/**	Convert UTF-8 encoded string to 8-bit LATIN-1 encoded string.
	The function returns a pointer to a new string in dynamically
	allocated memory. You must release the string after usage,
	call dk_delete().
	@param	s	UTF-8 encoded string.
	@param	p	Pointer to a variable to receive the error code
			(if any).
	@return	Pointer (dynamic) on success, NULL on error.
	On error the error code variable is set to
	- DK_ERR_MATH_OOR
	  if the decoding result character is out of range.
	- DK_ERR_INVALID_ARGS
	  if \a s is NULL or a decoding error occured.
	- DK_ERR_MEMORY
	  if there is not enough memory.
*/
EXTERN char * dkenc_str_utf82bits8 DK_PR((char *s, int *p));

/**	Convert 8-bit LATIN-1 encoded string to UTF-8 encoded string.
	The function returns a pointer to a new string in dynamically
	allocated memory. You must release the string after usage,
	call dk_delete().
	@param	s	The LATIN-1 encoded string.
	@return	Pointer (dynamic) on success, NULL on error (not enough
	memory).
*/
EXTERN char * dkenc_str_bits82utf8 DK_PR((char *s));

/**	Convert binary data to reverse ASCII-85 encoded string.
	@param	dp	Pointer to destination buffer.
	@param	ds	Destination buffer size in bytes.
	@param	sp	Pointer to source buffer.
	@param	ss	Source buffer size in bytes.
	@return	1 on success, 0 on error.
*/
EXTERN int
dkenc_bin_to_ra85 DK_PR((char *dp, size_t ds, char *sp, size_t ss));

/**	Convert reverse ASCII-85 encoded data to binary data.
	@param	dp	Pointer to destination buffer.
	@param	ds	Destination buffer size in bytes.
	@param	sp	Pointer to source buffer.
	@param	ss	Source buffer size in bytes.
	@return	The number of bytes written to the destination buffer.
*/
EXTERN size_t
dkenc_ra85_to_bin DK_PR((char *dp, size_t ds, char *sp, size_t ss));

/**	Convert reverse ASCII-85 encoded string to binary data.
	@param	dp	Pointer to destination buffer.
	@param	ds	Destination buffer size in bytes.
	@param	sp	Pointer to source string.
*/
EXTERN size_t
dkenc_ra85string_to_bin DK_PR((char *dp, size_t ds, char *sp));

/**	Convert binary data to ASCII-85 encoded string.
	@param	dp	Pointer to destination buffer.
	@param	ds	Destination buffer size in bytes.
	@param	sp	Pointer to source buffer.
	@param	ss	Source buffer size in bytes.
	@return	1 on success, 0 on error.
*/
EXTERN int
dkenc_bin_to_a85 DK_PR((char *dp, size_t ds, char *sp, size_t ss));

/**	Convert ASCII-85 encoded data to binary data.
	@param	dp	Pointer to destination buffer.
	@param	ds	Destination buffer size in bytes.
	@param	sp	Pointer to source buffer.
	@param	ss	Source buffer size in bytes.
	@return	The number of bytes written to the destination buffer.
*/
EXTERN size_t
dkenc_a85_to_bin DK_PR((char *dp, size_t ds, char *sp, size_t ss));

/**	Convert ASCII-85 encoded string to binary data.
	@param	dp	Pointer to destination buffer.
	@param	ds	Destination buffer size in bytes.
	@param	sp	Pointer to source string.
	@return	The number of bytes written to the destination buffer.
*/
EXTERN size_t
dkenc_a85string_to_bin DK_PR((char *dp, size_t ds, char *sp));

/**	Convert binary data to hex encoded string.
	Uppercase characters are used for 'A', 'B', 'C', D', 'E' and 'F'.
	@param	dp	Pointer to destination buffer.
	@param	ds	Destination buffer size in bytes.
	@param	sp	Pointer to source buffer.
	@param	ss	Source buffer size in bytes.
	@return	1 on success, 0 on error.
*/
EXTERN int
dkenc_bin_to_hex DK_PR((char *dp, size_t ds, char *sp, size_t ss));

/**	Convert hex encoded data to binary data.
	Both upper- and lowercase characters can be used for
	'a', 'b', 'c', 'd', 'e' and 'f'.
	@param	dp	Pointer to destination buffer.
	@param	ds	Destination buffer size in bytes.
	@param	sp	Pointer to source buffer.
	@param	ss	Source buffer size in bytes.
	@return	The number of bytes written to the destination buffer.
*/
EXTERN size_t
dkenc_hex_to_bin DK_PR((char *dp, size_t ds, char *sp, size_t ss));

/**	Convert hex encoded string to binary data.
	@param	dp	Pointer to destination buffer.
	@param	ds	Destination buffer size in bytes.
	@param	sp	Pointer to source string.
	@return	The number of bytes written to the destination buffer.
*/
EXTERN size_t
dkenc_hexstring_to_bin DK_PR((char *dp, size_t ds, char *sp));

/**	Calculate buffer size needed to convert binary
	data to ASCII85 or reverse ASCII85 string.
	@param	s	Source data size.
	@return	Needed destination buffer size.
*/
EXTERN size_t
dkenc_size_bin_to_a85 DK_PR((size_t s));

/**	Calculate buffer size needed to convert ASCII85
	or reverse-ASCII85 encoded data to binary.
	@param	sz	Source data size.
	@return	Needed destination buffer size.
*/
EXTERN size_t
dkenc_size_a85_to_bin DK_PR((size_t sz));

/**	Calculate bufer size needed to convert an ASCII85
	or reverse-ASCII85 encoded string to binary.
	@param	s	The encoded string.
	@return	Needed destination buffer size.
*/
EXTERN size_t
dkenc_size_a85string_to_bin DK_PR((char *s));

/**	Calculate buffer size needed to convert binary
	data to hexadecimal string.
	@param	s	Source data size.
	@return	Needed destination buffer size.
*/
EXTERN size_t
dkenc_size_bin_to_hex DK_PR((size_t s));

/**	Calculate bufer size needed to convert a hex
	encoded string to binary.
	@param	sz	Source data size.
	@return	Needed destination buffer size.
*/
EXTERN size_t
dkenc_size_hex_to_bin DK_PR((size_t sz));

/**	Calculate bufer size needed to convert a hex
	encoded string to binary.
	@param	s	The encoded string.
	@return	Needed destination buffer size.
*/
EXTERN size_t
dkenc_size_hexstring_to_bin DK_PR((char *s));

#if defined(__cplusplus)
}
#endif

#endif
/* DK_ENC_INCLUDED */



