Diff for /parser3/src/main/pa_charset.C between versions 1.22 and 1.33.2.4

version 1.22, 2002/03/18 08:16:15 version 1.33.2.4, 2003/01/29 11:06:43
Line 1 Line 1
 /** @file  /** @file
         Parser: Charset connection implementation.          Parser: Charset connection implementation.
   
         Copyright(c) 2001, 2002 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_value_includes.h"
   
 #ifdef XML  #ifdef XML
 #include "libxml/encoding.h"  #include "libxml/encoding.h"
Line 15 Line 16
   
 // globals  // globals
   
   #define CHARSET_UTF8_NAME "UTF-8"
   
   CharsetPtr UTF8_charset(new Charset(ConstStringPtr(new String(CHARSET_UTF8_NAME)), 
                                            ConstStringPtrZero/*no file=system*/));
   
 // consts  // consts
   
Line 74  static void element2case(unsigned char f Line 79  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(Pool& apool, const String& aname, const String *request_file_spec): Pooled(apool),  Charset::Charset(ConstStringPtr aname, ConstStringPtr afile_spec): 
         fname(aname) {          fname(aname),
           fname_cstr(aname->cstr()) {
   
         char *name_cstr=fname.cstr();          for(char *c=fname_cstr; *c; c++)
     for(char *c=name_cstr; *c; c++)  
         *c = toupper(*c);          *c = toupper(*c);
   
         if(request_file_spec) {          if(afile_spec) {
                 fisUTF8=false;                  fisUTF8=false;
                 loadDefinition(*request_file_spec);                  load_definition(fname);
 #ifdef XML  #ifdef XML
                 addEncoding(name_cstr);                  addEncoding(fname_cstr);
 #endif  #endif
         } else {          } else {
                 fisUTF8=true;                  fisUTF8=true;
Line 94  Charset::Charset(Pool& apool, const Stri Line 99  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
         // not deleting transcoder, that's not our business          // not deleting transcoder, that's not our business
 #endif  #endif
 }  }
   
 void Charset::loadDefinition(const String& request_file_spec) {  void Charset::load_definition(ConstStringPtr afile_spec) {
         // pcre_tables          // pcre_tables
         // lowcase, flipcase, bits digit+word+whitespace, masks          // lowcase, flipcase, bits digit+word+whitespace, masks
   
Line 116  void Charset::loadDefinition(const Strin Line 122  void Charset::loadDefinition(const Strin
   
         // charset          // charset
         memset(tables.fromTable, 0, sizeof(tables.fromTable));          memset(tables.fromTable, 0, sizeof(tables.fromTable));
         tables.toTable=(Charset_TransRec *)calloc(sizeof(Charset_TransRec)*MAX_CHARSET_UNI_CODES);          tables.toTable=(Charset_TransRec *)pool_for_load.calloc(sizeof(Charset_TransRec)*MAX_CHARSET_UNI_CODES);
         tables.toTableSize=0;          tables.toTableSize=0;
         // strangly vital          // strangly vital
         tables.toTable[tables.toTableSize].intCh=0;          tables.toTable[tables.toTableSize].intCh=0;
Line 124  void Charset::loadDefinition(const Strin Line 130  void Charset::loadDefinition(const Strin
         tables.toTableSize++;          tables.toTableSize++;
   
         // loading text          // loading text
         char *data=file_read_text(pool(), request_file_spec);          char *data=file_read_text(pool_for_load, *UTF8_charset, afile_spec);
   
         // ignore header          // ignore header
         getrow(&data);          getrow(&data);
Line 153  void Charset::loadDefinition(const Strin Line 159  void Charset::loadDefinition(const Strin
                         case 8:                          case 8:
                                 // charset                                  // charset
                                 if(tables.toTableSize>MAX_CHARSET_UNI_CODES)                                  if(tables.toTableSize>MAX_CHARSET_UNI_CODES)
                                         throw Exception(0, 0,                                          throw Exception("parser.runtime",
                                                 &request_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);
Line 191  void Charset::sort_ToTable() { Line 197  void Charset::sort_ToTable() {
 }  }
   
 static XMLByte xlatOneTo(const XMLCh toXlat,  static XMLByte xlatOneTo(const XMLCh toXlat,
                                                  const Charset::Tables& tables) {                                                   const Charset::Tables& tables,
                                                    XMLByte not_found) {
     unsigned int    lowOfs = 0;      unsigned int    lowOfs = 0;
     unsigned int    hiOfs = tables.toTableSize - 1;      unsigned int    hiOfs = tables.toTableSize - 1;
     XMLByte         curByte = 0;      XMLByte         curByte = 0;
Line 210  static XMLByte xlatOneTo(const XMLCh toX Line 217  static XMLByte xlatOneTo(const XMLCh toX
                         return tables.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 360  static int transcodeToUTF8( Line 367  static int transcodeToUTF8(
     // Return the characters read      // Return the characters read
     toFillLen = outPtr - toFill;      toFillLen = outPtr - toFill;
   
         return srcPtr==srcEnd?(int)toFillLen:-1;          //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;
 }  }
 static size_t transcodeFromUTF8(  /// @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,                                                                  const XMLByte *srcData, size_t& srcLen,
                                                                 XMLByte* toFill, size_t& toFillLen,                                                                  XMLByte* toFill, size_t& toFillLen,
                                                                 const Charset::Tables& tables) {                                                                  const Charset::Tables& tables) {
Line 404  static size_t transcodeFromUTF8( Line 420  static size_t transcodeFromUTF8(
                      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 413  static size_t transcodeFromUTF8( Line 429  static size_t transcodeFromUTF8(
         //  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, tables);                          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);
         }          }
   
Line 427  static size_t transcodeFromUTF8( Line 446  static size_t transcodeFromUTF8(
     // Return the characters read      // Return the characters read
     toFillLen = outPtr - toFill;      toFillLen = outPtr - toFill;
   
         return srcPtr==srcEnd?(int)toFillLen:-1;          //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  /// @todo not so memory-hungry with prescan
 void Charset::transcodeToUTF8(Pool& pool,  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*/;          dest_content_length=source_content_length*6/*so that surly enough, max utf8 seq len=6*/;
         XMLByte *dest_body=(XMLByte*)pool.malloc(dest_content_length);          XMLByte *dest_body=(XMLByte*)pool.malloc(dest_content_length);
   
         if(::transcodeToUTF8(          if(::transcodeToUTF8(
Line 451  void Charset::transcodeToUTF8(Pool& pool Line 478  void Charset::transcodeToUTF8(Pool& pool
 void Charset::transcodeFromUTF8(Pool& pool,  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/*surly enough*/;          dest_content_length=source_content_length*6/*so that surly enough, "&#255;" has max ratio */;
         XMLByte *dest_body=(XMLByte*)pool.malloc(dest_content_length);          XMLByte *dest_body=(XMLByte*)pool.malloc(dest_content_length);
   
         if(::transcodeFromUTF8(          if(::transcodeFromUTF8(
Line 484  void Charset::transcodeToCharset(Pool& p Line 511  void Charset::transcodeToCharset(Pool& p
                 for(XMLByte* outPtr=dest_body; srcPtr<srcEnd; srcPtr++) {                  for(XMLByte* outPtr=dest_body; srcPtr<srcEnd; srcPtr++) {
                         XMLCh curVal = tables.fromTable[*srcPtr];                          XMLCh curVal = tables.fromTable[*srcPtr];
                         if(curVal)                           if(curVal) 
                                 *outPtr++=xlatOneTo(curVal, dest_charset.tables);                                  *outPtr++=xlatOneTo(curVal, dest_charset.tables, '?');
                         else {                          else {
                                 // use the replacement character                                  // use the replacement character
                                 *outPtr++= '?';                                  *outPtr++= '?';
Line 539  void Charset::initTranscoder(const Strin Line 566  void Charset::initTranscoder(const Strin
   
 xmlCharEncodingHandler *Charset::transcoder(const String *source) {  xmlCharEncodingHandler *Charset::transcoder(const String *source) {
         if(!ftranscoder)          if(!ftranscoder)
                 throw Exception(0, 0,                  throw Exception("parser.runtime",
                         source,                          source,
                         "unsupported encoding");                          "unsupported encoding");
         return ftranscoder;          return ftranscoder;
Line 553  const char *Charset::transcode_cstr(xmlC Line 580  const char *Charset::transcode_cstr(xmlC
         int outlen=inlen+1; // max          int outlen=inlen+1; // max
         char *out=(char *)malloc(outlen*sizeof(char));          char *out=(char *)malloc(outlen*sizeof(char));
                   
         int size;          int error;
         if(xmlCharEncodingOutputFunc output=transcoder(0)->output) {          if(xmlCharEncodingOutputFunc output=transcoder(0)->output) {
                 size=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, size=inlen);                  memcpy(out, s, outlen=inlen);
         if(size<0)                  error=0;
                 throw Exception(0, 0,          }
           if(error<0)
                   throw Exception(0,
                         0,                          0,
                         "transcode_cstr failed (%d)", size);                          "transcode_cstr failed (%d)", error);
   
         out[size]=0;          out[outlen/*surely would be less then on input*/]=0;
         return out;          return out;
 }  }
 String& Charset::transcode(xmlChar *s) {   String& Charset::transcode(xmlChar *s
         return *NEW String(pool(), transcode_cstr(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) {   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
         return *NEW String(pool(), transcode_cstr(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  /// @test less memory using -maybe- xmlParserInputBufferCreateMem
 GdomeDOMString_auto_ptr Charset::transcode_buf(const char *buf, size_t buf_size) {   xmlChar *Charset::transcode_buf2xchar(const char *buf, size_t buf_size) {
         int outlen=buf_size*6/*max*/+1;          unsigned char *out;
         unsigned char *out=(unsigned char*)malloc(outlen*sizeof(unsigned char));          int outlen;
           int error;
         int size;  
         if(xmlCharEncodingInputFunc input=transcoder(0)->input) {          if(xmlCharEncodingInputFunc input=transcoder(0)->input) {
                 size=input(                  outlen=buf_size*6/*max*/;
                   out=(unsigned char*)malloc((outlen+1)*sizeof(unsigned char));
                   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 {
                 memcpy(out, buf, size=buf_size);                  outlen=buf_size;
                   out=(unsigned char*)malloc((outlen+1)*sizeof(unsigned char));
                   memcpy(out, buf, outlen);
                   error=0;
           }
                   
         if(size<0)          if(error<0)
                 throw Exception(0, 0,                  throw Exception(0,
                         0,                          0,
                         "transcode_buf failed (%d)", size);                          "transcode_buf failed (%d)", error);
   
         out[size]=0;          out[outlen/*surely would be less then on input*/]=0;
         return GdomeDOMString_auto_ptr((gchar*)out);          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));
 }  }
 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_buf(cstr, strlen(cstr));           return transcode_buf2dom(cstr, strlen(cstr)); 
 }  }
 #endif  #endif

Removed from v.1.22  
changed lines
  Added in v.1.33.2.4


E-mail: