2021-01-12 07:11:41 +13:00
/*
libzint - the open source barcode library
2022-06-03 07:32:25 +12:00
Copyright ( C ) 2021 - 2022 Robin Stuart < rstuart114 @ gmail . com >
2021-01-12 07:11:41 +13:00
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions
are met :
1. Redistributions of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
2. Redistributions in binary form must reproduce the above copyright
notice , this list of conditions and the following disclaimer in the
documentation and / or other materials provided with the distribution .
3. Neither the name of the project nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS " AND
ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION )
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT
LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE .
*/
# include "testcommon.h"
# include "test_big5_tab.h"
2022-06-03 07:32:25 +12:00
/* For local "private" testing using previous libiconv adaptation, not included for licensing reasons */
//#define TEST_JUST_SAY_GNO
# ifdef TEST_JUST_SAY_GNO
# include "../just_say_gno/big5_gnu.h"
# endif
INTERNAL int u_big5_test ( const unsigned int u , unsigned char * dest ) ;
// Version of `u_big5()` taking unsigned int destination for backward-compatible testing
static int u_big5_int ( unsigned int u , unsigned int * d ) {
unsigned char dest [ 2 ] ;
int ret = u_big5_test ( u , dest ) ;
if ( ret ) {
* d = ret = = 1 ? dest [ 0 ] : ( ( dest [ 0 ] < < 8 ) | dest [ 1 ] ) ;
}
return ret ;
}
2021-01-12 07:11:41 +13:00
// As control convert to Big5 using simple table generated from https://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT plus simple processing
2022-06-03 07:32:25 +12:00
static int u_big5_int2 ( unsigned int u , unsigned int * dest ) {
2021-01-12 07:11:41 +13:00
int tab_length = ARRAY_SIZE ( test_big5_tab ) ;
2022-06-03 07:32:25 +12:00
int start_i = test_big5_tab_ind [ u > > 10 ] ;
2021-01-12 07:11:41 +13:00
int end_i = start_i + 0x800 > tab_length ? tab_length : start_i + 0x800 ;
2021-06-24 02:00:49 +12:00
int i ;
2022-06-03 07:32:25 +12:00
if ( u < 0x80 ) {
* dest = u ;
return 1 ;
2021-06-24 02:00:49 +12:00
}
for ( i = start_i ; i < end_i ; i + = 2 ) {
2022-06-03 07:32:25 +12:00
if ( test_big5_tab [ i + 1 ] = = u ) {
* dest = test_big5_tab [ i ] ;
return * dest > 0xFF ? 2 : 1 ;
2021-01-12 07:11:41 +13:00
}
}
return 0 ;
}
2022-06-03 07:32:25 +12:00
# include <time.h>
# define TEST_PERF_TIME(arg) (((arg) * 1000.0) / CLOCKS_PER_SEC)
# define TEST_PERF_RATIO(a1, a2) (a2 ? TEST_PERF_TIME(a1) / TEST_PERF_TIME(a2) : 0)
# ifdef TEST_JUST_SAY_GNO
# define TEST_INT_PERF_ITERATIONS 100
# endif
static void test_u_big5_int ( int debug ) {
2021-01-12 07:11:41 +13:00
2021-06-24 02:00:49 +12:00
unsigned int i ;
2021-01-12 07:11:41 +13:00
int ret , ret2 ;
unsigned int val , val2 ;
2022-06-03 07:32:25 +12:00
# ifdef TEST_JUST_SAY_GNO
int j ;
clock_t start ;
clock_t total = 0 , total_gno = 0 ;
# else
( void ) debug ;
# endif
testStart ( " test_u_big5_int " ) ;
# ifdef TEST_JUST_SAY_GNO
if ( ( debug & ZINT_DEBUG_TEST_PERFORMANCE ) ) { /* -d 256 */
printf ( " test_u_big5_int perf iterations: %d \n " , TEST_INT_PERF_ITERATIONS ) ;
}
# endif
2021-06-24 02:00:49 +12:00
for ( i = 0 ; i < 0xFFFE ; i + + ) {
2021-01-12 07:11:41 +13:00
if ( i > = 0xD800 & & i < 0xE000 ) { // UTF-16 surrogates
continue ;
}
val = val2 = 0 ;
2022-06-03 07:32:25 +12:00
ret = u_big5_int ( i , & val ) ;
ret2 = u_big5_int2 ( i , & val2 ) ;
assert_equal ( ret , ret2 , " i:%d 0x%04X ret %d != ret2 %d, val 0x%04X, val2 0x%04X \n " , ( int ) i , i , ret , ret2 , val , val2 ) ;
if ( ret2 ) {
assert_equal ( val , val2 , " i:%d 0x%04X val 0x%04X != val2 0x%04X \n " , ( int ) i , i , val , val2 ) ;
}
# ifdef TEST_JUST_SAY_GNO
if ( ! ( debug & ZINT_DEBUG_TEST_PERFORMANCE ) ) { /* -d 256 */
val2 = 0 ;
ret2 = big5_wctomb_zint ( & val2 , i ) ;
} else {
for ( j = 0 ; j < TEST_INT_PERF_ITERATIONS ; j + + ) {
val = val2 = 0 ;
start = clock ( ) ;
ret = u_big5_int ( i , & val ) ;
total + = clock ( ) - start ;
start = clock ( ) ;
ret2 = big5_wctomb_zint ( & val2 , i ) ;
total_gno + = clock ( ) - start ;
}
}
2021-07-08 00:58:04 +12:00
assert_equal ( ret , ret2 , " i:%d 0x%04X ret %d != ret2 %d, val 0x%04X, val2 0x%04X \n " , ( int ) i , i , ret , ret2 , val , val2 ) ;
2021-01-12 07:11:41 +13:00
if ( ret2 ) {
2021-07-08 00:58:04 +12:00
assert_equal ( val , val2 , " i:%d 0x%04X val 0x%04X != val2 0x%04X \n " , ( int ) i , i , val , val2 ) ;
2021-01-12 07:11:41 +13:00
}
2022-06-03 07:32:25 +12:00
# endif
2021-01-12 07:11:41 +13:00
}
2022-06-03 07:32:25 +12:00
# ifdef TEST_JUST_SAY_GNO
if ( ( debug & ZINT_DEBUG_TEST_PERFORMANCE ) ) { /* -d 256 */
printf ( " test_u_big5_int perf totals: new % 8gms, gno % 8gms ratio %g \n " ,
TEST_PERF_TIME ( total ) , TEST_PERF_TIME ( total_gno ) , TEST_PERF_RATIO ( total , total_gno ) ) ;
}
# endif
2021-01-12 07:11:41 +13:00
testFinish ( ) ;
}
2021-04-20 22:49:14 +12:00
/* Convert UTF-8 string to Big5 and place in array of ints */
static int big5_utf8 ( struct zint_symbol * symbol , const unsigned char source [ ] , int * p_length ,
unsigned int * b5data ) {
int error_number ;
unsigned int i , length ;
# ifndef _MSC_VER
unsigned int utfdata [ * p_length + 1 ] ;
# else
unsigned int * utfdata = ( unsigned int * ) _alloca ( ( * p_length + 1 ) * sizeof ( unsigned int ) ) ;
# endif
error_number = utf8_to_unicode ( symbol , source , utfdata , p_length , 0 /*disallow_4byte*/ ) ;
if ( error_number ! = 0 ) {
return error_number ;
}
for ( i = 0 , length = * p_length ; i < length ; i + + ) {
2022-06-03 07:32:25 +12:00
if ( ! u_big5_int ( utfdata [ i ] , b5data + i ) ) {
2021-04-20 22:49:14 +12:00
strcpy ( symbol - > errtxt , " 800: Invalid character in input data " ) ;
return ZINT_ERROR_INVALID_DATA ;
}
}
return 0 ;
}
static void test_big5_utf8 ( int index ) {
struct item {
char * data ;
int length ;
int ret ;
int ret_length ;
unsigned int expected_b5data [ 20 ] ;
char * comment ;
} ;
// _ U+FF3F fullwidth low line, not in ISO/Win, in Big5 0xA1C4, UTF-8 EFBCBF
// ╴ U+2574 drawings box light left, not in ISO/Win, not in original Big5 but in "Big5-2003" as 0xA15A, UTF-8 E295B4
// s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
struct item data [ ] = {
/* 0*/ { " _ " , - 1 , 0 , 1 , { 0xA1C4 } , " " } ,
2021-06-10 22:15:39 +12:00
/* 1*/ { " ╴ " , - 1 , ZINT_ERROR_INVALID_DATA , - 1 , { 0 } , " " } ,
2021-04-20 22:49:14 +12:00
} ;
2021-06-24 02:00:49 +12:00
int data_size = ARRAY_SIZE ( data ) ;
int i , length , ret ;
2021-04-20 22:49:14 +12:00
2021-07-06 23:13:34 +12:00
struct zint_symbol symbol = { 0 } ;
2021-04-20 22:49:14 +12:00
unsigned int b5data [ 20 ] ;
2021-06-24 02:00:49 +12:00
testStart ( " test_big5_utf8 " ) ;
for ( i = 0 ; i < data_size ; i + + ) {
int ret_length ;
2021-04-20 22:49:14 +12:00
if ( index ! = - 1 & & i ! = index ) continue ;
2021-06-24 02:00:49 +12:00
length = data [ i ] . length = = - 1 ? ( int ) strlen ( data [ i ] . data ) : data [ i ] . length ;
ret_length = length ;
2021-04-20 22:49:14 +12:00
ret = big5_utf8 ( & symbol , ( unsigned char * ) data [ i ] . data , & ret_length , b5data ) ;
assert_equal ( ret , data [ i ] . ret , " i:%d ret %d != %d (%s) \n " , i , ret , data [ i ] . ret , symbol . errtxt ) ;
if ( ret = = 0 ) {
2021-06-24 02:00:49 +12:00
int j ;
2021-04-20 22:49:14 +12:00
assert_equal ( ret_length , data [ i ] . ret_length , " i:%d ret_length %d != %d \n " , i , ret_length , data [ i ] . ret_length ) ;
2021-06-24 02:00:49 +12:00
for ( j = 0 ; j < ret_length ; j + + ) {
2021-04-20 22:49:14 +12:00
assert_equal ( b5data [ j ] , data [ i ] . expected_b5data [ j ] , " i:%d b5data[%d] %04X != %04X \n " , i , j , b5data [ j ] , data [ i ] . expected_b5data [ j ] ) ;
}
}
}
testFinish ( ) ;
}
2021-01-12 07:11:41 +13:00
int main ( int argc , char * argv [ ] ) {
testFunction funcs [ ] = { /* name, func, has_index, has_generate, has_debug */
2022-06-03 07:32:25 +12:00
{ " test_u_big5_int " , test_u_big5_int , 0 , 0 , 1 } ,
2021-04-20 22:49:14 +12:00
{ " test_big5_utf8 " , test_big5_utf8 , 1 , 0 , 0 } ,
2021-01-12 07:11:41 +13:00
} ;
testRun ( argc , argv , funcs , ARRAY_SIZE ( funcs ) ) ;
testReport ( ) ;
return 0 ;
}
2022-06-03 07:32:25 +12:00
/* vim: set ts=4 sw=4 et : */