Annotation of parser3/src/main/pa_charset.C, revision 1.6
1.1 paf 1: /** @file
2: Parser: Charset connection implementation.
3:
1.4 paf 4: Copyright(c) 2001 ArtLebedev Group(http://www.artlebedev.com)
5: Author: Alexander Petrosyan<paf@design.ru>(http://paf.design.ru)
1.1 paf 6:
1.6 ! paf 7: $Id: pa_charset.C,v 1.5 2001/12/17 19:22:21 paf Exp $
1.1 paf 8: */
9:
10: #include "pa_charset.h"
11: //#include "pa_exception.h"
12: //#include "pa_common.h"
13: //#include "pa_threads.h"
14:
15: #ifdef XML
1.4 paf 16: # include<util/TransENameMap.hpp>
17: # include<util/XML256TableTranscoder.hpp>
18: # include<util/PlatformUtils.hpp>
19: # include<PlatformSupport/XalanTranscodingServices.hpp>
1.1 paf 20: #endif
21:
22: // globals
23:
24:
25: // consts
26:
27: #define MAX_CHARSET_UNI_CODES 500
28:
29: // helpers
30:
31: inline void prepare_case_tables(unsigned char *tables) {
32: unsigned char *lcc_table=tables+lcc_offset;
33: unsigned char *fcc_table=tables+fcc_offset;
34: for(int i=0; i<0x100; i++)
35: lcc_table[i]=fcc_table[i]=i;
36: }
37: inline void cstr2ctypes(unsigned char *tables, const unsigned char *cstr,
38: unsigned char bit) {
39: unsigned char *ctypes_table=tables+ctypes_offset;
40: ctypes_table[0]=bit;
41: for(; *cstr; cstr++) {
42: unsigned char c=*cstr;
43: ctypes_table[c]|=bit;
44: }
45: }
46: inline unsigned int to_wchar_code(const char *cstr) {
47: if(!cstr || !*cstr)
48: return 0;
49: if(cstr[1]==0)
1.4 paf 50: return(unsigned int)(unsigned char)cstr[0];
1.1 paf 51:
52: char *error_pos;
1.4 paf 53: return(unsigned int)strtol(cstr, &error_pos, 0);
1.1 paf 54: }
55: inline bool to_bool(const char *cstr) {
56: return cstr && *cstr!=0;
57: }
58: static void element2ctypes(unsigned char c, bool belongs,
59: unsigned char *tables, unsigned char bit, int group_offset=-1) {
60: if(!belongs)
61: return;
62:
63: unsigned char *ctypes_table=tables+ctypes_offset;
64:
65: ctypes_table[c]|=bit;
66: if(group_offset>=0)
1.4 paf 67: tables[cbits_offset+group_offset+c/8] |= 1<<(c%8);
1.1 paf 68: }
69: static void element2case(unsigned char from, unsigned char to,
70: unsigned char *tables) {
71: if(!to)
72: return;
73:
74: unsigned char *lcc_table=tables+lcc_offset;
75: unsigned char *fcc_table=tables+fcc_offset;
76: lcc_table[from]=to;
77: fcc_table[from]=to; fcc_table[to]=from;
78: }
79:
80: #ifdef XML
81: template <class TType> class ENameMapFor2 : public ENameMap {
1.4 paf 82: public:
1.1 paf 83: // -----------------------------------------------------------------------
84: // Constructors and Destructor
85: // -----------------------------------------------------------------------
86: ENameMapFor2(
87: const XMLCh* const encodingName
88: , const XMLCh* const fromTable
89: , const XMLTransService::TransRec* const toTable
90: , const unsigned int toTableSize
1.4 paf 91: ): ENameMap(encodingName),
1.1 paf 92: ffromTable(fromTable),
93: ftoTable(toTable),
94: ftoTableSize(toTableSize) {}
95:
96: // -----------------------------------------------------------------------
97: // Implementation of virtual factory method
98: // -----------------------------------------------------------------------
99: virtual XMLTranscoder* makeNew(const unsigned int blockSize) const {
100: return new TType(
101: getKey(),
102: blockSize,
103: ffromTable,
104: ftoTable, ftoTableSize);
105: }
106: private:
107: const XMLCh* const ffromTable;
108: const XMLTransService::TransRec* const ftoTable;
109: const unsigned int ftoTableSize;
110:
1.4 paf 111: private:
1.1 paf 112: // -----------------------------------------------------------------------
113: // Unimplemented constructors and operators
114: // -----------------------------------------------------------------------
115: ENameMapFor2();
116: ENameMapFor2(const ENameMapFor2<TType>&);
117: void operator=(const ENameMapFor2<TType>&);
118: };
119:
120: class XML256TableTranscoder2 : public XML256TableTranscoder {
121: public :
122: XML256TableTranscoder2(
123: const XMLCh* const encodingName
124: , const unsigned int blockSize
125: , const XMLCh* const fromTable
126: , const XMLTransService::TransRec* const toTable
127: , const unsigned int toTableSize
128: ) : XML256TableTranscoder(encodingName, blockSize, fromTable, toTable, toTableSize) {}
129:
1.4 paf 130: private:
1.1 paf 131: XML256TableTranscoder2();
132: XML256TableTranscoder2(const XML256TableTranscoder2&);
133: void operator=(const XML256TableTranscoder2&);
134: };
135: #endif
136:
137: // methods
138:
139: extern "C" unsigned char pcre_default_tables[]; // pcre/chartables.c
1.4 paf 140: Charset::Charset(Pool& apool, const String& aname, const String *file_spec): Pooled(apool),
1.1 paf 141: fname(apool) {
142: // fname
1.2 paf 143: char *name_cstr=(char *)malloc(aname.size()+1);
144: memcpy(name_cstr, aname.cstr(String::UL_AS_IS), aname.size()+1);
1.1 paf 145: fname.APPEND_CLEAN(name_cstr, aname.size(), 0, 0);
146:
147: if(file_spec) {
148: fisUTF8=false;
149: loadDefinition(*file_spec);
150: #ifdef XML
151: addEncoding(name_cstr);
152: #endif
153: } else {
154: fisUTF8=true;
1.4 paf 155: // grab default onces [for UTF-8 so to be able to make a-z =>A-Z
1.1 paf 156: memcpy(pcre_tables, pcre_default_tables, sizeof(pcre_tables));
157: }
158:
159: #ifdef XML
160: initTranscoder(&aname, name_cstr);
161: #endif
162: }
163:
164: Charset::~Charset() {
165: #ifdef XML
166: delete transcoder;
167: #endif
168: }
169:
170: void Charset::loadDefinition(const String& file_spec) {
171: // pcre_tables
172: // lowcase, flipcase, bits digit+word+whitespace, masks
173:
174: // must not move this inside of prepare_case_tables
175: // don't know the size there
176: memset(pcre_tables, 0, sizeof(pcre_tables));
177: prepare_case_tables(pcre_tables);
1.4 paf 178: cstr2ctypes(pcre_tables,(const unsigned char *)"*+?{^.$|()[", ctype_meta);
1.1 paf 179:
180: // charset
181: memset(fromTable, 0, sizeof(fromTable));
1.5 paf 182: toTable=(Charset_TransRec *)calloc(sizeof(Charset_TransRec)*MAX_CHARSET_UNI_CODES);
1.1 paf 183: toTableSize=0;
184: // strangly vital
185: toTable[toTableSize].intCh=0;
186: toTable[toTableSize].extCh=(XMLByte)0;
187: toTableSize++;
188:
189: // loading text
190: char *data=file_read_text(pool(), file_spec);
191:
192: // ignore header
193: getrow(&data);
194:
195: // parse cells
196: char *row;
197: while(row=getrow(&data)) {
198: // remove empty&comment lines
199: if(!*row || *row=='#')
200: continue;
201:
202: // char white-space digit hex-digit letter word lowercase unicode1 unicode2
203: unsigned int c=0;
204: char *cell;
205: for(int column=0; cell=lsplit(&row, '\t'); column++) {
206: switch(column) {
207: case 0: c=to_wchar_code(cell); break;
208: // pcre_tables
209: case 1: element2ctypes(c, to_bool(cell), pcre_tables, ctype_space, cbit_space); break;
210: case 2: element2ctypes(c, to_bool(cell), pcre_tables, ctype_digit, cbit_digit); break;
211: case 3: element2ctypes(c, to_bool(cell), pcre_tables, ctype_xdigit); break;
212: case 4: element2ctypes(c, to_bool(cell), pcre_tables, ctype_letter); break;
213: case 5: element2ctypes(c, to_bool(cell), pcre_tables, ctype_word, cbit_word); break;
214: case 6: element2case(c, to_wchar_code(cell), pcre_tables); break;
215: case 7:
216: case 8:
217: // charset
218: if(toTableSize>MAX_CHARSET_UNI_CODES)
219: throw Exception(0, 0,
220: &file_spec,
221: "charset must contain not more then %d unicode values", MAX_CHARSET_UNI_CODES);
222:
223: XMLCh unicode=(XMLCh)to_wchar_code(cell);
224: if(!unicode && column==7/*unicode1 column*/)
225: unicode=(XMLCh)c;
226: if(unicode) {
227: if(!fromTable[c])
228: fromTable[c]=unicode;
229: toTable[toTableSize].intCh=unicode;
230: toTable[toTableSize].extCh=(XMLByte)c;
231: toTableSize++;
232: }
233: break;
234: }
235: }
236: };
237:
238: // sort by the Unicode code point
239: sort_ToTable();
240: }
241:
242: #ifdef XML
243: void Charset::addEncoding(const char *name_cstr) {
244: // addEncoding
245: XalanDOMString sencoding(name_cstr);
246: const XMLCh* const auto_encoding_cstr=sencoding.c_str();
247: int size=sizeof(XMLCh)*(sencoding.size()+1);
248: XMLCh* pool_encoding_cstr=(XMLCh*)malloc(size);
249: memcpy(pool_encoding_cstr, auto_encoding_cstr, size);
250: XMLString::upperCase(pool_encoding_cstr);
251:
252: XMLPlatformUtils::fgTransService->addEncoding(
253: pool_encoding_cstr,
254: new ENameMapFor2<XML256TableTranscoder2>(
255: pool_encoding_cstr
256: , fromTable
257: , toTable
258: , toTableSize
259: ));
260: }
261:
262: void Charset::initTranscoder(const String *source, const char *name_cstr) {
263: XMLTransService::Codes resValue;
264: transcoder=XMLPlatformUtils::fgTransService->makeNewTranscoderFor(name_cstr, resValue, 60);
265: if(!transcoder)
266: throw Exception(0, 0,
267: source,
268: "unsupported encoding");
269: }
270: #endif
271:
272: static int sort_cmp_Trans_rec_intCh(const void *a, const void *b) {
273: return
274: static_cast<const Charset_TransRec *>(a)->intCh-
275: static_cast<const Charset_TransRec *>(b)->intCh;
276: }
277:
278: void Charset::sort_ToTable() {
279: _qsort(toTable, toTableSize, sizeof(*toTable),
280: sort_cmp_Trans_rec_intCh);
281: //FILE *f=fopen("c:\\temp\\a", "wb");
282: //fwrite(toTable, toTableSize, sizeof(*toTable), f);
283: //fclose(f);
284: }
285:
286: XMLByte Charset::xlatOneTo(const XMLCh toXlat) const {
287: unsigned int lowOfs = 0;
288: unsigned int hiOfs = toTableSize - 1;
289: XMLByte curByte = 0;
290: do {
291: // Calc the mid point of the low and high offset.
1.4 paf 292: const unsigned int midOfs =((hiOfs - lowOfs) / 2)+lowOfs;
1.1 paf 293:
294: // If our test char is greater than the mid point char, then
295: // we move up to the upper half. Else we move to the lower
296: // half. If its equal, then its our guy.
1.4 paf 297: if(toXlat>toTable[midOfs].intCh)
1.1 paf 298: lowOfs = midOfs;
1.4 paf 299: else if(toXlat<toTable[midOfs].intCh)
1.1 paf 300: hiOfs = midOfs;
301: else
302: return toTable[midOfs].extCh;
1.4 paf 303: } while(lowOfs+1<hiOfs);
1.1 paf 304:
305: return '?';
306: }
307:
308: void Charset::transcode(Pool& pool,
309: const Charset& source_charset, const void *source_body, size_t source_content_length,
310: const Charset& dest_charset, const void *& dest_body, size_t& dest_content_length
311: ) {
1.4 paf 312: if(!source_content_length) {
313: dest_body=0;
314: dest_content_length=0;
315: return;
316: }
317:
1.1 paf 318: switch((source_charset.isUTF8()?0x10:0x00)|(dest_charset.isUTF8()?0x01:0x00)) {
319: default: // 0x00
320: source_charset.transcodeToCharset(pool, dest_charset,
321: source_body, source_content_length,
322: dest_body, dest_content_length);
323: break;
324: case 0x01:
325: source_charset.transcodeToUTF8(pool,
326: source_body, source_content_length,
327: dest_body, dest_content_length);
328: break;
329: case 0x10:
330: dest_charset.transcodeFromUTF8(pool,
331: source_body, source_content_length,
332: dest_body, dest_content_length);
333: break;
334: case 0x11:
335: dest_body=source_body;
336: dest_content_length=source_content_length;
337: break;
338: }
339: }
340:
341: // ---------------------------------------------------------------------------
342: // Local static data
343: //
344: // gUTFBytes
345: // A list of counts of trailing bytes for each initial byte in the input.
346: //
347: // gUTFOffsets
348: // A list of values to offset each result char type, according to how
349: // many source bytes when into making it.
350: //
351: // gFirstByteMark
352: // A list of values to mask onto the first byte of an encoded sequence,
353: // indexed by the number of bytes used to create the sequence.
354: // ---------------------------------------------------------------------------
355: static const XMLByte gUTFBytes[0x100] = {
356: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
357: , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
358: , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
359: , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
360: , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
361: , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
362: , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
363: , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
364: , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
365: , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
366: , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
367: , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
368: , 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
369: , 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
370: , 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
371: , 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5
372: };
373:
374: static const uint gUTFOffsets[6] = {
375: 0, 0x3080, 0xE2080, 0x3C82080, 0xFA082080, 0x82082080
376: };
377:
378: static const XMLByte gFirstByteMark[7] = {
379: 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
380: };
381:
382: /// @todo not so memory-hungry with prescan
383: void Charset::transcodeToUTF8(Pool& pool,
384: const void *source_body, size_t source_content_length,
385: const void *& adest_body, size_t& adest_content_length) const {
386:
387: size_t dest_content_length=0;
388: XMLByte *dest_body=(XMLByte*)pool.malloc(source_content_length*6/*so that surly enough*/);
389:
390: const XMLByte* srcPtr=(const XMLByte*)source_body;
391: const XMLByte* srcEnd=(const XMLByte*)source_body+source_content_length;
392: XMLByte* outPtr=dest_body;
393:
1.4 paf 394: while(srcPtr<srcEnd) {
1.1 paf 395: uint curVal = fromTable[*srcPtr];
396: if(!curVal) {
397: // use the replacement character
1.4 paf 398: *outPtr++= '?';
399: srcPtr++;
1.1 paf 400: continue;
401: }
402:
403: // Figure out how many bytes we need
404: unsigned int encodedBytes;
1.4 paf 405: if(curVal<0x80)
1.1 paf 406: encodedBytes = 1;
1.4 paf 407: else if(curVal<0x800)
1.1 paf 408: encodedBytes = 2;
1.4 paf 409: else if(curVal<0x10000)
1.1 paf 410: encodedBytes = 3;
1.4 paf 411: else if(curVal<0x200000)
1.1 paf 412: encodedBytes = 4;
1.4 paf 413: else if(curVal<0x4000000)
1.1 paf 414: encodedBytes = 5;
1.4 paf 415: else if(curVal<= 0x7FFFFFFF)
1.1 paf 416: encodedBytes = 6;
417: else {
418: // use the replacement character
1.4 paf 419: *outPtr++= '?';
420: srcPtr++;
1.1 paf 421: continue;
422: }
423:
424: // If we cannot fully get this char into the output buffer,
425: // never
426:
427: // We can do it, so update the source index
428: srcPtr++;
429:
430: // And spit out the bytes. We spit them out in reverse order
431: // here, so bump up the output pointer and work down as we go.
1.4 paf 432: outPtr+= encodedBytes;
1.1 paf 433: switch(encodedBytes) {
1.4 paf 434: case 6: *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
435: curVal>>= 6;
436: case 5: *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
437: curVal>>= 6;
438: case 4: *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
439: curVal>>= 6;
440: case 3: *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
441: curVal>>= 6;
442: case 2: *--outPtr = XMLByte((curVal | 0x80UL) & 0xBFUL);
443: curVal>>= 6;
444: case 1: *--outPtr = XMLByte(curVal | gFirstByteMark[encodedBytes]);
1.1 paf 445: }
446:
447: // Add the encoded bytes back in again to indicate we've eaten them
1.4 paf 448: outPtr+= encodedBytes;
1.1 paf 449: }
450:
451: // return
452: adest_body=dest_body;
453: adest_content_length=outPtr-dest_body;
454: }
455: void Charset::transcodeFromUTF8(Pool& pool,
456: const void *source_body, size_t source_content_length,
457: const void *& adest_body, size_t& adest_content_length) const {
458: size_t dest_content_length=0;
459: XMLByte *dest_body=(XMLByte*)pool.malloc(source_content_length/*surly enough*/);
460:
461: const XMLByte* srcPtr=(const XMLByte*)source_body;
462: const XMLByte* srcEnd=(const XMLByte*)source_body+source_content_length;
463: XMLByte* outPtr=dest_body;
464:
465: // We now loop until we either run out of input data
1.4 paf 466: while(srcPtr<srcEnd) {
1.1 paf 467: // Get the next leading byte out
468: const XMLByte firstByte = *srcPtr;
469:
1.4 paf 470: // Special-case ASCII, which is a leading byte value of<= 127
471: if(firstByte<= 127) {
472: *outPtr++= firstByte;
1.1 paf 473: srcPtr++;
474: continue;
475: }
476:
477: // See how many trailing src bytes this sequence is going to require
478: const unsigned int trailingBytes = gUTFBytes[firstByte];
479:
480: // If there are not enough source bytes to do this one, then we
1.4 paf 481: // are done. Note that we done>= here because we are implicitly
1.1 paf 482: // counting the 1 byte we get no matter what.
1.4 paf 483: if(srcPtr+trailingBytes>= srcEnd)
1.1 paf 484: break;
485:
486: // Looks ok, so lets build up the value
487: uint tmpVal=0;
488: switch(trailingBytes) {
489: case 5: tmpVal+=*srcPtr++; tmpVal<<=6;
490: case 4: tmpVal+=*srcPtr++; tmpVal<<=6;
491: case 3: tmpVal+=*srcPtr++; tmpVal<<=6;
492: case 2: tmpVal+=*srcPtr++; tmpVal<<=6;
493: case 1: tmpVal+=*srcPtr++; tmpVal<<=6;
494: case 0: tmpVal+=*srcPtr++;
495: break;
496:
497: default:
498: throw Exception(0, 0,
499: 0,
1.4 paf 500: "transcodeFromUTF8 error: wrong trailingBytes value(%d)", trailingBytes);
1.1 paf 501: }
502: tmpVal-=gUTFOffsets[trailingBytes];
503:
504: // If it will fit into a single char, then put it in. Otherwise
505: // fail [*encode it as a surrogate pair. If its not valid, use the
506: // replacement char.*]
1.4 paf 507: if(!(tmpVal & 0xFFFF0000))
508: *outPtr++= xlatOneTo(tmpVal);
1.1 paf 509: else
510: throw Exception(0, 0,
511: 0,
1.4 paf 512: "transcodeFromUTF8 error: too big tmpVal(0x%08X)", tmpVal);
1.1 paf 513: }
514:
515: // return
516: adest_body=dest_body;
517: adest_content_length=outPtr-dest_body;
518: }
519:
520: /// transcode using both charsets
521: void Charset::transcodeToCharset(Pool& pool,
522: const Charset& dest_charset,
523: const void *source_body, size_t source_content_length,
1.6 ! paf 524: const void *& adest_body, size_t& adest_content_length) const {
1.3 paf 525: if(&dest_charset==this) {
1.6 ! paf 526: adest_body=source_body;
! 527: adest_content_length=source_content_length;
! 528: } else {
! 529: size_t dest_content_length=source_content_length;
! 530: unsigned char *dest_body=(unsigned char *)pool.malloc(dest_content_length);
! 531:
! 532: const XMLByte* srcPtr=(const XMLByte*)source_body;
! 533: const XMLByte* srcEnd=(const XMLByte*)source_body+source_content_length;
! 534:
! 535: for(XMLByte* outPtr=dest_body; srcPtr<srcEnd; srcPtr++) {
! 536: XMLCh curVal = fromTable[*srcPtr];
! 537: if(curVal)
! 538: *outPtr++=dest_charset.xlatOneTo(curVal);
! 539: else {
! 540: // use the replacement character
! 541: *outPtr++= '?';
! 542: }
! 543: }
1.1 paf 544:
1.6 ! paf 545: adest_body=dest_body;
! 546: adest_content_length=dest_content_length;
! 547: }
1.1 paf 548: }
549:
550: #ifdef XML
551: const char *Charset::transcode_cstr(const XalanDOMString& s) {
552: const unsigned int len=s.size()*2;
553: XMLByte* dest=(XMLByte *)malloc((len+1)*sizeof(XMLByte));
554: bool error=true;
555: try {
556: if(transcoder) {
557: unsigned int charsEaten;
558: unsigned int size=transcoder->transcodeTo(
559: s.c_str(), s.length(),
560: dest, len,
561: charsEaten,
562: XMLTranscoder::UnRep_RepChar //UnRep_Throw
563: );
564: dest[size]=0;
565: error=false;
566: }
567: } catch(XMLException& e) {
568: Exception::provide_source(pool(), 0, e);
569: }
1.4 paf 570: return(const char *)dest;
1.1 paf 571: }
572: String& Charset::transcode(const XalanDOMString& s) {
573: return *NEW String(pool(), transcode_cstr(s));
574: }
575:
1.4 paf 576: std::auto_ptr<XalanDOMString>Charset::transcode_buf(const char *buf, size_t buf_size) {
1.1 paf 577: unsigned int dest_size=0;
578: XMLCh* dest=(XMLCh *)malloc((buf_size+1)*sizeof(XMLCh));
579: unsigned char *charSizes=(unsigned char *)malloc(buf_size*sizeof(unsigned char));
580: XalanDOMString *result;
581: try {
582: if(transcoder) {
583: unsigned int bytesEaten;
584: unsigned int dest_size=transcoder->transcodeFrom(
585: (unsigned char *)buf,
586: (const unsigned int)buf_size,
1.4 paf 587: dest,(const unsigned int)buf_size,
1.1 paf 588: bytesEaten,
589: charSizes
590: );
591: result=new XalanDOMString(dest, dest_size);
592: }
593: } catch(XMLException& e) {
594: Exception::provide_source(pool(), 0, e);
595: result=0; //calm, compiler
596: }
597:
598: return std::auto_ptr<XalanDOMString>(result);
599: }
1.4 paf 600: std::auto_ptr<XalanDOMString>Charset::transcode(const String& s) {
1.1 paf 601: const char *cstr=s.cstr(String::UL_UNSPECIFIED);
602:
603: return transcode_buf(cstr, strlen(cstr));
604: }
605: #endif
E-mail: