Annotation of parser3/src/main/pa_charset_connection.C, revision 1.1

1.1     ! parser      1: /** @file
        !             2:        Parser: Charset connection implementation.
        !             3: 
        !             4:        Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
        !             5:        Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
        !             6: 
        !             7:        $Id: pa_sql_driver_manager.C,v 1.38 2001/09/26 10:32:26 parser Exp $
        !             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/XercesDefs.hpp>
        !            17: #      include <util/TransENameMap.hpp>
        !            18: #      include <util/XML256TableTranscoder.hpp>
        !            19: #      include <util/PlatformUtils.hpp>
        !            20: #      include <PlatformSupport/XalanTranscodingServices.hpp>
        !            21: #endif
        !            22: 
        !            23: 
        !            24: // globals
        !            25: 
        !            26: 
        !            27: // consts
        !            28: 
        !            29: #define MAX_CHARSET_UNI_CODES 500
        !            30: 
        !            31: //
        !            32: 
        !            33: inline void prepare_case_tables(unsigned char *tables) {
        !            34:        unsigned char *lcc_table=tables+lcc_offset;
        !            35:        unsigned char *fcc_table=tables+fcc_offset;
        !            36:        for(int i=0; i<0x100; i++)
        !            37:                lcc_table[i]=fcc_table[i]=i;
        !            38: }
        !            39: inline void cstr2ctypes(unsigned char *tables, const unsigned char *cstr, 
        !            40:                                                unsigned char bit) {
        !            41:        unsigned char *ctypes_table=tables+ctypes_offset;
        !            42:        ctypes_table[0]=bit;
        !            43:        for(; *cstr; cstr++) {
        !            44:                unsigned char c=*cstr;
        !            45:                ctypes_table[c]|=bit;
        !            46:        }
        !            47: }
        !            48: inline unsigned int to_wchar_code(const char *cstr) {
        !            49:        if(!cstr || !*cstr)
        !            50:                return 0;
        !            51:        if(cstr[1]==0)
        !            52:                return (unsigned int)(unsigned char)cstr[0];
        !            53: 
        !            54:        char *error_pos;
        !            55:        return (unsigned int)strtol(cstr, &error_pos, 0);
        !            56: }
        !            57: inline bool to_bool(const char *cstr) {
        !            58:        return cstr && *cstr!=0;
        !            59: }
        !            60: static void element2ctypes(unsigned char c, bool belongs,
        !            61:                                                   unsigned char *tables,  unsigned char bit, int group_offset=-1) {
        !            62:        if(!belongs)
        !            63:                return;
        !            64: 
        !            65:        unsigned char *ctypes_table=tables+ctypes_offset;
        !            66: 
        !            67:        ctypes_table[c]|=bit;
        !            68:        if(group_offset>=0)
        !            69:                tables[cbits_offset+group_offset+c/8] |= 1 << (c%8);
        !            70: }
        !            71: static void element2case(unsigned char from, unsigned char to,
        !            72:                                                 unsigned char *tables) {
        !            73:        if(!to) 
        !            74:                return;
        !            75: 
        !            76:        unsigned char *lcc_table=tables+lcc_offset;
        !            77:        unsigned char *fcc_table=tables+fcc_offset;
        !            78:        lcc_table[from]=to;
        !            79:        fcc_table[from]=to; fcc_table[to]=from;
        !            80: }
        !            81: 
        !            82: #ifdef XML
        !            83: 
        !            84: static int sort_cmp_Trans_rec_intCh(const void *a, const void *b) {
        !            85:        const XMLCh ca=static_cast<const XMLTransService::TransRec *>(a)->intCh;
        !            86:        const XMLCh cb=static_cast<const XMLTransService::TransRec *>(b)->intCh;
        !            87:        // move zeros to end of table
        !            88:        if(ca==0)
        !            89:                return +1;
        !            90:        if(cb==0)
        !            91:                return -1;
        !            92: 
        !            93:        //
        !            94:        return ca-cb;
        !            95: }
        !            96: 
        !            97: template <class TType> class ENameMapFor2 : public ENameMap
        !            98: {
        !            99: public :
        !           100:     // -----------------------------------------------------------------------
        !           101:     //  Constructors and Destructor
        !           102:     // -----------------------------------------------------------------------
        !           103:     ENameMapFor2(
        !           104:                const XMLCh* const encodingName
        !           105:         , const XMLCh* const                        fromTable
        !           106:         , const XMLTransService::TransRec* const    toTable
        !           107:         , const unsigned int                        toTableSize
        !           108:                ) : ENameMap(encodingName),
        !           109:                ffromTable(fromTable),
        !           110:                ftoTable(toTable),
        !           111:                ftoTableSize(toTableSize) {}
        !           112:     ~ENameMapFor2() {}
        !           113: 
        !           114:     // -----------------------------------------------------------------------
        !           115:     //  Implementation of virtual factory method
        !           116:     // -----------------------------------------------------------------------
        !           117:     virtual XMLTranscoder* makeNew(const unsigned int blockSize) const {
        !           118:                return new TType(
        !           119:                        getKey(), 
        !           120:                        blockSize,
        !           121:                        ffromTable,
        !           122:                        ftoTable, ftoTableSize);
        !           123:        }
        !           124: private:
        !           125:        const XMLCh* const                        ffromTable;
        !           126:        const XMLTransService::TransRec* const    ftoTable;
        !           127:        const unsigned int                        ftoTableSize;
        !           128: 
        !           129: private :
        !           130:     // -----------------------------------------------------------------------
        !           131:     //  Unimplemented constructors and operators
        !           132:     // -----------------------------------------------------------------------
        !           133:     ENameMapFor2();
        !           134:     ENameMapFor2(const ENameMapFor2<TType>&);
        !           135:     void operator=(const ENameMapFor2<TType>&);
        !           136: };
        !           137: 
        !           138: class XML256TableTranscoder2 : public XML256TableTranscoder
        !           139: {
        !           140: public :
        !           141:     XML256TableTranscoder2(
        !           142:         const   XMLCh* const                        encodingName
        !           143:         , const unsigned int                        blockSize
        !           144:         , const XMLCh* const                        fromTable
        !           145:         , const XMLTransService::TransRec* const    toTable
        !           146:         , const unsigned int                        toTableSize
        !           147:                ) : XML256TableTranscoder(encodingName, blockSize, fromTable, toTable, toTableSize) {}
        !           148: 
        !           149: private :
        !           150:     XML256TableTranscoder2();
        !           151:     XML256TableTranscoder2(const XML256TableTranscoder2&);
        !           152:     void operator=(const XML256TableTranscoder2&);
        !           153: };
        !           154: #endif
        !           155: 
        !           156: #undef XALAN_HACK_DIGITAL_ENTITIES
        !           157: #ifdef XALAN_HACK_DIGITAL_ENTITIES
        !           158: static void hack_s_maximumCharacterValues(const XalanDOMString& encoding) {
        !           159: /*
        !           160:        open:
        !           161:                xml-xalan/c/src/PlatformSupport/XalanTranscodingServices.hpp 
        !           162:        find: 
        !           163:                static const MaximumCharacterValueMapType&      s_maximumCharacterValues;
        !           164:        paste to next line:
        !           165:                friend static void hack_s_maximumCharacterValues(const XalanDOMString& encoding); // hack by paf
        !           166: */
        !           167: 
        !           168:        const_cast<XalanTranscodingServices::MaximumCharacterValueMapType &>(
        !           169:                XalanTranscodingServices::s_maximumCharacterValues).insert(
        !           170:                XalanTranscodingServices::MaximumCharacterValueMapType::value_type(encoding, 0xFFFF));
        !           171: }
        !           172: #endif
        !           173: 
        !           174: void Charset_connection::load(Pool& pool, time_t new_disk_time) {
        !           175:        // pcre_tables
        !           176:        // lowcase, flipcase, bits digit+word+whitespace, masks
        !           177:        prepare_case_tables(fpcre_tables);
        !           178:        cstr2ctypes(fpcre_tables, (const unsigned char *)"*+?{^.$|()[", ctype_meta);
        !           179: 
        !           180: #ifdef XML
        !           181:        // transcoder
        !           182:        XMLCh *fromTable=(XMLCh *)calloc(sizeof(XMLCh)*0x100);
        !           183:        XMLTransService::TransRec *toTable=(XMLTransService::TransRec *)calloc(
        !           184:                        sizeof(XMLTransService::TransRec)*MAX_CHARSET_UNI_CODES);
        !           185:        unsigned int toTableSz=0;
        !           186: #endif
        !           187: 
        !           188:        // loading text
        !           189:        char *data=file_read_text(pool, ffile_spec);
        !           190: 
        !           191:        // ignore header
        !           192:        getrow(&data);
        !           193: 
        !           194:        // parse cells
        !           195:        char *row_chars;
        !           196:        while(row_chars=getrow(&data)) {
        !           197:                if(!*row_chars) // remove empty lines
        !           198:                        continue;
        !           199: 
        !           200:                // char white-space     digit   hex-digit       letter  word    lowercase       unicode1        unicode2        
        !           201:                unsigned int c=0;
        !           202:                char *cell;
        !           203:                for(int column=0; cell=lsplit(&row_chars, '\t'); column++) {
        !           204:                        switch(column) {
        !           205:                        case 0: c=to_wchar_code(cell); break;
        !           206:                        // fpcre_tables
        !           207:                        case 1: element2ctypes(c, to_bool(cell), fpcre_tables, ctype_space, cbit_space); break;
        !           208:                        case 2: element2ctypes(c, to_bool(cell), fpcre_tables, ctype_digit, cbit_digit); break;
        !           209:                        case 3: element2ctypes(c, to_bool(cell), fpcre_tables, ctype_xdigit); break;
        !           210:                        case 4: element2ctypes(c, to_bool(cell), fpcre_tables, ctype_letter); break;
        !           211:                        case 5: element2ctypes(c, to_bool(cell), fpcre_tables, ctype_word, cbit_word); break;
        !           212:                        case 6: element2case(c, to_wchar_code(cell), fpcre_tables); break;
        !           213: #ifdef XML
        !           214:                        case 7:
        !           215:                        case 8:
        !           216:                                // transcoder
        !           217:                                if(toTableSz>MAX_CHARSET_UNI_CODES)
        !           218:                                        PTHROW(0, 0,
        !           219:                                                &ffile_spec,
        !           220:                                                "charset must contain not more then %d unicode values", MAX_CHARSET_UNI_CODES);
        !           221: 
        !           222:                                XMLCh unicode=(XMLCh)to_wchar_code(cell);
        !           223:                                if(!unicode && column==7/*unicode1 column*/)
        !           224:                                        unicode=(XMLCh)c;
        !           225:                                if(unicode) {
        !           226:                                        if(!fromTable[c])
        !           227:                                                fromTable[c]=unicode;
        !           228:                                        toTable[toTableSz].intCh=unicode;
        !           229:                                        toTable[toTableSz].extCh=(XMLByte)c;
        !           230:                                        toTableSz++;
        !           231:                                }
        !           232:                                break;
        !           233: #endif
        !           234:                        }
        !           235:                }
        !           236:        };
        !           237: 
        !           238: #ifdef XML
        !           239:        // sort by the Unicode code point
        !           240:        _qsort(toTable, toTableSz, sizeof(*toTable), 
        !           241:                sort_cmp_Trans_rec_intCh);
        !           242: 
        !           243:        // addEncoding
        !           244:        XalanDOMString sencoding(fname.cstr());
        !           245: #ifdef XALAN_HACK_DIGITAL_ENTITIES
        !           246:        hack_s_maximumCharacterValues(sencoding);
        !           247: #endif
        !           248:        const XMLCh* const auto_encoding_cstr=sencoding.c_str();
        !           249:        int size=sizeof(XMLCh)*(sencoding.size()+1);
        !           250:        XMLCh* pool_encoding_cstr=(XMLCh*)malloc(size);
        !           251:        memcpy(pool_encoding_cstr, auto_encoding_cstr, size);
        !           252:     XMLString::upperCase(pool_encoding_cstr);
        !           253: 
        !           254:        /// @todo delete prev encoding with same name
        !           255:     XMLPlatformUtils::fgTransService->addEncoding(
        !           256:                pool_encoding_cstr, 
        !           257:                new ENameMapFor2<XML256TableTranscoder2>(
        !           258:                        pool_encoding_cstr
        !           259:                        , fromTable
        !           260:                        , toTable
        !           261:                        , toTableSz
        !           262:                ));
        !           263: #endif
        !           264: 
        !           265:        prev_disk_time=new_disk_time;
        !           266: }

E-mail: