GME
13
|
00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one or more 00003 * contributor license agreements. See the NOTICE file distributed with 00004 * this work for additional information regarding copyright ownership. 00005 * The ASF licenses this file to You under the Apache License, Version 2.0 00006 * (the "License"); you may not use this file except in compliance with 00007 * the License. You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 /* 00019 * $Id: TransService.cpp 933523 2010-04-13 08:53:39Z amassari $ 00020 */ 00021 // --------------------------------------------------------------------------- 00022 // Includes 00023 // --------------------------------------------------------------------------- 00024 #include <xercesc/util/Janitor.hpp> 00025 #include <xercesc/util/TransService.hpp> 00026 #include <xercesc/util/XML88591Transcoder.hpp> 00027 #include <xercesc/util/XMLASCIITranscoder.hpp> 00028 #include <xercesc/util/XMLChTranscoder.hpp> 00029 #include <xercesc/util/XMLEBCDICTranscoder.hpp> 00030 #include <xercesc/util/XMLIBM1047Transcoder.hpp> 00031 #include <xercesc/util/XMLIBM1140Transcoder.hpp> 00032 #include <xercesc/util/XMLUCS4Transcoder.hpp> 00033 #include <xercesc/util/XMLUTF8Transcoder.hpp> 00034 #include <xercesc/util/XMLUTF16Transcoder.hpp> 00035 #include <xercesc/util/XMLWin1252Transcoder.hpp> 00036 #include <xercesc/util/XMLUniDefs.hpp> 00037 #include <xercesc/util/XMLUni.hpp> 00038 #include <xercesc/util/EncodingValidator.hpp> 00039 #include <xercesc/util/PlatformUtils.hpp> 00040 #include <xercesc/util/TransENameMap.hpp> 00041 #include <xercesc/util/XMLInitializer.hpp> 00042 #include <xercesc/util/TranscodingException.hpp> 00043 00044 XERCES_CPP_NAMESPACE_BEGIN 00045 00046 // --------------------------------------------------------------------------- 00047 // Local, static data 00048 // 00049 // gStrictIANAEncoding 00050 // A flag to control whether strict IANA encoding names checking should 00051 // be done 00052 // 00053 // --------------------------------------------------------------------------- 00054 static bool gStrictIANAEncoding = false; 00055 RefHashTableOf<ENameMap>* XMLTransService::gMappings = 0; 00056 RefVectorOf<ENameMap> * XMLTransService::gMappingsRecognizer = 0; 00057 00058 void XMLInitializer::initializeTransService() 00059 { 00060 XMLTransService::gMappings = new RefHashTableOf<ENameMap>(103); 00061 XMLTransService::gMappingsRecognizer = new RefVectorOf<ENameMap>( 00062 (XMLSize_t)XMLRecognizer::Encodings_Count); 00063 } 00064 00065 void XMLInitializer::terminateTransService() 00066 { 00067 delete XMLTransService::gMappingsRecognizer; 00068 XMLTransService::gMappingsRecognizer = 0; 00069 00070 delete XMLTransService::gMappings; 00071 XMLTransService::gMappings = 0; 00072 } 00073 00074 // --------------------------------------------------------------------------- 00075 // XMLTransService: Constructors and destructor 00076 // --------------------------------------------------------------------------- 00077 XMLTransService::XMLTransService() 00078 { 00079 } 00080 00081 XMLTransService::~XMLTransService() 00082 { 00083 } 00084 00085 // --------------------------------------------------------------------------- 00086 // Allow user specific encodings to be added to the mappings table. 00087 // Should be called after platform init 00088 // --------------------------------------------------------------------------- 00089 void XMLTransService::addEncoding(const XMLCh* const encoding, 00090 ENameMap* const ownMapping) 00091 { 00092 gMappings->put((void *) encoding, ownMapping); 00093 } 00094 00095 // --------------------------------------------------------------------------- 00096 // XMLTransService: Non-virtual API 00097 // --------------------------------------------------------------------------- 00098 XMLTranscoder* 00099 XMLTransService::makeNewTranscoderFor( const char* const encodingName 00100 , XMLTransService::Codes& resValue 00101 , const XMLSize_t blockSize 00102 , MemoryManager* const manager) 00103 { 00104 XMLCh* tmpName = XMLString::transcode(encodingName, manager); 00105 ArrayJanitor<XMLCh> janName(tmpName, manager); 00106 00107 return makeNewTranscoderFor(tmpName, resValue, blockSize, manager); 00108 } 00109 00110 XMLTranscoder* 00111 XMLTransService::makeNewTranscoderFor( const XMLCh* const encodingName 00112 , XMLTransService::Codes& resValue 00113 , const XMLSize_t blockSize 00114 , MemoryManager* const manager) 00115 { 00116 // 00117 // If strict IANA encoding flag is set, validate encoding name 00118 // 00119 if (gStrictIANAEncoding) 00120 { 00121 if (!EncodingValidator::instance()->isValidEncoding(encodingName)) 00122 { 00123 resValue = XMLTransService::UnsupportedEncoding; 00124 return 0; 00125 } 00126 } 00127 00128 // 00129 // First try to find it in our list of mappings to intrinsically 00130 // supported encodings. We have to upper case the passed encoding 00131 // name because we use a hash table and we stored all our mappings 00132 // in all uppercase. 00133 // 00134 const XMLSize_t bufSize = 2048; 00135 XMLCh upBuf[bufSize + 1]; 00136 if (!XMLString::copyNString(upBuf, encodingName, bufSize)) 00137 { 00138 resValue = XMLTransService::InternalFailure; 00139 return 0; 00140 } 00141 XMLString::upperCaseASCII(upBuf); 00142 ENameMap* ourMapping = gMappings->get(upBuf); 00143 00144 // If we found it, then call the factory method for it 00145 if (ourMapping) 00146 { 00147 XMLTranscoder* temp = ourMapping->makeNew(blockSize, manager); 00148 resValue = temp ? XMLTransService::Ok : XMLTransService::InternalFailure; 00149 return temp; 00150 } 00151 00152 // 00153 // It wasn't an intrinsic and it wasn't disallowed, so pass it on 00154 // to the trans service to see if he can make anything of it. 00155 // 00156 00157 XMLTranscoder* temp = makeNewXMLTranscoder(encodingName, resValue, blockSize, manager); 00158 00159 // if successful, set resValue to OK 00160 // if failed, the makeNewXMLTranscoder has already set the proper failing resValue 00161 if (temp) resValue = XMLTransService::Ok; 00162 00163 return temp; 00164 00165 } 00166 00167 00168 XMLTranscoder* 00169 XMLTransService::makeNewTranscoderFor( XMLRecognizer::Encodings encodingEnum 00170 , XMLTransService::Codes& resValue 00171 , const XMLSize_t blockSize 00172 , MemoryManager* const manager) 00173 { 00174 // 00175 // We can only make transcoder if the passed encodingEnum is under this range 00176 // 00177 if (encodingEnum < XMLRecognizer::Encodings_Min || encodingEnum > XMLRecognizer::Encodings_Max) { 00178 resValue = XMLTransService::InternalFailure; 00179 return 0; 00180 } 00181 00182 ENameMap* ourMapping = gMappingsRecognizer->elementAt(encodingEnum); 00183 00184 // If we found it, then call the factory method for it 00185 if (ourMapping) { 00186 XMLTranscoder* temp = ourMapping->makeNew(blockSize, manager); 00187 resValue = temp ? XMLTransService::Ok : XMLTransService::InternalFailure; 00188 return temp; 00189 } 00190 else { 00191 XMLTranscoder* temp = makeNewXMLTranscoder(XMLRecognizer::nameForEncoding(encodingEnum, manager), resValue, blockSize, manager); 00192 00193 // if successful, set resValue to OK 00194 // if failed, the makeNewXMLTranscoder has already set the proper failing resValue 00195 if (temp) resValue = XMLTransService::Ok; 00196 00197 return temp; 00198 } 00199 00200 } 00201 00202 00203 // --------------------------------------------------------------------------- 00204 // XMLTransTransService: Hidden Init Method 00205 // 00206 // This is called by platform utils during startup. 00207 // --------------------------------------------------------------------------- 00208 void XMLTransService::initTransService() 00209 { 00210 // 00211 // A stupid way to increment the fCurCount inside the RefVectorOf 00212 // 00213 for (XMLSize_t i = 0; i < (XMLSize_t)XMLRecognizer::Encodings_Count; i++) 00214 gMappingsRecognizer->addElement(0); 00215 00216 // 00217 // Add in the magical mapping for the native XMLCh transcoder. This 00218 // is used for internal entities. 00219 // 00220 gMappingsRecognizer->setElementAt(new ENameMapFor<XMLChTranscoder>(XMLUni::fgXMLChEncodingString), XMLRecognizer::XERCES_XMLCH); 00221 gMappings->put((void*)XMLUni::fgXMLChEncodingString, new ENameMapFor<XMLChTranscoder>(XMLUni::fgXMLChEncodingString)); 00222 00223 // 00224 // Add in our mappings for ASCII. 00225 // 00226 gMappingsRecognizer->setElementAt(new ENameMapFor<XMLASCIITranscoder>(XMLUni::fgUSASCIIEncodingString), XMLRecognizer::US_ASCII); 00227 gMappings->put((void*)XMLUni::fgUSASCIIEncodingString, new ENameMapFor<XMLASCIITranscoder>(XMLUni::fgUSASCIIEncodingString)); 00228 gMappings->put((void*)XMLUni::fgUSASCIIEncodingString2, new ENameMapFor<XMLASCIITranscoder>(XMLUni::fgUSASCIIEncodingString2)); 00229 gMappings->put((void*)XMLUni::fgUSASCIIEncodingString3, new ENameMapFor<XMLASCIITranscoder>(XMLUni::fgUSASCIIEncodingString3)); 00230 gMappings->put((void*)XMLUni::fgUSASCIIEncodingString4, new ENameMapFor<XMLASCIITranscoder>(XMLUni::fgUSASCIIEncodingString4)); 00231 00232 00233 // 00234 // Add in our mappings for UTF-8 00235 // 00236 gMappingsRecognizer->setElementAt(new ENameMapFor<XMLUTF8Transcoder>(XMLUni::fgUTF8EncodingString), XMLRecognizer::UTF_8); 00237 gMappings->put((void*)XMLUni::fgUTF8EncodingString, new ENameMapFor<XMLUTF8Transcoder>(XMLUni::fgUTF8EncodingString)); 00238 gMappings->put((void*)XMLUni::fgUTF8EncodingString2, new ENameMapFor<XMLUTF8Transcoder>(XMLUni::fgUTF8EncodingString2)); 00239 00240 // 00241 // Add in our mappings for Latin1 00242 // 00243 gMappings->put((void*)XMLUni::fgISO88591EncodingString, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString)); 00244 gMappings->put((void*)XMLUni::fgISO88591EncodingString2, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString2)); 00245 gMappings->put((void*)XMLUni::fgISO88591EncodingString3, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString3)); 00246 gMappings->put((void*)XMLUni::fgISO88591EncodingString4, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString4)); 00247 gMappings->put((void*)XMLUni::fgISO88591EncodingString5, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString5)); 00248 gMappings->put((void*)XMLUni::fgISO88591EncodingString6, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString6)); 00249 gMappings->put((void*)XMLUni::fgISO88591EncodingString7, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString7)); 00250 gMappings->put((void*)XMLUni::fgISO88591EncodingString8, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString8)); 00251 gMappings->put((void*)XMLUni::fgISO88591EncodingString9, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString9)); 00252 gMappings->put((void*)XMLUni::fgISO88591EncodingString10, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString10)); 00253 gMappings->put((void*)XMLUni::fgISO88591EncodingString11, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString11)); 00254 gMappings->put((void*)XMLUni::fgISO88591EncodingString12, new ENameMapFor<XML88591Transcoder>(XMLUni::fgISO88591EncodingString12)); 00255 00256 // 00257 // Add in our mappings for UTF-16 and UCS-4, little endian 00258 // 00259 bool swapped = XMLPlatformUtils::fgXMLChBigEndian; 00260 00261 gMappingsRecognizer->setElementAt(new EEndianNameMapFor<XMLUTF16Transcoder>(XMLUni::fgUTF16LEncodingString, swapped), XMLRecognizer::UTF_16L); 00262 gMappings->put 00263 ( 00264 (void*)XMLUni::fgUTF16LEncodingString, 00265 new EEndianNameMapFor<XMLUTF16Transcoder> 00266 ( 00267 XMLUni::fgUTF16LEncodingString 00268 , swapped 00269 ) 00270 ); 00271 00272 gMappings->put 00273 ( 00274 (void*)XMLUni::fgUTF16LEncodingString2, 00275 new EEndianNameMapFor<XMLUTF16Transcoder> 00276 ( 00277 XMLUni::fgUTF16LEncodingString2 00278 , swapped 00279 ) 00280 ); 00281 00282 gMappingsRecognizer->setElementAt(new EEndianNameMapFor<XMLUCS4Transcoder>(XMLUni::fgUCS4LEncodingString, swapped), XMLRecognizer::UCS_4L); 00283 gMappings->put 00284 ( 00285 (void*)XMLUni::fgUCS4LEncodingString, 00286 new EEndianNameMapFor<XMLUCS4Transcoder> 00287 ( 00288 XMLUni::fgUCS4LEncodingString 00289 , swapped 00290 ) 00291 ); 00292 00293 gMappings->put 00294 ( 00295 (void*)XMLUni::fgUCS4LEncodingString2, 00296 new EEndianNameMapFor<XMLUCS4Transcoder> 00297 ( 00298 XMLUni::fgUCS4LEncodingString2 00299 , swapped 00300 ) 00301 ); 00302 00303 // 00304 // Add in our mappings for UTF-16 and UCS-4, big endian 00305 // 00306 swapped = !XMLPlatformUtils::fgXMLChBigEndian; 00307 00308 gMappingsRecognizer->setElementAt(new EEndianNameMapFor<XMLUTF16Transcoder>(XMLUni::fgUTF16BEncodingString, swapped), XMLRecognizer::UTF_16B); 00309 gMappings->put 00310 ( 00311 (void*)XMLUni::fgUTF16BEncodingString, 00312 new EEndianNameMapFor<XMLUTF16Transcoder> 00313 ( 00314 XMLUni::fgUTF16BEncodingString 00315 , swapped 00316 ) 00317 ); 00318 00319 gMappings->put 00320 ( 00321 (void*)XMLUni::fgUTF16BEncodingString2, 00322 new EEndianNameMapFor<XMLUTF16Transcoder> 00323 ( 00324 XMLUni::fgUTF16BEncodingString2 00325 , swapped 00326 ) 00327 ); 00328 00329 gMappingsRecognizer->setElementAt(new EEndianNameMapFor<XMLUCS4Transcoder>(XMLUni::fgUCS4BEncodingString, swapped), XMLRecognizer::UCS_4B); 00330 gMappings->put 00331 ( 00332 (void*)XMLUni::fgUCS4BEncodingString, 00333 new EEndianNameMapFor<XMLUCS4Transcoder> 00334 ( 00335 XMLUni::fgUCS4BEncodingString 00336 , swapped 00337 ) 00338 ); 00339 00340 gMappings->put 00341 ( 00342 (void*)XMLUni::fgUCS4BEncodingString2, 00343 new EEndianNameMapFor<XMLUCS4Transcoder> 00344 ( 00345 XMLUni::fgUCS4BEncodingString2 00346 , swapped 00347 ) 00348 ); 00349 00350 // 00351 // Add in our mappings for UTF-16 and UCS-4 which does not indicate endian 00352 // assumes the same endian encoding as the OS 00353 // 00354 00355 gMappings->put 00356 ( 00357 (void*)XMLUni::fgUTF16EncodingString, 00358 new EEndianNameMapFor<XMLUTF16Transcoder> 00359 ( 00360 XMLUni::fgUTF16EncodingString 00361 , false 00362 ) 00363 ); 00364 gMappings->put 00365 ( 00366 (void*)XMLUni::fgUTF16EncodingString2, 00367 new EEndianNameMapFor<XMLUTF16Transcoder> 00368 ( 00369 XMLUni::fgUTF16EncodingString2 00370 , false 00371 ) 00372 ); 00373 gMappings->put 00374 ( 00375 (void*)XMLUni::fgUTF16EncodingString3, 00376 new EEndianNameMapFor<XMLUTF16Transcoder> 00377 ( 00378 XMLUni::fgUTF16EncodingString3 00379 , false 00380 ) 00381 ); 00382 gMappings->put 00383 ( 00384 (void*)XMLUni::fgUTF16EncodingString4, 00385 new EEndianNameMapFor<XMLUTF16Transcoder> 00386 ( 00387 XMLUni::fgUTF16EncodingString4 00388 , false 00389 ) 00390 ); 00391 gMappings->put 00392 ( 00393 (void*)XMLUni::fgUTF16EncodingString5, 00394 new EEndianNameMapFor<XMLUTF16Transcoder> 00395 ( 00396 XMLUni::fgUTF16EncodingString5 00397 , false 00398 ) 00399 ); 00400 gMappings->put 00401 ( 00402 (void*)XMLUni::fgUTF16EncodingString6, 00403 new EEndianNameMapFor<XMLUTF16Transcoder> 00404 ( 00405 XMLUni::fgUTF16EncodingString6 00406 , false 00407 ) 00408 ); 00409 gMappings->put 00410 ( 00411 (void*)XMLUni::fgUTF16EncodingString7, 00412 new EEndianNameMapFor<XMLUTF16Transcoder> 00413 ( 00414 XMLUni::fgUTF16EncodingString7 00415 , false 00416 ) 00417 ); 00418 gMappings->put 00419 ( 00420 (void*)XMLUni::fgUCS4EncodingString, 00421 new EEndianNameMapFor<XMLUCS4Transcoder> 00422 ( 00423 XMLUni::fgUCS4EncodingString 00424 , false 00425 ) 00426 ); 00427 gMappings->put 00428 ( 00429 (void*)XMLUni::fgUCS4EncodingString2, 00430 new EEndianNameMapFor<XMLUCS4Transcoder> 00431 ( 00432 XMLUni::fgUCS4EncodingString2 00433 , false 00434 ) 00435 ); 00436 gMappings->put 00437 ( 00438 (void*)XMLUni::fgUCS4EncodingString3, 00439 new EEndianNameMapFor<XMLUCS4Transcoder> 00440 ( 00441 XMLUni::fgUCS4EncodingString3 00442 , false 00443 ) 00444 ); 00445 gMappings->put 00446 ( 00447 (void*)XMLUni::fgUCS4EncodingString4, 00448 new EEndianNameMapFor<XMLUCS4Transcoder> 00449 ( 00450 XMLUni::fgUCS4EncodingString4 00451 , false 00452 ) 00453 ); 00454 gMappings->put 00455 ( 00456 (void*)XMLUni::fgUCS4EncodingString5, 00457 new EEndianNameMapFor<XMLUCS4Transcoder> 00458 ( 00459 XMLUni::fgUCS4EncodingString5 00460 , false 00461 ) 00462 ); 00463 00464 // 00465 // Add in our mappings for IBM037, and the one alias we support for 00466 // it, which is EBCDIC-CP-US. 00467 // 00468 gMappingsRecognizer->setElementAt(new ENameMapFor<XMLEBCDICTranscoder>(XMLUni::fgEBCDICEncodingString), XMLRecognizer::EBCDIC); 00469 gMappings->put((void*)XMLUni::fgIBM037EncodingString, new ENameMapFor<XMLEBCDICTranscoder>(XMLUni::fgIBM037EncodingString)); 00470 gMappings->put((void*)XMLUni::fgIBM037EncodingString2, new ENameMapFor<XMLEBCDICTranscoder>(XMLUni::fgIBM037EncodingString2)); 00471 00472 00473 //hhe 00474 gMappings->put((void*)XMLUni::fgIBM1047EncodingString, new ENameMapFor<XMLIBM1047Transcoder>(XMLUni::fgIBM1047EncodingString)); 00475 gMappings->put((void*)XMLUni::fgIBM1047EncodingString2, new ENameMapFor<XMLIBM1047Transcoder>(XMLUni::fgIBM1047EncodingString2)); 00476 00477 // 00478 // Add in our mappings for IBM037 with Euro update, i.e. IBM1140. It 00479 // has alias IBM01140, the one suggested by IANA 00480 // 00481 gMappings->put((void*)XMLUni::fgIBM1140EncodingString, new ENameMapFor<XMLIBM1140Transcoder>(XMLUni::fgIBM1140EncodingString)); 00482 gMappings->put((void*)XMLUni::fgIBM1140EncodingString2, new ENameMapFor<XMLIBM1140Transcoder>(XMLUni::fgIBM1140EncodingString2)); 00483 gMappings->put((void*)XMLUni::fgIBM1140EncodingString3, new ENameMapFor<XMLIBM1140Transcoder>(XMLUni::fgIBM1140EncodingString3)); 00484 gMappings->put((void*)XMLUni::fgIBM1140EncodingString4, new ENameMapFor<XMLIBM1140Transcoder>(XMLUni::fgIBM1140EncodingString4)); 00485 00486 // 00487 // Add in our mappings for Windows-1252. We don't have any aliases for 00488 // this one, so there is just one mapping. 00489 // 00490 gMappings->put((void*)XMLUni::fgWin1252EncodingString, new ENameMapFor<XMLWin1252Transcoder>(XMLUni::fgWin1252EncodingString)); 00491 00492 } 00493 00494 // --------------------------------------------------------------------------- 00495 // XMLTransService: IANA encoding setting 00496 // --------------------------------------------------------------------------- 00497 void XMLTransService::strictIANAEncoding(const bool newState) 00498 { 00499 gStrictIANAEncoding = newState; 00500 } 00501 00502 bool XMLTransService::isStrictIANAEncoding() 00503 { 00504 return gStrictIANAEncoding; 00505 } 00506 00507 // --------------------------------------------------------------------------- 00508 // XMLTranscoder: Public Destructor 00509 // --------------------------------------------------------------------------- 00510 XMLTranscoder::~XMLTranscoder() 00511 { 00512 fMemoryManager->deallocate(fEncodingName);//delete [] fEncodingName; 00513 } 00514 00515 00516 // --------------------------------------------------------------------------- 00517 // XMLTranscoder: Hidden Constructors 00518 // --------------------------------------------------------------------------- 00519 XMLTranscoder::XMLTranscoder(const XMLCh* const encodingName 00520 , const XMLSize_t blockSize 00521 , MemoryManager* const manager) : 00522 fBlockSize(blockSize) 00523 , fEncodingName(0) 00524 , fMemoryManager(manager) 00525 { 00526 fEncodingName = XMLString::replicate(encodingName, fMemoryManager); 00527 } 00528 00529 00530 // --------------------------------------------------------------------------- 00531 // XMLTranscoder: Protected helpers 00532 // --------------------------------------------------------------------------- 00533 00534 00535 // --------------------------------------------------------------------------- 00536 // XMLLCPTranscoder: Public Destructor 00537 // --------------------------------------------------------------------------- 00538 XMLLCPTranscoder::XMLLCPTranscoder() 00539 { 00540 } 00541 00542 00543 // --------------------------------------------------------------------------- 00544 // XMLLCPTranscoder: Hidden Constructors 00545 // --------------------------------------------------------------------------- 00546 XMLLCPTranscoder::~XMLLCPTranscoder() 00547 { 00548 } 00549 00550 // --------------------------------------------------------------------------- 00551 // TranscodeToStr: Public constructors and destructor 00552 // --------------------------------------------------------------------------- 00553 TranscodeToStr::TranscodeToStr(const XMLCh *in, const char *encoding, 00554 MemoryManager *manager) 00555 : fString(0), 00556 fBytesWritten(0), 00557 fMemoryManager(manager) 00558 { 00559 XMLTransService::Codes failReason; 00560 const XMLSize_t blockSize = 2048; 00561 00562 XMLTranscoder* trans = XMLPlatformUtils::fgTransService->makeNewTranscoderFor(encoding, failReason, blockSize, fMemoryManager); 00563 Janitor<XMLTranscoder> janTrans(trans); 00564 00565 transcode(in, XMLString::stringLen(in), trans); 00566 } 00567 00568 TranscodeToStr::TranscodeToStr(const XMLCh *in, XMLSize_t length, const char *encoding, 00569 MemoryManager *manager) 00570 : fString(0), 00571 fBytesWritten(0), 00572 fMemoryManager(manager) 00573 { 00574 XMLTransService::Codes failReason; 00575 const XMLSize_t blockSize = 2048; 00576 00577 XMLTranscoder* trans = XMLPlatformUtils::fgTransService->makeNewTranscoderFor(encoding, failReason, blockSize, fMemoryManager); 00578 Janitor<XMLTranscoder> janTrans(trans); 00579 00580 transcode(in, length, trans); 00581 } 00582 00583 TranscodeToStr::TranscodeToStr(const XMLCh *in, XMLTranscoder* trans, 00584 MemoryManager *manager) 00585 : fString(0), 00586 fBytesWritten(0), 00587 fMemoryManager(manager) 00588 { 00589 transcode(in, XMLString::stringLen(in), trans); 00590 } 00591 00592 TranscodeToStr::TranscodeToStr(const XMLCh *in, XMLSize_t length, XMLTranscoder* trans, 00593 MemoryManager *manager) 00594 : fString(0), 00595 fBytesWritten(0), 00596 fMemoryManager(manager) 00597 { 00598 transcode(in, length, trans); 00599 } 00600 00601 TranscodeToStr::~TranscodeToStr() 00602 { 00603 if(fString) 00604 fMemoryManager->deallocate(fString); 00605 } 00606 00607 // --------------------------------------------------------------------------- 00608 // TranscodeToStr: Private helper methods 00609 // --------------------------------------------------------------------------- 00610 void TranscodeToStr::transcode(const XMLCh *in, XMLSize_t len, XMLTranscoder* trans) 00611 { 00612 if(!in) return; 00613 00614 XMLSize_t allocSize = len * sizeof(XMLCh); 00615 fString = (XMLByte*)fMemoryManager->allocate(allocSize); 00616 00617 XMLSize_t charsRead = 0; 00618 XMLSize_t charsDone = 0; 00619 00620 while(true) { 00621 fBytesWritten += trans->transcodeTo(in + charsDone, len - charsDone, 00622 fString + fBytesWritten, allocSize - fBytesWritten, 00623 charsRead, XMLTranscoder::UnRep_Throw); 00624 if(charsRead == 0) 00625 ThrowXMLwithMemMgr(TranscodingException, XMLExcepts::Trans_BadSrcSeq, fMemoryManager); 00626 00627 charsDone += charsRead; 00628 00629 if(charsDone == len) break; 00630 00631 allocSize *= 2; 00632 XMLByte *newBuf = (XMLByte*)fMemoryManager->allocate(allocSize); 00633 memcpy(newBuf, fString, fBytesWritten); 00634 fMemoryManager->deallocate(fString); 00635 fString = newBuf; 00636 } 00637 00638 // null terminate 00639 if((fBytesWritten + 4) > allocSize) { 00640 allocSize = fBytesWritten + 4; 00641 XMLByte *newBuf = (XMLByte*)fMemoryManager->allocate(allocSize); 00642 memcpy(newBuf, fString, fBytesWritten); 00643 fMemoryManager->deallocate(fString); 00644 fString = newBuf; 00645 } 00646 fString[fBytesWritten + 0] = 0; 00647 fString[fBytesWritten + 1] = 0; 00648 fString[fBytesWritten + 2] = 0; 00649 fString[fBytesWritten + 3] = 0; 00650 } 00651 00652 // --------------------------------------------------------------------------- 00653 // TranscodeFromStr: Public constructors and destructor 00654 // --------------------------------------------------------------------------- 00655 TranscodeFromStr::TranscodeFromStr(const XMLByte *data, XMLSize_t length, const char *encoding, 00656 MemoryManager *manager) 00657 : fString(0), 00658 fCharsWritten(0), 00659 fMemoryManager(manager) 00660 { 00661 XMLTransService::Codes failReason; 00662 const XMLSize_t blockSize = 2048; 00663 00664 XMLTranscoder* trans = XMLPlatformUtils::fgTransService->makeNewTranscoderFor(encoding, failReason, blockSize, fMemoryManager); 00665 Janitor<XMLTranscoder> janTrans(trans); 00666 00667 transcode(data, length, trans); 00668 } 00669 00670 TranscodeFromStr::TranscodeFromStr(const XMLByte *data, XMLSize_t length, XMLTranscoder *trans, 00671 MemoryManager *manager) 00672 : fString(0), 00673 fCharsWritten(0), 00674 fMemoryManager(manager) 00675 { 00676 transcode(data, length, trans); 00677 } 00678 00679 TranscodeFromStr::~TranscodeFromStr() 00680 { 00681 if(fString) 00682 fMemoryManager->deallocate(fString); 00683 } 00684 00685 // --------------------------------------------------------------------------- 00686 // TranscodeFromStr: Private helper methods 00687 // --------------------------------------------------------------------------- 00688 void TranscodeFromStr::transcode(const XMLByte *in, XMLSize_t length, XMLTranscoder *trans) 00689 { 00690 if(!in) return; 00691 00692 XMLSize_t allocSize = length + 1; 00693 fString = (XMLCh*)fMemoryManager->allocate(allocSize * sizeof(XMLCh)); 00694 00695 XMLSize_t csSize = length; 00696 ArrayJanitor<unsigned char> charSizes((unsigned char*)fMemoryManager->allocate(csSize * sizeof(unsigned char)), 00697 fMemoryManager); 00698 00699 XMLSize_t bytesRead = 0; 00700 XMLSize_t bytesDone = 0; 00701 00702 while(true) { 00703 fCharsWritten += trans->transcodeFrom(in + bytesDone, length - bytesDone, 00704 fString + fCharsWritten, allocSize - fCharsWritten, 00705 bytesRead, charSizes.get()); 00706 if(bytesRead == 0) 00707 ThrowXMLwithMemMgr(TranscodingException, XMLExcepts::Trans_BadSrcSeq, fMemoryManager); 00708 00709 bytesDone += bytesRead; 00710 if(bytesDone == length) break; 00711 00712 allocSize *= 2; 00713 XMLCh *newBuf = (XMLCh*)fMemoryManager->allocate(allocSize * sizeof(XMLCh)); 00714 memcpy(newBuf, fString, fCharsWritten); 00715 fMemoryManager->deallocate(fString); 00716 fString = newBuf; 00717 00718 if((allocSize - fCharsWritten) > csSize) { 00719 csSize = allocSize - fCharsWritten; 00720 charSizes.reset((unsigned char*)fMemoryManager->allocate(csSize * sizeof(unsigned char)), 00721 fMemoryManager); 00722 } 00723 } 00724 00725 // null terminate 00726 if(fCharsWritten == allocSize) { 00727 allocSize += 1; 00728 XMLCh *newBuf = (XMLCh*)fMemoryManager->allocate(allocSize * sizeof(XMLCh)); 00729 memcpy(newBuf, fString, fCharsWritten); 00730 fMemoryManager->deallocate(fString); 00731 fString = newBuf; 00732 } 00733 fString[fCharsWritten] = 0; 00734 } 00735 00736 XERCES_CPP_NAMESPACE_END