source: icXML/icXML-devel/src/icxercesc/util/TransService.cpp @ 2720

Last change on this file since 2720 was 2720, checked in by cameron, 6 years ago

Initial check-in of icXML 0.8 source files

File size: 25.3 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * $Id: TransService.cpp 933523 2010-04-13 08:53:39Z amassari $
20 */
21// ---------------------------------------------------------------------------
22//  Includes
23// ---------------------------------------------------------------------------
24#include <xercesc/util/Janitor.hpp>
25#include <xercesc/util/TransService.hpp>
26#include <xercesc/util/XML88591Transcoder.hpp>
27#include <xercesc/util/XMLASCIITranscoder.hpp>
28#include <xercesc/util/XMLChTranscoder.hpp>
29#include <xercesc/util/XMLEBCDICTranscoder.hpp>
30#include <xercesc/util/XMLIBM1047Transcoder.hpp>
31#include <xercesc/util/XMLIBM1140Transcoder.hpp>
32#include <xercesc/util/XMLUCS4Transcoder.hpp>
33#include <xercesc/util/XMLUTF8Transcoder.hpp>
34#include <xercesc/util/XMLUTF16Transcoder.hpp>
35#include <xercesc/util/XMLWin1252Transcoder.hpp>
36#include <xercesc/util/XMLUniDefs.hpp>
37#include <xercesc/util/XMLUni.hpp>
38#include <xercesc/util/EncodingValidator.hpp>
39#include <xercesc/util/PlatformUtils.hpp>
40#include <xercesc/util/TransENameMap.hpp>
41#include <xercesc/util/XMLInitializer.hpp>
42#include <xercesc/util/TranscodingException.hpp>
43
44XERCES_CPP_NAMESPACE_BEGIN
45
46// ---------------------------------------------------------------------------
47//  Local, static data
48//
49//  gStrictIANAEncoding
50//      A flag to control whether strict IANA encoding names checking should
51//      be done
52//
53// ---------------------------------------------------------------------------
54static bool gStrictIANAEncoding = false;
55RefHashTableOf<ENameMap>* XMLTransService::gMappings = 0;
56RefVectorOf<ENameMap> * XMLTransService::gMappingsRecognizer = 0;
57
58void XMLInitializer::initializeTransService()
59{
60        XMLTransService::gMappings = new RefHashTableOf<ENameMap>(103);
61        XMLTransService::gMappingsRecognizer = new RefVectorOf<ENameMap>(
62          (XMLSize_t)XMLRecognizer::Encodings_Count);
63}
64
65void XMLInitializer::terminateTransService()
66{
67        delete XMLTransService::gMappingsRecognizer;
68        XMLTransService::gMappingsRecognizer = 0;
69
70        delete XMLTransService::gMappings;
71        XMLTransService::gMappings = 0;
72}
73
74// ---------------------------------------------------------------------------
75//  XMLTransService: Constructors and destructor
76// ---------------------------------------------------------------------------
77XMLTransService::XMLTransService()
78{
79}
80
81XMLTransService::~XMLTransService()
82{
83}
84
85// ---------------------------------------------------------------------------
86//    Allow user specific encodings to be added to the mappings table.
87//    Should be called after platform init
88// ---------------------------------------------------------------------------
89void XMLTransService::addEncoding(const XMLCh* const encoding,
90                                                                  ENameMap* const ownMapping)
91{
92        gMappings->put((void *) encoding, ownMapping);
93}
94
95// ---------------------------------------------------------------------------
96//  XMLTransService: Non-virtual API
97// ---------------------------------------------------------------------------
98// ---------------------------------------------------------------------------
99//  XMLTransService: Non-virtual API
100// ---------------------------------------------------------------------------
101XMLTranscoder*
102XMLTransService::makeNewTranscoderFor( const char* const             encodingName
103                                                                         ,       XMLTransService::Codes& resValue
104                                                                         , const XMLSize_t               blockSize
105                                                                         ,       MemoryManager* const    manager)
106{
107        XMLCh* tmpName = XMLString::transcode(encodingName, manager);
108        ArrayJanitor<XMLCh> janName(tmpName, manager);
109
110        return makeNewTranscoderFor(tmpName, resValue, blockSize, manager);
111}
112
113XMLTranscoder*
114XMLTransService::makeNewTranscoderFor( const XMLCh* const            encodingName
115                                                                         ,       XMLTransService::Codes& resValue
116                                                                         , const XMLSize_t               blockSize
117                                                                         ,       MemoryManager* const    manager)
118{
119        //
120        // If strict IANA encoding flag is set, validate encoding name
121        //
122        if (gStrictIANAEncoding)
123        {
124                if (!EncodingValidator::instance()->isValidEncoding(encodingName))
125                {
126                        resValue = XMLTransService::UnsupportedEncoding;
127                        return 0;
128                }
129        }
130
131        //
132        //  First try to find it in our list of mappings to intrinsically
133        //  supported encodings. We have to upper case the passed encoding
134        //  name because we use a hash table and we stored all our mappings
135        //  in all uppercase.
136        //
137        const XMLSize_t bufSize = 2048;
138        XMLCh upBuf[bufSize + 1];
139        if (!XMLString::copyNString(upBuf, encodingName, bufSize))
140        {
141                resValue = XMLTransService::InternalFailure;
142                return 0;
143        }
144        XMLString::upperCaseASCII(upBuf);
145        ENameMap* ourMapping = gMappings->get(upBuf);
146
147        // If we found it, then call the factory method for it
148        if (ourMapping)
149        {
150           XMLTranscoder* temp = ourMapping->makeNew(blockSize, manager);
151           resValue = temp ? XMLTransService::Ok : XMLTransService::InternalFailure;
152           return temp;
153        }
154
155        //
156        //  It wasn't an intrinsic and it wasn't disallowed, so pass it on
157        //  to the trans service to see if he can make anything of it.
158        //
159
160        XMLTranscoder* temp =  makeNewXMLTranscoder(encodingName, resValue, blockSize, manager);
161
162        // if successful, set resValue to OK
163        // if failed, the makeNewXMLTranscoder has already set the proper failing resValue
164        if (temp) resValue =  XMLTransService::Ok;
165
166        return temp;
167
168}
169
170
171XMLTranscoder*
172XMLTransService::makeNewTranscoderFor(  XMLRecognizer::Encodings        encodingEnum
173                                                                                ,       XMLTransService::Codes& resValue
174                                                                                , const XMLSize_t               blockSize
175                                                                                ,       MemoryManager* const    manager)
176{
177        //
178        // We can only make transcoder if the passed encodingEnum is under this range
179        //
180        if (encodingEnum < XMLRecognizer::Encodings_Min || encodingEnum > XMLRecognizer::Encodings_Max) {
181                resValue = XMLTransService::InternalFailure;
182                return 0;
183        }
184
185        ENameMap* ourMapping = gMappingsRecognizer->elementAt(encodingEnum);
186
187        // If we found it, then call the factory method for it
188    if (ourMapping)
189    {
190       XMLTranscoder * temp = ourMapping->makeNew(blockSize, manager);
191           resValue = temp ? XMLTransService::Ok : XMLTransService::InternalFailure;
192           return temp;
193        }
194    else
195    {
196                XMLTranscoder* temp =  makeNewXMLTranscoder(XMLRecognizer::nameForEncoding(encodingEnum, manager), resValue, blockSize, manager);
197
198                // if successful, set resValue to OK
199                // if failed, the makeNewXMLTranscoder has already set the proper failing resValue
200                if (temp) resValue =  XMLTransService::Ok;
201
202                return temp;
203        }
204
205}
206
207#if 0
208XMLTranscoder*
209XMLTransService::makeNewTranscoderFor( XMLRecognizer::Encodings   encodingEnum
210                                                                         , XMLTransService::Codes&    resValue
211                                                                         , const XMLSize_t            blockSize
212                                                                         ,       MemoryManager* const manager)
213{
214        XMLTranscoder * transcoder = NULL;
215
216        #define CREATE_TRANSCODER(FORMAT, ENCODING_STRING, TRANSCODER_TYPE) \
217                case XMLRecognizer::FORMAT: \
218                        transcoder = new (manager) TRANSCODER_TYPE(ENCODING_STRING, blockSize, manager); \
219                        break;
220
221        switch (encodingEnum)
222        {
223                CREATE_TRANSCODER(EBCDIC, XMLUni::fgIBM037EncodingString, XMLEBCDICTranscoder)
224                CREATE_TRANSCODER(UCS_4B, XMLUni::fgUCS4BEncodingString, XMLUCS4Transcoder)
225                CREATE_TRANSCODER(UCS_4L, XMLUni::fgUCS4LEncodingString, XMLUCS4Transcoder)
226                CREATE_TRANSCODER(US_ASCII, XMLUni::fgUSASCIIEncodingString, XMLASCIITranscoder)
227                CREATE_TRANSCODER(UTF_8, XMLUni::fgUTF8EncodingString, XMLUTF8Transcoder)
228                CREATE_TRANSCODER(UTF_16B, XMLUni::fgUTF16BEncodingString, XMLUTF16Transcoder)
229                CREATE_TRANSCODER(UTF_16L, XMLUni::fgUTF16LEncodingString, XMLUTF16Transcoder)
230                CREATE_TRANSCODER(XERCES_XMLCH, XMLUni::fgXMLChEncodingString, XMLChTranscoder)
231        }
232
233        #undef CREATE_TRANSCODER
234
235        resValue = transcoder ? XMLTransService::Ok : XMLTransService::InternalFailure;
236
237        return transcoder;
238}
239#endif
240
241// ---------------------------------------------------------------------------
242//  XMLTransTransService: Hidden Init Method
243//
244//  This is called by platform utils during startup.
245// ---------------------------------------------------------------------------
246void XMLTransService::initTransService()
247{
248        //
249        //  A stupid way to increment the fCurCount inside the RefVectorOf
250        //
251        for (XMLSize_t i = 0; i < (XMLSize_t)XMLRecognizer::Encodings_Count; i++)
252                gMappingsRecognizer->addElement(0);
253
254        //
255        //  Add in the magical mapping for the native XMLCh transcoder. This
256        //  is used for internal entities.
257        //
258        gMappingsRecognizer->setElementAt(new ENameMapFor<XMLChTranscoder>(XMLUni::fgXMLChEncodingString), XMLRecognizer::XERCES_XMLCH);
259        gMappings->put((void*)XMLUni::fgXMLChEncodingString, new ENameMapFor<XMLChTranscoder>(XMLUni::fgXMLChEncodingString));
260
261        //
262        //  Add in our mappings for ASCII.
263        //
264        gMappingsRecognizer->setElementAt(new ENameMapFor<XMLASCIITranscoder>(XMLUni::fgUSASCIIEncodingString), XMLRecognizer::US_ASCII);
265        gMappings->put((void*)XMLUni::fgUSASCIIEncodingString, new ENameMapFor<XMLASCIITranscoder>(XMLUni::fgUSASCIIEncodingString));
266        gMappings->put((void*)XMLUni::fgUSASCIIEncodingString2, new ENameMapFor<XMLASCIITranscoder>(XMLUni::fgUSASCIIEncodingString2));
267        gMappings->put((void*)XMLUni::fgUSASCIIEncodingString3, new ENameMapFor<XMLASCIITranscoder>(XMLUni::fgUSASCIIEncodingString3));
268        gMappings->put((void*)XMLUni::fgUSASCIIEncodingString4, new ENameMapFor<XMLASCIITranscoder>(XMLUni::fgUSASCIIEncodingString4));
269
270        //
271        //  Add in our mappings for UTF-8
272        //
273        gMappingsRecognizer->setElementAt(new ENameMapFor<XMLUTF8Transcoder>(XMLUni::fgUTF8EncodingString), XMLRecognizer::UTF_8);
274        gMappings->put((void*)XMLUni::fgUTF8EncodingString, new ENameMapFor<XMLUTF8Transcoder>(XMLUni::fgUTF8EncodingString));
275        gMappings->put((void*)XMLUni::fgUTF8EncodingString2, new ENameMapFor<XMLUTF8Transcoder>(XMLUni::fgUTF8EncodingString2));
276
277        //
278        //  Add in our mappings for Latin1
279        //
280        gMappings->put((void*)XMLUni::fgISO88591EncodingString, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString));
281        gMappings->put((void*)XMLUni::fgISO88591EncodingString2, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString2));
282        gMappings->put((void*)XMLUni::fgISO88591EncodingString3, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString3));
283        gMappings->put((void*)XMLUni::fgISO88591EncodingString4, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString4));
284        gMappings->put((void*)XMLUni::fgISO88591EncodingString5, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString5));
285        gMappings->put((void*)XMLUni::fgISO88591EncodingString6, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString6));
286        gMappings->put((void*)XMLUni::fgISO88591EncodingString7, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString7));
287        gMappings->put((void*)XMLUni::fgISO88591EncodingString8, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString8));
288        gMappings->put((void*)XMLUni::fgISO88591EncodingString9, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString9));
289        gMappings->put((void*)XMLUni::fgISO88591EncodingString10, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString10));
290        gMappings->put((void*)XMLUni::fgISO88591EncodingString11, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString11));
291        gMappings->put((void*)XMLUni::fgISO88591EncodingString12, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString12));
292
293        //
294        //  Add in our mappings for UTF-16 and UCS-4, little endian
295        //
296    const bool swapped = XMLPlatformUtils::fgXMLChBigEndian;
297
298        gMappingsRecognizer->setElementAt(new EEndianNameMapFor<XMLUTF16Transcoder>(XMLUni::fgUTF16LEncodingString, swapped), XMLRecognizer::UTF_16L);
299        gMappings->put
300        (
301                (void*)XMLUni::fgUTF16LEncodingString,
302                new EEndianNameMapFor<XMLUTF16Transcoder>
303                (
304                        XMLUni::fgUTF16LEncodingString
305                        , swapped
306                )
307        );
308
309        gMappings->put
310        (
311                (void*)XMLUni::fgUTF16LEncodingString2,
312                new EEndianNameMapFor<XMLUTF16Transcoder>
313                (
314                        XMLUni::fgUTF16LEncodingString2
315                        , swapped
316                )
317        );
318
319        gMappingsRecognizer->setElementAt(new EEndianNameMapFor<XMLUCS4Transcoder>(XMLUni::fgUCS4LEncodingString, swapped), XMLRecognizer::UCS_4L);
320        gMappings->put
321        (
322                (void*)XMLUni::fgUCS4LEncodingString,
323                new EEndianNameMapFor<XMLUCS4Transcoder>
324                (
325                        XMLUni::fgUCS4LEncodingString
326                        , swapped
327                )
328        );
329
330        gMappings->put
331        (
332                (void*)XMLUni::fgUCS4LEncodingString2,
333                new EEndianNameMapFor<XMLUCS4Transcoder>
334                (
335                        XMLUni::fgUCS4LEncodingString2
336                        , swapped
337                )
338        );
339
340        //
341        //  Add in our mappings for UTF-16 and UCS-4, big endian
342        //
343
344        gMappingsRecognizer->setElementAt(new EEndianNameMapFor<XMLUTF16Transcoder>(XMLUni::fgUTF16BEncodingString, swapped), XMLRecognizer::UTF_16B);
345        gMappings->put
346        (
347                (void*)XMLUni::fgUTF16BEncodingString,
348                new EEndianNameMapFor<XMLUTF16Transcoder>
349                (
350                        XMLUni::fgUTF16BEncodingString
351            , !swapped
352                )
353        );
354
355        gMappings->put
356        (
357                (void*)XMLUni::fgUTF16BEncodingString2,
358                new EEndianNameMapFor<XMLUTF16Transcoder>
359                (
360                        XMLUni::fgUTF16BEncodingString2
361            , !swapped
362                )
363        );
364
365        gMappingsRecognizer->setElementAt(new EEndianNameMapFor<XMLUCS4Transcoder>(XMLUni::fgUCS4BEncodingString, swapped), XMLRecognizer::UCS_4B);
366        gMappings->put
367        (
368                (void*)XMLUni::fgUCS4BEncodingString,
369                new EEndianNameMapFor<XMLUCS4Transcoder>
370                (
371                        XMLUni::fgUCS4BEncodingString
372            , !swapped
373                )
374        );
375
376        gMappings->put
377        (
378                (void*)XMLUni::fgUCS4BEncodingString2,
379                new EEndianNameMapFor<XMLUCS4Transcoder>
380                (
381                        XMLUni::fgUCS4BEncodingString2
382            , !swapped
383                )
384        );
385
386        //
387        //  Add in our mappings for UTF-16 and UCS-4 which does not indicate endian
388        //  assumes the same endian encoding as the OS
389        //
390
391        gMappings->put
392        (
393                (void*)XMLUni::fgUTF16EncodingString,
394                new EEndianNameMapFor<XMLUTF16Transcoder>
395                (
396                        XMLUni::fgUTF16EncodingString
397                        , false
398                )
399        );
400        gMappings->put
401        (
402                (void*)XMLUni::fgUTF16EncodingString2,
403                new EEndianNameMapFor<XMLUTF16Transcoder>
404                (
405                        XMLUni::fgUTF16EncodingString2
406                        , false
407                )
408        );
409        gMappings->put
410        (
411                (void*)XMLUni::fgUTF16EncodingString3,
412                new EEndianNameMapFor<XMLUTF16Transcoder>
413                (
414                        XMLUni::fgUTF16EncodingString3
415                        , false
416                )
417        );
418        gMappings->put
419        (
420                (void*)XMLUni::fgUTF16EncodingString4,
421                new EEndianNameMapFor<XMLUTF16Transcoder>
422                (
423                        XMLUni::fgUTF16EncodingString4
424                        , false
425                )
426        );
427        gMappings->put
428        (
429                (void*)XMLUni::fgUTF16EncodingString5,
430                new EEndianNameMapFor<XMLUTF16Transcoder>
431                (
432                        XMLUni::fgUTF16EncodingString5
433                        , false
434                )
435        );
436        gMappings->put
437        (
438                (void*)XMLUni::fgUTF16EncodingString6,
439                new EEndianNameMapFor<XMLUTF16Transcoder>
440                (
441                        XMLUni::fgUTF16EncodingString6
442                        , false
443                )
444        );
445        gMappings->put
446        (
447                (void*)XMLUni::fgUTF16EncodingString7,
448                new EEndianNameMapFor<XMLUTF16Transcoder>
449                (
450                        XMLUni::fgUTF16EncodingString7
451                        , false
452                )
453        );
454        gMappings->put
455        (
456                (void*)XMLUni::fgUCS4EncodingString,
457                new EEndianNameMapFor<XMLUCS4Transcoder>
458                (
459                        XMLUni::fgUCS4EncodingString
460                        , false
461                )
462        );
463        gMappings->put
464        (
465                (void*)XMLUni::fgUCS4EncodingString2,
466                new EEndianNameMapFor<XMLUCS4Transcoder>
467                (
468                        XMLUni::fgUCS4EncodingString2
469                        , false
470                )
471        );
472        gMappings->put
473        (
474                (void*)XMLUni::fgUCS4EncodingString3,
475                new EEndianNameMapFor<XMLUCS4Transcoder>
476                (
477                        XMLUni::fgUCS4EncodingString3
478                        , false
479                )
480        );
481        gMappings->put
482        (
483                (void*)XMLUni::fgUCS4EncodingString4,
484                new EEndianNameMapFor<XMLUCS4Transcoder>
485                (
486                        XMLUni::fgUCS4EncodingString4
487                        , false
488                )
489        );
490        gMappings->put
491        (
492                (void*)XMLUni::fgUCS4EncodingString5,
493                new EEndianNameMapFor<XMLUCS4Transcoder>
494                (
495                        XMLUni::fgUCS4EncodingString5
496                        , false
497                )
498        );
499
500        //
501        //  Add in our mappings for IBM037, and the one alias we support for
502        //  it, which is EBCDIC-CP-US.
503        //
504        gMappingsRecognizer->setElementAt(new ENameMapFor<XMLEBCDICTranscoder>(XMLUni::fgEBCDICEncodingString), XMLRecognizer::EBCDIC);
505        gMappings->put((void*)XMLUni::fgIBM037EncodingString, new ENameMapFor<XMLEBCDICTranscoder>(XMLUni::fgIBM037EncodingString));
506        gMappings->put((void*)XMLUni::fgIBM037EncodingString2, new ENameMapFor<XMLEBCDICTranscoder>(XMLUni::fgIBM037EncodingString2));
507
508
509    //
510    //  Add in our mappings for IBM1047, and the one alias we support for
511    //  it, which is EBCDIC-CP-US.
512    //
513        gMappings->put((void*)XMLUni::fgIBM1047EncodingString, new ENameMapFor<XMLIBM1047Transcoder>(XMLUni::fgIBM1047EncodingString));
514        gMappings->put((void*)XMLUni::fgIBM1047EncodingString2, new ENameMapFor<XMLIBM1047Transcoder>(XMLUni::fgIBM1047EncodingString2));
515
516        //
517        //  Add in our mappings for IBM037 with Euro update, i.e. IBM1140. It
518        //  has alias IBM01140, the one suggested by IANA
519        //
520        gMappings->put((void*)XMLUni::fgIBM1140EncodingString, new ENameMapFor<XMLIBM1140Transcoder>(XMLUni::fgIBM1140EncodingString));
521        gMappings->put((void*)XMLUni::fgIBM1140EncodingString2, new ENameMapFor<XMLIBM1140Transcoder>(XMLUni::fgIBM1140EncodingString2));
522        gMappings->put((void*)XMLUni::fgIBM1140EncodingString3, new ENameMapFor<XMLIBM1140Transcoder>(XMLUni::fgIBM1140EncodingString3));
523        gMappings->put((void*)XMLUni::fgIBM1140EncodingString4, new ENameMapFor<XMLIBM1140Transcoder>(XMLUni::fgIBM1140EncodingString4));
524
525        //
526        //  Add in our mappings for Windows-1252. We don't have any aliases for
527        //  this one, so there is just one mapping.
528        //
529        gMappings->put((void*)XMLUni::fgWin1252EncodingString, new ENameMapFor<XMLWin1252Transcoder>(XMLUni::fgWin1252EncodingString));
530
531}
532
533// ---------------------------------------------------------------------------
534//  XMLTransService: IANA encoding setting
535// ---------------------------------------------------------------------------
536void XMLTransService::strictIANAEncoding(const bool newState)
537{
538        gStrictIANAEncoding = newState;
539}
540
541bool XMLTransService::isStrictIANAEncoding()
542{
543        return gStrictIANAEncoding;
544}
545
546// ---------------------------------------------------------------------------
547//  XMLTranscoder: Is Swapped
548// ---------------------------------------------------------------------------
549bool XMLTranscoder::isSwapped() const
550{
551    return 0;
552}
553
554// ---------------------------------------------------------------------------
555//  XMLTranscoder: Public Destructor
556// ---------------------------------------------------------------------------
557XMLTranscoder::~XMLTranscoder()
558{
559
560}
561
562// ---------------------------------------------------------------------------
563//  XMLTranscoder: Hidden Constructors
564// ---------------------------------------------------------------------------
565XMLTranscoder::XMLTranscoder( const XMLCh* const    encodingName
566                                                        , const XMLSize_t       blockSize
567                                                        , MemoryManager* const  manager) :
568          fBlockSize(blockSize)
569        , fEncodingName(const_cast<XMLCh*>(encodingName))
570        , fMemoryManager(manager)
571{
572
573}
574
575// ---------------------------------------------------------------------------
576//  XMLCharacterSetAdapter: Public Destructor
577// ---------------------------------------------------------------------------
578
579XMLCharacterSetAdapter::~XMLCharacterSetAdapter()
580{
581
582}
583
584// ---------------------------------------------------------------------------
585//  XMLLCPTranscoder: Public Destructor
586// ---------------------------------------------------------------------------
587XMLLCPTranscoder::XMLLCPTranscoder()
588{
589}
590
591
592// ---------------------------------------------------------------------------
593//  XMLLCPTranscoder: Hidden Constructors
594// ---------------------------------------------------------------------------
595XMLLCPTranscoder::~XMLLCPTranscoder()
596{
597}
598
599// ---------------------------------------------------------------------------
600//  TranscodeToStr: Public constructors and destructor
601// ---------------------------------------------------------------------------
602TranscodeToStr::TranscodeToStr(const XMLCh *in, const char *encoding,
603                                                           MemoryManager *manager)
604        : fString(0),
605          fBytesWritten(0),
606          fMemoryManager(manager)
607{
608        XMLTransService::Codes failReason;
609        const XMLSize_t blockSize = 2048;
610
611        XMLTranscoder* trans = XMLPlatformUtils::fgTransService->makeNewTranscoderFor(encoding, failReason, blockSize, fMemoryManager);
612        Janitor<XMLTranscoder> janTrans(trans);
613
614        transcode(in, XMLString::stringLen(in), trans);
615}
616
617TranscodeToStr::TranscodeToStr(const XMLCh *in, XMLSize_t length, const char *encoding,
618                                                           MemoryManager *manager)
619        : fString(0),
620          fBytesWritten(0),
621          fMemoryManager(manager)
622{
623        XMLTransService::Codes failReason;
624        const XMLSize_t blockSize = 2048;
625
626        XMLTranscoder* trans = XMLPlatformUtils::fgTransService->makeNewTranscoderFor(encoding, failReason, blockSize, fMemoryManager);
627        Janitor<XMLTranscoder> janTrans(trans);
628
629        transcode(in, length, trans);
630}
631
632TranscodeToStr::TranscodeToStr(const XMLCh *in, XMLTranscoder* trans,
633                                                           MemoryManager *manager)
634        : fString(0),
635          fBytesWritten(0),
636          fMemoryManager(manager)
637{
638        transcode(in, XMLString::stringLen(in), trans);
639}
640
641TranscodeToStr::TranscodeToStr(const XMLCh *in, XMLSize_t length, XMLTranscoder* trans,
642                                                           MemoryManager *manager)
643        : fString(0),
644          fBytesWritten(0),
645          fMemoryManager(manager)
646{
647        transcode(in, length, trans);
648}
649
650TranscodeToStr::~TranscodeToStr()
651{
652        if(fString)
653                fMemoryManager->deallocate(fString);
654}
655
656// ---------------------------------------------------------------------------
657//  TranscodeToStr: Private helper methods
658// ---------------------------------------------------------------------------
659void TranscodeToStr::transcode(const XMLCh *in, XMLSize_t len, XMLTranscoder* trans)
660{
661        if(!in) return;
662
663        XMLSize_t allocSize = len * sizeof(XMLCh);
664        fString = (XMLByte*)fMemoryManager->allocate(allocSize);
665
666        XMLSize_t charsRead = 0;
667        XMLSize_t charsDone = 0;
668
669        while(true) {
670                fBytesWritten += trans->transcodeTo(in + charsDone, len - charsDone,
671                                                                                        fString + fBytesWritten, allocSize - fBytesWritten,
672                                                                                        charsRead, XMLTranscoder::UnRep_Throw);
673                if(charsRead == 0)
674                        ThrowXMLwithMemMgr(TranscodingException, XMLExcepts::Trans_BadSrcSeq, fMemoryManager);
675
676                charsDone += charsRead;
677
678                if(charsDone == len) break;
679
680                allocSize *= 2;
681                XMLByte *newBuf = (XMLByte*)fMemoryManager->allocate(allocSize);
682                memcpy(newBuf, fString, fBytesWritten);
683                fMemoryManager->deallocate(fString);
684                fString = newBuf;
685        }
686
687        // null terminate
688        if((fBytesWritten + 4) > allocSize) {
689                allocSize = fBytesWritten + 4;
690                XMLByte *newBuf = (XMLByte*)fMemoryManager->allocate(allocSize);
691                memcpy(newBuf, fString, fBytesWritten);
692                fMemoryManager->deallocate(fString);
693                fString = newBuf;
694        }
695        fString[fBytesWritten + 0] = 0;
696        fString[fBytesWritten + 1] = 0;
697        fString[fBytesWritten + 2] = 0;
698        fString[fBytesWritten + 3] = 0;
699}
700
701// ---------------------------------------------------------------------------
702//  TranscodeFromStr: Public constructors and destructor
703// ---------------------------------------------------------------------------
704TranscodeFromStr::TranscodeFromStr(const XMLByte *data, XMLSize_t length, const char *encoding,
705                                                                   MemoryManager *manager)
706        : fString(0),
707          fCharsWritten(0),
708          fMemoryManager(manager)
709{
710        XMLTransService::Codes failReason;
711        const XMLSize_t blockSize = 2048;
712
713        XMLTranscoder* trans = XMLPlatformUtils::fgTransService->makeNewTranscoderFor(encoding, failReason, blockSize, fMemoryManager);
714        Janitor<XMLTranscoder> janTrans(trans);
715
716        transcode(data, length, trans);
717}
718
719TranscodeFromStr::TranscodeFromStr(const XMLByte *data, XMLSize_t length, XMLTranscoder *trans,
720                                                                   MemoryManager *manager)
721        : fString(0),
722          fCharsWritten(0),
723          fMemoryManager(manager)
724{
725        transcode(data, length, trans);
726}
727
728TranscodeFromStr::~TranscodeFromStr()
729{
730        if(fString)
731                fMemoryManager->deallocate(fString);
732}
733
734// ---------------------------------------------------------------------------
735//  TranscodeFromStr: Private helper methods
736// ---------------------------------------------------------------------------
737void TranscodeFromStr::transcode(const XMLByte *in, XMLSize_t length, XMLTranscoder *trans)
738{
739        if(!in) return;
740
741        XMLSize_t allocSize = length + 1;
742        fString = (XMLCh*)fMemoryManager->allocate(allocSize * sizeof(XMLCh));
743
744        XMLSize_t csSize = length;
745        ArrayJanitor<unsigned char> charSizes((unsigned char*)fMemoryManager->allocate(csSize * sizeof(unsigned char)),
746                                                                                  fMemoryManager);
747
748        XMLSize_t bytesRead = 0;
749        XMLSize_t bytesDone = 0;
750
751        while(true) {
752                fCharsWritten += trans->transcodeFrom(in + bytesDone, length - bytesDone,
753                                                                                          fString + fCharsWritten, allocSize - fCharsWritten,
754                                                                                          bytesRead, charSizes.get());
755                if(bytesRead == 0)
756                        ThrowXMLwithMemMgr(TranscodingException, XMLExcepts::Trans_BadSrcSeq, fMemoryManager);
757
758                bytesDone += bytesRead;
759                if(bytesDone == length) break;
760
761                allocSize *= 2;
762                XMLCh *newBuf = (XMLCh*)fMemoryManager->allocate(allocSize * sizeof(XMLCh));
763                memcpy(newBuf, fString, fCharsWritten);
764                fMemoryManager->deallocate(fString);
765                fString = newBuf;
766
767                if((allocSize - fCharsWritten) > csSize) {
768                        csSize = allocSize - fCharsWritten;
769                        charSizes.reset((unsigned char*)fMemoryManager->allocate(csSize * sizeof(unsigned char)),
770                                                        fMemoryManager);
771                }
772        }
773
774        // null terminate
775        if(fCharsWritten == allocSize) {
776                allocSize += 1;
777                XMLCh *newBuf = (XMLCh*)fMemoryManager->allocate(allocSize * sizeof(XMLCh));
778                memcpy(newBuf, fString, fCharsWritten);
779                fMemoryManager->deallocate(fString);
780                fString = newBuf;
781        }
782        fString[fCharsWritten] = 0;
783}
784
785XERCES_CPP_NAMESPACE_END
Note: See TracBrowser for help on using the repository browser.