00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one 00003 * or more contributor license agreements. See the NOTICE file 00004 * distributed with this work for additional information 00005 * regarding copyright ownership. The ASF licenses this file 00006 * to you under the Apache License, Version 2.0 (the "License"); 00007 * you may not use this file except in compliance with the License. 00008 * You may obtain a copy of the License at 00009 * 00010 * http://www.apache.org/licenses/LICENSE-2.0 00011 * 00012 * Unless required by applicable law or agreed to in writing, software 00013 * distributed under the License is distributed on an "AS IS" BASIS, 00014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 * See the License for the specific language governing permissions and 00016 * limitations under the License. 00017 */ 00018 #if !defined(XALANUTF8WRITER_HEADER_GUARD_1357924680) 00019 #define XALANUTF8WRITER_HEADER_GUARD_1357924680 00020 00021 00022 #include <xalanc/XMLSupport/XalanFormatterWriter.hpp> 00023 00024 00025 00026 XALAN_CPP_NAMESPACE_BEGIN 00027 00028 00029 00030 inline char 00031 bits19to21(XalanUnicodeChar theChar) 00032 { 00033 return static_cast<char>((theChar >> 18) & 0x7); 00034 } 00035 00036 00037 00038 inline char 00039 bits13to18(XalanUnicodeChar theChar) 00040 { 00041 return static_cast<char>((theChar >> 12) & 0x3F); 00042 } 00043 00044 00045 00046 inline char 00047 bits13to16(XalanUnicodeChar theChar) 00048 { 00049 return static_cast<char>((theChar >> 12) & 0xF); 00050 } 00051 00052 00053 00054 inline char 00055 bits7to12(XalanUnicodeChar theChar) 00056 { 00057 return static_cast<char>((theChar >> 6) & 0x3f); 00058 } 00059 00060 00061 00062 inline char 00063 bits7to11(XalanUnicodeChar theChar) 00064 { 00065 return static_cast<char>((theChar >> 6) & 0x1f); 00066 } 00067 00068 00069 00070 inline char 00071 bits1to6(XalanUnicodeChar theChar) 00072 { 00073 return static_cast<char>(theChar & 0x3f); 00074 } 00075 00076 00077 00078 inline char 00079 leadingByteOf2(char theBits) 00080 { 00081 return static_cast<char>(0xC0 + theBits); 00082 } 00083 00084 00085 00086 inline char 00087 leadingByteOf3(char theBits) 00088 { 00089 return static_cast<char>(0xE0 + theBits); 00090 } 00091 00092 00093 00094 inline char 00095 leadingByteOf4(char theBits) 00096 { 00097 return static_cast<char>(0xF0 + theBits); 00098 } 00099 00100 00101 00102 inline char 00103 trailingByte(char theBits) 00104 { 00105 return static_cast<char>(0x80 + theBits); 00106 } 00107 00108 00109 00110 class XalanUTF8Writer : public XalanFormatterWriter 00111 { 00112 public: 00113 00114 typedef char value_type; 00115 00116 00117 XalanUTF8Writer( 00118 Writer& writer, 00119 MemoryManager& theMemoryManager); 00120 00121 virtual 00122 ~XalanUTF8Writer() 00123 { 00124 } 00125 00126 /** 00127 * Output a line break. 00128 */ 00129 void 00130 outputNewline() 00131 { 00132 assert(m_newlineString != 0); 00133 assert(length(m_newlineString) == m_newlineStringLength); 00134 00135 write( 00136 m_newlineString, 00137 m_newlineStringLength); 00138 } 00139 00140 size_type 00141 writeCDATAChar( 00142 const XalanDOMChar chars[], 00143 size_type start, 00144 size_type length, 00145 bool& /* outsideCDATA */) 00146 { 00147 assert(chars != 0 && length != 0 && start < length); 00148 00149 return write(chars, start, length); 00150 } 00151 00152 /** 00153 * Writes name characters. If characters that are not 00154 * representable are encountered, an exception is thrown. 00155 */ 00156 void 00157 writeNameChar( 00158 const XalanDOMChar* data, 00159 size_type theLength) 00160 { 00161 write(data, theLength); 00162 } 00163 00164 /** 00165 * Writes PI characters. If characters that are not 00166 * representable are encountered, an exception is thrown. 00167 */ 00168 void 00169 writePIChars( 00170 const XalanDOMChar* data, 00171 size_type theLength) 00172 { 00173 write(data, theLength); 00174 } 00175 00176 /** 00177 * Writes comment characters. If characters that are not 00178 * representable are encountered, an exception is thrown. 00179 */ 00180 void 00181 writeCommentChars( 00182 const XalanDOMChar* data, 00183 size_type theLength) 00184 { 00185 write(data, theLength); 00186 } 00187 00188 void 00189 safeWriteContent( 00190 const XalanDOMChar* theChars, 00191 size_type theLength) 00192 { 00193 for(size_type i = 0; i < theLength; ++i) 00194 { 00195 write(value_type(theChars[i])); 00196 } 00197 } 00198 00199 void 00200 write( 00201 const value_type* theChars, 00202 size_type theLength) 00203 { 00204 #if defined(NDEBUG) 00205 if (theLength > sizeof(m_buffer)) 00206 { 00207 flushBuffer(); 00208 00209 m_writer.write(theChars, 0, theLength); 00210 } 00211 else 00212 { 00213 if (m_bufferRemaining < theLength) 00214 { 00215 flushBuffer(); 00216 } 00217 00218 for(size_type i = 0; i < theLength; ++i) 00219 { 00220 *m_bufferPosition = theChars[i]; 00221 00222 ++m_bufferPosition; 00223 } 00224 00225 m_bufferRemaining -= theLength; 00226 } 00227 #else 00228 for(size_type i = 0; i < theLength; ++i) 00229 { 00230 write(theChars[i]); 00231 } 00232 #endif 00233 } 00234 00235 void 00236 write(const XalanDOMChar* theChars) 00237 { 00238 write(theChars, XalanDOMString::length(theChars)); 00239 } 00240 00241 void 00242 write(const XalanDOMString& theChars) 00243 { 00244 write(theChars.c_str(), theChars.length()); 00245 } 00246 00247 void 00248 write(value_type theChar) 00249 { 00250 assert(theChar < 128); 00251 00252 if (m_bufferRemaining == 0) 00253 { 00254 flushBuffer(); 00255 } 00256 00257 *m_bufferPosition = theChar; 00258 00259 ++m_bufferPosition; 00260 --m_bufferRemaining; 00261 } 00262 00263 void 00264 write( 00265 const XalanDOMChar* theChars, 00266 size_type theLength) 00267 { 00268 for(size_type i = 0; i < theLength; ++i) 00269 { 00270 if (isUTF16HighSurrogate(theChars[i]) == false) 00271 { 00272 write(static_cast<XalanUnicodeChar>(theChars[i])); 00273 } 00274 else if (i + 1 >= theLength) 00275 { 00276 throwInvalidUTF16SurrogateException( 00277 theChars[i], 00278 0, 00279 getMemoryManager()); 00280 } 00281 else 00282 { 00283 write( 00284 decodeUTF16SurrogatePair( 00285 theChars[i], 00286 theChars[i + 1], 00287 getMemoryManager())); 00288 00289 ++i; 00290 } 00291 } 00292 } 00293 00294 size_type 00295 write( 00296 const XalanDOMChar chars[], 00297 size_type start, 00298 size_type length) 00299 { 00300 const XalanDOMChar ch = chars[start]; 00301 00302 if (isUTF16HighSurrogate(ch) == false) 00303 { 00304 write(static_cast<XalanUnicodeChar>(ch)); 00305 } 00306 else if (start + 1 >= length) 00307 { 00308 throwInvalidUTF16SurrogateException( 00309 ch, 00310 0, 00311 getMemoryManager()); 00312 } 00313 else 00314 { 00315 write( 00316 decodeUTF16SurrogatePair( 00317 ch, 00318 chars[++start], 00319 getMemoryManager())); 00320 } 00321 00322 return start; 00323 } 00324 00325 void 00326 writeSafe( 00327 const XalanDOMChar* theChars, 00328 size_type theLength) 00329 { 00330 for(size_type i = 0; i < theLength; ++i) 00331 { 00332 const XalanDOMChar ch = theChars[i]; 00333 00334 if (isUTF16HighSurrogate(ch) == true) 00335 { 00336 if (i + 1 >= theLength) 00337 { 00338 throwInvalidUTF16SurrogateException( 00339 ch, 00340 0, 00341 getMemoryManager()); 00342 } 00343 else 00344 { 00345 write( 00346 decodeUTF16SurrogatePair( 00347 ch, 00348 theChars[i + 1], 00349 getMemoryManager())); 00350 00351 ++i; 00352 } 00353 } 00354 else 00355 { 00356 write(static_cast<XalanUnicodeChar>(ch)); 00357 } 00358 } 00359 00360 } 00361 00362 void 00363 write(const value_type* theChars) 00364 { 00365 write(theChars, XalanDOMString::length(theChars)); 00366 } 00367 00368 void 00369 flushWriter() 00370 { 00371 m_writer.flush(); 00372 } 00373 00374 void 00375 flushBuffer() 00376 { 00377 m_writer.write(m_buffer, 0, m_bufferPosition - m_buffer); 00378 00379 m_bufferPosition = m_buffer; 00380 m_bufferRemaining = kBufferSize; 00381 } 00382 00383 private: 00384 00385 void 00386 write(XalanUnicodeChar theChar) 00387 { 00388 if (theChar <= 0x7F) 00389 { 00390 write(char(theChar)); 00391 } 00392 else if (theChar <= 0x7FF) 00393 { 00394 if (m_bufferRemaining < 2) 00395 { 00396 flushBuffer(); 00397 } 00398 00399 *m_bufferPosition = leadingByteOf2(bits7to11(theChar)); 00400 ++m_bufferPosition; 00401 *m_bufferPosition = trailingByte(bits1to6(theChar)); 00402 ++m_bufferPosition; 00403 00404 m_bufferRemaining -= 2; 00405 } 00406 else if (theChar <= 0xFFFF) 00407 { 00408 // We should never get a high or low surrogate here... 00409 assert(theChar < 0xD800 || theChar > 0xDBFF); 00410 assert(theChar < 0xDC00 || theChar > 0xDFFF); 00411 00412 if (m_bufferRemaining < 3) 00413 { 00414 flushBuffer(); 00415 } 00416 00417 *m_bufferPosition = leadingByteOf3(bits13to16(theChar)); 00418 ++m_bufferPosition; 00419 *m_bufferPosition = trailingByte(bits7to12(theChar)); 00420 ++m_bufferPosition; 00421 *m_bufferPosition = trailingByte(bits1to6(theChar)); 00422 ++m_bufferPosition; 00423 00424 m_bufferRemaining -= 3; 00425 } 00426 else if (theChar <= 0x10FFFF) 00427 { 00428 if (m_bufferRemaining < 4) 00429 { 00430 flushBuffer(); 00431 } 00432 00433 *m_bufferPosition = leadingByteOf4(bits19to21(theChar)); 00434 ++m_bufferPosition; 00435 *m_bufferPosition = trailingByte(bits13to18(theChar)); 00436 ++m_bufferPosition; 00437 *m_bufferPosition = trailingByte(bits7to12(theChar)); 00438 ++m_bufferPosition; 00439 *m_bufferPosition = trailingByte(bits1to6(theChar)); 00440 ++m_bufferPosition; 00441 00442 m_bufferRemaining -= 4; 00443 } 00444 else 00445 { 00446 throwInvalidCharacterException(theChar, getMemoryManager()); 00447 } 00448 } 00449 00450 enum 00451 { 00452 kBufferSize = 512 // The size of the buffer 00453 }; 00454 00455 00456 // Data members... 00457 value_type m_buffer[kBufferSize]; 00458 00459 value_type* m_bufferPosition; 00460 00461 size_type m_bufferRemaining; 00462 }; 00463 00464 00465 00466 XALAN_CPP_NAMESPACE_END 00467 00468 00469 00470 #endif // XALANUTF8WRITER_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.11 |
|