00001 /* 00002 * Copyright 1999-2004 The Apache Software Foundation. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #if !defined(XALANUNICODESUBSETWRITER_HEADER_GUARD_1357924680) 00017 #define XALANUNICODESUBSETWRITER_HEADER_GUARD_1357924680 00018 00019 00020 #include <xalanc/XMLSupport/XalanFormatterWriter.hpp> 00021 00022 00023 00024 XALAN_CPP_NAMESPACE_BEGIN 00025 00026 00027 00028 00029 template <class Predicate, 00030 class ConstantsType> 00031 class XalanOtherEncodingWriter : public XalanFormatterWriter 00032 { 00033 public: 00034 00035 typedef XalanOtherEncodingWriter<Predicate, ConstantsType> ThisType; 00036 00037 class WriteCharRef 00038 { 00039 public: 00040 00041 WriteCharRef(ThisType& writer) : 00042 m_writer(writer) 00043 { 00044 } 00045 00046 void 00047 operator()(unsigned int value) const 00048 { 00049 m_writer.writeNumericCharacterReference(value); 00050 } 00051 00052 private: 00053 00054 ThisType& m_writer; 00055 }; 00056 00057 class ThrowTranscodingException 00058 { 00059 public: 00060 00061 ThrowTranscodingException(ThisType& writer) : 00062 m_writer(writer) 00063 { 00064 } 00065 00066 void 00067 operator()(unsigned int value) const 00068 { 00069 m_writer.throwInvalidCharacterException(value, m_writer.getMemoryManager()); 00070 } 00071 00072 private: 00073 00074 ThisType& m_writer; 00075 }; 00076 00077 friend class WriteCharRef; 00078 friend class ThrowTranscodingException; 00079 00080 typedef XalanDOMChar value_type; 00081 00082 XalanOtherEncodingWriter( 00083 Writer& writer, 00084 MemoryManager& theMemoryManager) : 00085 XalanFormatterWriter( 00086 writer, 00087 theMemoryManager), 00088 m_buffer(), 00089 m_bufferPosition(m_buffer), 00090 m_bufferRemaining(kBufferSize), 00091 m_predicate(writer.getStream()), 00092 m_constants(), 00093 m_charRefFunctor(*this), 00094 m_exceptionFunctor(*this) 00095 { 00096 } 00097 00098 virtual 00099 ~XalanOtherEncodingWriter() 00100 { 00101 } 00102 00106 void 00107 outputNewline() 00108 { 00109 assert(m_newlineString != 0); 00110 assert(length(m_newlineString) == m_newlineStringLength); 00111 00112 write( 00113 m_newlineString, 00114 m_newlineStringLength); 00115 } 00116 00121 size_type 00122 writeCDATAChar( 00123 const XalanDOMChar chars[], 00124 size_type start, 00125 size_type length, 00126 bool& outsideCDATA) 00127 { 00128 assert(chars != 0 && length > 0 && start < length); 00129 00130 const XalanDOMChar theChar = chars[start]; 00131 00132 unsigned int value = theChar; 00133 00134 size_type result = start; 00135 00136 if (isUTF16HighSurrogate(theChar) == true) 00137 { 00138 if (start + 1 >= length) 00139 { 00140 throwInvalidUTF16SurrogateException( 00141 theChar, 00142 0, 00143 getMemoryManager()); 00144 } 00145 else 00146 { 00147 value = decodeUTF16SurrogatePair(theChar, chars[start+1], getMemoryManager()); 00148 00149 ++result; 00150 } 00151 } 00152 00153 if(m_predicate(value)) 00154 { 00155 if (outsideCDATA == false) 00156 { 00157 // We have a representable char in the normal state, 00158 // so just print it. 00159 write(value); 00160 } 00161 else 00162 { 00163 // The previous character was a not representable. 00164 // Open the CDATA section again, print the character, 00165 // then change the flag. 00166 write( 00167 m_constants.s_cdataOpenString, 00168 m_constants.s_cdataOpenStringLength); 00169 00170 write(value); 00171 00172 outsideCDATA = false; 00173 } 00174 } 00175 else 00176 { 00177 if(outsideCDATA == false) 00178 { 00179 // we have a non-representable char in the normal state - 00180 // close the CDATA section and print the value 00181 write( 00182 m_constants.s_cdataCloseString, 00183 m_constants.s_cdataCloseStringLength); 00184 00185 writeNumericCharacterReference(value); 00186 00187 outsideCDATA = true; 00188 } 00189 else 00190 { 00191 writeNumericCharacterReference(value); 00192 } 00193 } 00194 00195 return result; 00196 } 00197 00202 void 00203 writeNameChar( 00204 const XalanDOMChar* data, 00205 size_type theLength) 00206 { 00207 for( size_type i = 0; i < theLength; ++i) 00208 { 00209 i = write(data, i , theLength, m_exceptionFunctor); 00210 } 00211 } 00212 00217 void 00218 writePIChars( 00219 const XalanDOMChar* data, 00220 size_type theLength) 00221 { 00222 for( size_type i = 0; i < theLength; ) 00223 { 00224 i = write(data, i , theLength, m_exceptionFunctor); 00225 } 00226 } 00227 00233 void 00234 writeCommentChars( 00235 const XalanDOMChar* data, 00236 size_type theLength) 00237 { 00238 for( size_type i = 0; i < theLength; ) 00239 { 00240 i = write(data, i , theLength, m_exceptionFunctor); 00241 } 00242 } 00243 00244 void 00245 write( 00246 const XalanDOMChar* theChars, 00247 size_type theLength) 00248 { 00249 for(size_type i = 0; i < theLength; ++i) 00250 { 00251 write(theChars[i]); 00252 } 00253 } 00254 00255 void 00256 write(const XalanDOMString& theChars) 00257 { 00258 write(theChars.c_str(), theChars.length()); 00259 } 00260 00265 void 00266 write(XalanDOMChar theChar) 00267 { 00268 assert( 00269 isUTF16HighSurrogate(theChar) == false && 00270 isUTF16LowSurrogate(theChar) == false); 00271 00272 if (m_bufferRemaining == 0) 00273 { 00274 flushBuffer(); 00275 } 00276 00277 if(m_predicate(theChar)) 00278 { 00279 *m_bufferPosition = theChar; 00280 00281 ++m_bufferPosition; 00282 --m_bufferRemaining; 00283 } 00284 else 00285 { 00286 writeNumericCharacterReference(theChar); 00287 } 00288 } 00289 00290 size_type 00291 write( 00292 const XalanDOMChar chars[], 00293 size_type start, 00294 size_type length) 00295 { 00296 00297 return write(chars, start, length, m_charRefFunctor); 00298 } 00299 00300 void 00301 writeSafe( 00302 const XalanDOMChar* theChars, 00303 size_type theLength) 00304 { 00305 for(size_type i = 0; i < theLength; ++i) 00306 { 00307 const XalanDOMChar ch = theChars[i]; 00308 00309 if (isUTF16HighSurrogate(ch) == true) 00310 { 00311 if (i + 1 >= theLength) 00312 { 00313 throwInvalidUTF16SurrogateException(ch, 0, getMemoryManager()); 00314 } 00315 else 00316 { 00317 unsigned int value = decodeUTF16SurrogatePair(ch, theChars[i+1], getMemoryManager()); 00318 00319 if(this->m_isPresentable(value)) 00320 { 00321 write(value); 00322 } 00323 else 00324 { 00325 this->writeNumberedEntityReference(value); 00326 } 00327 00328 ++i; 00329 } 00330 } 00331 else 00332 { 00333 write((unsigned int)ch); 00334 } 00335 } 00336 } 00337 00338 void 00339 write(const XalanDOMChar* theChars) 00340 { 00341 write(theChars, XalanDOMString::length(theChars)); 00342 } 00343 00344 void 00345 flushWriter() 00346 { 00347 m_writer.flush(); 00348 } 00349 00350 void 00351 flushBuffer() 00352 { 00353 m_writer.write(m_buffer, 0, m_bufferPosition - m_buffer); 00354 00355 m_bufferPosition = m_buffer; 00356 m_bufferRemaining = kBufferSize; 00357 } 00358 00359 private: 00360 00374 00375 template <class TranscodingFailureFunctor> 00376 size_type 00377 write( 00378 const XalanDOMChar chars[], 00379 size_type start, 00380 size_type length, 00381 TranscodingFailureFunctor& failureHandler) 00382 { 00383 assert(chars != 0 && length > 0); 00384 assert(start <= length); 00385 00386 size_type result = start; 00387 00388 const XalanDOMChar ch = chars[start]; 00389 00390 unsigned int value = ch; 00391 00392 if (XalanFormatterWriter::isUTF16HighSurrogate(ch) == true) 00393 { 00394 if (start + 1 >= length) 00395 { 00396 throwInvalidUTF16SurrogateException( 00397 ch, 00398 0, 00399 getMemoryManager()); 00400 } 00401 else 00402 { 00403 value = decodeUTF16SurrogatePair(ch, chars[start+1], getMemoryManager()); 00404 00405 ++result; 00406 } 00407 } 00408 00409 if(m_predicate(value)) 00410 { 00411 write(value); 00412 } 00413 else 00414 { 00415 failureHandler(value); 00416 } 00417 00418 return result; 00419 } 00420 00427 void 00428 write(unsigned int theChar) 00429 { 00430 // encode back UTF-32 into UTF-16 00431 00432 if( theChar > 0xFFFF ) 00433 { 00434 if (m_bufferRemaining < 2) 00435 { 00436 flushBuffer(); 00437 } 00438 00439 *m_bufferPosition = (XalanDOMChar((theChar >> 10) + 0xD7C0)); 00440 00441 ++m_bufferPosition; 00442 00443 *m_bufferPosition = (XalanDOMChar((theChar & 0x03FF) + 0xDC00)); 00444 00445 ++m_bufferPosition; 00446 00447 m_bufferRemaining = m_bufferRemaining - size_type(2); 00448 } 00449 else 00450 { 00451 if (m_bufferRemaining == 0) 00452 { 00453 flushBuffer(); 00454 } 00455 00456 *m_bufferPosition = XalanDOMChar(theChar); 00457 00458 ++m_bufferPosition; 00459 --m_bufferRemaining; 00460 } 00461 } 00462 00463 void 00464 writeNumericCharacterReference(unsigned int theNumber) 00465 { 00466 write(formatNumericCharacterReference(theNumber)); 00467 } 00468 00469 enum 00470 { 00471 kBufferSize = 512u // The size of the buffer 00472 }; 00473 00474 00475 // Data members... 00476 XalanDOMChar m_buffer[kBufferSize]; 00477 00478 XalanDOMChar* m_bufferPosition; 00479 00480 size_type m_bufferRemaining; 00481 00482 const Predicate m_predicate; 00483 00484 const ConstantsType m_constants; 00485 00486 const WriteCharRef m_charRefFunctor; 00487 00488 const ThrowTranscodingException m_exceptionFunctor; 00489 }; 00490 00491 00492 00493 XALAN_CPP_NAMESPACE_END 00494 00495 00496 00497 #endif // XALANUNICODESUBSETWRITER_HEADER_GUARD_1357924680
Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.
Xalan-C++ XSLT Processor Version 1.10 |
|