/*
 * Copyright (C) 2010 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
FILE_SECBOOT ( PERMITTED );

#include <stdint.h>
#include <stdio.h>
#include <errno.h>
#include <assert.h>
#include <ipxe/string.h>
#include <ipxe/vsprintf.h>
#include <ipxe/base16.h>

/** @file
 *
 * Base16 encoding
 *
 */

/**
 * Encode hexadecimal string (with optional byte separator character)
 *
 * @v separator		Byte separator character, or 0 for no separator
 * @v raw		Raw data
 * @v raw_len		Length of raw data
 * @v data		Buffer
 * @v len		Length of buffer
 * @ret len		Encoded length
 */
size_t hex_encode ( char separator, const void *raw, size_t raw_len,
		    char *data, size_t len ) {
	const uint8_t *bytes = raw;
	const char delimiter[2] = { separator, '\0' };
	size_t used = 0;
	unsigned int i;

	if ( len )
		data[0] = 0; /* Ensure that a terminating NUL exists */
	for ( i = 0 ; i < raw_len ; i++ ) {
		used += ssnprintf ( ( data + used ), ( len - used ),
				    "%s%02x", ( used ? delimiter : "" ),
				    bytes[i] );
	}
	return used;
}

/**
 * Decode hexadecimal string (with optional byte separator character)
 *
 * @v separator		Byte separator character, or 0 for no separator
 * @v encoded		Encoded string
 * @v data		Buffer
 * @v len		Length of buffer
 * @ret len		Length of data, or negative error
 */
int hex_decode ( char separator, const char *encoded, void *data, size_t len ) {
	uint8_t *out = data;
	unsigned int count = 0;
	unsigned int sixteens;
	unsigned int units;
	int optional;

	/* Strip out optionality flag from separator character */
	optional = ( separator & HEX_DECODE_OPTIONAL );
	separator &= ~HEX_DECODE_OPTIONAL;

	/* Decode string */
	while ( *encoded ) {

		/* Check separator, if applicable */
		if ( count && separator ) {
			if ( *encoded == separator ) {
				encoded++;
			} else if ( ! optional ) {
				return -EINVAL;
			}
		}

		/* Extract digits.  Note that either digit may be NUL,
		 * which would be interpreted as an invalid value by
		 * digit_value(); there is therefore no need for an
		 * explicit end-of-string check.
		 */
		sixteens = digit_value ( *(encoded++) );
		if ( sixteens >= 16 )
			return -EINVAL;
		units = digit_value ( *(encoded++) );
		if ( units >= 16 )
			return -EINVAL;

		/* Store result */
		if ( count < len )
			out[count] = ( ( sixteens << 4 ) | units );
		count++;

	}
	return count;
}
