1
/* ccv.c --- charset conversion
2
* by Hirotsugu Kakugawa
5
* 20 Jan 1999 Added to check /usr/local/share/site/
6
* 16 Feb 1999 Added encoding conversion funcs for Row-Cell and WangSung.
7
* 14 Sep 1999 Added alias for charset & encoding names (but not tested yet)
10
* Copyright (C) 1997-1999 Hirotsugu Kakugawa.
11
* All rights reserved.
13
* This file is part of the VFlib Library. This library is free
14
* software; you can redistribute it and/or modify it under the terms of
15
* the GNU Library General Public License as published by the Free
16
* Software Foundation; either version 2 of the License, or (at your
17
* option) any later version. This library is distributed in the hope
18
* that it will be useful, but WITHOUT ANY WARRANTY; without even the
19
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20
* PURPOSE. See the GNU Library General Public License for more details.
21
* You should have received a copy of the GNU Library General Public
22
* License along with this library; if not, write to the Free Software
23
* Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33
#include <sys/types.h>
34
#include <sys/param.h>
36
#include "VFlib-3_6.h"
44
#define NAMEPP(s) ((s!=NULL)?s:"*")
46
#define CS_NAME_XCHARS ".-_ "
47
#define CS_NAME_XCHARS_TO '_'
49
#define CCV_TBL_INITIAL_SIZE 32
50
static int ccv_tbl_index = 0;
51
static int ccv_tbl_size = 0;
52
static struct s_ccv_info *ccv_tbl = NULL;
54
Private int ccv_add_conv_info(struct s_ccv_info*,int,char*);
55
Private int ccv_load(struct s_ccv_info *ccvi);
56
Private int ccv_read_header(struct s_ccv_info *ccvi);
57
Private void ccv_read_aliases(FILE *fp, char ***oalias_tbl);
58
Private int ccv_read_file(struct s_ccv_info *ccvi,int);
59
Private int ccv_read_file_alloc_blocks(struct s_ccv_info *);
60
Private int ccv_read_file_block_array(FILE*, struct s_ccv_info*, int);
61
Private int ccv_read_file_block_random_array(FILE*, struct s_ccv_info*, int);
62
Private int ccv_file_read_list(FILE *fp, char *buff, int nbuff);
63
Private int ccv_file_read_elem(FILE *fp, char *buff, int nbuff);
65
Private char *make_canonical_charset_name(char*);
66
Private int cmp_alias(char **alias_tbl, char *name, int how_compare);
67
Private int cmp_charset_name(char*,char*);
68
Private int cmp_enc_name(char*,char*);
70
Private long ccv_conv_array(int,long);
71
Private long ccv_conv_random_array(int,long);
72
Private long ccv_no_conv(int ccvi_index, long code_point);
73
Private long ccv_jis2kuten(int ccvi_index, long code_point);
74
Private long ccv_jis2euc(int ccvi_index, long code_point);
75
Private long ccv_jis2sjis(int ccvi_index, long code_point);
76
Private long ccv_kuten2jis(int ccvi_index, long code_point);
77
Private long ccv_euc2jis(int ccvi_index, long code_point);
78
Private long ccv_euc2sjis(int ccvi_index, long code_point);
79
Private long ccv_sjis2jis(int ccvi_index, long code_point);
80
Private long ccv_wansung2rc(int ccvi_index, long code_point);
81
Private long ccv_rc2wansung(int ccvi_index, long code_point);
82
Private long ccv_jis2seq2_0(int ccvi_index, long code_point);
83
Private long ccv_jis2seq2_1(int ccvi_index, long code_point);
90
static struct s_ccv_info *ccv_tbl_new;
92
if (ccv_tbl == NULL){ /* initialization */
94
ccv_tbl_size = CCV_TBL_INITIAL_SIZE;
95
ALLOCN_IF_ERR(ccv_tbl, struct s_ccv_info, ccv_tbl_size){
97
vf_error = VF_ERR_NO_MEMORY;
101
vf_ccv_install_func(NULL, "ISO", NULL, "ISO", ccv_no_conv);
102
vf_ccv_install_func(NULL, "ISO2022", NULL, "ISO2022", ccv_no_conv);
103
vf_ccv_install_func(NULL, "UNICODE", NULL, "UNICODE", ccv_no_conv);
104
vf_ccv_install_func(NULL, "JIS", NULL, "JIS", ccv_no_conv);
105
vf_ccv_install_func(NULL, "SJIS", NULL, "SJIS", ccv_no_conv);
107
vf_ccv_install_func(NULL, "JIS", NULL, "SJIS", ccv_jis2sjis);
108
vf_ccv_install_func(NULL, "ISO2022", NULL, "SJIS", ccv_jis2sjis);
109
vf_ccv_install_func(NULL, "SJIS", NULL, "JIS", ccv_sjis2jis);
110
vf_ccv_install_func(NULL, "SJIS", NULL, "ISO2022", ccv_sjis2jis);
111
vf_ccv_install_func(NULL, "EUC", NULL, "JIS", ccv_euc2jis);
112
vf_ccv_install_func(NULL, "EUC", NULL, "ISO2022", ccv_euc2jis);
113
vf_ccv_install_func(NULL, "EUC", NULL, "SJIS", ccv_euc2sjis);
114
vf_ccv_install_func(NULL, "KU-TEN", NULL, "JIS", ccv_kuten2jis);
115
vf_ccv_install_func(NULL, "ROW-CELL", NULL, "JIS", ccv_kuten2jis);
116
vf_ccv_install_func(NULL, "KU-TEN", NULL, "ISO2022", ccv_kuten2jis);
117
vf_ccv_install_func(NULL, "ROW-CELL", NULL, "ISO2022", ccv_kuten2jis);
118
vf_ccv_install_func(NULL, "JIS", NULL, "ROW-CELL", ccv_jis2kuten);
119
vf_ccv_install_func(NULL, "ISO2022", NULL, "ROW-CELL", ccv_jis2kuten);
120
vf_ccv_install_func(NULL, "JIS", NULL, "KU-TEN", ccv_jis2kuten);
121
vf_ccv_install_func(NULL, "ISO2022", NULL, "KU-TEN", ccv_jis2kuten);
122
vf_ccv_install_func(NULL, "JIS", NULL, "SEQUENTIAL2-0",ccv_jis2seq2_0);
123
vf_ccv_install_func(NULL, "ISO2022",NULL, "SEQUENTIAL2-0",ccv_jis2seq2_0);
124
vf_ccv_install_func(NULL, "JIS", NULL, "SEQUENTIAL2-1",ccv_jis2seq2_1);
125
vf_ccv_install_func(NULL, "ISO2022",NULL, "SEQUENTIAL2-1",ccv_jis2seq2_1);
127
vf_ccv_install_func(NULL, "ISO2022", NULL, "WANSUNG", ccv_jis2euc);
128
vf_ccv_install_func(NULL, "JIS", NULL, "WANSUNG", ccv_jis2euc);
129
vf_ccv_install_func(NULL, "ROW-CELL", NULL, "WANSUNG", ccv_rc2wansung);
130
vf_ccv_install_func(NULL, "KU-TEN", NULL, "WANSUNG", ccv_rc2wansung);
131
vf_ccv_install_func(NULL, "WANSUNG", NULL, "ROW-CELL", ccv_wansung2rc);
132
vf_ccv_install_func(NULL, "WANSUNG", NULL, "KU-TEN", ccv_wansung2rc);
138
new_size = ccv_tbl_size + 8;
139
ALLOCN_IF_ERR(ccv_tbl_new, struct s_ccv_info, new_size){
142
for (i = 0; i < ccv_tbl_index; i++){
143
memcpy(&ccv_tbl_new[i], &ccv_tbl[i], sizeof(struct s_ccv_info));
146
ccv_tbl_size = new_size;
147
ccv_tbl = ccv_tbl_new;
154
ccv_no_conv(int ccvi_index, long code_point)
160
ccv_jis2kuten(int ccvi_index, long code_point)
164
if (code_point < 256)
166
c1 = code_point / 0x100;
167
c2 = code_point % 0x100;
168
return (c1 - 0x20)*0x100 + (c2 - 0x20);
172
ccv_jis2euc(int ccvi_index, long code_point)
176
if (code_point < 256)
178
c1 = code_point / 0x100;
179
c2 = code_point % 0x100;
180
return (c1 + 0x80)*0x100 + (c2 + 0x80);
184
ccv_jis2sjis(int ccvi_index, long code_point)
187
int row_offset, cell_offset;
189
if (code_point < 256)
191
/* Snarfed from 'jis2sjis()' in UJIP by Ken R Lunde. */
192
c1 = code_point / 0x100;
193
c2 = code_point % 0x100;
194
row_offset = (c1 < 95) ? 112 : 176;
195
cell_offset = (c1 % 2) ? ((c2 > 95) ? 32 : 31) : 126;
196
c1 = ((c1 + 1) >> 1) + row_offset;
198
return c1*0x100 + c2;
202
ccv_kuten2jis(int ccvi_index, long code_point)
206
if (code_point < 256)
208
c1 = code_point / 0x100;
209
c2 = code_point % 0x100;
210
return (c1 + 0x20)*0x100 + (c2 + 0x20);
214
ccv_euc2jis(int ccvi_index, long code_point)
218
if (code_point < 256)
220
c1 = code_point / 0x100;
221
c2 = code_point % 0x100;
222
return (c1 - 0x80)*0x100 + (c2 - 0x80);
226
ccv_euc2sjis(int ccvi_index, long code_point)
230
code_point_jis = ccv_euc2jis(ccvi_index, code_point);
231
return ccv_jis2sjis(ccvi_index, code_point_jis);
235
ccv_sjis2jis(int ccvi_index, long code_point)
238
int row_offset, cell_offset, adjust;
240
if (code_point < 256)
242
/* Snarfed from 'sjis2jis()' in UJIP by Ken R Lunde. */
243
c1 = code_point / 0x100;
244
c2 = code_point % 0x100;
249
row_offset = (c1 < 160) ? 112 : 176;
250
cell_offset = (adjust == 1) ? ((c2 > 127) ? 32 : 31) : 126;
251
c1 = ((c1 - row_offset) << 1) - adjust;
253
return c1*0x100 + c2;
257
ccv_rc2wansung(int ccvi_index, long code_point)
261
if (code_point < 256)
263
c1 = code_point / 0x100;
264
c2 = code_point % 0x100;
265
return (c1 + 0xa0)*0x100 + (c2 + 0xa0);
269
ccv_wansung2rc(int ccvi_index, long code_point)
273
if (code_point < 256)
275
c1 = code_point / 0x100;
276
c2 = code_point % 0x100;
277
return (c1 - 0xa0)*0x100 + (c2 - 0xa0);
282
ccv_jis2seq2_0(int ccvi_index, long code_point)
286
b0 = (code_point / 0x1) % 0x100;
287
b1 = (code_point / 0x100) % 0x100;
289
if ((b0 < 0x21) || (b0 > 0x7e))
291
if ((b1 < 0x21) || (b1 > 0x7e))
294
return 94 * (b1-0x21) + (b0-0x21) + 0;
298
ccv_jis2seq2_1(int ccvi_index, long code_point)
302
b0 = (code_point / 0x1) % 0x100;
303
b1 = (code_point / 0x100) % 0x100;
305
if ((b0 < 0x21) || (b0 > 0x7e))
307
if ((b1 < 0x21) || (b1 > 0x7e))
310
return 94 * (b1-0x21) + (b0-0x21) + 1;
316
vf_ccv_require(char *cs1_name, char *cs1_enc,
317
char *cs2_name, char *cs2_enc)
322
printf(">> CCV searching conversion: %s %s => %s %s\n",
323
NAMEPP(cs1_name), NAMEPP(cs1_enc),
324
NAMEPP(cs2_name), NAMEPP(cs2_enc));
326
if ((cs1_name == NULL) && (cs1_enc == NULL))
329
for (i = 0; i < ccv_tbl_index; i++){
330
if ( ((ccv_tbl[i].cs1_name == NULL)
331
|| (cmp_charset_name(ccv_tbl[i].cs1_name, cs1_name) == 0)
332
|| (cmp_alias(ccv_tbl[i].cs1_name_aliases, cs1_name, 0) == 0))
333
&& ((ccv_tbl[i].cs2_name == NULL)
334
|| (cmp_charset_name(ccv_tbl[i].cs2_name, cs2_name) == 0)
335
|| (cmp_alias(ccv_tbl[i].cs2_name_aliases, cs2_name, 0) == 0))
336
&& ((ccv_tbl[i].cs1_enc == NULL) || (cs1_enc == NULL)
337
|| (cmp_enc_name(ccv_tbl[i].cs1_enc, cs1_enc) == 0)
338
|| (cmp_alias(ccv_tbl[i].cs1_enc_aliases, cs1_enc, 1) == 0))
339
&& ((ccv_tbl[i].cs2_enc == NULL) || (cs2_enc == NULL)
340
|| (cmp_enc_name(ccv_tbl[i].cs2_enc, cs2_enc) == 0)
341
|| (cmp_alias(ccv_tbl[i].cs2_enc_aliases, cs2_enc, 1) == 0)) ){
342
if (vf_dbg_ccv == 1){
343
printf(">> CCV use conversion #%d [%s %s => %s %s]\n", i,
344
NAMEPP(ccv_tbl[i].cs1_name), NAMEPP(ccv_tbl[i].cs1_enc),
345
NAMEPP(ccv_tbl[i].cs2_name), NAMEPP(ccv_tbl[i].cs2_enc));
347
if (ccv_tbl[i].load_stat == CCV_STAT_AUTOLOAD){
348
if (ccv_load(&ccv_tbl[i]) < 0)
350
ccv_tbl[i].load_stat = CCV_STAT_LOADED;
359
cmp_alias(char **alias_tbl, char *name, int how_compare)
363
if (alias_tbl == NULL)
366
if (how_compare == 0){
367
for (pp = alias_tbl; *pp != NULL; pp++){
368
if (cmp_charset_name(*pp, name) == 0)
372
for (pp = alias_tbl; *pp != NULL; pp++){
373
if (cmp_enc_name(*pp, name) == 0)
383
ccv_add_conv_info(struct s_ccv_info *ccvi,
384
int load_stat, char *file_name)
388
if (ccv_tbl_index >= ccv_tbl_size){
390
printf(">> CCV expand table\n");
391
if (vf_ccv_init() < 0){
392
fprintf(stderr, "VFlib: too many code coversion table.\n");
397
ccv_tbl[ccv_tbl_index].cs1_name = ccvi->cs1_name;
398
ccv_tbl[ccv_tbl_index].cs1_name_aliases = ccvi->cs1_name_aliases;
399
ccv_tbl[ccv_tbl_index].cs1_enc = ccvi->cs1_enc;
400
ccv_tbl[ccv_tbl_index].cs1_enc_aliases = ccvi->cs1_enc_aliases;
401
ccv_tbl[ccv_tbl_index].cs2_name = ccvi->cs2_name;
402
ccv_tbl[ccv_tbl_index].cs2_name_aliases = ccvi->cs2_name_aliases;
403
ccv_tbl[ccv_tbl_index].cs2_enc = ccvi->cs2_enc;
404
ccv_tbl[ccv_tbl_index].cs2_enc_aliases = ccvi->cs2_enc_aliases;
405
ccv_tbl[ccv_tbl_index].block_size = ccvi->block_size;
406
ccv_tbl[ccv_tbl_index].load_stat = load_stat;
407
ccv_tbl[ccv_tbl_index].conv = ccvi->conv;
408
ccv_tbl[ccv_tbl_index].arg = ccvi->arg;
409
ccv_tbl[ccv_tbl_index].arg_type = ccvi->arg_type;
410
ccv_tbl[ccv_tbl_index].c1min = ccvi->c1min;
411
ccv_tbl[ccv_tbl_index].c1max = ccvi->c1max;
412
ccv_tbl[ccv_tbl_index].c2min = ccvi->c2min;
413
ccv_tbl[ccv_tbl_index].c2max = ccvi->c2max;
414
ccv_tbl[ccv_tbl_index].nblocks = ccvi->nblocks;
415
if (file_name != NULL){
416
ccv_tbl[ccv_tbl_index].file_name = vf_strdup(file_name);
417
if (ccv_tbl[ccv_tbl_index].file_name == NULL){
418
vf_error = VF_ERR_NO_MEMORY;
422
ccv_tbl[ccv_tbl_index].file_name = NULL;
425
if (vf_dbg_ccv == 1){
426
printf(">> CCV installed #%d [%s %s => %s %s]\n",
428
NAMEPP(ccv_tbl[ccv_tbl_index].cs1_name),
429
NAMEPP(ccv_tbl[ccv_tbl_index].cs1_enc),
430
NAMEPP(ccv_tbl[ccv_tbl_index].cs2_name),
431
NAMEPP(ccv_tbl[ccv_tbl_index].cs2_enc));
432
if ((pp = ccv_tbl[ccv_tbl_index].cs1_name_aliases) != NULL){
433
q = NAMEPP(ccv_tbl[ccv_tbl_index].cs1_name);
434
for ( ; *pp != NULL; pp++)
435
printf(">> alias %s: %s\n", *pp, q);
437
if ((pp = ccv_tbl[ccv_tbl_index].cs1_enc_aliases) != NULL){
438
q = NAMEPP(ccv_tbl[ccv_tbl_index].cs1_enc);
439
for ( ; *pp != NULL; pp++)
440
printf(">> alias %s: %s\n", *pp, q);
442
if ((pp = ccv_tbl[ccv_tbl_index].cs2_name_aliases) != NULL){
443
q = NAMEPP(ccv_tbl[ccv_tbl_index].cs2_name);
444
for ( ; *pp != NULL; pp++)
445
printf(">> alias %s: %s\n", *pp, q);
447
if ((pp = ccv_tbl[ccv_tbl_index].cs2_enc_aliases) != NULL){
448
q = NAMEPP(ccv_tbl[ccv_tbl_index].cs2_enc);
449
for ( ; *pp != NULL; pp++)
450
printf(">> alias %s: %s\n", *pp, q);
459
make_canonical_charset_name(char *cs_name)
466
if ((canon = vf_strdup(cs_name)) == NULL)
468
for (p = canon; *p != '\0'; p++){
469
if (vf_index(CS_NAME_XCHARS, *p) != NULL)
470
*p = CS_NAME_XCHARS_TO;
478
cmp_charset_name(char *canon, char *name)
489
if (vf_index(CS_NAME_XCHARS, *p) != NULL)
490
cp = CS_NAME_XCHARS_TO;
492
if (vf_index(CS_NAME_XCHARS, *q) != NULL)
493
cq = CS_NAME_XCHARS_TO;
498
} while ((*p != '\0') && (*q != '\0'));
503
cmp_enc_name(char *enc1, char *enc2)
511
if (vf_index(CS_NAME_XCHARS, *p) != NULL)
512
cp = CS_NAME_XCHARS_TO;
514
if (vf_index(CS_NAME_XCHARS, *q) != NULL)
515
cq = CS_NAME_XCHARS_TO;
520
} while ((*p != '\0') && (*q != '\0'));
527
vf_ccv_autoload(char *file_name)
529
struct s_ccv_info ccv_info;
532
printf(">> CCV autoload: %s\n", file_name);
534
ccv_info.file_name = vf_strdup(file_name);
536
if (ccv_read_header(&ccv_info) < 0){
538
printf(">> CCV failed autoload\n");
543
printf(" %s %s => %s %s 0x%02x 0x%02x 0x%02x 0x%02x\n",
544
ccv_info.cs1_name, ccv_info.cs1_enc,
545
ccv_info.cs2_name, ccv_info.cs2_enc,
546
ccv_info.c1min, ccv_info.c1max, ccv_info.c2min, ccv_info.c2max);
549
ccv_add_conv_info(&ccv_info, CCV_STAT_AUTOLOAD, file_name);
552
printf(">> CCV autoload done.\n");
559
vf_ccv_install_func(char *cs1_name, char *cs1_enc,
560
char *cs2_name, char *cs2_enc,
561
long (*conv)(int,long))
563
struct s_ccv_info ccv_info;
565
ccv_info.cs1_name = cs1_name;
566
ccv_info.cs1_name_aliases = NULL;
567
ccv_info.cs1_enc = cs1_enc;
568
ccv_info.cs1_enc_aliases = NULL;
569
ccv_info.cs2_name = cs2_name;
570
ccv_info.cs2_name_aliases = NULL;
571
ccv_info.cs2_enc = cs2_enc;
572
ccv_info.cs2_enc_aliases = NULL;
573
ccv_info.arg_type = CCV_ARG_TYPE_FUNC;
574
ccv_info.conv = conv;
577
ccv_info.block_size = 0;
582
ccv_info.nblocks = 0;
583
ccv_info.file_name = NULL;
585
ccv_add_conv_info(&ccv_info, CCV_STAT_LOADED, NULL);
592
ccv_load(struct s_ccv_info *ccvi)
595
printf(">> CCV loading %s\n", ccvi->file_name);
597
return ccv_read_file(ccvi, 0);
601
ccv_read_header(struct s_ccv_info *ccvi)
603
return ccv_read_file(ccvi, 1);
607
ccv_read_file(struct s_ccv_info *ccvi, int header_only)
610
char key[256], val[256];
613
ccvi->file_path = vf_path_find_runtime_file("ccv", ccvi->file_name,
616
if (vf_dbg_ccv == 1){
617
if (ccvi->file_path != NULL)
618
printf(">> CCV autoload file %s: %s\n",
619
ccvi->file_name, ccvi->file_path);
621
printf(">> CCV autoload file %s: not found\n", ccvi->file_name);
624
if (ccvi->file_path == NULL)
627
if ((fp = vf_fm_OpenTextFileStream(ccvi->file_path)) == NULL)
630
if (header_only == 1){
631
ccvi->cs1_name_aliases = NULL;
632
ccvi->cs1_enc_aliases = NULL;
633
ccvi->cs2_name_aliases = NULL;
634
ccvi->cs2_enc_aliases = NULL;
637
while (ccv_file_read_list(fp, key, sizeof(key)) >= 0){
638
v = ccv_file_read_elem(fp, val, sizeof(val));
643
if (( (vf_strcmp_ci(key, "charset-from-name") == 0)
644
|| (vf_strcmp_ci(key, "charset-external-name") == 0))
645
&& (header_only == 1)){
646
ccvi->cs1_name = make_canonical_charset_name(val);
647
ccv_read_aliases(fp, &ccvi->cs1_name_aliases);
648
} else if (( (vf_strcmp_ci(key, "charset-from-encoding") == 0)
649
|| (vf_strcmp_ci(key, "charset-external-encoding") == 0))
650
&& (header_only == 1)){
651
ccvi->cs1_enc = vf_strdup(val);
652
ccv_read_aliases(fp, &ccvi->cs1_enc_aliases);
653
} else if (( (vf_strcmp_ci(key, "charset-to-name") == 0)
654
|| (vf_strcmp_ci(key, "charset-internal-name") == 0))
655
&& (header_only == 1)){
656
ccvi->cs2_name = make_canonical_charset_name(val);
657
ccv_read_aliases(fp, &ccvi->cs2_name_aliases);
658
} else if (( (vf_strcmp_ci(key, "charset-to-encoding") == 0)
659
|| (vf_strcmp_ci(key, "charset-internal-encoding") == 0))
660
&& (header_only == 1)){
661
ccvi->cs2_enc = vf_strdup(val);
662
ccv_read_aliases(fp, &ccvi->cs2_enc_aliases);
663
} else if ((vf_strcmp_ci(key, "table-type") == 0)
664
&& (header_only == 1)){
666
if (vf_strcmp_ci(val, "array") == 0){
667
ccvi->arg_type = CCV_ARG_TYPE_ARRAY;
668
ccvi->conv = ccv_conv_array;
669
} else if (vf_strcmp_ci(val, "random-arrays") == 0){
670
ccvi->arg_type = CCV_ARG_TYPE_RANDOM_ARRAY;
671
ccvi->conv = ccv_conv_random_array;
673
fprintf(stderr, "VFlib: broken code conversion file: %s\n",
677
} else if ((vf_strcmp_ci(key, "nblocks") == 0) && (header_only == 1)){
678
sscanf(val, "%i", &ccvi->nblocks);
679
} else if ((vf_strcmp_ci(key, "c1-min") == 0) && (header_only == 1)){
680
sscanf(val, "%i", &ccvi->c1min);
681
} else if ((vf_strcmp_ci(key, "c1-max") == 0) && (header_only == 1)){
682
sscanf(val, "%i", &ccvi->c1max);
683
} else if ((vf_strcmp_ci(key, "c2-min") == 0) && (header_only == 1)){
684
sscanf(val, "%i", &ccvi->c2min);
685
} else if ((vf_strcmp_ci(key, "c2-max") == 0) && (header_only == 1)){
686
sscanf(val, "%i", &ccvi->c2max);
687
} else if ((vf_strcmp_ci(key, "block-size") == 0) && (header_only == 1)){
688
sscanf(val, "%i", &ccvi->block_size);
689
} else if (vf_strcmp_ci(key, "block") == 0){
690
if (header_only == 1){
693
ccv_read_file_alloc_blocks(ccvi);
694
sscanf(val, "%i", &block);
695
if (ccvi->arg_type == CCV_ARG_TYPE_ARRAY){
696
ccv_read_file_block_array(fp, ccvi, block);
698
ccv_read_file_block_random_array(fp, ccvi, block);
708
ccv_read_aliases(FILE *fp, char ***alias_tbl)
715
while (ccv_file_read_elem(fp, val, sizeof(val)) > 0){
716
names[nnames++] = vf_strdup(val);
723
if ((*alias_tbl = (char**)malloc(sizeof(char*) * (nnames + 1))) != NULL){
724
for (i = 0; i < nnames; i++){
725
(*alias_tbl)[i] = names[i];
727
(*alias_tbl)[nnames] = NULL;
732
ccv_read_file_alloc_blocks(struct s_ccv_info *ccvi)
735
CCV_RANDOM_ARRAY rarray;
737
switch (ccvi->arg_type){
738
case CCV_ARG_TYPE_ARRAY:
739
array = (long*)calloc(ccvi->nblocks * (ccvi->c2max - ccvi->c2min + 1),
743
ccvi->arg = (long)array;
745
case CCV_ARG_TYPE_RANDOM_ARRAY:
747
rarray = (CCV_RANDOM_ARRAY)calloc(1, sizeof(struct s_ccv_random_array));
751
= (int*)calloc(ccvi->nblocks, sizeof(int));
753
= (long*)calloc(ccvi->nblocks * (ccvi->c2max - ccvi->c2min + 1),
756
|| (rarray->block_index == NULL) || (rarray->tbl == NULL))
758
ccvi->arg = (long)rarray;
766
ccv_read_file_block_array(FILE *fp, struct s_ccv_info *ccvi, int block)
768
int code, base, b, c, v;
769
char key[256], val[256];
773
printf(">> CCV Reding table (array) nblocks=%d\n", ccvi->nblocks);
775
tbl = (long*)ccvi->arg;
776
for (b = ccvi->c1min; ; ){
778
printf(" Block %d", block);
779
base = block * (ccvi->c2max - ccvi->c2min + 1);
780
for (c = ccvi->c2min; c <= ccvi->c2max; c++){
781
if ((v = ccv_file_read_elem(fp, val, sizeof(val))) <= 0){
782
fprintf(stderr, "VFlib warning: broken code conversion table: %s\n",
786
sscanf(val, "%i", &code);
787
tbl[base + (c - ccvi->c2min)] = code;
788
#if defined(DEBUG) && 0
789
printf("\n 0x%04x ==> 0x%04x", b*ccvi->block_size+c, code);
793
if ((++b) > ccvi->c1max)
797
if (ccv_file_read_list(fp, key, sizeof(key)) < 0){
798
fprintf(stderr, "VFlib warning: broken code conversion table: %s\n",
802
if (vf_strcmp_ci(key, "block") == 0)
805
ccv_file_read_elem(fp, val, sizeof(val));
806
sscanf(val, "%i", &block);
815
ccv_read_file_block_random_array(FILE *fp, struct s_ccv_info *ccvi, int block)
817
int code, base, b, c, v;
818
char key[256], val[256];
819
int *block_index, index;
821
CCV_RANDOM_ARRAY rarray;
824
printf(">> CCV reding table (random-arrays) nblocks=%d", ccvi->nblocks);
826
rarray = (CCV_RANDOM_ARRAY)ccvi->arg;
827
block_index = rarray->block_index;
831
printf(" Block %d", block);
832
rarray->block_index[b] = block;
833
base = b * (ccvi->c2max - ccvi->c2min + 1);
834
for (c = ccvi->c2min; c <= ccvi->c2max; c++){
835
if ((v = ccv_file_read_elem(fp, val, sizeof(val))) <= 0){
836
fprintf(stderr, "VFlib warning: broken code conversion table: %s\n",
840
sscanf(val, "%i", &code);
841
index = base + (c - ccvi->c2min);
843
#if defined(DEBUG) && 0
844
printf("\n 0x%04x ==> 0x%04x (%d)",
845
(block + ccvi->c1min)*ccvi->block_size+c, code, index);
849
if ((++b) >= ccvi->nblocks)
853
if ((v = ccv_file_read_list(fp, key, sizeof(key))) == 0)
856
fprintf(stderr, "VFlib warning: broken code conversion table: %s\n",
860
if (vf_strcmp_ci(key, "block") == 0)
863
ccv_file_read_elem(fp, val, sizeof(val));
864
sscanf(val, "%i", &block);
872
ccv_file_read_list(FILE *fp, char *buff, int nbuff)
879
while ((ch = getc(fp)) != EOF){
882
if (ch == ';'){ /* coment begins. skip until the eol */
883
while ((ch = getc(fp)) != '\n'){
892
/* read the car part of an s-exp */
894
while ((ch = getc(fp)) != EOF){
897
if (isspace((int)ch))
907
printf("\n* %s: ", buff);
913
ccv_file_read_elem(FILE *fp, char *buff, int nbuff)
918
while ((ch = getc(fp)) != EOF){
928
while ((ch = getc(fp)) != EOF){
931
if (isspace((int)ch))
949
vf_ccv_conv(int ccvi_index, long code_point)
956
cv_code_point = (*ccv_tbl[ccvi_index].conv)(ccvi_index, code_point);
958
if (vf_dbg_ccv_map == 1)
959
printf(">> CCV code conversion: 0x%04lx => 0x%04lx\n",
960
code_point, cv_code_point);
962
return cv_code_point;
967
ccv_conv_array(int ccvi_index, long code_point)
973
ccvi = &ccv_tbl[ccvi_index];
974
c1 = code_point / ccvi->block_size;
975
c2 = code_point % ccvi->block_size;
976
if ( (c1 < ccvi->c1min) || (ccvi->c1max < c1)
977
|| (c2 < ccvi->c2min) || (ccvi->c2max < c2) ){
980
index = (c1 - ccvi->c1min) * (ccvi->c2max - ccvi->c2min + 1)
981
+ (c2 - ccvi->c2min);
982
tbl = (long*) ccvi->arg;
987
ccv_conv_random_array(int ccvi_index, long code_point)
989
int c1, c2, index, i;
991
CCV_RANDOM_ARRAY cra;
993
ccvi = &ccv_tbl[ccvi_index];
994
c1 = code_point / ccvi->block_size;
995
c2 = code_point % ccvi->block_size;
996
if ( (c1 < ccvi->c1min) || (ccvi->c1max < c1)
997
|| (c2 < ccvi->c2min) || (ccvi->c2max < c2) ){
1000
cra = (CCV_RANDOM_ARRAY)ccvi->arg;
1001
for (i = 0; i < ccvi->nblocks; i++){ /** TOO SLOW! **/
1002
/*printf("\n index %d %d", cra->block_index[i], c1);*/
1003
if (cra->block_index[i]+ccvi->c1min == c1)
1006
if (i == ccvi->nblocks)
1008
index = i * (ccvi->c2max - ccvi->c2min + 1) + (c2 - ccvi->c2min);
1009
return cra->tbl[index];
1017
* Usage: dbg-ccv filename - cs1_name cs1_enc cs2_name cs2_enc code_point ...
1020
main(int argc, char **argv)
1032
if (strcmp(argv[0], "-") == 0){
1037
vf_ccv_autoload(argv[0]);
1045
i = vf_ccv_require(argv[0], argv[1], argv[2], argv[3]);
1053
sscanf(argv[0], "%i", &cc);
1054
cvcc = vf_ccv_conv(i, (long)cc);
1055
printf("\n Conv 0x%x ==> 0x%x", cc, (int)cvcc);