/* Copyright (C) 2015-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk4utf16.ctr */ /** @file dk4utf16.c The dk4utf16 module. */ #line 212 "dk4utf16.ctr" #include "dk4conf.h" #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif #include "dk4types.h" #include "dk4error.h" #include "dk4utf16.h" #include "dk4mem.h" #include "dk4rec26.h" #line 230 "dk4utf16.ctr" /** State value in dk4_utf16_decoder_t. */ enum { /** No surrogate yet. */ DK4_UTF16_DEC_ST_EMPTY = 0, /** Found high surrogate, expecting corresponding low surrogate. */ DK4_UTF16_DEC_ST_HAVE_HIGH_SURROGATE , /** Found low surrogate, expecting corresponding high surrogate. */ DK4_UTF16_DEC_ST_HAVE_LOW_SURROGATE }; void dk4utf16_init(dk4_utf16_decoder_t *ptr) { #if DK4_USE_ASSERT assert(NULL != ptr); #endif if (NULL != ptr) { ptr->uc = dkC32(0); ptr->state = DK4_UTF16_DEC_ST_EMPTY; } } int dk4utf16_add(dk4_utf16_decoder_t *ptr, dk4_c16_t word) { int back = DK4_EDSTM_ERROR; #if DK4_USE_ASSERT assert(NULL != ptr); #endif if (NULL != ptr) { switch (ptr->state) { case DK4_UTF16_DEC_ST_EMPTY: { if ((dkC32(0x0000DC00) & ((dk4_c32_t)word)) == dkC32(0x0000DC00)) { ptr->state = DK4_UTF16_DEC_ST_HAVE_LOW_SURROGATE; ptr->uc = ((dk4_c32_t)word) & dkC32(0x000003FF); back = DK4_EDSTM_ACCEPT; } else { if ((dkC32(0x0000DC00) & ((dk4_c32_t)word)) == dkC32(0x0000D800)) { ptr->state = DK4_UTF16_DEC_ST_HAVE_HIGH_SURROGATE; ptr->uc = ((((dk4_c32_t)word) << 10) & dkC32(0x000FFC00)); back = DK4_EDSTM_ACCEPT; } else { ptr->uc = ((dk4_c32_t)word) & dkC32(0x0000FFFF); back = DK4_EDSTM_FINISHED; } } } break; case DK4_UTF16_DEC_ST_HAVE_HIGH_SURROGATE: { if ((dkC32(0x0000DC00) & ((dk4_c32_t)word)) == dkC32(0x0000DC00)) { ptr->uc |= (((dk4_c32_t)word) & dkC32(0x000003FF)); ptr->uc += dkC32(0x00010000); ptr->state = DK4_UTF16_DEC_ST_EMPTY; back = DK4_EDSTM_FINISHED; } else { back = DK4_EDSTM_ERROR; ptr->state = DK4_UTF16_DEC_ST_EMPTY; } } break; case DK4_UTF16_DEC_ST_HAVE_LOW_SURROGATE: { if ((((dk4_c32_t)word) & dkC32(0x0000DC00)) == dkC32(0x0000D800)) { ptr->uc |= ((((dk4_c32_t)word) << 10) & dkC32(0x000FFC00)); ptr->uc += dkC32(0x00010000); ptr->state = DK4_UTF16_DEC_ST_EMPTY; back = DK4_EDSTM_FINISHED; } else { back = DK4_EDSTM_ERROR; ptr->state = DK4_UTF16_DEC_ST_EMPTY; } } break; } } return back; } dk4_c32_t dk4utf16_get(dk4_utf16_decoder_t const *ptr) { dk4_c32_t back = dkC32(0); #if DK4_USE_ASSERT assert(NULL != ptr); #endif if (NULL != ptr) { back = ptr->uc; } return back; } int dk4utf16_is_empty(dk4_utf16_decoder_t const *ptr) { int back = 0; #if DK4_USE_ASSERT assert(NULL != ptr); #endif if (NULL != ptr) { if (DK4_UTF16_DEC_ST_EMPTY == ptr->state) { back = 1; } } return back; } int dk4utf16_encode(dk4_c16_t *rb, size_t *pszrb, dk4_c32_t c, dk4_er_t *erp) { int back = 0; #line 358 "dk4utf16.ctr" #if DK4_USE_ASSERT assert(NULL != rb); assert(NULL != pszrb); assert(2 < *pszrb); #endif if ((NULL != rb) && (NULL != pszrb)) { if (2 < *pszrb) { #line 365 "dk4utf16.ctr" if ( dkC32(0x00010000) <= c ) { #line 366 "dk4utf16.ctr" if ( dkC32(0x0010FFFF) >= c ) { #line 367 "dk4utf16.ctr" back = 1; *pszrb = 2; rb[0] = (dk4_c16_t)(((c >> 10) & dkC32(0x000003FF)) | dkC32(0x0000D800)); rb[1] = (dk4_c16_t)((c & dkC32(0x000003FF)) | dkC32(0x0000DC00)); rb[2] = (dk4_c16_t)0; } else { #line 375 "dk4utf16.ctr" dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } else { #line 378 "dk4utf16.ctr" #if VERSION_BEFORE_20141125 if ((0x0000DC00 & c) != dkC32(0x0000DC00)) { #line 380 "dk4utf16.ctr" if ((0x0000DC00 & c) != dkC32(0x0000D800)) { #line 381 "dk4utf16.ctr" back = 1; *pszrb = 1; rb[0] = (dk4_c16_t)(c & dkC32(0x0000FFFF)); rb[1] = (dk4_c16_t)0; } else { #line 386 "dk4utf16.ctr" dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } else { #line 389 "dk4utf16.ctr" dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } #else if ((dkC32(0x0000DFFF) < c) || (dkC32(0x0000D800) > c)) { #line 394 "dk4utf16.ctr" back = 1; *pszrb = 1; rb[0] = (dk4_c16_t)(c & dkC32(0x0000FFFF)); rb[1] = (dk4_c16_t)0; } else { #line 399 "dk4utf16.ctr" dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } #endif } } else { #line 404 "dk4utf16.ctr" dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL); } } else { #line 407 "dk4utf16.ctr" dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 409 "dk4utf16.ctr" return back; } void dk4utf16_byte_init(dk4_utf16_byte_decoder_t *ptr, int msb) { #if DK4_USE_ASSERT assert(NULL != ptr); #endif if (NULL != ptr) { dk4utf16_init(&(ptr->dec)); ptr->msb = msb; ptr->state = 0; ptr->saved = (dk4_c16_t)0; } } int dk4utf16_byte_add(dk4_utf16_byte_decoder_t *ptr, unsigned char byte) { int back = DK4_EDSTM_ERROR; #if DK4_USE_ASSERT assert(NULL != ptr); #endif if (NULL != ptr) { if (0 != ptr->state) { ptr->state = 0; if (0 != ptr->msb) { ptr->saved |= (((dk4_c16_t)byte) & dkC16(0x00FF)); } else { ptr->saved |= ((((dk4_c16_t)byte) << 8) & dkC16(0xFF00)); } back = dk4utf16_add(&(ptr->dec), ptr->saved); ptr->saved = (dk4_c16_t)0; } else { ptr->state = 1; if (0 != ptr->msb) { ptr->saved = ((((dk4_c16_t)byte) << 8) & dkC16(0xFF00)); } else { ptr->saved = (((dk4_c16_t)byte) & dkC16(0x00FF)); } back = DK4_EDSTM_ACCEPT; } } return back; } dk4_c32_t dk4utf16_byte_get(dk4_utf16_byte_decoder_t *ptr) { dk4_c32_t back = dkC32(0); #if DK4_USE_ASSERT assert(NULL != ptr); #endif if (NULL != ptr) { back = dk4utf16_get(&(ptr->dec)); } return back; } int dk4utf16_byte_is_empty(dk4_utf16_byte_decoder_t *ptr) { int back = 0; #if DK4_USE_ASSERT assert(NULL != ptr); #endif if (NULL != ptr) { back = dk4utf16_is_empty(&(ptr->dec)); if (0 != ptr->state) { back = 0; } } return back; } int dk4utf16_byte_encode( unsigned char *rb, size_t *pszrb, dk4_c32_t c, int msb, dk4_er_t *erp ) { dk4_c16_t buf[3]; size_t sz; int back = 0; #if DK4_USE_ASSERT assert(NULL != rb); assert(NULL != pszrb); assert(4 < pszrb); #endif if ((NULL != rb) && (NULL != pszrb)) { if (4 < *pszrb) { sz = DK4_SIZEOF(buf,dk4_c16_t); if (0 != dk4utf16_encode(buf, &sz, c, erp)) { back = 1; if (0 != msb) { rb[0] = (unsigned char)((buf[0] >> 8) & dkC16(0x00FF)); rb[1] = (unsigned char)(buf[0] & dkC16(0x00FF)); } else { rb[1] = (unsigned char)((buf[0] >> 8) & dkC16(0x00FF)); rb[0] = (unsigned char)(buf[0] & dkC16(0x00FF)); } if (1 < sz) { if (0 != msb) { rb[2] = (unsigned char)((buf[1] >> 8) & dkC16(0x00FF)); rb[3] = (unsigned char)(buf[1] & dkC16(0x00FF)); } else { rb[3] = (unsigned char)((buf[1] >> 8) & dkC16(0x00FF)); rb[2] = (unsigned char)(buf[1] & dkC16(0x00FF)); } *pszrb = 4; rb[4] = '\0'; } else { *pszrb = 2; rb[2] = '\0'; } } } else { dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; }