summaryrefslogtreecommitdiffstatshomepage
path: root/src/tools/imgtool/charconv.cpp
blob: 34a912dcb8918ba61e1a540c52ff1b8c3d19b3b3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// license:BSD-3-Clause
// copyright-holders:Nathan Woods
/***************************************************************************

    charconv.c

    Imgtool character set conversion routines.

***************************************************************************/

#include "corestr.h"
#include "charconv.h"


/*-------------------------------------------------
    utf8_from_latin1 - convert an ISO-8859-1
    character sequence to an UTF-8 string
-------------------------------------------------*/

static char *utf8_from_latin1(const char *src)
{
	char *buffer, *bufptr;

	/* validate input */
	if (!src)
	{
		return nullptr;
	}

	/* allocate space for result, twice the source len to be safe */
	buffer = (char *) osd_malloc(strlen(src) * 2 + 1);

	/* point to the start */
	bufptr = buffer;

	do
	{
		unsigned char c = *src;

		if (c < 0x80)
		{
			*bufptr++ = c;
		}
		else if (c < 0xc0)
		{
			*bufptr++ = '\xc2';
			*bufptr++ = c;
		}
		else
		{
			*bufptr++ = '\xc3';
			*bufptr++ = c - 0x40;
		}
	} while (*src++);

	return buffer;
}


/*-------------------------------------------------
    latin1_from_utf8 - convert an UTF-8
    character sequence to an ISO-8859-1 string
-------------------------------------------------*/

static char *latin1_from_utf8(const char *src)
{
	char *buffer, *bufptr;

	/* validate input */
	if (!src)
	{
		return nullptr;
	}

	/* allocate space for result */
	buffer = (char *) osd_malloc(strlen(src) + 1);

	/* point to the start */
	bufptr = buffer;

	do
	{
		unsigned char c = *src;

		if (c < 0x80)
		{
			*bufptr++ = c;
		}
		else if (c == 0xc2)
		{
			c = *++src;
			*bufptr++ = c;
		}
		else if (c == 0xc3)
		{
			c = *++src;
			*bufptr++ = c + 0x40;
		}
		else
		{
			/* conversion failed */
			*bufptr++ = '\0';
			break;
		}
	} while(*src++);

	return buffer;
}


/*-------------------------------------------------
    utf8_from_native - convert specified character
    sequence to an UTF-8 string
-------------------------------------------------*/

char *utf8_from_native(imgtool_charset charset, const char *src)
{
	char *result;

	switch (charset)
	{
		case IMGTOOL_CHARSET_UTF8:
			result = core_strdup(src);
			break;

		case IMGTOOL_CHARSET_ISO_8859_1:
			result = utf8_from_latin1(src);
			break;

		default:
			result = nullptr;
			break;
	}
	return result;
}


/*-------------------------------------------------
    native_from_utf8 - convert an UTF-8 string
    to specified character set
-------------------------------------------------*/

char *native_from_utf8(imgtool_charset charset, const char *src)
{
	char *result;

	switch (charset)
	{
		case IMGTOOL_CHARSET_UTF8:
			result = core_strdup(src);
			break;

		case IMGTOOL_CHARSET_ISO_8859_1:
			result = latin1_from_utf8(src);
			break;

		default:
			result = nullptr;
			break;
	}
	return result;
}