Diff for /parser3/src/main/pa_charset.C between versions 1.33.2.12 and 1.34

version 1.33.2.12, 2003/02/26 10:17:30 version 1.34, 2003/03/21 09:43:48
Line 1 Line 1
 /** @file  /** @file
         Parser: Charset connection implementation.          Parser: Charset connection implementation.
   
         Copyright(c) 2001-2003 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)
 */  */
   
 static const char* IDENT_CHARSET_C="$Date$";  static const char* IDENT_CHARSET_C="$Date$";
   
 #include "pa_charset.h"  #include "pa_charset.h"
   #include "pa_array.h"
   #include "pa_hash.h"
   
 #ifdef XML  #ifdef XML
 #include "libxml/encoding.h"  #include "libxml/encoding.h"
Line 15  static const char* IDENT_CHARSET_C="$Dat Line 17  static const char* IDENT_CHARSET_C="$Dat
   
 // globals  // globals
   
 #define CHARSET_UTF8_NAME "UTF-8"  
   
 CharsetPtr UTF8_charset(new Charset(StringPtr(new String(CHARSET_UTF8_NAME)),   // consts
                                          StringPtr(0)/*no file=system*/));  
   #define MAX_CHARSET_UNI_CODES 500
   
 // helpers  // helpers
   
Line 37  inline void cstr2ctypes(unsigned char *t Line 39  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 46  inline unsigned int to_wchar_code(const Line 48  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 74  static void element2case(unsigned char f Line 76  static void element2case(unsigned char f
 // methods  // methods
   
 extern "C" unsigned char pcre_default_tables[]; // pcre/chartables.c  extern "C" unsigned char pcre_default_tables[]; // pcre/chartables.c
 Charset::Charset(StringPtr aname, StringPtr afile_spec):   Charset::Charset(Pool& apool, const String& aname, const String *request_file_spec): Pooled(apool),
         fname(aname),          fname(aname) {
         fname_cstr(aname->cstr()) {  
   
         for(char *c=fname_cstr; *c; c++)          char *name_cstr=fname.cstr();
       for(char *c=name_cstr; *c; c++)
         *c = toupper(*c);          *c = toupper(*c);
   
         if(afile_spec) {          if(request_file_spec) {
                 fisUTF8=false;                  fisUTF8=false;
                 load_definition(afile_spec);                  loadDefinition(*request_file_spec);
 #ifdef XML  #ifdef XML
                 addEncoding(fname_cstr);                  addEncoding(name_cstr);
 #endif  #endif
         } else {          } else {
                 fisUTF8=true;                  fisUTF8=true;
Line 94  Charset::Charset(StringPtr aname, String Line 96  Charset::Charset(StringPtr aname, String
         }          }
   
 #ifdef XML  #ifdef XML
         initTranscoder(fname, fname_cstr);          initTranscoder(&aname, name_cstr);
 #endif  #endif
 }  }
   
 Charset::~Charset() {  Charset::~Charset() {
         // @todonow unregister encodings  
 #ifdef XML  #ifdef XML
         // not deleting transcoder, that's not our business          // not deleting transcoder, that's not our business
 #endif  #endif
 }  }
   
 void Charset::load_definition(StringPtr afile_spec) {  void Charset::loadDefinition(const String& request_file_spec) {
         // pcre_tables          // pcre_tables
         // lowcase, flipcase, bits digit+word+whitespace, masks          // lowcase, flipcase, bits digit+word+whitespace, masks
   
Line 116  void Charset::load_definition(StringPtr Line 117  void Charset::load_definition(StringPtr
         cstr2ctypes(pcre_tables,(const unsigned char *)"*+?{^.$|()[", ctype_meta);          cstr2ctypes(pcre_tables,(const unsigned char *)"*+?{^.$|()[", ctype_meta);
   
         // charset          // charset
         memset(&tables, 0, sizeof(tables));          memset(tables.fromTable, 0, sizeof(tables.fromTable));
           tables.toTable=(Charset_TransRec *)calloc(sizeof(Charset_TransRec)*MAX_CHARSET_UNI_CODES);
           tables.toTableSize=0;
         // strangly vital          // strangly vital
         tables.toTable[tables.toTableSize].intCh=0;          tables.toTable[tables.toTableSize].intCh=0;
         tables.toTable[tables.toTableSize].extCh=(XMLByte)0;          tables.toTable[tables.toTableSize].extCh=(XMLByte)0;
         tables.toTableSize++;          tables.toTableSize++;
   
         // loading text          // loading text
         Pool pool_for_load_only;          char *data=file_read_text(pool(), request_file_spec);
         char *data=file_read_text(pool_for_load_only, *UTF8_charset, afile_spec);  
   
         // ignore header          // ignore header
         getrow(&data);          getrow(&data);
Line 154  void Charset::load_definition(StringPtr Line 156  void Charset::load_definition(StringPtr
                                 // charset                                  // charset
                                 if(tables.toTableSize>MAX_CHARSET_UNI_CODES)                                  if(tables.toTableSize>MAX_CHARSET_UNI_CODES)
                                         throw Exception("parser.runtime",                                          throw Exception("parser.runtime",
                                                 afile_spec,                                                  &request_file_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);
Line 415  static int transcodeFromUTF8( Line 417  static int transcodeFromUTF8(
   
             default:              default:
                 throw Exception(0,                  throw Exception(0,
                                         Exception::undefined_source,                                          0,
                                         "transcodeFromUTF8 error: wrong trailingBytes value(%d)", trailingBytes);                                          "transcodeFromUTF8 error: wrong trailingBytes value(%d)", trailingBytes);
         }          }
         tmpVal-=gUTFOffsets[trailingBytes];          tmpVal-=gUTFOffsets[trailingBytes];
Line 430  static int transcodeFromUTF8( Line 432  static int transcodeFromUTF8(
                                 outPtr+=sprintf((char *)outPtr, "&#%d;", tmpVal); // &#decimal;                                  outPtr+=sprintf((char *)outPtr, "&#%d;", tmpVal); // &#decimal;
                 } else                  } else
                         throw Exception(0,                          throw Exception(0,
                                 Exception::undefined_source,                                  0,
                                 "transcodeFromUTF8 error: too big tmpVal(0x%08X)", tmpVal);                                  "transcodeFromUTF8 error: too big tmpVal(0x%08X)", tmpVal);
         }          }
   
Line 456  void Charset::transcodeToUTF8(Pool& pool Line 458  void Charset::transcodeToUTF8(Pool& pool
                                                                  const void *source_body, size_t source_content_length,                                                                   const void *source_body, size_t source_content_length,
                                                                  const void *& adest_body, size_t& dest_content_length) const {                                                                   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*/;          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];          XMLByte *dest_body=(XMLByte*)pool.malloc(dest_content_length);
   
         if(::transcodeToUTF8(          if(::transcodeToUTF8(
                 (XMLByte *)source_body, source_content_length,                  (XMLByte *)source_body, source_content_length,
Line 473  void Charset::transcodeFromUTF8(Pool& po Line 475  void Charset::transcodeFromUTF8(Pool& po
                                                                    const void *source_body, size_t source_content_length,                                                                     const void *source_body, size_t source_content_length,
                                                                    const void *& adest_body, size_t& dest_content_length) const {                                                                     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 */;          dest_content_length=source_content_length*6/*so that surly enough, "&#255;" has max ratio */;
         XMLByte *dest_body=new(pool) XMLByte[dest_content_length];          XMLByte *dest_body=(XMLByte*)pool.malloc(dest_content_length);
   
         if(::transcodeFromUTF8(          if(::transcodeFromUTF8(
                 (XMLByte *)source_body, source_content_length,                  (XMLByte *)source_body, source_content_length,
Line 497  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=new(pool) unsigned char[dest_content_length];                  unsigned char *dest_body=(unsigned char *)pool.malloc(dest_content_length);
   
                 const XMLByte* srcPtr=(XMLByte *)source_body;                  const XMLByte* srcPtr=(XMLByte *)source_body;
                 const XMLByte* srcEnd=(XMLByte *)source_body+source_content_length;                  const XMLByte* srcEnd=(XMLByte *)source_body+source_content_length;
Line 545  static int         xml256CharEncodingOut Line 547  static int         xml256CharEncodingOut
   
 void Charset::addEncoding(char *name_cstr) {  void Charset::addEncoding(char *name_cstr) {
         xmlCharEncodingHandler *handler=          xmlCharEncodingHandler *handler=
                 (xmlCharEncodingHandler *)[ADD to local array of autoptrs to autofree]new ...(sizeof(xmlCharEncodingHandler));                  (xmlCharEncodingHandler *)malloc(sizeof(xmlCharEncodingHandler));
         handler->name=name_cstr;          handler->name=name_cstr;
         handler->input=xml256CharEncodingInputFunc; handler->inputInfo=&tables;          handler->input=xml256CharEncodingInputFunc; handler->inputInfo=&tables;
         handler->output=xml256CharEncodingOutputFunc; handler->outputInfo=&tables;          handler->output=xml256CharEncodingOutputFunc; handler->outputInfo=&tables;
Line 553  void Charset::addEncoding(char *name_cst Line 555  void Charset::addEncoding(char *name_cst
         xmlRegisterCharEncodingHandler(handler);          xmlRegisterCharEncodingHandler(handler);
 }  }
   
 void Charset::initTranscoder(const String *source, const char* name_cstr) {  void Charset::initTranscoder(const String *source, const char *name_cstr) {
         ftranscoder=xmlFindCharEncodingHandler(name_cstr);          ftranscoder=xmlFindCharEncodingHandler(name_cstr);
         transcoder(source); // check right way          transcoder(source); // check right way
 }  }
Line 566  xmlCharEncodingHandler *Charset::transco Line 568  xmlCharEncodingHandler *Charset::transco
         return ftranscoder;          return ftranscoder;
 }  }
   
 CharPtr Charset::transcode_cstr(xmlChar *s) {  const char *Charset::transcode_cstr(xmlChar *s) {
         if(!s)          if(!s)
                 return "";                  return "";
   
         int inlen=strlen((const char* )s);          int inlen=strlen((const char *)s);
         int outlen=inlen+1; // max          int outlen=inlen+1; // max
         char *out=new char[outlen];          char *out=(char *)malloc(outlen*sizeof(char));
                   
         int error;          int error;
         if(xmlCharEncodingOutputFunc output=transcoder(0)->output) {          if(xmlCharEncodingOutputFunc output=transcoder(0)->output) {
Line 601  String& Charset::transcode(xmlChar *s Line 603  String& Charset::transcode(xmlChar *s
         result.APPEND_CLEAN(transcode_cstr(s), 0/*auto-size*/, origin->origin().file, origin->origin().line);          result.APPEND_CLEAN(transcode_cstr(s), 0/*auto-size*/, origin->origin().file, origin->origin().line);
         return result;           return result; 
 }  }
 const char* Charset::transcode_cstr(GdomeDOMString *s) {   const char *Charset::transcode_cstr(GdomeDOMString *s) { 
         return s?transcode_cstr(BAD_CAST s->str):"";          return s?transcode_cstr(BAD_CAST s->str):"";
 }  }
 String& Charset::transcode(GdomeDOMString *s  String& Charset::transcode(GdomeDOMString *s
Line 615  String& Charset::transcode(GdomeDOMStrin Line 617  String& Charset::transcode(GdomeDOMStrin
 }  }
   
 /// @test less memory using -maybe- xmlParserInputBufferCreateMem  /// @test less memory using -maybe- xmlParserInputBufferCreateMem
 xmlChar *Charset::transcode_buf2xchar(Pool& pool, const char* buf, size_t buf_size) {  xmlChar *Charset::transcode_buf2xchar(const char *buf, size_t buf_size) {
         unsigned char *out;          unsigned char *out;
         int outlen;          int outlen;
         int error;          int error;
         if(xmlCharEncodingInputFunc input=transcoder(0)->input) {          if(xmlCharEncodingInputFunc input=transcoder(0)->input) {
                 outlen=buf_size*6/*max*/;                  outlen=buf_size*6/*max*/;
                 out=new(pool) unsigned char[outlen+1];                  out=(unsigned char*)malloc((outlen+1)*sizeof(unsigned char));
                 error=input(                  error=input(
                         out, &outlen,                          out, &outlen,
                         (const unsigned char *)buf,  (int *)&buf_size,                          (const unsigned char *)buf,  (int *)&buf_size,
                         transcoder(0)->inputInfo);                          transcoder(0)->inputInfo);
         } else {          } else {
                 outlen=buf_size;                  outlen=buf_size;
                 out=new(pool) unsigned char[outlen+1];                  out=(unsigned char*)malloc((outlen+1)*sizeof(unsigned char));
                 memcpy(out, buf, outlen);                  memcpy(out, buf, outlen);
                 error=0;                  error=0;
         }          }
Line 641  xmlChar *Charset::transcode_buf2xchar(Po Line 643  xmlChar *Charset::transcode_buf2xchar(Po
         out[outlen/*surely would be less then on input*/]=0;          out[outlen/*surely would be less then on input*/]=0;
         return (xmlChar *)out;          return (xmlChar *)out;
 }  }
 GdomeDOMString_auto_ptr Charset::transcode_buf2dom(const char* buf, size_t buf_size) {   GdomeDOMString_auto_ptr Charset::transcode_buf2dom(const char *buf, size_t buf_size) { 
         return GdomeDOMString_auto_ptr((gchar*)transcode_buf2xchar(buf, buf_size));          return GdomeDOMString_auto_ptr((gchar*)transcode_buf2xchar(buf, buf_size));
 }  }
 GdomeDOMString_auto_ptr Charset::transcode(const String& s) {   GdomeDOMString_auto_ptr Charset::transcode(const String& s) { 
         CharPtr cstr=s.cstr(String::UL_UNSPECIFIED);          const char *cstr=s.cstr(String::UL_UNSPECIFIED);
   
         return transcode_buf2dom(cstr, strlen(cstr));           return transcode_buf2dom(cstr, strlen(cstr)); 
 }  }
 #endif  #endif
   
   String& Charset::transcode(Pool& pool, 
           const Charset& source_transcoder, 
           const Charset& dest_transcoder, 
           const String& src) {
   
           const char *src_ptr=src.cstr(String::UL_UNSPECIFIED);
           size_t src_size=strlen(src_ptr);
   
           const void *dest_ptr;
           size_t dest_size;
   
           Charset::transcode(pool, 
                   source_transcoder, (const void*)src_ptr, src_size,
                   dest_transcoder, dest_ptr, dest_size);
   
           return *new(pool) String(pool, (const char*)dest_ptr, dest_size);
   }
   
   void Charset::transcode(Pool& pool, 
           const Charset& source_transcoder, 
           const Charset& dest_transcoder, 
           Array& src) {
           for(int i=0; i<src.size(); i++)
                   src.put(i, &transcode(pool, source_transcoder, dest_transcoder, *src.get_string(i)));
   }
   
   #ifndef DOXYGEN
   struct Transcode_pair_info {
           Pool* pool;
           const Charset* source_transcoder;
           const Charset* dest_transcoder;
   };
   #endif
   static void transcode_pair(const Hash::Key& key, Hash::Val *& value, void *raw_info) {
           Transcode_pair_info& info=*static_cast<Transcode_pair_info*>(raw_info);
           value=&Charset::transcode(*info.pool, 
                   *info.source_transcoder, 
                   *info.dest_transcoder, 
                   *static_cast<String*>(value));
   }
   void Charset::transcode(Pool& pool, 
           const Charset& source_transcoder, 
           const Charset& dest_transcoder, 
           Hash& src) {
           Transcode_pair_info info={&pool, &source_transcoder, &dest_transcoder};
           src.for_each(transcode_pair, &info);
   }

Removed from v.1.33.2.12  
changed lines
  Added in v.1.34


E-mail: