Diff for /parser3/src/main/pa_charset.C between versions 1.33.2.19.2.2 and 1.33.4.1

version 1.33.2.19.2.2, 2003/03/19 16:28:08 version 1.33.4.1, 2003/03/17 14:48:05
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_charsets.h"  
   
 #ifdef XML  #ifdef XML
 #include "libxml/encoding.h"  #include "libxml/encoding.h"
 #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 31  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 40  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 68  static void element2case(unsigned char f Line 74  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(const String& aname, const String& 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 88  Charset::Charset(const String& aname, co Line 94  Charset::Charset(const String& aname, co
         }          }
   
 #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(const String& 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 110  void Charset::load_definition(const Stri Line 115  void Charset::load_definition(const Stri
         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 148  void Charset::load_definition(const Stri Line 154  void Charset::load_definition(const Stri
                                 // 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 208  static XMLByte xlatOneTo(const XMLCh toX Line 214  static XMLByte xlatOneTo(const XMLCh toX
     return not_found;      return not_found;
 }  }
   
 void Charset::transcode(  void Charset::transcode(Pool& pool,
         const Charset& source_charset, const void* source_body, size_t source_content_length,          const Charset& source_charset, const void *source_body, size_t source_content_length,
         const Charset& dest_charset, const void *& dest_body, size_t& dest_content_length          const Charset& dest_charset, const void *& dest_body, size_t& dest_content_length
         ) {          ) {
         if(!source_content_length) {          if(!source_content_length) {
Line 235  void Charset::transcode( Line 241  void Charset::transcode(
                                 dest_body, dest_content_length);                                  dest_body, dest_content_length);
                         break;                          break;
                 case 0x11:                  case 0x11:
                         dest_body=pool.copy((char*)source_body, dest_content_length=source_content_length);                          dest_body=source_body;
                           dest_content_length=source_content_length;
                         break;                          break;
         }          }
 }  }
