Annotation of parser3/src/main/pa_charset_connection.C, revision 1.12
1.1 parser 1: /** @file
2: Parser: Charset connection implementation.
3:
4: Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
1.11 paf 5: Author: Alexander Petrosyan <paf@design.ru> (http://paf.design.ru)
1.1 parser 6:
1.12 ! paf 7: $Id: pa_charset_connection.C,v 1.11 2001/11/05 11:46:27 paf Exp $
1.1 parser 8: */
9:
10: #include "pa_charset_connection.h"
11: //#include "pa_exception.h"
12: //#include "pa_common.h"
13: //#include "pa_threads.h"
14:
15: #ifdef XML
16: # include <util/TransENameMap.hpp>
17: # include <util/XML256TableTranscoder.hpp>
18: # include <util/PlatformUtils.hpp>
19: # include <PlatformSupport/XalanTranscodingServices.hpp>
20: #endif
21:
22: // globals
23:
24:
25: // consts
26:
27: #define MAX_CHARSET_UNI_CODES 500
28:
29: //
30:
31: inline void prepare_case_tables(unsigned char *tables) {
32: unsigned char *lcc_table=tables+lcc_offset;
33: unsigned char *fcc_table=tables+fcc_offset;
34: for(int i=0; i<0x100; i++)
35: lcc_table[i]=fcc_table[i]=i;
36: }
37: inline void cstr2ctypes(unsigned char *tables, const unsigned char *cstr,
38: unsigned char bit) {
39: unsigned char *ctypes_table=tables+ctypes_offset;
40: ctypes_table[0]=bit;
41: for(; *cstr; cstr++) {
42: unsigned char c=*cstr;
43: ctypes_table[c]|=bit;
44: }
45: }
46: inline unsigned int to_wchar_code(const char *cstr) {
47: if(!cstr || !*cstr)
48: return 0;
49: if(cstr[1]==0)
50: return (unsigned int)(unsigned char)cstr[0];
51:
52: char *error_pos;
53: return (unsigned int)strtol(cstr, &error_pos, 0);
54: }
55: inline bool to_bool(const char *cstr) {
56: return cstr && *cstr!=0;
57: }
58: static void element2ctypes(unsigned char c, bool belongs,
59: unsigned char *tables, unsigned char bit, int group_offset=-1) {
60: if(!belongs)
61: return;
62:
63: unsigned char *ctypes_table=tables+ctypes_offset;
64:
65: ctypes_table[c]|=bit;
66: if(group_offset>=0)
67: tables[cbits_offset+group_offset+c/8] |= 1 << (c%8);
68: }
69: static void element2case(unsigned char from, unsigned char to,
70: unsigned char *tables) {
71: if(!to)
72: return;
73:
74: unsigned char *lcc_table=tables+lcc_offset;
75: unsigned char *fcc_table=tables+fcc_offset;
76: lcc_table[from]=to;
77: fcc_table[from]=to; fcc_table[to]=from;
78: }
79:
80: #ifdef XML
81:
82: template <class TType> class ENameMapFor2 : public ENameMap
83: {
84: public :
85: // -----------------------------------------------------------------------
86: // Constructors and Destructor
87: // -----------------------------------------------------------------------
88: ENameMapFor2(
89: const XMLCh* const encodingName
90: , const XMLCh* const fromTable
91: , const XMLTransService::TransRec* const toTable
92: , const unsigned int toTableSize
93: ) : ENameMap(encodingName),
94: ffromTable(fromTable),
95: ftoTable(toTable),
96: ftoTableSize(toTableSize) {}
97:
98: // -----------------------------------------------------------------------
99: // Implementation of virtual factory method
100: // -----------------------------------------------------------------------
101: virtual XMLTranscoder* makeNew(const unsigned int blockSize) const {
102: return new TType(
103: getKey(),
104: blockSize,
105: ffromTable,
106: ftoTable, ftoTableSize);
107: }
108: private:
109: const XMLCh* const ffromTable;
110: const XMLTransService::TransRec* const ftoTable;
111: const unsigned int ftoTableSize;
112:
113: private :
114: // -----------------------------------------------------------------------
115: // Unimplemented constructors and operators
116: // -----------------------------------------------------------------------
117: ENameMapFor2();
118: ENameMapFor2(const ENameMapFor2<TType>&);
119: void operator=(const ENameMapFor2<TType>&);
120: };
121:
122: class XML256TableTranscoder2 : public XML256TableTranscoder
123: {
124: public :
125: XML256TableTranscoder2(
126: const XMLCh* const encodingName
127: , const unsigned int blockSize
128: , const XMLCh* const fromTable
129: , const XMLTransService::TransRec* const toTable
130: , const unsigned int toTableSize
131: ) : XML256TableTranscoder(encodingName, blockSize, fromTable, toTable, toTableSize) {}
132:
133: private :
134: XML256TableTranscoder2();
135: XML256TableTranscoder2(const XML256TableTranscoder2&);
136: void operator=(const XML256TableTranscoder2&);
137: };
138: #endif
139:
140: void Charset_connection::load(Pool& pool, time_t new_disk_time) {
141: // pcre_tables
142: // lowcase, flipcase, bits digit+word+whitespace, masks
1.9 parser 143:
144: // must not move this inside of prepare_case_tables
145: // don't know the size there
1.12 ! paf 146: memset(ftranscoder.pcre_tables, 0, sizeof(ftranscoder.pcre_tables));
! 147: prepare_case_tables(ftranscoder.pcre_tables);
! 148: cstr2ctypes(ftranscoder.pcre_tables, (const unsigned char *)"*+?{^.$|()[", ctype_meta);
1.1 parser 149:
150: // transcoder
1.12 ! paf 151: memset(ftranscoder.fromTable, 0, sizeof(ftranscoder.fromTable));
! 152: ftranscoder.toTable=(XMLTransService::TransRec *)calloc(
1.1 parser 153: sizeof(XMLTransService::TransRec)*MAX_CHARSET_UNI_CODES);
1.12 ! paf 154: ftranscoder.toTableSize=0;
1.7 parser 155: // strangly vital
1.12 ! paf 156: ftranscoder.toTable[ftranscoder.toTableSize].intCh=0;
! 157: ftranscoder.toTable[ftranscoder.toTableSize].extCh=(XMLByte)0;
! 158: ftranscoder.toTableSize++;
1.1 parser 159:
160: // loading text
161: char *data=file_read_text(pool, ffile_spec);
162:
163: // ignore header
164: getrow(&data);
165:
166: // parse cells
1.6 parser 167: char *row;
168: while(row=getrow(&data)) {
169: // remove empty&comment lines
170: if(!*row || *row=='#')
1.1 parser 171: continue;
172:
173: // char white-space digit hex-digit letter word lowercase unicode1 unicode2
174: unsigned int c=0;
175: char *cell;
1.6 parser 176: for(int column=0; cell=lsplit(&row, '\t'); column++) {
1.1 parser 177: switch(column) {
178: case 0: c=to_wchar_code(cell); break;
1.12 ! paf 179: // ftranscoder.pcre_tables
! 180: case 1: element2ctypes(c, to_bool(cell), ftranscoder.pcre_tables, ctype_space, cbit_space); break;
! 181: case 2: element2ctypes(c, to_bool(cell), ftranscoder.pcre_tables, ctype_digit, cbit_digit); break;
! 182: case 3: element2ctypes(c, to_bool(cell), ftranscoder.pcre_tables, ctype_xdigit); break;
! 183: case 4: element2ctypes(c, to_bool(cell), ftranscoder.pcre_tables, ctype_letter); break;
! 184: case 5: element2ctypes(c, to_bool(cell), ftranscoder.pcre_tables, ctype_word, cbit_word); break;
! 185: case 6: element2case(c, to_wchar_code(cell), ftranscoder.pcre_tables); break;
1.1 parser 186: case 7:
187: case 8:
188: // transcoder
1.12 ! paf 189: if(ftranscoder.toTableSize>MAX_CHARSET_UNI_CODES)
1.10 parser 190: throw Exception(0, 0,
1.1 parser 191: &ffile_spec,
192: "charset must contain not more then %d unicode values", MAX_CHARSET_UNI_CODES);
193:
194: XMLCh unicode=(XMLCh)to_wchar_code(cell);
195: if(!unicode && column==7/*unicode1 column*/)
196: unicode=(XMLCh)c;
197: if(unicode) {
1.12 ! paf 198: if(!ftranscoder.fromTable[c])
! 199: ftranscoder.fromTable[c]=unicode;
! 200: ftranscoder.toTable[ftranscoder.toTableSize].intCh=unicode;
! 201: ftranscoder.toTable[ftranscoder.toTableSize].extCh=(XMLByte)c;
! 202: ftranscoder.toTableSize++;
1.1 parser 203: }
204: break;
205: }
206: }
207: };
208:
209: // sort by the Unicode code point
1.12 ! paf 210: ftranscoder.sort_ToTable();
1.1 parser 211:
1.12 ! paf 212: #ifdef XML
1.1 parser 213: // addEncoding
214: XalanDOMString sencoding(fname.cstr());
215: const XMLCh* const auto_encoding_cstr=sencoding.c_str();
216: int size=sizeof(XMLCh)*(sencoding.size()+1);
217: XMLCh* pool_encoding_cstr=(XMLCh*)malloc(size);
218: memcpy(pool_encoding_cstr, auto_encoding_cstr, size);
219: XMLString::upperCase(pool_encoding_cstr);
220:
221: XMLPlatformUtils::fgTransService->addEncoding(
222: pool_encoding_cstr,
223: new ENameMapFor2<XML256TableTranscoder2>(
224: pool_encoding_cstr
1.12 ! paf 225: , ftranscoder.fromTable
! 226: , ftranscoder.toTable
! 227: , ftranscoder.toTableSize
1.1 parser 228: ));
229: #endif
230:
231: prev_disk_time=new_disk_time;
232: }
E-mail: