diff options
Diffstat (limited to 'src/u8c/u8.h.d/u8dec.c')
-rw-r--r-- | src/u8c/u8.h.d/u8dec.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/src/u8c/u8.h.d/u8dec.c b/src/u8c/u8.h.d/u8dec.c index 365c81a..4cba14f 100644 --- a/src/u8c/u8.h.d/u8dec.c +++ b/src/u8c/u8.h.d/u8dec.c @@ -19,23 +19,24 @@ # include <stdint.h> # include <u8c/SIZE_C.h> # include <u8c/err.h> -# include <u8c/u32.h> +# include <u8c/str.h> # include <u8c/u8.h> # include <uchar.h> -bool u8c_u8dec(size_t * const _sz,char32_t const * * const _out,unsigned char const * const _in) { - assert(_out != NULL); - assert(_in != NULL); - register size_t insz = SIZE_C(0x0); - register size_t outsz = SIZE_C(0x1); - for(register size_t n = SIZE_C(0x0);n <= SIZE_MAX;outsz += SIZE_C(0x1)) { /* First pass: get size of input array and determine size of output array. */ +struct u8c_u8dec_tuple u8c_u8dec(unsigned char const * const restrict _in) { + struct u8c_u8dec_tuple ret = { + .stat = false, + }; + register size_t insz = SIZE_C(0x0); + for(register size_t n = SIZE_C(0x0);n <= SIZE_MAX;ret.strsz += SIZE_C(0x1)) { /* First pass: get size of input array and determine size of output array. */ register unsigned char const tmp = _in[n]; if(tmp == UINT8_C(0x0)) { /* Null-terminator: end of string has been reached. */ insz = n; goto nottoobig; } if(tmp >= UINT8_C(0b11111000)) { /* Too big. */ - u8c_seterr(U"u8c_u8dec: Character out of range (too big).",u8c_errtyp_u8oor); - return true; + u8c_seterr(u8c_errtyp_u8oor,U"u8c_u8dec: Character out of range (too big)."); + ret.stat = true; + return ret; } if(tmp >= UINT8_C(0b11110000)) { /* Four byte. */ n += SIZE_C(0x4); @@ -53,15 +54,18 @@ bool u8c_u8dec(size_t * const _sz,char32_t const * * const _out,unsigned char co n += SIZE_C(0x1); } /* Input is not null-terminated. */ - u8c_seterr(U"u8c_u8dec: Unterminated input.",u8c_errtyp_untermin); - return true; + u8c_seterr(u8c_errtyp_untermin,U"u8c_u8dec: Unterminated input."); + ret.stat = true; + return ret; nottoobig:; - if(_sz != NULL) { - *_sz = outsz; - } uint_least32_t * out = NULL; - if(u8c_u32alloc(&out,outsz + SIZE_C(0x1))) { - return false; + { + struct u8c_stralloc_tuple const tuple = u8c_stralloc(ret.strsz + SIZE_C(0x1)); + if(tuple.stat) { + ret.stat = true; + return ret; + } + out = tuple.str; } for(register size_t n = SIZE_C(0x0),outn = SIZE_C(0x0);n < insz;outn += SIZE_C(0x1)) { /* Second pass: decode UTF-8. */ if(_in[n] >= UINT8_C(0b11110000)) { /* Four bytes. */ @@ -99,7 +103,6 @@ nottoobig:; n += SIZE_C(0x1); continue; } - u8c_u32free(_out); - *_out = out; - return false; + ret.str = out; + return ret; } |