/* 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: dk4utf8.ctr */ /** @file dk4utf8.c The dk4utf8 module. */ #line 137 "dk4utf8.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 "dk4utf8.h" #include "dk4rec26.h" #line 155 "dk4utf8.ctr" void dk4utf8_init(dk4_utf8_decoder_t *ptr) { #if DK4_USE_ASSERT assert(NULL != ptr); #endif if (NULL != ptr) { ptr->uc = dkC32(0); ptr->bfc = 0; ptr->bfn = 0; } } int dk4utf8_add(dk4_utf8_decoder_t *ptr, unsigned char byte) { int back = DK4_EDSTM_ERROR; #if DK4_USE_ASSERT assert(NULL != ptr); #endif if (NULL != ptr) { switch (ptr->bfc) { case 0: { if (0x7F < byte) { /* more than 1 byte */ if ((0xE0 & byte) == 0xC0) { /* 2 bytes */ ptr->uc = (((dk4_c32_t)byte) << 6) & dkC32(0x000007C0); ptr->bfc = 2; ptr->bfn = 1; back = DK4_EDSTM_ACCEPT; } else { if ((0xF0 & byte) == 0xE0) { /* 3 bytes */ ptr->uc = (((dk4_c32_t)byte) << 12) & dkC32(0x0000F000); ptr->bfc = 3; ptr->bfn = 1; back = DK4_EDSTM_ACCEPT; } else { if ((0xF8 & byte) == 0xF0) { /* 4 bytes */ ptr->uc = (((dk4_c32_t)byte) << 18) & dkC32(0x001C0000); ptr->bfc = 4; ptr->bfn = 1; back = DK4_EDSTM_ACCEPT; } else { if ((0xFC & byte) == 0xF8) { /* 5 bytes */ ptr->uc = ((((dk4_c32_t)byte) << 24) & dkC32(0x03000000)); ptr->bfc = 5; ptr->bfn = 1; back = DK4_EDSTM_ACCEPT; } else { if ((0xFE & byte) == 0xFC) { /* 6 bytes */ ptr->uc = dkC32(0x40000000); ptr->bfc = 6; ptr->bfn = 1; back = DK4_EDSTM_ACCEPT; } else { /* ERROR: Illegal input! */ } } } } } } else { /* just one byte */ ptr->uc = (dk4_c32_t)byte; ptr->uc &= dkC32(0xFF); back = DK4_EDSTM_FINISHED; ptr->bfn = 0; } } break; case 2: { switch (ptr->bfn) { case 1: { if ((0xC0 & byte) == 0x80) { back = DK4_EDSTM_FINISHED; ptr->uc |= (((dk4_c32_t)byte) & dkC32(0x0000003F)); } ptr->bfc = 0; ptr->bfn = 0; } break; } } break; case 3: { switch (ptr->bfn) { case 1: { if ((0xC0 & byte) == 0x80) { back = DK4_EDSTM_ACCEPT; ptr->uc |= ((((dk4_c32_t)byte) << 6) & dkC32(0x00000FC0)); } ptr->bfn = 2; } break; case 2: { if ((0xC0 & byte) == 0x80) { back = DK4_EDSTM_FINISHED; ptr->uc |= (((dk4_c32_t)byte) & dkC32(0x0000003F)); } ptr->bfc = 0; ptr->bfn = 0; } break; } } break; case 4: { switch (ptr->bfn) { case 1: { if ((0xC0 & byte) == 0x80) { back = DK4_EDSTM_ACCEPT; ptr->uc |= ((((dk4_c32_t)byte) << 12) & dkC32(0x0003F000)); } ptr->bfn = 2; } break; case 2: { if ((0xC0 & byte) == 0x80) { back = DK4_EDSTM_ACCEPT; ptr->uc |= ((((dk4_c32_t)byte) << 6) & dkC32(0x00000FC0)); } ptr->bfn = 3; } break; case 3: { if ((0xC0 & byte) == 0x80) { back = DK4_EDSTM_FINISHED; ptr->uc |= (((dk4_c32_t)byte) & dkC32(0x0000003F)); } ptr->bfc = 0; ptr->bfn = 0; } break; } } break; case 5: { switch (ptr->bfn) { case 1: { if ((0xC0 & byte) == 0x80) { back = DK4_EDSTM_ACCEPT; ptr->uc |= ((((dk4_c32_t)byte) << 18) & dkC32(0x00FC0000)); } ptr->bfn = 2; } break; case 2: { if ((0xC0 & byte) == 0x80) { back = DK4_EDSTM_ACCEPT; ptr->uc |= ((((dk4_c32_t)byte) << 12) & dkC32(0x0003F000)); } ptr->bfn = 3; } break; case 3: { if ((0xC0 & byte) == 0x80) { back = DK4_EDSTM_ACCEPT; ptr->uc |= ((((dk4_c32_t)byte) << 6) & dkC32(0x00000FC0)); } ptr->bfn = 4; } break; case 4: { if ((0xC0 & byte) == 0x80) { back = DK4_EDSTM_FINISHED; ptr->uc |= (((dk4_c32_t)byte) & dkC32(0x0000003F)); } ptr->bfc = 0; ptr->bfn = 0; } break; } } break; case 6: { switch (ptr->bfn) { case 1: { if ((0xC0 & byte) == 0x80) { back = DK4_EDSTM_ACCEPT; ptr->uc |= ((((dk4_c32_t)byte) << 24) & dkC32(0x3F000000)); } ptr->bfn = 2; } break; case 2: { if ((0xC0 & byte) == 0x80) { back = DK4_EDSTM_ACCEPT; ptr->uc |= ((((dk4_c32_t)byte) << 18) & dkC32(0x00FC0000)); } ptr->bfn = 3; } break; case 3: { if ((0xC0 & byte) == 0x80) { back = DK4_EDSTM_ACCEPT; ptr->uc |= ((((dk4_c32_t)byte) << 12) & dkC32(0x0003F000)); } ptr->bfn = 4; } break; case 4: { if ((0xC0 & byte) == 0x80) { back = DK4_EDSTM_ACCEPT; ptr->uc |= ((((dk4_c32_t)byte) << 6) & dkC32(0x00000FC0)); } ptr->bfn = 5; } break; case 5: { if ((0xC0 & byte) == 0x80) { back = DK4_EDSTM_FINISHED; ptr->uc |= (((dk4_c32_t)byte) & dkC32(0x0000003F)); } ptr->bfc = 0; ptr->bfn = 0; } break; } } break; } } return back; } dk4_c32_t dk4utf8_get(dk4_utf8_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 dk4utf8_is_empty(dk4_utf8_decoder_t const *ptr) { int back = 0; #if DK4_USE_ASSERT assert(NULL != ptr); #endif if (NULL != ptr) { if (0 == ptr->bfc) { back = 1; } } return back; } int dk4utf8_encode(unsigned char *rb, size_t *pszrb, dk4_c32_t c, dk4_er_t *erp) { int back = 0; #line 401 "dk4utf8.ctr" #if DK4_USE_ASSERT assert(NULL != rb); assert(NULL != pszrb); assert(6 < *pszrb); #endif if ((NULL != rb) && (NULL != pszrb)) { if (6 < *pszrb) { if (dkC32(0x7F) < c) { if (dkC32(0x000007FF) < c) { if (dkC32(0x001FFFFF) < c) { if (dkC32(0x03FFFFFF) < c) { if (dkC32(0x80000000) < c) { /* 6 bytes */ back = 1; *pszrb = 6; rb[0] = ((unsigned char)((c >> 30) & dkC32(0x00000001))) | 0xFC; rb[1] = ((unsigned char)((c >> 24) & dkC32(0x0000003F))) | 0x80; rb[2] = ((unsigned char)((c >> 18) & dkC32(0x0000003F))) | 0x80; rb[3] = ((unsigned char)((c >> 12) & dkC32(0x0000003F))) | 0x80; rb[4] = ((unsigned char)((c >> 6) & dkC32(0x0000003F))) | 0x80; rb[5] = ((unsigned char)( c & dkC32(0x0000003F))) | 0x80; rb[6] = '\0'; } else { /* 5 bytes */ back = 1; *pszrb = 5; rb[0] = ((unsigned char)((c >> 24) & dkC32(0x00000003))) | 0xF8; rb[1] = ((unsigned char)((c >> 18) & dkC32(0x0000003F))) | 0x80; rb[2] = ((unsigned char)((c >> 12) & dkC32(0x0000003F))) | 0x80; rb[3] = ((unsigned char)((c >> 6) & dkC32(0x0000003F))) | 0x80; rb[4] = ((unsigned char)( c & dkC32(0x0000003F))) | 0x80; rb[5] = '\0'; } } else { /* 4 bytes */ back = 1; *pszrb = 4; rb[0] = ((unsigned char)((c >> 18) & dkC32(0x00000007))) | 0xF0; rb[1] = ((unsigned char)((c >> 12) & dkC32(0x0000003F))) | 0x80; rb[2] = ((unsigned char)((c >> 6) & dkC32(0x0000003F))) | 0x80; rb[3] = ((unsigned char)( c & dkC32(0x0000003F))) | 0x80; rb[4] = '\0'; } } else { /* 3 bytes */ back = 1; *pszrb = 3; rb[0] = ((unsigned char)((c >> 12) & dkC32(0x0000000F))) | 0xE0; rb[1] = ((unsigned char)((c >> 6) & dkC32(0x0000003F))) | 0x80; rb[2] = ((unsigned char)( c & dkC32(0x0000003F))) | 0x80; rb[3] = '\0'; } } else { /* 2 bytes */ back = 1; *pszrb = 2; rb[0] = ((unsigned char)((c >> 6) & dkC32(0x0000001F))) | 0xC0; rb[1] = ((unsigned char)( c & dkC32(0x0000003F))) | 0x80; rb[2] = '\0'; } } else { /* 1 byte */ back = 1; *pszrb = 1; rb[0] = (unsigned char)(c & dkC32(0x0000007F)); rb[1] = '\0'; } } else { dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 468 "dk4utf8.ctr" return back; }