Diff for /parser3/src/main/pa_charset.C between versions 1.2 and 1.33.2.19.2.19

version 1.2, 2001/12/15 21:39:32 version 1.33.2.19.2.19, 2003/04/10 08:33:05
Line 1 Line 1
 /** @file  /** @file
         Parser: Charset connection implementation.          Parser: Charset connection implementation.
   
         Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)          Copyright(c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)
         Author: Alexander Petrosyan <paf@design.ru> (http://paf.design.ru)          Author: Alexander Petrosyan<paf@design.ru>(http://paf.design.ru)
   
         $Id$  
 */  */
   
   static const char* IDENT_CHARSET_C="$Date$";
   
 #include "pa_charset.h"  #include "pa_charset.h"
 //#include "pa_exception.h"  #include "pa_charsets.h"
 //#include "pa_common.h"  
 //#include "pa_threads.h"  
   
 #ifdef XML  #ifdef XML
 #       include <util/TransENameMap.hpp>  #include "libxml/encoding.h"
 #       include <util/XML256TableTranscoder.hpp>  
 #       include <util/PlatformUtils.hpp>  
 #       include <PlatformSupport/XalanTranscodingServices.hpp>  
 #endif  #endif
   
 // globals  
   
   
 // consts  
   
 #define MAX_CHARSET_UNI_CODES 500  
   
 // helpers  // helpers
   
 inline void prepare_case_tables(unsigned char *tables) {  inline void prepare_case_tables(unsigned char *tables) {
Line 43  inline void cstr2ctypes(unsigned char *t Line 31  inline void cstr2ctypes(unsigned char *t
                 ctypes_table[c]|=bit;                  ctypes_table[c]|=bit;
         }          }
 }  }
 inline unsigned int to_wchar_code(const char *cstr) {  inline unsigned int to_wchar_code(const char* cstr) {
         if(!cstr || !*cstr)          if(!cstr || !*cstr)
                 return 0;                  return 0;
         if(cstr[1]==0)          if(cstr[1]==0)
                 return (unsigned int)(unsigned char)cstr[0];                  return(unsigned int)(unsigned char)cstr[0];
   
         char *error_pos;          char *error_pos;
         return (unsigned int)strtol(cstr, &error_pos, 0);          return(unsigned int)strtol(cstr, &error_pos, 0);
 }  }
 inline bool to_bool(const char *cstr) {  inline bool to_bool(const char* cstr) {
         return cstr && *cstr!=0;          return cstr && *cstr!=0;
 }  }
 static void element2ctypes(unsigned char c, bool belongs,  static void element2ctypes(unsigned char c, bool belongs,
Line 64  static void element2ctypes(unsigned char Line 52  static void element2ctypes(unsigned char
   
         ctypes_table[c]|=bit;          ctypes_table[c]|=bit;
         if(group_offset>=0)          if(group_offset>=0)
                 tables[cbits_offset+group_offset+c/8] |= 1 << (c%8);                  tables[cbits_offset+group_offset+c/8] |= 1<<(c%8);
 }  }
 static void element2case(unsigned char from, unsigned char to,  static void element2case(unsigned char from, unsigned char to,
                                                  unsigned char *tables) {                                                   unsigned char *tables) {
Line 77  static void element2case(unsigned char f Line 65  static void element2case(unsigned char f
         fcc_table[from]=to; fcc_table[to]=from;          fcc_table[from]=to; fcc_table[to]=from;
 }  }
   
 #ifdef XML  
 template <class TType> class ENameMapFor2 : public ENameMap {  
 public :  
     // -----------------------------------------------------------------------  
     //  Constructors and Destructor  
     // -----------------------------------------------------------------------  
     ENameMapFor2(  
                 const XMLCh* const encodingName  
         , const XMLCh* const                        fromTable  
         , const XMLTransService::TransRec* const    toTable  
         , const unsigned int                        toTableSize  
                 ) : ENameMap(encodingName),  
                 ffromTable(fromTable),  
                 ftoTable(toTable),  
                 ftoTableSize(toTableSize) {}  
   
     // -----------------------------------------------------------------------  
     //  Implementation of virtual factory method  
     // -----------------------------------------------------------------------  
     virtual XMLTranscoder* makeNew(const unsigned int blockSize) const {  
                 return new TType(  
                         getKey(),   
                         blockSize,  
                         ffromTable,  
                         ftoTable, ftoTableSize);  
         }  
 private:  
         const XMLCh* const                        ffromTable;  
         const XMLTransService::TransRec* const    ftoTable;  
         const unsigned int                        ftoTableSize;  
   
 private :  
     // -----------------------------------------------------------------------  
     //  Unimplemented constructors and operators  
     // -----------------------------------------------------------------------  
     ENameMapFor2();  
     ENameMapFor2(const ENameMapFor2<TType>&);  
     void operator=(const ENameMapFor2<TType>&);  
 };  
   
 class XML256TableTranscoder2 : public XML256TableTranscoder {  
 public :  
     XML256TableTranscoder2(  
         const   XMLCh* const                        encodingName  
         , const unsigned int                        blockSize  
         , const XMLCh* const                        fromTable  
         , const XMLTransService::TransRec* const    toTable  
         , const unsigned int                        toTableSize  
                 ) : XML256TableTranscoder(encodingName, blockSize, fromTable, toTable, toTableSize) {}  
   
 private :  
     XML256TableTranscoder2();  
     XML256TableTranscoder2(const XML256TableTranscoder2&);  
     void operator=(const XML256TableTranscoder2&);  
 };  
 #endif  
   
 // methods  // methods
   
 extern "C" unsigned char pcre_default_tables[]; // pcre/chartables.c  extern "C" unsigned char pcre_default_tables[]; // pcre/chartables.c
 Charset::Charset(Pool& apool, const String& aname, const String *file_spec) : Pooled(apool),  Charset::Charset(Request_charsets* charsets, const StringBody ANAME, const String* afile_spec): 
         fname(apool) {          FNAME(ANAME),
         // fname          FNAME_CSTR(ANAME.cstrm()) {
         char *name_cstr=(char *)malloc(aname.size()+1);  
         memcpy(name_cstr, aname.cstr(String::UL_AS_IS), aname.size()+1);  
         fname.APPEND_CLEAN(name_cstr, aname.size(), 0, 0);  
   
         if(file_spec) {          if(afile_spec) {
                 fisUTF8=false;                  fisUTF8=false;
                 loadDefinition(*file_spec);                  load_definition(*charsets, *afile_spec);
 #ifdef XML  #ifdef XML
                 addEncoding(name_cstr);                  addEncoding(FNAME_CSTR);
 #endif  #endif
         } else {          } else {
                 fisUTF8=true;                  fisUTF8=true;
                 // grab default onces [for UTF-8 so to be able to make a-z => A-Z                  // grab default onces [for UTF-8 so to be able to make a-z =>A-Z
                 memcpy(pcre_tables, pcre_default_tables, sizeof(pcre_tables));                  memcpy(pcre_tables, pcre_default_tables, sizeof(pcre_tables));
         }          }
   
 #ifdef XML  #ifdef XML
         initTranscoder(&aname, name_cstr);          initTranscoder(FNAME, FNAME_CSTR);
 #endif  
 }  
   
 Charset::~Charset() {  
 #ifdef XML  
         delete transcoder;  
 #endif  #endif
 }  }
   
 void Charset::loadDefinition(const String& file_spec) {  void Charset::load_definition(Request_charsets& charsets, const String& afile_spec) {
         // pcre_tables          // pcre_tables
         // lowcase, flipcase, bits digit+word+whitespace, masks          // lowcase, flipcase, bits digit+word+whitespace, masks
   
Line 175  void Charset::loadDefinition(const Strin Line 97  void Charset::loadDefinition(const Strin
         // don't know the size there          // don't know the size there
         memset(pcre_tables, 0, sizeof(pcre_tables));           memset(pcre_tables, 0, sizeof(pcre_tables)); 
         prepare_case_tables(pcre_tables);          prepare_case_tables(pcre_tables);
         cstr2ctypes(pcre_tables, (const unsigned char *)"*+?{^.$|()[", ctype_meta);          cstr2ctypes(pcre_tables,(const unsigned char *)"*+?{^.$|()[", ctype_meta);
   
         // charset          // charset
         memset(fromTable, 0, sizeof(fromTable));          memset(&tables, 0, sizeof(tables));
         toTable=(XMLTransService::TransRec *)calloc(  
                         sizeof(XMLTransService::TransRec)*MAX_CHARSET_UNI_CODES);  
         toTableSize=0;  
         // strangly vital          // strangly vital
         toTable[toTableSize].intCh=0;          tables.toTable[tables.toTableSize].intCh=0;
         toTable[toTableSize].extCh=(XMLByte)0;          tables.toTable[tables.toTableSize].extCh=(XMLByte)0;
         toTableSize++;          tables.toTableSize++;
   
         // loading text          // loading text
         char *data=file_read_text(pool(), file_spec);          char *data=file_read_text(charsets, afile_spec);
   
         // ignore header          // ignore header
         getrow(&data);          getrow(&data);
Line 216  void Charset::loadDefinition(const Strin Line 135  void Charset::loadDefinition(const Strin
                         case 7:                          case 7:
                         case 8:                          case 8:
                                 // charset                                  // charset
                                 if(toTableSize>MAX_CHARSET_UNI_CODES)                                  if(tables.toTableSize>MAX_CHARSET_UNI_CODES)
                                         throw Exception(0, 0,                                          throw Exception("parser.runtime",
                                                 &file_spec,                                                  &afile_spec,
                                                 "charset must contain not more then %d unicode values", MAX_CHARSET_UNI_CODES);                                                  "charset must contain not more then %d unicode values", MAX_CHARSET_UNI_CODES);
   
                                 XMLCh unicode=(XMLCh)to_wchar_code(cell);                                  XMLCh unicode=(XMLCh)to_wchar_code(cell);
                                 if(!unicode && column==7/*unicode1 column*/)                                  if(!unicode && column==7/*unicode1 column*/)
                                         unicode=(XMLCh)c;                                          unicode=(XMLCh)c;
                                 if(unicode) {                                  if(unicode) {
                                         if(!fromTable[c])                                          if(!tables.fromTable[c])
                                                 fromTable[c]=unicode;                                                  tables.fromTable[c]=unicode;
                                         toTable[toTableSize].intCh=unicode;                                          tables.toTable[tables.toTableSize].intCh=unicode;
                                         toTable[toTableSize].extCh=(XMLByte)c;                                          tables.toTable[tables.toTableSize].extCh=(XMLByte)c;
                                         toTableSize++;                                          tables.toTableSize++;
                                 }                                  }
                                 break;                                  break;
                         }                          }
Line 240  void Charset::loadDefinition(const Strin Line 159  void Charset::loadDefinition(const Strin
         sort_ToTable();          sort_ToTable();
 }  }
   
 #ifdef XML  
 void Charset::addEncoding(const char *name_cstr) {  
         // addEncoding  
         XalanDOMString sencoding(name_cstr);  
         const XMLCh* const auto_encoding_cstr=sencoding.c_str();  
         int size=sizeof(XMLCh)*(sencoding.size()+1);  
         XMLCh* pool_encoding_cstr=(XMLCh*)malloc(size);  
         memcpy(pool_encoding_cstr, auto_encoding_cstr, size);  
     XMLString::upperCase(pool_encoding_cstr);  
   
     XMLPlatformUtils::fgTransService->addEncoding(  
                 pool_encoding_cstr,   
                 new ENameMapFor2<XML256TableTranscoder2>(  
                         pool_encoding_cstr  
                         , fromTable  
                         , toTable  
                         , toTableSize  
                 ));  
 }  
   
 void Charset::initTranscoder(const String *source, const char *name_cstr) {  
         XMLTransService::Codes resValue;  
         transcoder=XMLPlatformUtils::fgTransService->makeNewTranscoderFor(name_cstr, resValue, 60);  
         if(!transcoder)  
                 throw Exception(0, 0,  
                         source,  
                         "unsupported encoding");  
 }  
 #endif  
   
 static int sort_cmp_Trans_rec_intCh(const void *a, const void *b) {  static int sort_cmp_Trans_rec_intCh(const void *a, const void *b) {
         return           return 
                 static_cast<const Charset_TransRec *>(a)->intCh-                  static_cast<const Charset_TransRec *>(a)->intCh-
Line 277  static int sort_cmp_Trans_rec_intCh(cons Line 166  static int sort_cmp_Trans_rec_intCh(cons
 }  }
   
 void Charset::sort_ToTable() {  void Charset::sort_ToTable() {
         _qsort(toTable, toTableSize, sizeof(*toTable),           _qsort(tables.toTable, tables.toTableSize, sizeof(*tables.toTable), 
                 sort_cmp_Trans_rec_intCh);                  sort_cmp_Trans_rec_intCh);
         //FILE *f=fopen("c:\\temp\\a", "wb");          //FILE *f=fopen("c:\\temp\\a", "wb");
         //fwrite(toTable, toTableSize, sizeof(*toTable), f);          //fwrite(tables.toTable, tables.toTableSize, sizeof(*tables.toTable), f);
         //fclose(f);          //fclose(f);
 }  }
   
 XMLByte Charset::xlatOneTo(const XMLCh toXlat) const {  static XMLByte xlatOneTo(const XMLCh toXlat,
     unsigned int    lowOfs = 0;                           const Charset::Tables& tables,
     unsigned int    hiOfs = toTableSize - 1;                           XMLByte not_found) {
     XMLByte         curByte = 0;          unsigned int    lowOfs = 0;
     do {          unsigned int    hiOfs = tables.toTableSize - 1;
         // Calc the mid point of the low and high offset.          XMLByte         curByte = 0;
         const unsigned int midOfs = ((hiOfs - lowOfs) / 2) + lowOfs;          do {
                   // Calc the mid point of the low and high offset.
         //  If our test char is greater than the mid point char, then                  const unsigned int midOfs =((hiOfs - lowOfs) / 2)+lowOfs;
         //  we move up to the upper half. Else we move to the lower                  
         //  half. If its equal, then its our guy.                  //  If our test char is greater than the mid point char, then
         if (toXlat > toTable[midOfs].intCh)                  //  we move up to the upper half. Else we move to the lower
             lowOfs = midOfs;                  //  half. If its equal, then its our guy.
                 else if (toXlat < toTable[midOfs].intCh)                  if(toXlat>tables.toTable[midOfs].intCh)
                           lowOfs = midOfs;
                   else if(toXlat<tables.toTable[midOfs].intCh)
                         hiOfs = midOfs;                          hiOfs = midOfs;
                 else                  else
                         return toTable[midOfs].extCh;                          return tables.toTable[midOfs].extCh;
         } while(lowOfs + 1 < hiOfs);          } while(lowOfs+1<hiOfs);
           
     return '?';          return not_found;
 }  }
   
 void Charset::transcode(Pool& pool,  String::C Charset::transcode(const String::C src,
         const Charset& source_charset, const void *source_body, size_t source_content_length,          const Charset& source_charset, 
         const Charset& dest_charset, const void *& dest_body, size_t& dest_content_length          const Charset& dest_charset) {
         ) {          if(!src.length)
                   return String::C(0, 0);
   
         switch((source_charset.isUTF8()?0x10:0x00)|(dest_charset.isUTF8()?0x01:0x00)) {          switch((source_charset.isUTF8()?0x10:0x00)|(dest_charset.isUTF8()?0x01:0x00)) {
                 default: // 0x00                  default: // 0x00
                         source_charset.transcodeToCharset(pool, dest_charset,                          return source_charset.transcodeToCharset(src, dest_charset);
                                 source_body, source_content_length,  
                                 dest_body, dest_content_length);  
                         break;  
                 case 0x01:                  case 0x01:
                         source_charset.transcodeToUTF8(pool,                          return source_charset.transcodeToUTF8(src);
                                 source_body, source_content_length,  
                                 dest_body, dest_content_length);  
                         break;  
                 case 0x10:                  case 0x10:
                         dest_charset.transcodeFromUTF8(pool,                          return dest_charset.transcodeFromUTF8(src);
                                 source_body, source_content_length,  
                                 dest_body, dest_content_length);  
                         break;  
                 case 0x11:                  case 0x11:
                         dest_body=source_body;                          return src;
                         dest_content_length=source_content_length;  
                         break;  
         }          }
 }  }
   
Line 374  static const XMLByte gFirstByteMark[7] = Line 256  static const XMLByte gFirstByteMark[7] =
     0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC      0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
 };  };
   
 /// @todo not so memory-hungry with prescan  static int transcodeToUTF8(
 void Charset::transcodeToUTF8(Pool& pool,                             const XMLByte* srcData, size_t& srcLen,
                                                                  const void *source_body, size_t source_content_length,                             XMLByte *toFill, size_t& toFillLen,
                                                                  const void *& adest_body, size_t& adest_content_length) const {                             const Charset::Tables& tables) {
                   const XMLByte* srcPtr=srcData;
         size_t dest_content_length=0;          const XMLByte* srcEnd=srcData+srcLen;
         XMLByte *dest_body=(XMLByte*)pool.malloc(source_content_length*6/*so that surly enough*/);          XMLByte* outPtr=toFill;
           XMLByte* outEnd=toFill+toFillLen;
         const XMLByte* srcPtr=(const XMLByte*)source_body;  
         const XMLByte* srcEnd=(const XMLByte*)source_body+source_content_length;  
         XMLByte* outPtr=dest_body;  
   
     while (srcPtr < srcEnd) {          while(srcPtr<srcEnd) {
         uint curVal = fromTable[*srcPtr];                  uint curVal = tables.fromTable[*srcPtr];
                 if(!curVal) {                  if(!curVal) {
             // use the replacement character                          // use the replacement character
             *outPtr++ = '?';                          *outPtr++= '?';
             srcPtr ++;                          srcPtr++;
             continue;                          continue;
         }                  }
   
         // Figure out how many bytes we need  
         unsigned int encodedBytes;  
         if (curVal < 0x80)  
             encodedBytes = 1;  
         else if (curVal < 0x800)  
             encodedBytes = 2;  
         else if (curVal < 0x10000)  
             encodedBytes = 3;  
         else if (curVal < 0x200000)  
             encodedBytes = 4;  
         else if (curVal < 0x4000000)  
             encodedBytes = 5;  
         else if (curVal <= 0x7FFFFFFF)  
             encodedBytes = 6;  
         else {  
             // use the replacement character  
             *outPtr++ = '?';  
             srcPtr ++;  
             continue;  
         }  
   
         //  If we cannot fully get this char into the output buffer,  
                 // never  
   
         // We can do it, so update the source index  
         srcPtr++;  
   
         //  And spit out the bytes. We spit them out in reverse order                  // Figure out how many bytes we need
         //  here, so bump up the output pointer and work down as we go.                  unsigned int encodedBytes;
         outPtr += encodedBytes;                  if(curVal<0x80)
         switch(encodedBytes) {                          encodedBytes = 1;
             case 6 : *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);                  else if(curVal<0x800)
                      curVal >>= 6;                          encodedBytes = 2;
             case 5 : *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);                  else if(curVal<0x10000)
                      curVal >>= 6;                          encodedBytes = 3;
             case 4 : *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);                  else if(curVal<0x200000)
                      curVal >>= 6;                          encodedBytes = 4;
             case 3 : *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);                  else if(curVal<0x4000000)
                      curVal >>= 6;                          encodedBytes = 5;
             case 2 : *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);                  else if(curVal<= 0x7FFFFFFF)
                      curVal >>= 6;                          encodedBytes = 6;
             case 1 : *--outPtr = XMLByte(curVal | gFirstByteMark[encodedBytes]);                  else {
         }                          // use the replacement character
                           *outPtr++= '?';
                           srcPtr++;
                           continue;
                   }
   
         // Add the encoded bytes back in again to indicate we've eaten them                  //  If we cannot fully get this char into the output buffer
         outPtr += encodedBytes;                  if (outPtr + encodedBytes > outEnd)
     }                          break;
                   
         // return                  // We can do it, so update the source index
         adest_body=dest_body;                  srcPtr++;
         adest_content_length=outPtr-dest_body;                  
 }                  //  And spit out the bytes. We spit them out in reverse order
 void Charset::transcodeFromUTF8(Pool& pool,                  //  here, so bump up the output pointer and work down as we go.
                                                                    const void *source_body, size_t source_content_length,                  outPtr+= encodedBytes;
                                                                    const void *& adest_body, size_t& adest_content_length) const {                  switch(encodedBytes) {
         size_t dest_content_length=0;                  case 6: *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
         XMLByte *dest_body=(XMLByte*)pool.malloc(source_content_length/*surly enough*/);                          curVal>>= 6;
                   case 5: *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
         const XMLByte* srcPtr=(const XMLByte*)source_body;                          curVal>>= 6;
         const XMLByte* srcEnd=(const XMLByte*)source_body+source_content_length;                  case 4: *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
         XMLByte* outPtr=dest_body;                          curVal>>= 6;
                   case 3: *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
                           curVal>>= 6;
                   case 2: *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
                           curVal>>= 6;
                   case 1: *--outPtr = XMLByte(curVal | gFirstByteMark[encodedBytes]);
                   }
                   
                   // Add the encoded bytes back in again to indicate we've eaten them
                   outPtr+= encodedBytes;
           }
           
           // Update the bytes eaten
           srcLen = srcPtr - srcData;
           
           // Return the characters read
           toFillLen = outPtr - toFill;
           
           //return srcPtr==srcEnd?(int)toFillLen:-1;
   /*
   xmlCharEncodingInputFunc
   Returns :
   the number of byte written, or -1 by lack of space, or -2 if the transcoding failed. The value of inlen after return is the
   number of octets consumed as the return value is positive, else unpredictiable. The value of outlen after return is the number
   of ocetes consumed.
   */
           return 0;
   }
   /// @todo digital entites only when xml/html output [at output in html/xml mode, in html part of a letter]
   static int transcodeFromUTF8(
                                                                   const XMLByte* srcData, size_t& srcLen,
                                                                   XMLByte* toFill, size_t& toFillLen,
                                                                   const Charset::Tables& tables) {
           const XMLByte* srcPtr=srcData;
           const XMLByte* srcEnd=srcData+srcLen;
           XMLByte* outPtr=toFill;
           XMLByte* outEnd=toFill+toFillLen;
   
     //  We now loop until we either run out of input data      //  We now loop until we either run out of input data, or room to store
     while (srcPtr < srcEnd) {      while ((srcPtr < srcEnd) && (outPtr < outEnd)) {
         // Get the next leading byte out          // Get the next leading byte out
         const XMLByte firstByte = *srcPtr;          const XMLByte firstByte =* srcPtr;
   
         // Special-case ASCII, which is a leading byte value of <= 127          // Special-case ASCII, which is a leading byte value of<= 127
         if (firstByte <= 127) {          if(firstByte<= 127) {
             *outPtr++ = firstByte;              *outPtr++= firstByte;
             srcPtr++;              srcPtr++;
             continue;              continue;
         }          }
Line 473  void Charset::transcodeFromUTF8(Pool& po Line 365  void Charset::transcodeFromUTF8(Pool& po
         const unsigned int trailingBytes = gUTFBytes[firstByte];          const unsigned int trailingBytes = gUTFBytes[firstByte];
   
         //  If there are not enough source bytes to do this one, then we          //  If there are not enough source bytes to do this one, then we
         //  are done. Note that we done >= here because we are implicitly          //  are done. Note that we done>= here because we are implicitly
         //  counting the 1 byte we get no matter what.          //  counting the 1 byte we get no matter what.
         if (srcPtr + trailingBytes >= srcEnd)          if(srcPtr+trailingBytes>= srcEnd)
             break;              break;
   
         // Looks ok, so lets build up the value          // Looks ok, so lets build up the value
Line 490  void Charset::transcodeFromUTF8(Pool& po Line 382  void Charset::transcodeFromUTF8(Pool& po
                      break;                       break;
   
             default:              default:
                 throw Exception(0, 0,                  throw Exception(0,
                                         0,                                          0,
                                         "transcodeFromUTF8 error: wrong trailingBytes value (%d)", trailingBytes);                                          "transcodeFromUTF8 error: wrong trailingBytes value(%d)", trailingBytes);
         }          }
         tmpVal-=gUTFOffsets[trailingBytes];          tmpVal-=gUTFOffsets[trailingBytes];
   
         //  If it will fit into a single char, then put it in. Otherwise          //  If it will fit into a single char, then put it in. Otherwise
         //  fail [*encode it as a surrogate pair. If its not valid, use the          //  fail [*encode it as a surrogate pair. If its not valid, use the
         //  replacement char.*]          //  replacement char.*]
         if (!(tmpVal & 0xFFFF0000))          if(!(tmpVal & 0xFFFF0000)) {
             *outPtr++ = xlatOneTo(tmpVal);                          if(XMLByte xlat=xlatOneTo(tmpVal, tables, 0))
                 else                                  *outPtr++=xlat;
                         throw Exception(0, 0,                          else 
                                   outPtr+=sprintf((char *)outPtr, "&#%d;", tmpVal); // &#decimal;
                   } else
                           throw Exception(0,
                                 0,                                  0,
                                 "transcodeFromUTF8 error: too big tmpVal (0x%08X)", tmpVal);                                  "transcodeFromUTF8 error: too big tmpVal(0x%08X)", tmpVal);
         }          }
   
         // return      // Update the bytes eaten
         adest_body=dest_body;      srcLen = srcPtr - srcData;
         adest_content_length=outPtr-dest_body;  
 }  
   
 /// transcode using both charsets      // Return the characters read
 void Charset::transcodeToCharset(Pool& pool,      toFillLen = outPtr - toFill;
                                                                            const Charset& dest_charset,  
                                                                            const void *source_body, size_t source_content_length,          //return srcPtr==srcEnd?(int)toFillLen:-1;
                                                                            const void *& adest_body, size_t& dest_content_length) const {  
         throw Exception(0, 0,  
                 0,  
                 "transcodeToCharset not supported(yet)");  
 /*  /*
         void *dest_body;  xmlCharEncodingOutputFunc
   Returns :
   the number of byte written, or -1 by lack of space, or -2 if the transcoding failed. The value of inlen after return is the
   number of octets consumed as the return value is positive, else unpredictiable. The value of outlen after return is the number
   of ocetes consumed.
   */
           return 0;
   }
   
   /// @todo not so memory-hungry with prescan
   const String::C Charset::transcodeToUTF8(const String::C src) const {
           size_t src_length=src.length;
           size_t dest_length=src.length*6/*so that surly enough, max utf8 seq len=6*/;
           XMLByte *dest_body=new(PointerFreeGC) XMLByte[dest_length+1/*for terminator*/];
   
           if(::transcodeToUTF8(
                   (XMLByte *)src.str, src_length,
                   dest_body, dest_length,
                   tables)<0)
                   throw(0, 0,
                           0,
                           "Charset::transcodeToUTF8 buffer overflow");
   
           dest_body[dest_length]=0; // terminator
           return String::C((char*)dest_body, dest_length);
   }
   const String::C Charset::transcodeFromUTF8(const String::C src) const {
           size_t src_length=src.length;
           size_t dest_length=src.length*6/*so that surly enough, "&#255;" has max ratio */;
           XMLByte *dest_body=new(PointerFreeGC) XMLByte[dest_length+1/*for terminator*/];
   
           if(::transcodeFromUTF8(
                   (XMLByte *)src.str, src_length,
                   dest_body, dest_length,
                   tables)<0)
                   throw(0, 0,
                           0,
                           "Charset::transcodeFromUTF8 buffer overflow");
   
           dest_body[dest_length]=0; // terminator
           return String::C((char*)dest_body, dest_length);
   }
   
         dest_body=pool.malloc(dest_content_length=source_content_length);  /// transcode using both charsets
         // dummy  const String::C Charset::transcodeToCharset(const String::C src, 
         memset(dest_body, '?', dest_content_length);                                              const Charset& dest_charset) const {
           if(&dest_charset==this) 
                   return src;
           else {
                   size_t dest_length=src.length;
                   XMLByte* dest_body=new(PointerFreeGC) XMLByte[dest_length+1/*for terminator*/];
   
                   XMLByte* output=dest_body;
                   const XMLByte* input=(XMLByte *)src.str;
                   while(XMLCh c=*input++) {
                           XMLCh curVal = tables.fromTable[c];
                           *output++=curVal?
                                   xlatOneTo(curVal, dest_charset.tables, '?') // OK
                                   :'?'; // use the replacement character
                   }
   
         adest_body=dest_body;*/                  dest_body[dest_length]=0; // terminator
                   return String::C((char*)dest_body, dest_length);
           }
 }                         }                       
   
 #ifdef XML  #ifdef XML
 const char *Charset::transcode_cstr(const XalanDOMString& s) {   
         const unsigned int len=s.size()*2;  static const Charset::Tables* tables[MAX_CHARSETS];
         XMLByte* dest=(XMLByte *)malloc((len+1)*sizeof(XMLByte));  
         bool error=true;  #define declareXml256ioFuncs(i) \
         try {          static int xml256CharEncodingInputFunc##i( \
                 if(transcoder) {                  unsigned char *out, int *outlen, \
                         unsigned int charsEaten;                  const unsigned char *in, int *inlen) { \
                         unsigned int size=transcoder->transcodeTo(                  return transcodeToUTF8( \
                                 s.c_str(), s.length(),                          in, *(size_t*)inlen, \
                                 dest, len,                          out, *(size_t*)outlen, \
                                 charsEaten,                          *tables[i]); \
                                 XMLTranscoder::UnRep_RepChar //UnRep_Throw          } \
                         );          static int xml256CharEncodingOutputFunc##i( \
                         dest[size]=0;                  unsigned char *out, int *outlen, \
                         error=false;                  const unsigned char *in, int *inlen) { \
                 }                  return transcodeFromUTF8( \
         } catch(XMLException& e) {                          in, *(size_t*)inlen, \
                 Exception::provide_source(pool(), 0, e);                          out, *(size_t*)outlen, \
                           *tables[i]); \
         }          }
         return (const char *)dest;  
   declareXml256ioFuncs(0) declareXml256ioFuncs(1)
   declareXml256ioFuncs(2) declareXml256ioFuncs(3)
   declareXml256ioFuncs(4) declareXml256ioFuncs(5)
   declareXml256ioFuncs(6) declareXml256ioFuncs(7)
   declareXml256ioFuncs(8) declareXml256ioFuncs(9)
   
   static xmlCharEncodingInputFunc inputFuncs[MAX_CHARSETS]={
           xml256CharEncodingInputFunc0,   xml256CharEncodingInputFunc1,
           xml256CharEncodingInputFunc2,   xml256CharEncodingInputFunc3,
           xml256CharEncodingInputFunc4,   xml256CharEncodingInputFunc5,
           xml256CharEncodingInputFunc6,   xml256CharEncodingInputFunc7,
           xml256CharEncodingInputFunc8,   xml256CharEncodingInputFunc9
   };
   static xmlCharEncodingOutputFunc outputFuncs[MAX_CHARSETS]={
           xml256CharEncodingOutputFunc0,  xml256CharEncodingOutputFunc1,
           xml256CharEncodingOutputFunc2,  xml256CharEncodingOutputFunc3,
           xml256CharEncodingOutputFunc4,  xml256CharEncodingOutputFunc5,
           xml256CharEncodingOutputFunc6,  xml256CharEncodingOutputFunc7,
           xml256CharEncodingOutputFunc8,  xml256CharEncodingOutputFunc9
   };
   static size_t handlers_count=0;
   
   void Charset::addEncoding(char *name_cstr) {
           if(handlers_count==MAX_CHARSETS)
                   throw Exception(0,
                           0,
                           "already allocated %d handlers, no space for new encoding '%s'",
                                   MAX_CHARSETS, name_cstr);
   
           xmlCharEncodingHandler* handler=new(PointerFreeGC) xmlCharEncodingHandler;
           {
                   handler->name=name_cstr;
                   handler->input=inputFuncs[handlers_count]; 
                   handler->output=outputFuncs[handlers_count]; 
                   ::tables[handlers_count]=&tables;
                   handlers_count++;
           }
           
           xmlRegisterCharEncodingHandler(handler);
   
 }  }
 String& Charset::transcode(const XalanDOMString& s) {   
         return *NEW String(pool(), transcode_cstr(s));   void Charset::initTranscoder(const StringBody NAME, const char* name_cstr) {
           ftranscoder=xmlFindCharEncodingHandler(name_cstr);
           transcoder(NAME); // check right way
 }  }
   
 std::auto_ptr<XalanDOMString> Charset::transcode_buf(const char *buf, size_t buf_size) {   xmlCharEncodingHandler& Charset::transcoder(const StringBody NAME) {
         unsigned int dest_size=0;          if(!ftranscoder)
         XMLCh* dest=(XMLCh *)malloc((buf_size+1)*sizeof(XMLCh));                  throw Exception("parser.runtime",
         unsigned char *charSizes=(unsigned char *)malloc(buf_size*sizeof(unsigned char));                          new String(NAME, String::L_TAINTED),
         XalanDOMString *result;                          "unsupported encoding");
         try {          return *ftranscoder;
                 if(transcoder) {  }
                         unsigned int bytesEaten;  
                         unsigned int dest_size=transcoder->transcodeFrom(  const char* Charset::transcode_cstr(xmlChar* s) {
                                 (unsigned char *)buf,          if(!s)
                                 (const unsigned int)buf_size,                  return "";
                                 dest, (const unsigned int)buf_size,  
                                 bytesEaten,          int inlen=strlen((const char* )s);
                                 charSizes          int outlen=inlen+1; // max
                         );          char *out=new(PointerFreeGC) char[outlen];
                         result=new XalanDOMString(dest, dest_size);          
                 }          int error;
         } catch(XMLException& e) {          if(xmlCharEncodingOutputFunc output=transcoder(FNAME).output) {
                 Exception::provide_source(pool(), 0, e);                  error=output(
                 result=0; //calm, compiler                          (unsigned char*)out, &outlen,
                           (const unsigned char*)s, &inlen);
           } else {
                   memcpy(out, s, outlen=inlen);
                   error=0;
           }
           if(error<0)
                   throw Exception(0,
                           0,
                           "transcode_cstr failed (%d)", error);
   
           out[outlen/*surely would be less then on input*/]=0;
           return out;
   }
   const String& Charset::transcode(xmlChar* s) { 
           return *new String(transcode_cstr(s), 0/*auto-size*/, true);
   }
   const char* Charset::transcode_cstr(GdomeDOMString* s) { 
           return s?transcode_cstr(BAD_CAST s->str):"";
   }
   const String& Charset::transcode(GdomeDOMString* s) { 
           return *new String(transcode_cstr(s), 0/*auto-size*/, true);
   }
   
   /// @test less memory using -maybe- xmlParserInputBufferCreateMem
   void* Charset::transcode_buf2mchar(transcode_buf_malloc_func malloc_func, 
                                      const char* buf, size_t buf_size) {
           unsigned char* out;
           int outlen;
           int error;
           if(xmlCharEncodingInputFunc input=transcoder(FNAME).input) {
                   outlen=buf_size*6/*max*/;
                   out=(unsigned char*)malloc_func(outlen+1);
           } else {
                   outlen=buf_size;
                   out=(unsigned char*)malloc_func(outlen+1);
                   memcpy(out, buf, outlen);
                   error=0;
         }          }
                   
         return std::auto_ptr<XalanDOMString>(result);          if(error<0)
                   throw Exception(0,
                           0,
                           "transcode_buf failed (%d)", error);
   
           out[outlen/*surely would be less then on input*/]=0;
           return out;
   }
   
   xmlChar* Charset::transcode_buf2xchar(const char* buf, size_t buf_size) {
           return static_cast<xmlChar*>(transcode_buf2mchar(xmlMalloc, buf, buf_size));
   }
   static void* g_malloc_wrapper(size_t size) {
           if(void* out=g_malloc(size))
                   return out;
   
           return pa_fail_alloc("g_malloc_wrapper", size);
   }
   gchar* Charset::transcode_buf2gchar(const char* buf, size_t buf_size) {
           return static_cast<gchar*>(transcode_buf2mchar(g_malloc_wrapper, buf, buf_size));
   }
   GdomeDOMString_auto_ptr Charset::transcode_buf2dom(const char* buf, size_t buf_size) { 
           return GdomeDOMString_auto_ptr(transcode_buf2gchar(buf, buf_size));
   }
   GdomeDOMString_auto_ptr Charset::transcode(const String& s) { 
           const char* cstr=s.cstr(String::L_UNSPECIFIED);
   
           return transcode_buf2dom(cstr, strlen(cstr)); 
 }  }
 std::auto_ptr<XalanDOMString> Charset::transcode(const String& s) {   GdomeDOMString_auto_ptr Charset::transcode(const StringBody s) { 
         const char *cstr=s.cstr(String::UL_UNSPECIFIED);          const char* cstr=s.cstr();
   
         return transcode_buf(cstr, strlen(cstr));           return transcode_buf2dom(cstr, s.length()); 
 }  }
 #endif  #endif

Removed from v.1.2  
changed lines
  Added in v.1.33.2.19.2.19


E-mail: