/*
 * unicode.c
 *
 * PURPOSE
 *	Routines for converting between UTF-8 and OSTA Compressed Unicode.
 *      Also handles filename mangling
 *
 * DESCRIPTION
 *	OSTA Compressed Unicode is explained in the OSTA UDF specification.
 *		http://www.osta.org/
 *	UTF-8 is explained in the IETF RFC XXXX.
 *		ftp://ftp.internic.net/rfc/rfcxxxx.txt
 *
 * COPYRIGHT
 *	This file is distributed under the terms of the GNU General Public
 *	License (GPL). Copies of the GPL can be obtained from:
 *		ftp://prep.ai.mit.edu/pub/gnu/GPL
 *	Each contributing author retains all rights to their own work.
 */

#include "udfdecl.h"

#include <linux/kernel.h>
#include <linux/string.h>	/* for memset */
#include <linux/nls.h>
#include <linux/udf_fs.h>

#include "udf_sb.h"

static int udf_translate_to_linux(uint8_t *, uint8_t *, int, uint8_t *, int);

static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen)
{
	if ( (!dest) || (!src) || (!strlen) || (strlen > UDF_NAME_LEN-2) )
		return 0;
	memset(dest, 0, sizeof(struct ustr));
	memcpy(dest->u_name, src, strlen);
	dest->u_cmpID = 0x08;
	dest->u_len = strlen;
	return strlen;
}

/*
 * udf_build_ustr
 */
int udf_build_ustr(struct ustr *dest, dstring *ptr, int size)
{
	int usesize;

	if ( (!dest) || (!ptr) || (!size) )
		return -1;

	memset(dest, 0, sizeof(struct ustr));
	usesize= (size > UDF_NAME_LEN) ? UDF_NAME_LEN : size;
	dest->u_cmpID=ptr[0];
	dest->u_len=ptr[size-1];
	memcpy(dest->u_name, ptr+1, usesize-1);
	return 0;
}

/*
 * udf_build_ustr_exact
 */
static int udf_build_ustr_exact(struct ustr *dest, dstring *ptr, int exactsize)
{
	if ( (!dest) || (!ptr) || (!exactsize) )
		return -1;

	memset(dest, 0, sizeof(struct ustr));
	dest->u_cmpID=ptr[0];
	dest->u_len=exactsize-1;
	memcpy(dest->u_name, ptr+1, exactsize-1);
	return 0;
}

/*
 * udf_ocu_to_utf8
 *
 * PURPOSE
 *	Convert OSTA Compressed Unicode to the UTF-8 equivalent.
 *
 * DESCRIPTION
 *	This routine is only called by udf_filldir().
 *
 * PRE-CONDITIONS
 *	utf			Pointer to UTF-8 output buffer.
 *	ocu			Pointer to OSTA Compressed Unicode input buffer
 *				of size UDF_NAME_LEN bytes.
 * 				both of type "struct ustr *"
 *
 * POST-CONDITIONS
 *	<return>		Zero on success.
 *
 * HISTORY
 *	November 12, 1997 - Andrew E. Mileski
 *	Written, tested, and released.
 */
int udf_CS0toUTF8(struct ustr *utf_o, struct ustr *ocu_i)
{
	uint8_t *ocu;
	uint32_t c;
	uint8_t cmp_id, ocu_len;
	int i;

	ocu = ocu_i->u_name;

	ocu_len = ocu_i->u_len;
	cmp_id = ocu_i->u_cmpID;
	utf_o->u_len = 0;

	if (ocu_len == 0)
	{
		memset(utf_o, 0, sizeof(struct ustr));
		utf_o->u_cmpID = 0;
		utf_o->u_len = 0;
		return 0;
	}

	if ((cmp_id != 8) && (cmp_id != 16))
	{
		printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n", cmp_id, ocu_i->u_name);
		return 0;
	}

	for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN-3)) ;)
	{

		/* Expand OSTA compressed Unicode to Unicode */
		c = ocu[i++];
		if (cmp_id == 16)
			c = (c << 8) | ocu[i++];

		/* Compress Unicode to UTF-8 */
		if (c < 0x80U)
			utf_o->u_name[utf_o->u_len++] = (uint8_t)c;
		else if (c < 0x800U)
		{
			utf_o->u_name[utf_o->u_len++] = (uint8_t)(0xc0 | (c >> 6));
			utf_o->u_name[utf_o->u_len++] = (uint8_t)(0x80 | (c & 0x3f));
		}
		else
		{
			utf_o->u_name[utf_o->u_len++] = (uint8_t)(0xe0 | (c >> 12));
			utf_o->u_name[utf_o->u_len++] = (uint8_t)(0x80 | ((c >> 6) & 0x3f));
			utf_o->u_name[utf_o->u_len++] = (uint8_t)(0x80 | (c & 0x3f));
		}
	}
	utf_o->u_cmpID=8;

	return utf_o->u_len;
}

/*
 *
 * udf_utf8_to_ocu
 *
 * PURPOSE
 *	Convert UTF-8 to the OSTA Compressed Unicode equivalent.
 *
 * DESCRIPTION
 *	This routine is only called by udf_lookup().
 *
 * PRE-CONDITIONS
 *	ocu			Pointer to OSTA Compressed Unicode output
 *				buffer of size UDF_NAME_LEN bytes.
 *	utf			Pointer to UTF-8 input buffer.
 *	utf_len			Length of UTF-8 input buffer in bytes.
 *
 * POST-CONDITIONS
 *	<return>		Zero on success.
 *
 * HISTORY
 *	November 12, 1997 - Andrew E. Mileski
 *	Written, tested, and released.
 */
static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length)
{
	unsigned c, i, max_val, utf_char;
	int utf_cnt, u_len;

	memset(ocu, 0, sizeof(dstring) * length);
	ocu[0] = 8;
	max_val = 0xffU;

try_again:
	u_len = 0U;
	utf_char = 0U;
	utf_cnt = 0U;
	for (i = 0U; i < utf->u_len; i++)
	{
		c = (uint8_t)utf->u_name[i];

		/* Complete a multi-byte UTF-8 character */
		if (utf_cnt)
		{
			utf_char = (utf_char << 6) | (c & 0x3fU);
			if (--utf_cnt)
				continue;
		}
		else
		{
			/* Check for a multi-byte UTF-8 character */
			if (c & 0x80U)
			{
				/* Start a multi-byte UTF-8 character */
				if ((c & 0xe0U) == 0xc0U)
				{
					utf_char = c & 0x1fU;
					utf_cnt = 1;
				}
				else if ((c & 0xf0U) == 0xe0U)
				{
					utf_char = c & 0x0fU;
					utf_cnt = 2;
				}
				else if ((c & 0xf8U) == 0xf0U)
				{
					utf_char = c & 0x07U;
					utf_cnt = 3;
				}
				else if ((c & 0xfcU) == 0xf8U)
				{
					utf_char = c & 0x03U;
					utf_cnt = 4;
				}
				else if ((c & 0xfeU) == 0xfcU)
				{
					utf_char = c & 0x01U;
					utf_cnt = 5;
				}
				else
					goto error_out;
				continue;
			} else
				/* Single byte UTF-8 character (most common) */
				utf_char = c;
		}

		/* Choose no compression if necessary */
		if (utf_char > max_val)
		{
			if ( 0xffU == max_val )
			{
				max_val = 0xffffU;
				ocu[0] = (uint8_t)0x10U;
				goto try_again;
			}
			goto error_out;
		}

		if (max_val == 0xffffU)
		{
			ocu[++u_len] = (uint8_t)(utf_char >> 8);
		}
		ocu[++u_len] = (uint8_t)(utf_char & 0xffU);
	}


	if (utf_cnt)
	{
error_out:
		ocu[++u_len] = '?';
		printk(KERN_DEBUG "udf: bad UTF-8 character\n");
	}

	ocu[length - 1] = (uint8_t)u_len + 1;
	return u_len + 1;
}

static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o, struct ustr *ocu_i)
{
	uint8_t *ocu;
	uint32_t c;
	uint8_t cmp_id, ocu_len;
	int i;

	ocu = ocu_i->u_name;

	ocu_len = ocu_i->u_len;
	cmp_id = ocu_i->u_cmpID;
	utf_o->u_len = 0;

	if (ocu_len == 0)
	{
		memset(utf_o, 0, sizeof(struct ustr));
		utf_o->u_cmpID = 0;
		utf_o->u_len = 0;
		return 0;
	}

	if ((cmp_id != 8) && (cmp_id != 16))
	{
		printk(KERN_ERR "udf: unknown compression code (%d) stri=%s\n", cmp_id, ocu_i->u_name);
		return 0;
	}

	for (i = 0; (i < ocu_len) && (utf_o->u_len <= (UDF_NAME_LEN-3)) ;)
	{
		/* Expand OSTA compressed Unicode to Unicode */
		c = ocu[i++];
		if (cmp_id == 16)
			c = (c << 8) | ocu[i++];

		utf_o->u_len += nls->uni2char(c, &utf_o->u_name[utf_o->u_len], 
			UDF_NAME_LEN - utf_o->u_len);
	}
	utf_o->u_cmpID=8;

	return utf_o->u_len;
}

static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni, int length)
{
	unsigned len, i, max_val;
	uint16_t uni_char;
	int u_len;

	memset(ocu, 0, sizeof(dstring) * length);
	ocu[0] = 8;
	max_val = 0xffU;

try_again:
	u_len = 0U;
	for (i = 0U; i < uni->u_len; i++)
	{
		len = nls->char2uni(&uni->u_name[i], uni->u_len-i, &uni_char);
		if (len <= 0)
			continue;

		if (uni_char > max_val)
		{
			max_val = 0xffffU;
			ocu[0] = (uint8_t)0x10U;
			goto try_again;
		}
		
		if (max_val == 0xffffU)
			ocu[++u_len] = (uint8_t)(uni_char >> 8);
		ocu[++u_len] = (uint8_t)(uni_char & 0xffU);
		i += len - 1;
	}

	ocu[length - 1] = (uint8_t)u_len + 1;
	return u_len + 1;
}

int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname, int flen)
{
	struct ustr filename, unifilename;
	int len;

	if (udf_build_ustr_exact(&unifilename, sname, flen))
	{
		return 0;
	}

	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8))
	{
		if (!udf_CS0toUTF8(&filename, &unifilename) )
		{
			udf_debug("Failed in udf_get_filename: sname = %s\n", sname);
			return 0;
		}
	}
	else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
	{
		if (!udf_CS0toNLS(UDF_SB(sb)->s_nls_map, &filename, &unifilename) )
		{
			udf_debug("Failed in udf_get_filename: sname = %s\n", sname);
			return 0;
		}
	}
	else
		return 0;

	if ((len = udf_translate_to_linux(dname, filename.u_name, filename.u_len,
		unifilename.u_name, unifilename.u_len)))
	{
		return len;
	}
	return 0;
}

int udf_put_filename(struct super_block *sb, const uint8_t *sname, uint8_t *dname, int flen)
{
	struct ustr unifilename;
	int namelen;

	if ( !(udf_char_to_ustr(&unifilename, sname, flen)) )
	{
		return 0;
	}

	if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8))
	{
		if ( !(namelen = udf_UTF8toCS0(dname, &unifilename, UDF_NAME_LEN)) )
		{
			return 0;
		}
	}
	else if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
	{
		if ( !(namelen = udf_NLStoCS0(UDF_SB(sb)->s_nls_map, dname, &unifilename, UDF_NAME_LEN)) )
		{
			return 0;
		}
	}
	else
		return 0;

	return namelen;
}

#define ILLEGAL_CHAR_MARK	'_'
#define EXT_MARK			'.'
#define CRC_MARK			'#'
#define EXT_SIZE			5

static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, int udfLen, uint8_t *fidName, int fidNameLen)
{
	int index, newIndex = 0, needsCRC = 0;	
	int extIndex = 0, newExtIndex = 0, hasExt = 0;
	unsigned short valueCRC;
	uint8_t curr;
	const uint8_t hexChar[] = "0123456789ABCDEF";

	if (udfName[0] == '.' && (udfLen == 1 ||
		(udfLen == 2 && udfName[1] == '.')))
	{
		needsCRC = 1;
		newIndex = udfLen;
		memcpy(newName, udfName, udfLen);
	}
	else
	{	
		for (index = 0; index < udfLen; index++)
		{
			curr = udfName[index];
			if (curr == '/' || curr == 0)
			{
				needsCRC = 1;
				curr = ILLEGAL_CHAR_MARK;
				while (index+1 < udfLen && (udfName[index+1] == '/' ||
					udfName[index+1] == 0))
					index++;
			}
			if (curr == EXT_MARK && (udfLen - index - 1) <= EXT_SIZE)
			{
				if (udfLen == index + 1)
					hasExt = 0;
				else
				{
					hasExt = 1;
					extIndex = index;
					newExtIndex = newIndex;
				}
			}
			if (newIndex < 256)
				newName[newIndex++] = curr;
			else
				needsCRC = 1;
		}
	}
	if (needsCRC)
	{
		uint8_t ext[EXT_SIZE];
		int localExtIndex = 0;

		if (hasExt)
		{
			int maxFilenameLen;
			for(index = 0; index<EXT_SIZE && extIndex + index +1 < udfLen;
				index++ )
			{
				curr = udfName[extIndex + index + 1];

				if (curr == '/' || curr == 0)
				{
					needsCRC = 1;
					curr = ILLEGAL_CHAR_MARK;
					while(extIndex + index + 2 < udfLen && (index + 1 < EXT_SIZE
						&& (udfName[extIndex + index + 2] == '/' ||
							udfName[extIndex + index + 2] == 0)))
						index++;
				}
				ext[localExtIndex++] = curr;
			}
			maxFilenameLen = 250 - localExtIndex;
			if (newIndex > maxFilenameLen)
				newIndex = maxFilenameLen;
			else
				newIndex = newExtIndex;
		}
		else if (newIndex > 250)
			newIndex = 250;
		newName[newIndex++] = CRC_MARK;
		valueCRC = udf_crc(fidName, fidNameLen, 0);
		newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12];
		newName[newIndex++] = hexChar[(valueCRC & 0x0f00) >> 8];
		newName[newIndex++] = hexChar[(valueCRC & 0x00f0) >> 4];
		newName[newIndex++] = hexChar[(valueCRC & 0x000f)];

		if (hasExt)
		{
			newName[newIndex++] = EXT_MARK;
			for (index = 0;index < localExtIndex ;index++ )
				newName[newIndex++] = ext[index];
		}
	}
	return newIndex;
}
