/* 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: dk4a85d.ctr */ /** @file dk4a85d.c The dk4a85d module. */ #line 137 "dk4a85d.ctr" #include "dk4conf.h" #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif #include "dk4a85d.h" #include "dk4mem.h" #include "dk4edstm.h" #line 154 "dk4a85d.ctr" /** Powers of 85. */ static const unsigned long dk4a85e_pow_85[] = { (85UL * 85UL * 85UL * 85UL), (85UL * 85UL * 85UL), (85UL * 85UL), 85UL }; void dk4a85_dec_init(dk4_a85_dec_t *dec, dk4_er_t *erp) { #if DK4_USE_ASSERT assert(NULL != dec); #endif if (NULL != dec) { DK4_MEMRES(dec, sizeof(dk4_a85_dec_t)); dec->os = 0; dec->is = 0; dec->tf = 0; } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } } int dk4a85_dec_add(dk4_a85_dec_t *dec, char input, dk4_er_t *erp) { unsigned long val; int back = DK4_EDSTM_ERROR; #if DK4_USE_ASSERT assert(NULL != dec); #endif if (NULL != dec) { if (0 != dec->tf) { if ('>' == input) { back = DK4_EDSTM_STOP; } else { dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } else { switch (input) { case ' ' : case '\t' : case '\r' : case '\n' : case 0x00 : case 0x0C : { back = DK4_EDSTM_ACCEPT; } break; case '~' : { back = DK4_EDSTM_ACCEPT; dec->tf = 1; } break; case 'z' : { if (0 == dec->is) { dec->ob[0] = 0x00; dec->ob[1] = 0x00; dec->ob[2] = 0x00; dec->ob[3] = 0x00; dec->os = 4; back = DK4_EDSTM_FINISHED; } else { dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } break; default : { if (((char)32 < input) && ((char)118 > input)) { dec->ib[dec->is] = input; dec->is += 1; back = DK4_EDSTM_ACCEPT; if (5 <= dec->is) { val = dk4a85e_pow_85[0] * ((unsigned long)((unsigned char)(dec->ib[0] - (char)33)) & 0xFFUL) + dk4a85e_pow_85[1] * ((unsigned long)((unsigned char)(dec->ib[1] - (char)33)) & 0xFFUL) + dk4a85e_pow_85[2] * ((unsigned long)((unsigned char)(dec->ib[2] - (char)33)) & 0xFFUL) + dk4a85e_pow_85[3] * ((unsigned long)((unsigned char)(dec->ib[3] - (char)33)) & 0xFFUL) + ((unsigned long)((unsigned char)(dec->ib[4] - (char)33)) & 0xFFUL) ; dec->ob[0] = (unsigned char)((val >> 24) & 0xFFUL); dec->ob[1] = (unsigned char)((val >> 16) & 0xFFUL); dec->ob[2] = (unsigned char)((val >> 8) & 0xFFUL); dec->ob[3] = (unsigned char)((val ) & 0xFFUL); dec->is = 0; dec->os = 4; back = DK4_EDSTM_FINISHED; } } else { dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } break; } } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; } /* During encoding sequences of 4 binary bytes b1, b2, b3, and b4 are converted to five base-85 values a1, a2, a3, a4, and a5 fullfilling the equation v=b1*256^3+b2*256^2+b3*256+b4=a1*85^4+a2*85^3+a3*85^2+a4*85+a5 For complete sequences encoding and decoding are straightforward. For an incomplete final sequence of n binary bytes (1<=n<=3), only n+1 a values are encoded. In the example we assume a 2 byte sequence b1 and b2. The value v is calculated as v=b1*256^3+b2*256^2+0*256+0=a1*85^4+a2*85^3+a3*85^2+a4*85+a5. As we have 2 binary bytes, 3 text coefficients a1, a2, and a3 are written to encoded output, a4 and a5 are skipped. From these 3 coefficients the decoder can calculate v'=a1*85^4+a2*85^3+a3*85^2+0*85+0 which we can split into v'=b1'*256^3+b2'*256^2+b3'*256+b4' Obviously v' is less than or equal to v because v'=v-a4*85-a5. We have v=v' only if a4=0 and a5=0, this results in b3=0 and b4=0. Otherwise we have v>v'. As the final 2 bytes of v are zero, decreasing v to v' results in a non-zero value in the final 2 bytes and a decrease by 1 in the first 2 bytes. So if v' & 0x0000FFFF is nonzero we have to calculate v = v' + 0x00010000 before splitting v into b1, b2, b3, and b4. */ int dk4a85_dec_finish(dk4_a85_dec_t *dec, dk4_er_t *erp) { unsigned long val; /* 32 bit value */ int back = DK4_EDSTM_ERROR; #line 302 "dk4a85d.ctr" #if DK4_USE_ASSERT assert(NULL != dec); #endif if (NULL != dec) { if (0 == dec->is) { back = DK4_EDSTM_ACCEPT; } else { switch (dec->is) { case 4: { #line 311 "dk4a85d.ctr" /* Calculate 32 bit value from encoded values. */ val = dk4a85e_pow_85[0] * ((unsigned long)((unsigned char)(dec->ib[0] - (char)33)) & 0xFFUL) + dk4a85e_pow_85[1] * ((unsigned long)((unsigned char)(dec->ib[1] - (char)33)) & 0xFFUL) + dk4a85e_pow_85[2] * ((unsigned long)((unsigned char)(dec->ib[2] - (char)33)) & 0xFFUL) + dk4a85e_pow_85[3] * ((unsigned long)((unsigned char)(dec->ib[3] - (char)33)) & 0xFFUL) ; #line 327 "dk4a85d.ctr" /* Check whether truncation of a5 modified the 32 bit value, correct least significant used byte if necessary. */ if (0UL != (val & 0x000000FFUL)) { val += 0x00000100UL; } /* Split 32 bit value into bytes. */ #line 336 "dk4a85d.ctr" dec->ob[0] = (unsigned char)((val >> 24) & 0xFFUL); dec->ob[1] = (unsigned char)((val >> 16) & 0xFFUL); dec->ob[2] = (unsigned char)((val >> 8) & 0xFFUL); /* Set input size, output size and result. */ dec->is = 0; dec->os = 3; back = DK4_EDSTM_FINISHED; } break; case 3: { #line 346 "dk4a85d.ctr" /* Calculate 32 bit value from encoded values. */ val = dk4a85e_pow_85[0] * ((unsigned long)((unsigned char)(dec->ib[0] - (char)33)) & 0xFFUL) + dk4a85e_pow_85[1] * ((unsigned long)((unsigned char)(dec->ib[1] - (char)33)) & 0xFFUL) + dk4a85e_pow_85[2] * ((unsigned long)((unsigned char)(dec->ib[2] - (char)33)) & 0xFFUL) ; #line 359 "dk4a85d.ctr" /* Check whether truncation of a4 and a5 modified the 32 bit value, correct least significant used byte if necessary. */ if (0UL != (val & 0x0000FFFFUL)) { val += 0x00010000UL; } #line 366 "dk4a85d.ctr" /* Split 32 bit value into bytes. */ dec->ob[0] = (unsigned char)((val >> 24) & 0xFFUL); dec->ob[1] = (unsigned char)((val >> 16) & 0xFFUL); /* Set input size, output size and result. */ dec->is = 0; dec->os = 2; back = DK4_EDSTM_FINISHED; } break; case 2: { #line 377 "dk4a85d.ctr" /* Calculate 32 bit value from encoded values. */ val = dk4a85e_pow_85[0] * ((unsigned long)((unsigned char)(dec->ib[0] - (char)33)) & 0xFFUL) + dk4a85e_pow_85[1] * ((unsigned long)((unsigned char)(dec->ib[1] - (char)33)) & 0xFFUL) ; #line 387 "dk4a85d.ctr" /* Check whether truncation of a3, a4, and a5 modified the 32 bit value, correct least significant used byte if necessary. */ if (0UL != (val & 0x00FFFFFFUL)) { val += 0x01000000UL; } #line 394 "dk4a85d.ctr" /* Split 32 bit value into bytes. */ dec->ob[0] = (unsigned char)((val >> 24) & 0xFFUL); /* Set input size, output size and result. */ dec->is = 0; dec->os = 1; back = DK4_EDSTM_FINISHED; } break; default: { dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } break; } } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 411 "dk4a85d.ctr" return back; } int dk4a85_dec_output( const unsigned char **dptr, size_t *szptr, dk4_a85_dec_t const *dec, dk4_er_t *erp ) { int back = 0; #if DK4_USE_ASSERT assert(NULL != dec); assert(NULL != dptr); assert(NULL != szptr); #endif if ((NULL != dec) && (NULL != dptr) && (NULL != szptr)) { if (0 < dec->os) { *dptr = &(dec->ob[0]); *szptr = dec->os; back = 1; } else { *dptr = NULL; *szptr = 0; back = 0; } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; }