Diff for /parser3/src/main/pa_charset.C between versions 1.6 and 1.33.2.10

version 1.6, 2001/12/19 16:41:02 version 1.33.2.10, 2003/02/19 16:19:00
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_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  // globals
   
   #define CHARSET_UTF8_NAME "UTF-8"
   
 // consts  CharsetPtr UTF8_charset(new Charset(StringPtr(new String(CHARSET_UTF8_NAME)), 
                                            StringPtr(0)/*no file=system*/));
 #define MAX_CHARSET_UNI_CODES 500  
   
 // helpers  // helpers
   
Line 43  inline void cstr2ctypes(unsigned char *t Line 37  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)
Line 52  inline unsigned int to_wchar_code(const Line 46  inline unsigned int to_wchar_code(const
         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 77  static void element2case(unsigned char f Line 71  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(StringPtr aname, StringPtr afile_spec): 
         fname(apool) {          fname(aname),
         // fname          fname_cstr(aname->cstr()) {
         char *name_cstr=(char *)malloc(aname.size()+1);  
         memcpy(name_cstr, aname.cstr(String::UL_AS_IS), aname.size()+1);          for(char *c=fname_cstr; *c; c++)
         fname.APPEND_CLEAN(name_cstr, aname.size(), 0, 0);          *c = toupper(*c);
   
         if(file_spec) {          if(afile_spec) {
                 fisUTF8=false;                  fisUTF8=false;
                 loadDefinition(*file_spec);                  load_definition(afile_spec);
 #ifdef XML  #ifdef XML
                 addEncoding(name_cstr);                  addEncoding(fname_cstr);
 #endif  #endif
         } else {          } else {
                 fisUTF8=true;                  fisUTF8=true;
Line 157  Charset::Charset(Pool& apool, const Stri Line 94  Charset::Charset(Pool& apool, const Stri
         }          }
   
 #ifdef XML  #ifdef XML
         initTranscoder(&aname, name_cstr);          initTranscoder(fname, fname_cstr);
 #endif  #endif
 }  }
   
 Charset::~Charset() {  Charset::~Charset() {
           // @todonow unregister encodings
 #ifdef XML  #ifdef XML
         delete transcoder;          // not deleting transcoder, that's not our business
 #endif  #endif
 }  }
   
 void Charset::loadDefinition(const String& file_spec) {  void Charset::load_definition(StringPtr afile_spec) {
         // pcre_tables          // pcre_tables
         // lowcase, flipcase, bits digit+word+whitespace, masks          // lowcase, flipcase, bits digit+word+whitespace, masks
   
Line 178  void Charset::loadDefinition(const Strin Line 116  void Charset::loadDefinition(const Strin
         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.fromTable, 0, sizeof(tables.fromTable));
         toTable=(Charset_TransRec *)calloc(sizeof(Charset_TransRec)*MAX_CHARSET_UNI_CODES);          memset(tables.toTable, 0, sizeof(tables.toTable));
         toTableSize=0;          tables.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);          Pool pool_for_load_only;
           char *data=file_read_text(pool_for_load_only, *UTF8_charset, afile_spec);
   
         // ignore header          // ignore header
         getrow(&data);          getrow(&data);
Line 215  void Charset::loadDefinition(const Strin Line 154  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 239  void Charset::loadDefinition(const Strin Line 178  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 276  static int sort_cmp_Trans_rec_intCh(cons Line 185  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,
                                                    const Charset::Tables& tables,
                                                    XMLByte not_found) {
     unsigned int    lowOfs = 0;      unsigned int    lowOfs = 0;
     unsigned int    hiOfs = toTableSize - 1;      unsigned int    hiOfs = tables.toTableSize - 1;
     XMLByte         curByte = 0;      XMLByte         curByte = 0;
     do {      do {
         // Calc the mid point of the low and high offset.          // Calc the mid point of the low and high offset.
Line 294  XMLByte Charset::xlatOneTo(const XMLCh t Line 205  XMLByte Charset::xlatOneTo(const XMLCh t
         //  If our test char is greater than the mid point char, then          //  If our test char is greater than the mid point char, then
         //  we move up to the upper half. Else we move to the lower          //  we move up to the upper half. Else we move to the lower
         //  half. If its equal, then its our guy.          //  half. If its equal, then its our guy.
         if(toXlat>toTable[midOfs].intCh)          if(toXlat>tables.toTable[midOfs].intCh)
             lowOfs = midOfs;              lowOfs = midOfs;
                 else if(toXlat<toTable[midOfs].intCh)                  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,  void Charset::transcode(Pool& pool,
Line 379  static const XMLByte gFirstByteMark[7] = Line 290  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++= '?';
Line 421  void Charset::transcodeToUTF8(Pool& pool Line 329  void Charset::transcodeToUTF8(Pool& pool
             continue;              continue;
         }          }
   
         //  If we cannot fully get this char into the output buffer,          //  If we cannot fully get this char into the output buffer
                 // never          if (outPtr + encodedBytes > outEnd)
               break;
   
         // We can do it, so update the source index          // We can do it, so update the source index
         srcPtr++;          srcPtr++;
Line 448  void Charset::transcodeToUTF8(Pool& pool Line 357  void Charset::transcodeToUTF8(Pool& pool
         outPtr+= encodedBytes;          outPtr+= encodedBytes;
     }      }
   
         // return      // Update the bytes eaten
         adest_body=dest_body;      srcLen = srcPtr - srcData;
         adest_content_length=outPtr-dest_body;  
       // 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;
 }  }
 void Charset::transcodeFromUTF8(Pool& pool,  /// @todo digital entites only when xml/html output [at output in html/xml mode, in html part of a letter]
                                                                    const void *source_body, size_t source_content_length,  static int transcodeFromUTF8(
                                                                    const void *& adest_body, size_t& adest_content_length) const {                                                                  const XMLByte *srcData, size_t& srcLen,
         size_t dest_content_length=0;                                                                  XMLByte* toFill, size_t& toFillLen,
         XMLByte *dest_body=(XMLByte*)pool.malloc(source_content_length/*surly enough*/);                                                                  const Charset::Tables& tables) {
           const XMLByte* srcPtr=srcData;
         const XMLByte* srcPtr=(const XMLByte*)source_body;          const XMLByte* srcEnd=srcData+srcLen;
         const XMLByte* srcEnd=(const XMLByte*)source_body+source_content_length;          XMLByte* outPtr=toFill;
         XMLByte* outPtr=dest_body;          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;
   
Line 495  void Charset::transcodeFromUTF8(Pool& po Line 416  void Charset::transcodeFromUTF8(Pool& po
                      break;                       break;
   
             default:              default:
                 throw Exception(0, 0,                  throw Exception(0,
                                         0,                                          Exception::undefined_source,
                                         "transcodeFromUTF8 error: wrong trailingBytes value(%d)", trailingBytes);                                          "transcodeFromUTF8 error: wrong trailingBytes value(%d)", trailingBytes);
         }          }
         tmpVal-=gUTFOffsets[trailingBytes];          tmpVal-=gUTFOffsets[trailingBytes];
Line 504  void Charset::transcodeFromUTF8(Pool& po Line 425  void Charset::transcodeFromUTF8(Pool& po
         //  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 
                                 0,                                  outPtr+=sprintf((char *)outPtr, "&#%d;", tmpVal); // &#decimal;
                   } else
                           throw Exception(0,
                                   Exception::undefined_source,
                                 "transcodeFromUTF8 error: too big tmpVal(0x%08X)", tmpVal);                                  "transcodeFromUTF8 error: too big tmpVal(0x%08X)", tmpVal);
         }          }
   
       // Update the bytes eaten
       srcLen = srcPtr - srcData;
   
       // Return the characters read
       toFillLen = outPtr - toFill;
   
           //return srcPtr==srcEnd?(int)toFillLen:-1;
   /*
   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
   void Charset::transcodeToUTF8(Pool& pool,
                                                                    const void *source_body, size_t source_content_length,
                                                                    const void *& adest_body, size_t& dest_content_length) const {
           dest_content_length=source_content_length*6/*so that surly enough, max utf8 seq len=6*/;
           XMLByte *dest_body=new(pool) XMLByte[dest_content_length];
   
           if(::transcodeToUTF8(
                   (XMLByte *)source_body, source_content_length,
                   dest_body, dest_content_length,
                   tables)<0)
                   throw(0, 0,
                           0,
                           "Charset::transcodeToUTF8 buffer overflow");
   
           // return
           adest_body=dest_body;
   }
   void Charset::transcodeFromUTF8(Pool& pool,
                                                                      const void *source_body, size_t source_content_length,
                                                                      const void *& adest_body, size_t& dest_content_length) const {
           dest_content_length=source_content_length*6/*so that surly enough, "&#255;" has max ratio */;
           XMLByte *dest_body=new(pool) XMLByte[dest_content_length];
   
           if(::transcodeFromUTF8(
                   (XMLByte *)source_body, source_content_length,
                   dest_body, dest_content_length,
                   tables)<0)
                   throw(0, 0,
                           0,
                           "Charset::transcodeToUTF8 buffer overflow");
   
         // return          // return
         adest_body=dest_body;          adest_body=dest_body;
         adest_content_length=outPtr-dest_body;  
 }  }
   
 /// transcode using both charsets  /// transcode using both charsets
Line 527  void Charset::transcodeToCharset(Pool& p Line 499  void Charset::transcodeToCharset(Pool& p
                 adest_content_length=source_content_length;                  adest_content_length=source_content_length;
         } else {          } else {
                 size_t dest_content_length=source_content_length;                  size_t dest_content_length=source_content_length;
                 unsigned char *dest_body=(unsigned char *)pool.malloc(dest_content_length);                  unsigned char *dest_body=new(pool) unsigned char[dest_content_length];
   
                 const XMLByte* srcPtr=(const XMLByte*)source_body;                  const XMLByte* srcPtr=(XMLByte *)source_body;
                 const XMLByte* srcEnd=(const XMLByte*)source_body+source_content_length;                  const XMLByte* srcEnd=(XMLByte *)source_body+source_content_length;
   
                 for(XMLByte* outPtr=dest_body; srcPtr<srcEnd; srcPtr++) {                  for(XMLByte* outPtr=dest_body; srcPtr<srcEnd; srcPtr++) {
                         XMLCh curVal = fromTable[*srcPtr];                          XMLCh curVal = tables.fromTable[*srcPtr];
                         if(curVal)                           if(curVal) 
                                 *outPtr++=dest_charset.xlatOneTo(curVal);                                  *outPtr++=xlatOneTo(curVal, dest_charset.tables, '?');
                         else {                          else {
                                 // use the replacement character                                  // use the replacement character
                                 *outPtr++= '?';                                  *outPtr++= '?';
Line 548  void Charset::transcodeToCharset(Pool& p Line 520  void Charset::transcodeToCharset(Pool& p
 }                         }                       
   
 #ifdef XML  #ifdef XML
 const char *Charset::transcode_cstr(const XalanDOMString& s) {   static int         xml256CharEncodingInputFunc     (
         const unsigned int len=s.size()*2;                                                                                                          unsigned char *out,
         XMLByte* dest=(XMLByte *)malloc((len+1)*sizeof(XMLByte));                                                                                                          int *outlen,
         bool error=true;                                                                                                          const unsigned char *in,
         try {                                                                                                          int *inlen, 
                 if(transcoder) {                                                                                                          void *info) {
                         unsigned int charsEaten;          return transcodeToUTF8(
                         unsigned int size=transcoder->transcodeTo(                                                          in, *(size_t*)inlen,
                                 s.c_str(), s.length(),                                                          out, *(size_t*)outlen,
                                 dest, len,                                                          *(const Charset::Tables *)info);
                                 charsEaten,  }
                                 XMLTranscoder::UnRep_RepChar //UnRep_Throw  
                         );  static int         xml256CharEncodingOutputFunc    (
                         dest[size]=0;                                                                                                          unsigned char *out,
                         error=false;                                                                                                          int *outlen,
                 }                                                                                                          const unsigned char *in,
         } catch(XMLException& e) {                                                                                                          int *inlen, 
                 Exception::provide_source(pool(), 0, e);                                                                                                          void *info) {
         }          return transcodeFromUTF8(
         return(const char *)dest;                                                          in, *(size_t*)inlen,
                                                           out, *(size_t*)outlen,
                                                           *(const Charset::Tables *)info);
   }
   
   
   void Charset::addEncoding(char *name_cstr) {
           xmlCharEncodingHandler *handler=
                   (xmlCharEncodingHandler *)[ADD to local array of autoptrs to autofree]new ...(sizeof(xmlCharEncodingHandler));
           handler->name=name_cstr;
           handler->input=xml256CharEncodingInputFunc; handler->inputInfo=&tables;
           handler->output=xml256CharEncodingOutputFunc; handler->outputInfo=&tables;
           
           xmlRegisterCharEncodingHandler(handler);
 }  }
 String& Charset::transcode(const XalanDOMString& s) {   
         return *NEW String(pool(), transcode_cstr(s));   void Charset::initTranscoder(const String *source, const char* name_cstr) {
           ftranscoder=xmlFindCharEncodingHandler(name_cstr);
           transcoder(source); // check right way
 }  }
   
 std::auto_ptr<XalanDOMString>Charset::transcode_buf(const char *buf, size_t buf_size) {   xmlCharEncodingHandler *Charset::transcoder(const String *source) {
         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));                          source,
         XalanDOMString *result;                          "unsupported encoding");
         try {          return ftranscoder;
                 if(transcoder) {  }
                         unsigned int bytesEaten;  
                         unsigned int dest_size=transcoder->transcodeFrom(  CharPtr 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 char[outlen];
                         result=new XalanDOMString(dest, dest_size);          
                 }          int error;
         } catch(XMLException& e) {          if(xmlCharEncodingOutputFunc output=transcoder(0)->output) {
                 Exception::provide_source(pool(), 0, e);                  error=output(
                 result=0; //calm, compiler                          (unsigned char*)out, &outlen,
                           (const unsigned char*)s, &inlen,
                           transcoder(0)->outputInfo);
           } 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;
   }
   String& Charset::transcode(xmlChar *s
   #ifndef NO_STRING_ORIGIN
                   , const String *origin
   #endif
                                                      ) { 
           String& result=*NEW String(pool());
           result.APPEND_CLEAN(transcode_cstr(s), 0/*auto-size*/, origin->origin().file, origin->origin().line);
           return result; 
   }
   const char* Charset::transcode_cstr(GdomeDOMString *s) { 
           return s?transcode_cstr(BAD_CAST s->str):"";
   }
   String& Charset::transcode(GdomeDOMString *s
   #ifndef NO_STRING_ORIGIN
                   , const String *origin
   #endif
                                                      ) { 
           String& result=*NEW String(pool());
           result.APPEND_CLEAN(transcode_cstr(s), 0/*auto-size*/, origin->origin().file, origin->origin().line);
           return result; 
   }
   
   /// @test less memory using -maybe- xmlParserInputBufferCreateMem
   xmlChar *Charset::transcode_buf2xchar(Pool& pool, const char* buf, size_t buf_size) {
           unsigned char *out;
           int outlen;
           int error;
           if(xmlCharEncodingInputFunc input=transcoder(0)->input) {
                   outlen=buf_size*6/*max*/;
                   out=new(pool) unsigned char[outlen+1];
                   error=input(
                           out, &outlen,
                           (const unsigned char *)buf,  (int *)&buf_size,
                           transcoder(0)->inputInfo);
           } else {
                   outlen=buf_size;
                   out=new(pool) unsigned char[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 (xmlChar *)out;
   }
   GdomeDOMString_auto_ptr Charset::transcode_buf2dom(const char* buf, size_t buf_size) { 
           return GdomeDOMString_auto_ptr((gchar*)transcode_buf2xchar(buf, buf_size));
 }  }
 std::auto_ptr<XalanDOMString>Charset::transcode(const String& s) {   GdomeDOMString_auto_ptr Charset::transcode(const String& s) { 
         const char *cstr=s.cstr(String::UL_UNSPECIFIED);          const char* cstr=s.cstr(String::UL_UNSPECIFIED);
   
         return transcode_buf(cstr, strlen(cstr));           return transcode_buf2dom(cstr, strlen(cstr)); 
 }  }
 #endif  #endif

Removed from v.1.6  
changed lines
  Added in v.1.33.2.10


E-mail: