diff options
Diffstat (limited to 'support/dktools/dk4utf16.ctr')
-rw-r--r-- | support/dktools/dk4utf16.ctr | 542 |
1 files changed, 0 insertions, 542 deletions
diff --git a/support/dktools/dk4utf16.ctr b/support/dktools/dk4utf16.ctr deleted file mode 100644 index db1c5deab3..0000000000 --- a/support/dktools/dk4utf16.ctr +++ /dev/null @@ -1,542 +0,0 @@ -%% options - -copyright owner = Dirk Krause -copyright year = 2015-xxxx -SPDX-License-Identifier: BSD-3-Clause - - - -%% header - -/** @file - Encode and decode 32 bit characters - in UTF-16 encoding. - - CRT on Windows: Not used. - - The character to encode to UTF-16 must be in - range U+00000000 to U+0010FFFF. - (the hexadecimal numbers range defined by UNICODE). - - The character must not be in range U+0000D800 to U+0000DFFF which - is reserved for surrogate pairs. - - Characters up to U+0000FFFF are converted to 16 bits and passed - "as is". - - For characters above, we substract U+00010000 and split the result - in two 10-bit blocks. - We prepend bits 110110 to the higher 10 bits, this results in the - "high surrogate". - We prepend bits 110111 to the lower 10 bits, this results in the - "low surrogate". - - When decoding we have to check for a byte order marker (BOM) at - start of stream. The character U+0000FEFF as first character in the - stream can be used to mark encoding and/or byte order. - If we read an UTF-16 encoded stream and have 0xFEFF as first character - we can leave byte order as is. If the first character is 0xFFFE we - have to change byte order in each word. - -*/ - -#ifndef DK4CONF_H_INCLUDED -#if DK4_BUILDING_DKTOOLS4 -#include "dk4conf.h" -#else -#include <dktools-4/dk4conf.h> -#endif -#endif - -#ifndef DK4CONF_H_INCLUDED -#if DK4_BUILDING_DKTOOLS4 -#include "dk4types.h" -#else -#include <dktools-4/dk4types.h> -#endif -#endif - -#ifndef DK4ERROR_H_INCLUDED -#if DK4_BUILDING_DKTOOLS4 -#include "dk4error.h" -#else -#include <dktools-4/dk4error.h> -#endif -#endif - -#ifndef DK4DEC_H_INCLUDED -#if DK4_BUILDING_DKTOOLS4 -#include "dk4edstm.h" -#else -#include <dktools-4/dk4edstm.h> -#endif -#endif - -/** Decode UTF-16 encoded data. -*/ -typedef struct { - dk4_c32_t uc; /**< Unicode character to produce. */ - int state; /**< Decoder state. */ -} dk4_utf16_decoder_t; - - - -/** Decode UTF-16 encoded bytes. -*/ -typedef struct { - dk4_utf16_decoder_t dec; /**< Decoder UTF-16 to 32-bit char. */ - int msb; /**< Flag: Most significant byte comes first. */ - int state; /**< Decoder state. */ - dk4_c16_t saved; /**< Partial input character saved. */ -} dk4_utf16_byte_decoder_t; - - - -#ifdef __cplusplus -extern "C" { -#endif - -/** Initialize the UTF-16 decoder. - @param ptr Decoder to initialize. -*/ -void -dk4utf16_init(dk4_utf16_decoder_t *ptr); - -/** Add one word to the decoder. - @param ptr Decoder to use. - @param word Word to add. - @return Operation result, one from: - DK4_EDSTM_ACCEPT if the byte was added to the next output - without completing output, - DK4_EDSTM_FINISHED, if the byte was added to the next output - completing the output, or - DK4_EDSTM_ERROR on error. -*/ -int -dk4utf16_add(dk4_utf16_decoder_t *ptr, dk4_c16_t word); - -/** Retrieve a completed Unicode character from the decoder. - @param ptr Decoder to obtain character from. -*/ -dk4_c32_t -dk4utf16_get(dk4_utf16_decoder_t const *ptr); - -/** Check whether the decoder is empty. - @param ptr Decoder to check. - @return 1 on success, 0 on error. -*/ -int -dk4utf16_is_empty(dk4_utf16_decoder_t const *ptr); - -/** UTF-16 encode UNICODE character. - @param rb Result buffer, should be at least 3 dk4_c16_t. - @param pszrb Size of the result buffer, in: available, out: used. - @param c Character to encode. - @param erp Error report, may be NULL. - @return 1 on success, 0 on error. - - Error codes: - - DK4_E_INVALID_ARGUMENTS<br> - if rb or pszrb is NULL, - - DK4_E_BUFFER_TOO_SMALL<br> - if the buffer size is less than 3, - - DK4_E_SYNTAX<br> - if c is out of the encodable range. -*/ -int -dk4utf16_encode(dk4_c16_t *rb, size_t *pszrb, dk4_c32_t c, dk4_er_t *erp); - -/** Initialize the UTF-16 decoder. - @param ptr Decoder to initialize. - @param msb Flag: Most significant byte comes first. -*/ -void -dk4utf16_byte_init(dk4_utf16_byte_decoder_t *ptr, int msb); - -/** Add one byte to the decoder. - @param ptr Decoder to use. - @param byte Byte to add. - @return Operation result, one from: - DK4_EDSTM_ACCEPT if the byte was added to the next output - without completing output, - DK4_EDSTM_FINISHED, if the byte was added to the next output - completing the output, or - DK4_EDSTM_ERROR on error. -*/ -int -dk4utf16_byte_add(dk4_utf16_byte_decoder_t *ptr, unsigned char byte); - -/** Retrieve a completed Unicode character from the decoder. - @param ptr Decoder to obtain character from. -*/ -dk4_c32_t -dk4utf16_byte_get(dk4_utf16_byte_decoder_t *ptr); - -/** Check whether a decoder is empty. - @param ptr Decoder to check. - @return 1 on success, 0 on error. -*/ -int -dk4utf16_byte_is_empty(dk4_utf16_byte_decoder_t *ptr); - -/** UTF-16 encode UNICODE character, write to bytes. - @param rb Result buffer, should be at least 5 bytes. - @param pszrb Size of the result buffer (number of bytes), - in: available, out: used. - @param c Character to encode. - @param msb Flag: Write most significant byte first. - @param erp Error report, may be NULL. - @return 1 on success, 0 on error. - - Error codes: - - DK4_E_INVALID_ARGUMENTS<br> - if rb or pszrb is NULL, - - DK4_E_BUFFER_TOO_SMALL<br> - if the buffer size is less than 3, - - DK4_E_SYNTAX<br> - if c is out of the encodable range. -*/ -int -dk4utf16_byte_encode( - unsigned char *rb, size_t *pszrb, dk4_c32_t c, int msb, dk4_er_t *erp -); - - -#ifdef __cplusplus -} -#endif - - - -%% module - -#include "dk4conf.h" - -#if DK4_HAVE_ASSERT_H -#ifndef ASSERT_H_INCLUDED -#include <assert.h> -#define ASSERT_H_INCLUDED 1 -#endif -#endif - -#include "dk4types.h" -#include "dk4error.h" -#include "dk4utf16.h" -#include "dk4mem.h" -#include "dk4rec26.h" - - -$!trace-include - - - -/** 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; - $? "+ dk4utf16_encode %08lx", dk4recode_c32_to_ul(c) -#if DK4_USE_ASSERT - assert(NULL != rb); - assert(NULL != pszrb); - assert(2 < *pszrb); -#endif - if ((NULL != rb) && (NULL != pszrb)) { - if (2 < *pszrb) { $? ". args ok" - if ( dkC32(0x00010000) <= c ) { $? ". surrogate pair" - if ( dkC32(0x0010FFFF) >= c ) { $? ". in range" - 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 { $? "! out of range" - dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); - } - } else { $? ". single 16-bit char" -#if VERSION_BEFORE_20141125 - if ((0x0000DC00 & c) != dkC32(0x0000DC00)) { $? ". range 1 ok" - if ((0x0000DC00 & c) != dkC32(0x0000D800)) { $? ". range 2 ok" - back = 1; - *pszrb = 1; - rb[0] = (dk4_c16_t)(c & dkC32(0x0000FFFF)); - rb[1] = (dk4_c16_t)0; - } else { $? "! range check 2" - dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); - } - } else { $? "! range check 1" - dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); - } -#else - if ((dkC32(0x0000DFFF) < c) || (dkC32(0x0000D800) > c)) { - $? ". range ok, not in surrogates range" - back = 1; - *pszrb = 1; - rb[0] = (dk4_c16_t)(c & dkC32(0x0000FFFF)); - rb[1] = (dk4_c16_t)0; - } else { $? "! range check, in surrogates range" - dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); - } -#endif - } - } else { $? "! buffer size" - dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL); - } - } else { $? "! args" - dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); - } $? "- dk4utf16_encode %d", back - 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; -} - - |