Xalan-C++ API Documentation

The Xalan C++ XSLT Processor Version 1.10

Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

XalanUTF8Writer.hpp

Go to the documentation of this file.
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

Interpreting class diagrams

Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.

dot

Xalan-C++ XSLT Processor Version 1.10
Copyright © 1999-2004 The Apache Software Foundation. All Rights Reserved.

Apache Logo