aboutsummaryrefslogtreecommitdiff
path: root/arch/all/core/src/stdlib/wchar.c
blob: 4475fdd61bd82b73c846055d55855c4064bbcf0c (plain)
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
/* ****************************************************************************
 * stdlib/wchar.c -- Wide char-related utilities.
 * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
 *
 * This file is part of libcarrot.
 * libcarrot is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 3.0 of the License,
 * or (at your option) any later version.
 *
 * libcarrot 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with the libcarrot; if not, see <http://www.gnu.org/licenses/>.
 *
 * Functions from this file come from libfontcharacter, which is
 * Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
 * ************************************************************************* */
#include <stdlib.h>
#include <string.h>

/* ************************************************************************* */
/*  Character translations                                                   */
/* ************************************************************************* */
/**
 *	wctomb:
 *	FONTCHARACTER to multi-byte character conversion.
 *
 *	@arg	s		pointer to the multi-byte string.
 *	@arg	fc		the FONTCHARACTER character.
 *	@return			the
 */

int wctomb(char *s, wchar_t fc)
{
	/* extended? */
	if (fc > 0xff) {
		*s++ = (fc >> 8) & 0xff;
		*s = fc & 0xff;
		return (2);
	}

	/* normal char. */
	*s = fc;
	return (fc != 0x00 && fc != 0xFF);
}

/**
 *	mbtowc:
 *	Multi-byte to FONTCHARACTER character conversion.
 *
 *	@arg	pfc		pointer to the FONTCHARACTER character.
 *	@arg	s		the multi-byte source string.
 *	@arg	n		the size of the destination buffer.
 *	@return			the number of bytes used (-1 if error).
 */

int mbtowc(wchar_t *pfc, const char *s, size_t n)
{
	const unsigned char *us = (const unsigned char*)s;

	/* so that the 'no size = unlimited' (n == 0) case is easy to manage */
	n--;

	/* nul character? */
	if (!*us || *us == 0xFF)
		return (0);

	/* extended char? */
	if (*us && strchr("\x7F\xF7\xF9\xE5\xE6\xE7", *us)) {
		if (!n) return (-1);
		*pfc = *us;
		*pfc <<= 8;
		*pfc |= *(us + 1);
		return (2);
	}

	/* single-byte character! */
	*pfc = *us;
	return (1);
}
/* ************************************************************************* */
/*  String translations                                                      */
/* ************************************************************************* */
/**
 *	wcstombs:
 *	FONTCHARACTER to multi-byte string conversion.
 *
 *	@arg	dst		the destination.
 *	@arg	src		the source.
 *	@arg	n		the size of the source.
 *	@return			the size of the destination.
 */

size_t wcstombs(char *dst, const wchar_t *src, size_t n)
{
	char buf[2]; int count;
	size_t len = 0;
	n--; /* terminating character */

	/* main loop */
	while (1) {
		/* to multi-byte */
		count = wctomb(buf, *src++);
		if (count <= 0) break;

		/* copy */
		if ((size_t)count > n) break;
		if (dst) {
			memcpy(dst, buf, count);
			dst += count;
		}
		len += count;
		n -= count;
	}
	if (dst) *dst = 0;
	return (len);
}

/**
 *	mbstowcs:
 *	Multi-byte to FONTCHARACTER string conversion.
 *
 *	This function imitates `mbstowcs` (unicode), but for CASIO's encoding.
 *	You should be able to use it the same way.
 *
 *	@arg	dest	the destination.
 *	@arg	src		the source.
 *	@arg	n		the size of the source.
 *	@return			the size of the destination.
 */

size_t mbstowcs(wchar_t *dest, const char *src, size_t n)
{
	size_t len = 0, count; wchar_t wc;
	n--; /* terminating character */

	while (n--) {
		/* read the FONTCHARACTER char */
		count = mbtowc(&wc, src, 0);
		if (count <= 0)
			break;

		/* write the entry and iterate */
		if (dest) *dest++ = wc;
		src += count;
		len++;
	}

	/* write the terminating entry and return length */
	if (dest) *dest = 0;
	return (len);
}