Line 366  of ocetes consumed. Line 373  of ocetes consumed.
 }  }
 /// @todo digital entites only when xml/html output [at output in html/xml mode, in html part of a letter]  /// @todo digital entites only when xml/html output [at output in html/xml mode, in html part of a letter]
 static int transcodeFromUTF8(  static int transcodeFromUTF8(
                                                                 const XMLByte* srcData, size_t& srcLen,                                                                  const XMLByte *srcData, size_t& srcLen,
                                                                 XMLByte* toFill, size_t& toFillLen,                                                                  XMLByte* toFill, size_t& toFillLen,
                                                                 const Charset::Tables& tables) {                                                                  const Charset::Tables& tables) {
         const XMLByte* srcPtr=srcData;          const XMLByte* srcPtr=srcData;
Line 377  static int transcodeFromUTF8( Line 384  static int transcodeFromUTF8(
     //  We now loop until we either run out of input data, or room to store      //  We now loop until we either run out of input data, or room to store
     while ((srcPtr < srcEnd) && (outPtr < outEnd)) {      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) {
Line 445  of ocetes consumed. Line 452  of ocetes consumed.
 }  }
   
 /// @todo not so memory-hungry with prescan  /// @todo not so memory-hungry with prescan
 void Charset::transcodeToUTF8(  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 XMLByte[dest_content_length];          XMLByte *dest_body=(XMLByte*)pool.malloc_atomic(dest_content_length);
   
         if(::transcodeToUTF8(          if(::transcodeToUTF8(
                 (XMLByte *)source_body, source_content_length,                  (XMLByte *)source_body, source_content_length,
Line 462  void Charset::transcodeToUTF8( Line 469  void Charset::transcodeToUTF8(
         // return          // return
         adest_body=dest_body;          adest_body=dest_body;
 }  }
 void Charset::transcodeFromUTF8(  void Charset::transcodeFromUTF8(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, "&#255;" has max ratio */;          dest_content_length=source_content_length*6/*so that surly enough, "&#255;" has max ratio */;
         XMLByte *dest_body=new XMLByte[dest_content_length];          XMLByte *dest_body=(XMLByte*)pool.malloc_atomic(dest_content_length);
   
         if(::transcodeFromUTF8(          if(::transcodeFromUTF8(
                 (XMLByte *)source_body, source_content_length,                  (XMLByte *)source_body, source_content_length,
Line 481  void Charset::transcodeFromUTF8( Line 488  void Charset::transcodeFromUTF8(
 }  }
   
 /// transcode using both charsets  /// transcode using both charsets
 void Charset::transcodeToCharset(  void Charset::transcodeToCharset(Pool& pool,
                                                                            const Charset& dest_charset,                                                                             const Charset& dest_charset,
                                                                            const void* source_body, size_t source_content_length,                                                                             const void *source_body, size_t source_content_length,
                                                                            const void *& adest_body, size_t& adest_content_length) const {                                                                             const void *& adest_body, size_t& adest_content_length) const {
         if(&dest_charset==this) {          if(&dest_charset==this) {
                 adest_body=pool.copy((char*)source_body, adest_content_length=source_content_length);                  adest_body=source_body;
                   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 unsigned char[dest_content_length];                  unsigned char *dest_body=(unsigned char *)pool.malloc_atomic(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 536  static int         xml256CharEncodingOut Line 544  static int         xml256CharEncodingOut
   
   
 void Charset::addEncoding(char *name_cstr) {  void Charset::addEncoding(char *name_cstr) {
         xmlCharEncodingHandler* handler=new xmlCharEncodingHandler;          xmlCharEncodingHandler *handler=
         fcreated_handler=xmlCharEncodingHandlerPtr(handler);                  (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 546  void Charset::addEncoding(char *name_cst Line 553  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
 }  }
   
 xmlCharEncodingHandler& Charset::transcoder(const String* source) {  xmlCharEncodingHandler *Charset::transcoder(const String *source) {
         if(!ftranscoder)          if(!ftranscoder)
                 throw Exception("parser.runtime",                  throw Exception("parser.runtime",
                         source,                          source,
                         "unsupported encoding");                          "unsupported encoding");
         return *ftranscoder;          return ftranscoder;
 }  }
   
 const char* Charset::transcode_cstrxmlChar* 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_atomic(outlen*sizeof(char));
                   
         int error;          int error;
         if(xmlCharEncodingOutputFunc output=transcoder(0).output) {          if(xmlCharEncodingOutputFunc output=transcoder(0)->output) {
                 error=output(                  error=output(
                         (unsigned char*)out, &outlen,                          (unsigned char*)out, &outlen,
                         (const unsigned char*)s, &inlen,                          (const unsigned char*)s, &inlen,
                         transcoder(0).outputInfo);                          transcoder(0)->outputInfo);
         } else {          } else {
                 memcpy(out, s, outlen=inlen);                  memcpy(out, s, outlen=inlen);
                 error=0;                  error=0;
Line 585  const char* Charset::transcode_cstrxmlCh Line 592  const char* Charset::transcode_cstrxmlCh
         out[outlen/*surely would be less then on input*/]=0;          out[outlen/*surely would be less then on input*/]=0;
         return out;          return out;
 }  }
 const String& Charset::transcodexmlChar* s  String& Charset::transcode(xmlChar *s
 #ifndef NO_STRING_ORIGIN  #ifndef NO_STRING_ORIGIN
                 , const String& origin                  , const String *origin
 #endif  #endif
                                                    ) {                                                      ) { 
         const String& result(new String());          String& result=*NEW String(pool());
         result->APPEND_CLEAN(          result.APPEND_CLEAN(transcode_cstr(s), 0/*auto-size*/, origin->origin().file, origin->origin().line);
                 transcode_cstr(pool, s), 0/*auto-size*/,   
                 origin->origin().file, origin->origin().line);  
         return result;           return result; 
 }  }
 const char* Charset::transcode_cstrGdomeDOMString* s) {   const char *Charset::transcode_cstr(GdomeDOMString *s) { 
         return s?transcode_cstr(pool, BAD_CAST s->str):"";          return s?transcode_cstr(BAD_CAST s->str):"";
 }  }
 const String& Charset::transcodeGdomeDOMString* s  String& Charset::transcode(GdomeDOMString *s
 #ifndef NO_STRING_ORIGIN  #ifndef NO_STRING_ORIGIN
                 , const String& origin                  , const String *origin
 #endif  #endif
                                                    ) {                                                      ) { 
         const String& result(new String());          String& result=*NEW String(pool());
         result->APPEND_CLEAN(transcode_cstr(pool, 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; 
 }  }
   
 /// @test less memory using -maybe- xmlParserInputBufferCreateMem  /// @test less memory using -maybe- xmlParserInputBufferCreateMem
 void* Charset::transcode_buf2mchar(transcode_buf_malloc_func malloc_func,   xmlChar *Charset::transcode_buf2xchar(const char *buf, size_t buf_size) {
                                                                    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=(unsigned char*)malloc_func(outlen+1);                  out=(unsigned char*)malloc_atomic((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=(unsigned char*)malloc_func(outlen+1);                  out=(unsigned char*)malloc_atomic((outlen+1)*sizeof(unsigned char));
                 memcpy(out, buf, outlen);                  memcpy(out, buf, outlen);
                 error=0;                  error=0;
         }          }
Line 635  void* Charset::transcode_buf2mchar(trans Line 639  void* Charset::transcode_buf2mchar(trans
                         "transcode_buf failed (%d)", error);                          "transcode_buf failed (%d)", error);
   
         out[outlen/*surely would be less then on input*/]=0;          out[outlen/*surely would be less then on input*/]=0;
         return out;          return (xmlChar *)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) {  
         return g_malloc(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) {   GdomeDOMString_auto_ptr Charset::transcode_buf2dom(const char *buf, size_t buf_size) { 
         return GdomeDOMString_auto_ptr(transcode_buf2gchar(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) { 
         const char* 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)); 
 }  }

Removed from v.1.33.2.19.2.2  
changed lines
  Added in v.1.33.4.1


E-mail: