Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/waterbox/libc/functions/uchar/c16rtomb.c
2 views
1
/* c16rtomb( char *, char16_t, mbstate_t * )
2
3
This file is part of the Public Domain C Library (PDCLib).
4
Permission is granted to use, modify, and / or redistribute at will.
5
*/
6
7
#ifndef REGTEST
8
#include <uchar.h>
9
#include <errno.h>
10
#include <stdint.h>
11
#include <assert.h>
12
#include <stdlib.h>
13
#include "_PDCLIB_encoding.h"
14
#include "_PDCLIB_locale.h"
15
16
size_t c16rtomb_l(
17
char *restrict s,
18
char16_t c16,
19
mbstate_t *restrict ps,
20
locale_t restrict l
21
)
22
{
23
const char16_t *restrict psrc = &c16;
24
char buf[s ? 0 : MB_CUR_MAX];
25
s = s ? s : buf;
26
27
if(!l->_Codec->__c16stombs) {
28
// Codec doesn't support direct conversion - translate via UCS-4
29
if(ps->_Surrogate == 0) {
30
// No pending surrogate
31
if((c16 & 0xF800) == 0xD800) {
32
// Surrogate range
33
if((c16 & 0x0400) == 0) {
34
// 0xD800 -> 0xDBFF leading surrogate
35
ps->_Surrogate = c16;
36
37
// Need more data
38
// Return 0 - we haven't output anything yet
39
40
/* STD: ISO/IEC 9899:2011 is very implcifit about this being
41
* the correct return value. N1040, from which the
42
* function was adopted, is explicit about 0 being a
43
* valid return.
44
*/
45
return (size_t) 0;
46
} else {
47
// 0xDC00 -> 0xDFFF trailing surrogate
48
errno = EILSEQ;
49
return (size_t) -1;
50
}
51
} else {
52
// BMP range - UTF16 == UCS-4, pass through to c32rtomb_l
53
return c32rtomb_l(s, c16, ps, l);
54
}
55
} else {
56
// We have a stored surrogate
57
if((c16 & 0xFC00) == 0xDC00) {
58
// Trailing surrogate
59
char32_t c32 = (ps->_Surrogate & 0x3FF) << 10 | (c16 & 0x3FF);
60
ps->_Surrogate = 0;
61
return c32rtomb_l(s, c32, ps, l);
62
} else {
63
// Not a trailing surrogate - encoding error
64
errno = EILSEQ;
65
return (size_t) -1;
66
}
67
68
}
69
} else {
70
// Codec supports direct conversion
71
size_t srcsz = 1;
72
size_t dstsz = MB_CUR_MAX;
73
size_t dstrem = dstsz;
74
75
if(l->_Codec->__c16stombs(&s, &dstrem, &psrc, &srcsz, ps)) {
76
// Successful conversion
77
return dstsz - dstrem;
78
} else {
79
errno = EILSEQ;
80
return (size_t) -1;
81
}
82
}
83
}
84
85
size_t c16rtomb(
86
char *restrict s,
87
char16_t c16,
88
mbstate_t *restrict ps
89
)
90
{
91
return c16rtomb_l(s, c16, ps, _PDCLIB_threadlocale());
92
}
93
94
#endif
95
96
#ifdef TEST
97
#include "_PDCLIB_test.h"
98
99
int main( void )
100
{
101
TESTCASE( NO_TESTDRIVER );
102
return TEST_RESULTS;
103
}
104
#endif
105
106