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(XALANUTF8WRITER_HEADER_GUARD_1357924680) 00017 #define XALANUTF8WRITER_HEADER_GUARD_1357924680 00018 00019 00020 #include <xalanc/XMLSupport/XalanFormatterWriter.hpp> 00021 00022 00023 00024 XALAN_CPP_NAMESPACE_BEGIN 00025 00026 00027 00028 inline char 00029 bits19to21(unsigned int theChar) 00030 { 00031 return char((theChar >> 18) & 0x7); 00032 } 00033 00034 00035 00036 inline char 00037 bits13to18(unsigned int theChar) 00038 { 00039 return char((theChar >> 12) & 0x3F); 00040 } 00041 00042 00043 00044 inline char 00045 bits13to16(unsigned int theChar) 00046 { 00047 return char((theChar >> 12) & 0xF); 00048 } 00049 00050 00051 00052 inline char 00053 bits7to12(unsigned int theChar) 00054 { 00055 return char((theChar >> 6) & 0x3f); 00056 } 00057 00058 00059 00060 inline char 00061 bits7to11(unsigned int theChar) 00062 { 00063 return char((theChar >> 6) & 0x1f); 00064 } 00065 00066 00067 00068 inline char 00069 bits1to6(unsigned int theChar) 00070 { 00071 return char(theChar & 0x3f); 00072 } 00073 00074 00075 00076 inline char 00077 leadingByteOf2(char theBits) 00078 { 00079 return char(0xC0 + theBits); 00080 } 00081 00082 00083 00084 inline char 00085 leadingByteOf3(char theBits) 00086 { 00087 return char(0xE0 + theBits); 00088 } 00089 00090 00091 00092 inline char 00093 leadingByteOf4(char theBits) 00094 { 00095 return char(0xF0 + theBits); 00096 } 00097 00098 00099 00100 inline char 00101 trailingByte(char theBits) 00102 { 00103 return char(0x80 + theBits); 00104 } 00105 00106 00107 00108 class XalanUTF8Writer : public XalanFormatterWriter 00109 { 00110 public: 00111 00112 typedef char value_type; 00113 00114 00115 XalanUTF8Writer( 00116 Writer& writer, 00117 MemoryManager& theMemoryManager); 00118 00119 virtual 00120 ~XalanUTF8Writer() 00121 { 00122 } 00123 00127 void 00128 outputNewline() 00129 { 00130 assert(m_newlineString != 0); 00131 assert(length(m_newlineString) == m_newlineStringLength); 00132 00133 write( 00134 m_newlineString, 00135 m_newlineStringLength); 00136 } 00137 00138 size_type 00139 writeCDATAChar( 00140 const XalanDOMChar chars[], 00141 size_type start, 00142 size_type length, 00143 bool& /* outsideCDATA */) 00144 { 00145 assert(chars != 0 && length != 0 && start < length); 00146 00147 return write(chars, start, length); 00148 } 00149 00153 void writeNameChar(const XalanDOMChar* data, 00154 size_type theLength) 00155 { 00156 write(data, theLength); 00157 } 00158 00162 void writePIChars(const XalanDOMChar* data, 00163 size_type theLength) 00164 { 00165 write(data, theLength); 00166 } 00167 00171 void writeCommentChars(const XalanDOMChar* data, 00172 size_type theLength) 00173 { 00174 write(data, theLength); 00175 } 00176 00177 void 00178 safeWriteContent( 00179 const XalanDOMChar* theChars, 00180 XalanDOMString::size_type theLength) 00181 { 00182 for(size_type i = 0; i < theLength; ++i) 00183 { 00184 write(value_type(theChars[i])); 00185 } 00186 } 00187 00188 void 00189 write( 00190 const value_type* theChars, 00191 XalanDOMString::size_type theLength) 00192 { 00193 #if defined(NDEBUG) 00194 if (theLength > sizeof(m_buffer)) 00195 { 00196 flushBuffer(); 00197 00198 m_writer.write(theChars, 0, theLength); 00199 } 00200 else 00201 { 00202 if (m_bufferRemaining < theLength) 00203 { 00204 flushBuffer(); 00205 } 00206 00207 for(size_type i = 0; i < theLength; ++i) 00208 { 00209 *m_bufferPosition = theChars[i]; 00210 00211 ++m_bufferPosition; 00212 } 00213 00214 m_bufferRemaining -= theLength; 00215 } 00216 #else 00217 for(XalanDOMString::size_type i = 0; i < theLength; ++i) 00218 { 00219 write(theChars[i]); 00220 } 00221 #endif 00222 } 00223 00224 void 00225 write(const XalanDOMChar* theChars) 00226 { 00227 write(theChars, XalanDOMString::length(theChars)); 00228 } 00229 00230 void 00231 write(const XalanDOMString& theChars) 00232 { 00233 write(theChars.c_str(), theChars.length()); 00234 } 00235 00236 void 00237 write(value_type theChar) 00238 { 00239 assert(theChar < 128); 00240 00241 if (m_bufferRemaining == 0) 00242 { 00243 flushBuffer(); 00244 } 00245 00246 *m_bufferPosition = theChar; 00247 00248 ++m_bufferPosition; 00249 --m_bufferRemaining; 00250 } 00251 00252 void 00253 write( 00254 const XalanDOMChar* theChars, 00255 XalanDOMString::size_type theLength) 00256 { 00257 for(size_type i = 0; i < theLength; ++i) 00258 { 00259 write((unsigned int)theChars[i]); 00260 } 00261 } 00262 00263 size_type 00264 write( 00265 const XalanDOMChar chars[], 00266 XalanDOMString::size_type start, 00267 XalanDOMString::size_type length) 00268 { 00269 XalanDOMChar ch = chars[start]; 00270 00271 if (XalanFormatterWriter::isUTF16HighSurrogate(ch) == false) 00272 { 00273 write((unsigned int)ch); 00274 } 00275 else 00276 { 00277 if (start + 1 >= length) 00278 { 00279 XalanFormatterWriter::throwInvalidUTF16SurrogateException( 00280 ch, 00281 0, 00282 getMemoryManager()); 00283 } 00284 else 00285 { 00286 write( 00287 XalanFormatterWriter::decodeUTF16SurrogatePair( 00288 ch, 00289 chars[++start], 00290 getMemoryManager())); 00291 } 00292 } 00293 00294 return start; 00295 } 00296 00297 void 00298 writeSafe( 00299 const XalanDOMChar* theChars, 00300 XalanDOMString::size_type theLength) 00301 { 00302 XalanDOMChar ch = 0; 00303 00304 for(size_type i = 0; i < theLength; ++i) 00305 { 00306 ch = theChars[i]; 00307 00308 if (XalanFormatterWriter::isUTF16HighSurrogate(ch) == true) 00309 { 00310 if (i + 1 >= theLength) 00311 { 00312 XalanFormatterWriter::throwInvalidUTF16SurrogateException(ch, 0, getMemoryManager()); 00313 } 00314 else 00315 { 00316 write(XalanFormatterWriter::decodeUTF16SurrogatePair(ch, theChars[i+1], getMemoryManager())); 00317 00318 ++i; 00319 } 00320 } 00321 else 00322 { 00323 write((unsigned int)ch); 00324 } 00325 } 00326 00327 } 00328 00329 void 00330 write(const value_type* theChars) 00331 { 00332 write(theChars, XalanDOMString::length(theChars)); 00333 } 00334 00335 void 00336 flushWriter() 00337 { 00338 m_writer.flush(); 00339 } 00340 00341 void 00342 flushBuffer() 00343 { 00344 m_writer.write(m_buffer, 0, m_bufferPosition - m_buffer); 00345 00346 m_bufferPosition = m_buffer; 00347 m_bufferRemaining = kBufferSize; 00348 } 00349 00350 private: 00351 00352 void 00353 write(unsigned int theChar) 00354 { 00355 if (theChar <= 0x7F) 00356 { 00357 write(char(theChar)); 00358 } 00359 else if (theChar <= 0x7FF) 00360 { 00361 if (m_bufferRemaining < 2) 00362 { 00363 flushBuffer(); 00364 } 00365 00366 *m_bufferPosition = leadingByteOf2(bits7to11(theChar)); 00367 ++m_bufferPosition; 00368 *m_bufferPosition = trailingByte(bits1to6(theChar)); 00369 ++m_bufferPosition; 00370 00371 m_bufferRemaining -= 2; 00372 } 00373 else if (theChar <= 0xFFFF) 00374 { 00375 // We should never get a high or low surrogate here... 00376 assert(theChar < 0xD800 || theChar > 0xDBFF); 00377 assert(theChar < 0xDC00 || theChar > 0xDFFF); 00378 00379 if (m_bufferRemaining < 3) 00380 { 00381 flushBuffer(); 00382 } 00383 00384 *m_bufferPosition = leadingByteOf3(bits13to16(theChar)); 00385 ++m_bufferPosition; 00386 *m_bufferPosition = trailingByte(bits7to12(theChar)); 00387 ++m_bufferPosition; 00388 *m_bufferPosition = trailingByte(bits1to6(theChar)); 00389 ++m_bufferPosition; 00390 00391 m_bufferRemaining -= 3; 00392 } 00393 else if (theChar <= 0x10FFFF) 00394 { 00395 if (m_bufferRemaining < 4) 00396 { 00397 flushBuffer(); 00398 } 00399 00400 *m_bufferPosition = leadingByteOf4(bits19to21(theChar)); 00401 ++m_bufferPosition; 00402 *m_bufferPosition = trailingByte(bits13to18(theChar)); 00403 ++m_bufferPosition; 00404 *m_bufferPosition = trailingByte(bits7to12(theChar)); 00405 ++m_bufferPosition; 00406 *m_bufferPosition = trailingByte(bits1to6(theChar)); 00407 ++m_bufferPosition; 00408 00409 m_bufferRemaining -= 4; 00410 } 00411 else 00412 { 00413 XalanFormatterWriter::throwInvalidCharacterException(theChar, getMemoryManager()); 00414 } 00415 } 00416 00417 enum 00418 { 00419 kBufferSize = 512 // The size of the buffer 00420 }; 00421 00422 00423 // Data members... 00424 value_type m_buffer[kBufferSize]; 00425 00426 value_type* m_bufferPosition; 00427 00428 XalanDOMString::size_type m_bufferRemaining; 00429 }; 00430 00431 00432 00433 XALAN_CPP_NAMESPACE_END 00434 00435 00436 00437 #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.10 |
|