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: