Path: blob/master/waterbox/libc/functions/uchar/c16rtomb.c
2 views
/* c16rtomb( char *, char16_t, mbstate_t * )12This file is part of the Public Domain C Library (PDCLib).3Permission is granted to use, modify, and / or redistribute at will.4*/56#ifndef REGTEST7#include <uchar.h>8#include <errno.h>9#include <stdint.h>10#include <assert.h>11#include <stdlib.h>12#include "_PDCLIB_encoding.h"13#include "_PDCLIB_locale.h"1415size_t c16rtomb_l(16char *restrict s,17char16_t c16,18mbstate_t *restrict ps,19locale_t restrict l20)21{22const char16_t *restrict psrc = &c16;23char buf[s ? 0 : MB_CUR_MAX];24s = s ? s : buf;2526if(!l->_Codec->__c16stombs) {27// Codec doesn't support direct conversion - translate via UCS-428if(ps->_Surrogate == 0) {29// No pending surrogate30if((c16 & 0xF800) == 0xD800) {31// Surrogate range32if((c16 & 0x0400) == 0) {33// 0xD800 -> 0xDBFF leading surrogate34ps->_Surrogate = c16;3536// Need more data37// Return 0 - we haven't output anything yet3839/* STD: ISO/IEC 9899:2011 is very implcifit about this being40* the correct return value. N1040, from which the41* function was adopted, is explicit about 0 being a42* valid return.43*/44return (size_t) 0;45} else {46// 0xDC00 -> 0xDFFF trailing surrogate47errno = EILSEQ;48return (size_t) -1;49}50} else {51// BMP range - UTF16 == UCS-4, pass through to c32rtomb_l52return c32rtomb_l(s, c16, ps, l);53}54} else {55// We have a stored surrogate56if((c16 & 0xFC00) == 0xDC00) {57// Trailing surrogate58char32_t c32 = (ps->_Surrogate & 0x3FF) << 10 | (c16 & 0x3FF);59ps->_Surrogate = 0;60return c32rtomb_l(s, c32, ps, l);61} else {62// Not a trailing surrogate - encoding error63errno = EILSEQ;64return (size_t) -1;65}6667}68} else {69// Codec supports direct conversion70size_t srcsz = 1;71size_t dstsz = MB_CUR_MAX;72size_t dstrem = dstsz;7374if(l->_Codec->__c16stombs(&s, &dstrem, &psrc, &srcsz, ps)) {75// Successful conversion76return dstsz - dstrem;77} else {78errno = EILSEQ;79return (size_t) -1;80}81}82}8384size_t c16rtomb(85char *restrict s,86char16_t c16,87mbstate_t *restrict ps88)89{90return c16rtomb_l(s, c16, ps, _PDCLIB_threadlocale());91}9293#endif9495#ifdef TEST96#include "_PDCLIB_test.h"9798int main( void )99{100TESTCASE( NO_TESTDRIVER );101return TEST_RESULTS;102}103#endif104105106