Diff for /parser3/src/main/pa_charset.C between versions 1.66 and 1.83

version 1.66, 2008/08/15 16:54:01 version 1.83, 2009/10/15 01:07:54
Line 1 Line 1
 /** @file  /** @file
         Parser: Charset connection implementation.          Parser: Charset connection implementation.
   
         Copyright(c) 2001-2005 ArtLebedev Group (http://www.artlebedev.com)          Copyright(c) 2001-2009 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)
 */  */
   
Line 15  static const char * const IDENT_CHARSET_ Line 15  static const char * const IDENT_CHARSET_
 #endif  #endif
   
 //#define PA_PATCHED_LIBXML_BACKWARD  //#define PA_PATCHED_LIBXML_BACKWARD
   
   // reduce memory usage by pre-calculation utf-8 string length
 #define PRECALCULATE_DEST_LENGTH  #define PRECALCULATE_DEST_LENGTH
   
 // globals  // globals
Line 191  void Charset::sort_ToTable() { Line 193  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) {                           XMLByte not_found) {
         int    lo = 0;          int lo = 0;
         int    hi = tables.toTableSize - 1;          int hi = tables.toTableSize - 1;
         while(lo<=hi) {          while(lo<=hi) {
                 // Calc the mid point of the low and high offset.                  // Calc the mid point of the low and high offset.
                 const unsigned int i = (lo + hi) / 2;                  const unsigned int i = (lo + hi) / 2;
Line 261  static const XMLByte gUTFBytes[0x100] = Line 263  static const XMLByte gUTFBytes[0x100] =
 };  };
   
 static const uint gUTFOffsets[6] = {  static const uint gUTFOffsets[6] = {
     0, 0x3080, 0xE2080, 0x3C82080, 0xFA082080, 0x82082080          0, 0x3080, 0xE2080, 0x3C82080, 0xFA082080, 0x82082080
 };  };
   
 static const XMLByte gFirstByteMark[7] = {  static const XMLByte gFirstByteMark[7] = {
     0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC          0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
 };  };
   
 static int transcodeToUTF8(const XMLByte* srcData, size_t& srcLen,  static int transcodeToUTF8(const XMLByte* srcData, int& srcLen,
                            XMLByte *toFill, size_t& toFillLen,                                  XMLByte *toFill, int& toFillLen,
                            const Charset::Tables& tables) {                                  const Charset::Tables& tables) {
         const XMLByte* srcPtr=srcData;          const XMLByte* srcPtr=srcData;
         const XMLByte* srcEnd=srcData+srcLen;          const XMLByte* srcEnd=srcData+srcLen;
         XMLByte* outPtr=toFill;          XMLByte* outPtr=toFill;
Line 351  of ocetes consumed. Line 353  of ocetes consumed.
         return 0;          return 0;
 }  }
 /// @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(const XMLByte* srcData, size_t& srcLen,  static int transcodeFromUTF8(const XMLByte* srcData, int& srcLen,
                              XMLByte* toFill, size_t& toFillLen,                                  XMLByte* toFill, int& toFillLen,
                              const Charset::Tables& tables) {                                  const Charset::Tables& tables) {
         const XMLByte* srcPtr=srcData;          const XMLByte* srcPtr=srcData;
         const XMLByte* srcEnd=srcData+srcLen;          const XMLByte* srcEnd=srcData+srcLen;
         XMLByte* outPtr=toFill;          XMLByte* outPtr=toFill;
Line 431  of ocetes consumed. Line 433  of ocetes consumed.
         return 0;          return 0;
 }  }
   
 static bool is_escaped(char c){  static bool isEscaped(XMLByte c){
         return          return
                 !(                  !(
                         (c<=127)                          (c<=127)
Line 444  static bool is_escaped(char c){ Line 446  static bool is_escaped(char c){
                 );                  );
 }  }
   
 // read one utf8 character, return number of bytes needed for store it  // read one UTF8 char and return length of this char (in bytes)
 static unsigned int readChar(const XMLByte*& srcPtr, const XMLByte* srcEnd, XMLByte& firstByte, XMLCh& UTF8Char){  static unsigned int readUTF8Char(const XMLByte*& srcPtr, const XMLByte* srcEnd, XMLByte& firstByte, XMLCh& UTF8Char){
         if(!srcPtr || !*srcPtr || srcPtr>=srcEnd)          if(!srcPtr || !*srcPtr || srcPtr>=srcEnd)
                 return 0;                  return 0;
   
Line 479  static unsigned int readChar(const XMLBy Line 481  static unsigned int readChar(const XMLBy
         return trailingBytes+1;          return trailingBytes+1;
 }  }
   
 static unsigned int skipChar(const XMLByte*& srcPtr, const XMLByte* srcEnd){  // skip UTF8 char and return length of this char (in bytes)
   static unsigned int skipUTF8Char(const XMLByte*& srcPtr, const XMLByte* srcEnd){
         if(!srcPtr || !*srcPtr || srcPtr>=srcEnd)          if(!srcPtr || !*srcPtr || srcPtr>=srcEnd)
                 return 0;                  return 0;
   
Line 489  static unsigned int skipChar(const XMLBy Line 492  static unsigned int skipChar(const XMLBy
         return trailingBytes;          return trailingBytes;
 }  }
   
 // read char, return number of bytes needed for store it as UTF8  // read non-UTF8 char, and return number of bytes needed for store this char in UTF8
 static unsigned int readChar(const XMLByte*& srcPtr, const XMLByte* srcEnd, XMLByte& firstByte, XMLCh& UTF8Char, const Charset::Tables& tables){  static unsigned int readChar(const XMLByte*& srcPtr, const XMLByte* srcEnd, XMLByte& firstByte, XMLCh& UTF8Char, const Charset::Tables& tables){
         if(!srcPtr || !*srcPtr || srcPtr>=srcEnd)          if(!srcPtr || !*srcPtr || srcPtr>=srcEnd)
                 return 0;                  return 0;
Line 515  static unsigned int readChar(const XMLBy Line 518  static unsigned int readChar(const XMLBy
         return 1;          return 1;
 }  }
   
 static int escape(const XMLByte* srcData, size_t& srcLen,  static int escapeUTF8(const XMLByte* srcData, size_t& srcLen,
                              XMLByte* toFill, size_t& toFillLen) {                                  XMLByte* toFill, size_t& toFillLen) {
         const XMLByte* srcPtr=srcData;          const XMLByte* srcPtr=srcData;
         const XMLByte* srcEnd=srcData+srcLen;  
         XMLByte* outPtr=toFill;          XMLByte* outPtr=toFill;
         XMLByte* outEnd=toFill+toFillLen;          XMLByte* outEnd=toFill+toFillLen;
         XMLByte firstByte;  
         XMLCh UTF8Char;  
         uint charSize;  
   
         // loop until we either run out of input data, or room to store          // loop until we either run out of input data, or room to store
         while((outPtr < outEnd) && (charSize=readChar(srcPtr, srcEnd, firstByte, UTF8Char))){          for(UTF8_string_iterator i((XMLByte *)srcPtr, srcLen); (outPtr < outEnd) && i.has_next(); ){
                 if(charSize==1){                  if(i.getCharSize()==1){
                         if(is_escaped(firstByte)) // %XX                          if(isEscaped(i.getFirstByte())) // %XX
                                 outPtr+=sprintf((char*)outPtr, "%%%02X", firstByte);                                  outPtr+=sprintf((char*)outPtr, "%%%02X", i.getFirstByte());
                         else                          else
                                 *outPtr++=firstByte;                                  *outPtr++=i.getFirstByte();
                 } else                  } else
                         outPtr+=sprintf((char*)outPtr, "%%u%04X", UTF8Char); // %uXXXX                          outPtr+=sprintf((char*)outPtr, "%%u%04X", i.next()); // %uXXXX
         }          }
           
         // Update the bytes eaten          // Update the bytes eaten
         srcLen=srcPtr-srcData;          srcLen=srcPtr-srcData;
                   
Line 551  static int escape(const XMLByte* srcData Line 548  static int escape(const XMLByte* srcData
         const XMLByte* srcPtr=srcData;          const XMLByte* srcPtr=srcData;
         const XMLByte* srcEnd=srcData+srcLen;          const XMLByte* srcEnd=srcData+srcLen;
         XMLByte* outPtr=toFill;          XMLByte* outPtr=toFill;
         //XMLByte* outEnd=toFill+toFillLen;  
         XMLByte firstByte;          XMLByte firstByte;
         XMLCh UTF8Char;          XMLCh UTF8Char;
         uint charSize;          uint charSize;
Line 559  static int escape(const XMLByte* srcData Line 555  static int escape(const XMLByte* srcData
         while(charSize=readChar(srcPtr, srcEnd, firstByte, UTF8Char, tables)){          while(charSize=readChar(srcPtr, srcEnd, firstByte, UTF8Char, tables)){
                 if(charSize==1){                  if(charSize==1){
                         if(firstByte){                          if(firstByte){
                                 if(is_escaped(firstByte)) // %XX                                  if(isEscaped(firstByte)) // %XX
                                         outPtr+=sprintf((char*)outPtr, "%%%02X", firstByte);                                          outPtr+=sprintf((char*)outPtr, "%%%02X", firstByte);
                                 else                                  else
                                         *outPtr++=firstByte;                                          *outPtr++=firstByte;
Line 586  String::C Charset::escape(const String:: Line 582  String::C Charset::escape(const String::
   
 #ifdef PRECALCULATE_DEST_LENGTH  #ifdef PRECALCULATE_DEST_LENGTH
         size_t dest_length=0;          size_t dest_length=0;
         const XMLByte* srcPtr=(XMLByte*)src.str;  
         const XMLByte* srcEnd=srcPtr+src_length;  
         XMLByte firstByte;  
         XMLCh UTF8Char;  
   
         if(source_charset.isUTF8()){          if(source_charset.isUTF8()){
                 while(uint charSize=readChar(srcPtr, srcEnd, firstByte, UTF8Char)){                  for(UTF8_string_iterator i((XMLByte *)src.str, src_length); i.has_next(); ){
                         if(charSize==1)                          if(i.getCharSize()==1)
                                 dest_length+=!is_escaped(firstByte)?1:3/*%XX*/;                                  dest_length+=!isEscaped(i.getFirstByte())?1/*as-is*/:3/*%XX*/;
                         else                          else
                                 dest_length+=6; // '%uXXXX'                                  dest_length+=6/*%uXXXX*/;
                 }                  }
         } else {          } else {
                   const XMLByte* srcPtr=(XMLByte*)src.str;
                   const XMLByte* srcEnd=srcPtr+src_length;
                   XMLByte firstByte;
                   XMLCh UTF8Char;
                 while(uint charSize=readChar(srcPtr, srcEnd, firstByte, UTF8Char, source_charset.tables)){                  while(uint charSize=readChar(srcPtr, srcEnd, firstByte, UTF8Char, source_charset.tables)){
                         if(charSize==1)                          if(charSize==1)
                                 dest_length+=(!firstByte/*replacement char '?'*/ || !is_escaped(firstByte))?1:3/*'%XX'*/;                                  dest_length+=(!firstByte/*replacement char '?'*/ || !isEscaped(firstByte))?1:3/*'%XX'*/;
                         else                          else
                                 dest_length+=6; // '%uXXXX'                                  dest_length+=6; // '%uXXXX'
                 }                  }
Line 619  String::C Charset::escape(const String:: Line 615  String::C Charset::escape(const String::
   
         int status;          int status;
         if(source_charset.isUTF8()){          if(source_charset.isUTF8()){
                 status=::escape((XMLByte *)src.str, src_length, dest_body, dest_length);                  status=::escapeUTF8((XMLByte *)src.str, src_length, dest_body, dest_length);
         } else {          } else {
                 status=::escape((XMLByte *)src.str, src_length, dest_body, dest_length, source_charset.tables);                  status=::escape((XMLByte *)src.str, src_length, dest_body, dest_length, source_charset.tables);
         }          }
Line 627  String::C Charset::escape(const String:: Line 623  String::C Charset::escape(const String::
         if(status<0)          if(status<0)
                 throw Exception(0,                  throw Exception(0,
                         0,                          0,
                         "Charset::escapeString buffer overflow");                          "Charset::escape buffer overflow");
   
         assert(dest_length<=saved_dest_length);          assert(dest_length<=saved_dest_length);
         dest_body[dest_length]=0; // terminator          dest_body[dest_length]=0; // terminator
Line 636  String::C Charset::escape(const String:: Line 632  String::C Charset::escape(const String::
                   
 String::Body Charset::escape(const String::Body src, const Charset& source_charset) {  String::Body Charset::escape(const String::Body src, const Charset& source_charset) {
         const char *src_ptr=src.cstr();          const char *src_ptr=src.cstr();
         size_t src_size=strlen(src_ptr);          size_t src_size=src.length();
   
         String::C dest=Charset::escape(String::C(src_ptr, src_size),          String::C dest=Charset::escape(String::C(src_ptr, src_size), source_charset);
                 source_charset);  
   
         return String::Body(dest.str, dest.length);          return String::Body(dest.length ? dest.str:0);
 }  }
   
 String& Charset::escape(const String& src, const Charset& source_charset) {  String& Charset::escape(const String& src, const Charset& source_charset) {
         if(!src.length())          if(src.is_empty())
                 return *new String("", 0, false);                  return *new String();
   
         return *new String(escape((String::Body)src, source_charset), String::L_CLEAN);          return *new String(escape((String::Body)src, source_charset), String::L_CLEAN);
 }  }
   
 const String::C Charset::transcodeToUTF8(const String::C src) const {  const String::C Charset::transcodeToUTF8(const String::C src) const {
         size_t src_length=src.length;          int src_length=src.length;
   
 #ifdef PRECALCULATE_DEST_LENGTH  #ifdef PRECALCULATE_DEST_LENGTH
         size_t dest_length=0;          int dest_length=0;
         const XMLByte* srcPtr=(XMLByte*)src.str;          const XMLByte* srcPtr=(XMLByte*)src.str;
         const XMLByte* srcEnd=srcPtr+src_length;          const XMLByte* srcEnd=srcPtr+src_length;
         XMLByte firstByte;          XMLByte firstByte;
         XMLCh UTF8Char;          XMLCh UTF8Char;
         while(uint charSize=readChar(srcPtr, srcEnd, firstByte, UTF8Char, tables))          while(uint charSize=readChar(srcPtr, srcEnd, firstByte, UTF8Char, tables))
                 dest_length+=charSize;                  dest_length+=charSize;
 #else  #else
         size_t dest_length=src_length*6; // so that surly enough (max utf8 seq len=6) but too memory-hyngry          int dest_length=src_length*6; // so that surly enough (max utf8 seq len=6) but too memory-hyngry
 #endif  #endif
   
         //throw Exception(0,0,"%u",dest_length);          //throw Exception(0,0,"%u",dest_length);
   
 #ifndef NDEBUG  #ifndef NDEBUG
         size_t saved_dest_length=dest_length;          int saved_dest_length=dest_length;
 #endif  #endif
         XMLByte *dest_body=new(PointerFreeGC) XMLByte[dest_length+1/*for terminator*/];          XMLByte *dest_body=new(PointerFreeGC) XMLByte[dest_length+1/*for terminator*/];
   
Line 687  const String::C Charset::transcodeToUTF8 Line 682  const String::C Charset::transcodeToUTF8
 }  }
   
 static XMLCh change_case_UTF8(const XMLCh src, const Charset::UTF8CaseTable& table) {  static XMLCh change_case_UTF8(const XMLCh src, const Charset::UTF8CaseTable& table) {
         int    lo = 0;          int lo = 0;
         int    hi = table.size - 1;          int hi = table.size - 1;
         while(lo<=hi) {          while(lo<=hi) {
                 // Calc the mid point of the low and high offset.                  // Calc the mid point of the low and high offset.
                 const unsigned int i = (lo + hi) / 2;                  const unsigned int i = (lo + hi) / 2;
Line 827  static size_t getDecNumLength(XMLCh UTF8 Line 822  static size_t getDecNumLength(XMLCh UTF8
 }  }
   
 const String::C Charset::transcodeFromUTF8(const String::C src) const {  const String::C Charset::transcodeFromUTF8(const String::C src) const {
         size_t src_length=src.length;          int src_length=src.length;
   
 #ifdef PRECALCULATE_DEST_LENGTH  #ifdef PRECALCULATE_DEST_LENGTH
         size_t dest_length=0;          int dest_length=0;
         const XMLByte* srcPtr=(XMLByte*)src.str;          for(UTF8_string_iterator i((XMLByte *)src.str, src_length); i.has_next(); ){
         const XMLByte* srcEnd=srcPtr+src_length;                  if(i.getCharSize()==1)
         XMLByte firstByte;  
         XMLCh UTF8Char;  
         while(uint charSize=readChar(srcPtr, srcEnd, firstByte, UTF8Char)){  
                 if(charSize==1)  
                         dest_length++;                          dest_length++;
                 else                  else
                         dest_length+=(UTF8Char & 0xFFFF0000)                          dest_length+=(i.next() & 0xFFFF0000)
                                                         ?charSize*3     // '%XX' for each byte                                                          ?i.getCharSize()*3      // '%XX' for each byte
                                                         :(xlatOneTo(UTF8Char, tables, 0)!=0)                                                          :(xlatOneTo(i.next(), tables, 0)!=0)
                                                                 ?1              // can convert it to single char                                                                  ?1              // can convert it to single char
                                                                 :getDecNumLength(UTF8Char)+3;           // &#XX; - &#XXXXX;                                                                  :getDecNumLength(i.next())+3;           // &#XX; - &#XXXXX;
         }          }
 #else  #else
         // so that surly enough, "&#XXX;" has max ratio (huh? 8 bytes needed for '&#XXXXX;')          // so that surly enough, "&#XXX;" has max ratio (huh? 8 bytes needed for '&#XXXXX;')
         size_t dest_length=src_length*6;          int dest_length=src_length*6;
 #endif  #endif
   
         //throw Exception(0,0,"%u",dest_length);  
   
 #ifndef NDEBUG  #ifndef NDEBUG
         size_t saved_dest_length=dest_length;          int saved_dest_length=dest_length;
 #endif  #endif
         XMLByte *dest_body=new(PointerFreeGC) XMLByte[dest_length+1/*for terminator*/];          XMLByte *dest_body=new(PointerFreeGC) XMLByte[dest_length+1/*for terminator*/];
   
Line 872  const String::C Charset::transcodeFromUT Line 860  const String::C Charset::transcodeFromUT
   
 /// transcode using both charsets  /// transcode using both charsets
 const String::C Charset::transcodeToCharset(const String::C src,   const String::C Charset::transcodeToCharset(const String::C src, 
                                             const Charset& dest_charset) const {                                                  const Charset& dest_charset) const {
         if(&dest_charset==this)           if(&dest_charset==this) 
                 return src;                  return src;
         else {          else {
Line 911  static const Charset::Tables* tables[MAX Line 899  static const Charset::Tables* tables[MAX
                 unsigned char *out, int *outlen, \                  unsigned char *out, int *outlen, \
                 const unsigned char *in, int *inlen, void*) { \                  const unsigned char *in, int *inlen, void*) { \
                 return transcodeToUTF8( \                  return transcodeToUTF8( \
                         in, *(size_t*)inlen, \                          in, *inlen, \
                         out, *(size_t*)outlen, \                          out, *outlen, \
                         *tables[i]); \                          *tables[i]); \
         } \          } \
         static int xml256CharEncodingOutputFunc##i( \          static int xml256CharEncodingOutputFunc##i( \
                 unsigned char *out, int *outlen, \                  unsigned char *out, int *outlen, \
                 const unsigned char *in, int *inlen, void*) { \                  const unsigned char *in, int *inlen, void*) { \
                 return transcodeFromUTF8( \                  return transcodeFromUTF8( \
                         in, *(size_t*)inlen, \                          in, *inlen, \
                         out, *(size_t*)outlen, \                          out, *outlen, \
                         *tables[i]); \                          *tables[i]); \
         }          }
   
Line 931  static const Charset::Tables* tables[MAX Line 919  static const Charset::Tables* tables[MAX
                 unsigned char *out, int *outlen, \                  unsigned char *out, int *outlen, \
                 const unsigned char *in, int *inlen) { \                  const unsigned char *in, int *inlen) { \
                 return transcodeToUTF8( \                  return transcodeToUTF8( \
                         in, *(size_t*)inlen, \                          in, *inlen, \
                         out, *(size_t*)outlen, \                          out, *outlen, \
                         *tables[i]); \                          *tables[i]); \
         } \          } \
         static int xml256CharEncodingOutputFunc##i( \          static int xml256CharEncodingOutputFunc##i( \
                 unsigned char *out, int *outlen, \                  unsigned char *out, int *outlen, \
                 const unsigned char *in, int *inlen) { \                  const unsigned char *in, int *inlen) { \
                 return transcodeFromUTF8( \                  return transcodeFromUTF8( \
                         in, *(size_t*)inlen, \                          in, *inlen, \
                         out, *(size_t*)outlen, \                          out, *outlen, \
                         *tables[i]); \                          *tables[i]); \
         }          }
   
Line 1036  String::C Charset::transcode_cstr(const Line 1024  String::C Charset::transcode_cstr(const
 }  }
 const String& Charset::transcode(const xmlChar* s) {   const String& Charset::transcode(const xmlChar* s) { 
         String::C cstr=transcode_cstr(s);          String::C cstr=transcode_cstr(s);
         return *new String(cstr.str, cstr.length, true);          return *new String(cstr.str, String::L_TAINTED);
 }  }
   
 /// @test less memory using -maybe- xmlParserInputBufferCreateMem  /// @test less memory using -maybe- xmlParserInputBufferCreateMem
Line 1078  xmlChar* Charset::transcode_buf2xchar(co Line 1066  xmlChar* Charset::transcode_buf2xchar(co
         assert(outlen<=saved_outlen); out[outlen]=0;          assert(outlen<=saved_outlen); out[outlen]=0;
         return out;          return out;
 }  }
 xmlChar* Charset::transcode(const String& s) {   
         const char* cstr=s.cstr(String::L_UNSPECIFIED);  
   
         return transcode_buf2xchar(cstr, strlen(cstr));   xmlChar* Charset::transcode(const String& s) {
           String::Body sbody=s.cstr_to_string_body_untaint(String::L_AS_IS);
           return transcode_buf2xchar(sbody.cstr(), sbody.length()); 
 }  }
 xmlChar* Charset::transcode(const String::Body s) {   
         const char* cstr=s.cstr();  
   
         return transcode_buf2xchar(cstr, s.length());   xmlChar* Charset::transcode(const String::Body s) {
           return transcode_buf2xchar(s.cstr(), s.length()); 
 }  }
 #endif  #endif
   
Line 1095  String::Body Charset::transcode(const St Line 1082  String::Body Charset::transcode(const St
         const Charset& dest_transcoder) {          const Charset& dest_transcoder) {
   
         const char *src_ptr=src.cstr();          const char *src_ptr=src.cstr();
         size_t src_size=strlen(src_ptr);          size_t src_size=src.length();
   
         String::C dest=Charset::transcode(String::C(src_ptr, src_size),          String::C dest=Charset::transcode(String::C(src_ptr, src_size), source_transcoder, dest_transcoder);
                 source_transcoder,  
                 dest_transcoder);  
   
         return String::Body(dest.str, dest.length);          return String::Body(dest.length ? dest.str:0);
 }  }
   
 String& Charset::transcode(const String& src,   String& Charset::transcode(const String& src, 
         const Charset& source_transcoder,           const Charset& source_transcoder, 
         const Charset& dest_transcoder) {          const Charset& dest_transcoder) {
         if(!src.length())          if(src.is_empty())
                 return *new String("", 0, false);                  return *new String();
   
         return *new String(transcode((String::Body)src, source_transcoder, dest_transcoder), String::L_CLEAN);          return *new String(transcode((String::Body)src, source_transcoder, dest_transcoder), String::L_CLEAN);
 }  }
Line 1126  struct Transcode_pair_info { Line 1111  struct Transcode_pair_info {
         const Charset* dest_transcoder;          const Charset* dest_transcoder;
 };  };
 #endif  #endif
 static void transcode_pair(const String::Body /*akey*/,   static void transcode_pair(HashStringValue::key_type /*akey*/, 
                          String::Body& avalue,                            String::Body& avalue, 
                          Transcode_pair_info* info) {                           Transcode_pair_info* info) {
         avalue=Charset::transcode(avalue,          avalue=Charset::transcode(avalue,
Line 1143  void Charset::transcode(HashStringString Line 1128  void Charset::transcode(HashStringString
   
 size_t getUTF8BytePos(const XMLByte* srcBegin, const XMLByte* srcEnd, size_t charPos){  size_t getUTF8BytePos(const XMLByte* srcBegin, const XMLByte* srcEnd, size_t charPos){
         const XMLByte* ptr=srcBegin;          const XMLByte* ptr=srcBegin;
         while(charPos-- && skipChar(ptr, srcEnd));          while(charPos-- && skipUTF8Char(ptr, srcEnd));
   
         return ptr-srcBegin;          return ptr-srcBegin;
 }  }
Line 1152  size_t getUTF8CharPos(const XMLByte* src Line 1137  size_t getUTF8CharPos(const XMLByte* src
         size_t charPos=0;          size_t charPos=0;
         const XMLByte* ptr=srcBegin;          const XMLByte* ptr=srcBegin;
         const XMLByte* ptrEnd=srcBegin+bytePos;          const XMLByte* ptrEnd=srcBegin+bytePos;
         while(skipChar(ptr, srcEnd)){          while(skipUTF8Char(ptr, srcEnd)){
                 if(ptr>ptrEnd)                  if(ptr>ptrEnd)
                         return charPos;                          return charPos;
                 charPos++;                  charPos++;
Line 1166  size_t getUTF8CharPos(const XMLByte* src Line 1151  size_t getUTF8CharPos(const XMLByte* src
   
 size_t lengthUTF8(const XMLByte* srcBegin, const XMLByte* srcEnd){  size_t lengthUTF8(const XMLByte* srcBegin, const XMLByte* srcEnd){
         size_t size=0;          size_t size=0;
         while(skipChar(srcBegin, srcEnd))          while(skipUTF8Char(srcBegin, srcEnd))
                 size++;                  size++;
   
         return size;          return size;
 }  }
   
   bool UTF8_string_iterator::has_next(){
           fcharSize=readUTF8Char(fsrcPtr, fsrcEnd, ffirstByte, fUTF8Char);
           return fcharSize!=0;
   }

Removed from v.1.66  
changed lines
  Added in v.1.83


E-mail: