--- parser3/src/main/pa_charset.C 2002/01/25 09:32:07 1.18 +++ parser3/src/main/pa_charset.C 2003/03/21 09:43:48 1.34 @@ -1,13 +1,15 @@ /** @file 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(http://paf.design.ru) - - $Id: pa_charset.C,v 1.18 2002/01/25 09:32:07 paf Exp $ */ +static const char* IDENT_CHARSET_C="$Date: 2003/03/21 09:43:48 $"; + #include "pa_charset.h" +#include "pa_array.h" +#include "pa_hash.h" #ifdef XML #include "libxml/encoding.h" @@ -153,7 +155,7 @@ void Charset::loadDefinition(const Strin case 8: // charset if(tables.toTableSize>MAX_CHARSET_UNI_CODES) - throw Exception(0, 0, + throw Exception("parser.runtime", &request_file_spec, "charset must contain not more then %d unicode values", MAX_CHARSET_UNI_CODES); @@ -191,7 +193,8 @@ void Charset::sort_ToTable() { } static XMLByte xlatOneTo(const XMLCh toXlat, - const Charset::Tables& tables) { + const Charset::Tables& tables, + XMLByte not_found) { unsigned int lowOfs = 0; unsigned int hiOfs = tables.toTableSize - 1; XMLByte curByte = 0; @@ -210,7 +213,7 @@ static XMLByte xlatOneTo(const XMLCh toX return tables.toTable[midOfs].extCh; } while(lowOfs+1output) { - size=output( + error=output( (unsigned char*)out, &outlen, (const unsigned char*)s, &inlen, transcoder(0)->outputInfo); - } else - memcpy(out, s, size=inlen); - if(size<0) - throw Exception(0, 0, + } else { + memcpy(out, s, outlen=inlen); + error=0; + } + if(error<0) + throw Exception(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; } -String& Charset::transcode(xmlChar *s) { - return *NEW String(pool(), transcode_cstr(s)); +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) { - return *NEW String(pool(), transcode_cstr(s)); +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 -GdomeDOMString_auto_ptr Charset::transcode_buf(const char *buf, size_t buf_size) { - int outlen=buf_size*6/*max*/+1; - unsigned char *out=(unsigned char*)malloc(outlen*sizeof(unsigned char)); - - int size; +xmlChar *Charset::transcode_buf2xchar(const char *buf, size_t buf_size) { + unsigned char *out; + int outlen; + int error; 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, (const unsigned char *)buf, (int *)&buf_size, transcoder(0)->inputInfo); - } else - memcpy(out, buf, size=buf_size); + } else { + outlen=buf_size; + out=(unsigned char*)malloc((outlen+1)*sizeof(unsigned char)); + memcpy(out, buf, outlen); + error=0; + } - if(size<0) - throw Exception(0, 0, + if(error<0) + throw Exception(0, 0, - "transcode_buf failed (%d)", size); + "transcode_buf failed (%d)", error); - out[size]=0; - return GdomeDOMString_auto_ptr((gchar*)out); + 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)); } GdomeDOMString_auto_ptr Charset::transcode(const String& s) { const char *cstr=s.cstr(String::UL_UNSPECIFIED); - return transcode_buf(cstr, strlen(cstr)); + return transcode_buf2dom(cstr, strlen(cstr)); } #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(raw_info); + value=&Charset::transcode(*info.pool, + *info.source_transcoder, + *info.dest_transcoder, + *static_cast(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); +}