dbertoni    2003/07/14 18:02:17

  Modified:    c/src/xalanc/XMLSupport XMLSupportInit.cpp
  Added:       c/src/xalanc/XMLSupport FormatterToXML_UTF16.cpp
                        FormatterToXML_UTF16.hpp FormatterToXML_UTF8.cpp
                        FormatterToXML_UTF8.hpp
  Log:
  New UTF XML serializers.
  
  Revision  Changes    Path
  1.2       +10 -1     xml-xalan/c/src/xalanc/XMLSupport/XMLSupportInit.cpp
  
  Index: XMLSupportInit.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/xalanc/XMLSupport/XMLSupportInit.cpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XMLSupportInit.cpp        29 Jun 2003 03:57:59 -0000      1.1
  +++ XMLSupportInit.cpp        15 Jul 2003 01:02:17 -0000      1.2
  @@ -2,7 +2,7 @@
    * The Apache Software License, Version 1.1
    *
    *
  - * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights 
  + * Copyright (c) 2000-2003 The Apache Software Foundation.  All rights 
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -59,6 +59,11 @@
   
   
   
  +#include "FormatterToXML_UTF8.hpp"
  +#include "FormatterToXML_UTF16.hpp"
  +
  +
  +
   XALAN_CPP_NAMESPACE_BEGIN
   
   
  @@ -96,6 +101,8 @@
   void
   XMLSupportInit::initialize()
   {
  +     FormatterToXML_UTF8::initialize();
  +     FormatterToXML_UTF16::initialize();
   }
   
   
  @@ -103,6 +110,8 @@
   void
   XMLSupportInit::terminate()
   {
  +     FormatterToXML_UTF16::terminate();
  +     FormatterToXML_UTF8::terminate();
   }
   
   
  
  
  
  1.1                  xml-xalan/c/src/xalanc/XMLSupport/FormatterToXML_UTF16.cpp
  
  Index: FormatterToXML_UTF16.cpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *      notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *      notice, this list of conditions and the following disclaimer in
   *      the documentation and/or other materials provided with the
   *      distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *      if any, must include the following acknowledgment:  
   *             "This product includes software developed by the
   *              Apache Software Foundation (http://www.apache.org/)."
   *      Alternately, this acknowledgment may appear in the software itself,
   *      if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" and "Apache Software Foundation" must
   *      not be used to endorse or promote products derived from this
   *      software without prior written permission. For written 
   *      permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *      nor may "Apache" appear in their name, without prior written
   *      permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.        IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  
  // Class header file.
  #include "FormatterToXML_UTF16.hpp"
  
  
  
  #include <xercesc/sax/AttributeList.hpp>
  #include <xercesc/sax/SAXException.hpp>
  
  
  
  #include <xalanc/PlatformSupport/DOMStringHelper.hpp>
  #include <xalanc/PlatformSupport/Writer.hpp>
  #include <xalanc/PlatformSupport/XalanOutputStream.hpp>
  #include <xalanc/PlatformSupport/XalanTranscodingServices.hpp>
  #include <xalanc/PlatformSupport/XalanUnicode.hpp>
  
  
  
  #include <xalanc/DOMSupport/DOMServices.hpp>
  
  
  
  XALAN_CPP_NAMESPACE_BEGIN
  
  
  
  const XalanDOMChar    FormatterToXML_UTF16::s_specialChars[kSpecialsSize] =
  {
        kNotSpecial,            // 0
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kBothSpecial,           // 0xA -- linefeed  Special because we normalize as 
requested.
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,            // 0x10
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,            // 0x20
        kNotSpecial,
        kAttributeSpecial,      // 0x22 '"'
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kBothSpecial,           // 0x26 -- '&'
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,            // 0x30
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kBothSpecial,           // 0x3C '<'
        kNotSpecial,
        kBothSpecial            // 0x3E '>'
  };
  
  
  
  FormatterToXML_UTF16::FormatterToXML_UTF16(
                        Writer&                                 writer,
                        const XalanDOMString&   version,
                        const XalanDOMString&   mediaType,
                        const XalanDOMString&   doctypeSystem,
                        const XalanDOMString&   doctypePublic,
                        bool                                    xmlDecl,
                        const XalanDOMString&   standalone) :
        FormatterListener(OUTPUT_METHOD_XML),
        m_writer(&writer),
        m_shouldWriteXMLHeader(xmlDecl),
        m_needToOutputDocTypeDecl(true),
        m_nextIsRaw(false),
        m_doctypeSystem(doctypeSystem),
        m_doctypePublic(doctypePublic),
        m_spaceBeforeClose(false),
        m_version(version),
        m_standalone(standalone),
        m_mediaType(mediaType),
        m_elemStack(),
        m_newlineString(0),
        m_newlineStringLength(0),
        m_buffer(),
        m_bufferPosition(m_buffer),
        m_bufferRemaining(kBufferSize)
  {
        if(isEmpty(m_doctypePublic) == false)
        {
                if(startsWith(
                        m_doctypePublic,
                        s_xhtmlDocTypeString) == true)
                {
                        m_spaceBeforeClose = true;
                }
        }
  
        const XalanOutputStream* const  theStream = writer.getStream();
  
        if (theStream == 0)
        {
                m_newlineString = XalanOutputStream::defaultNewlineString();
        }
        else
        {
                m_newlineString = theStream->getNewlineString();
        }
  
        assert(m_newlineString != 0);
  
        m_newlineStringLength = length(m_newlineString);
  
        assert(m_newlineString != 0);
  
        const XalanTranscodingServices::XalanXMLByte*   theProlog =
                XalanTranscodingServices::getStreamProlog(s_utf16String);
        assert(theProlog != 0);
  
        const size_t    theLength = XalanTranscodingServices::length(theProlog);
        assert(theLength == 2);
  
  #if defined(XALAN_OLD_STYLE_CASTS)
        m_writer->write((const char*)theProlog, 0, theLength);
  #else
        m_writer->write(reinterpret_cast<const char*>(theProlog), 0, theLength);
  #endif
  }
  
  
  
  FormatterToXML_UTF16::~FormatterToXML_UTF16()
  {
  }
  
  
  
  inline void
  FormatterToXML_UTF16::flushBuffer()
  {
        m_writer->write((const char*)m_buffer, 0, (m_bufferPosition - m_buffer) * 
sizeof m_buffer[0]);
  
        m_bufferPosition = m_buffer;
        m_bufferRemaining = kBufferSize;
  }
  
  
  
  inline void
  FormatterToXML_UTF16::write(
                        const XalanDOMChar*             theChars,
                        size_type                               theLength)
  {
        if (theLength > sizeof(m_buffer))
        {
                flushBuffer();
  
                m_writer->write(theChars, 0, theLength);
        }
        else
        {
                if (m_bufferRemaining < theLength)
                {
                        flushBuffer();
                }
  
                for(size_type i = 0; i < theLength; ++i)
                {
                        *m_bufferPosition = theChars[i];
  
                        ++m_bufferPosition;
                }
  
                m_bufferRemaining -= theLength;
        }
  }
  
  
  
  void
  FormatterToXML_UTF16::writeName(const XalanDOMChar*           theChars)
  {
        write(theChars, length(theChars));
  }
  
  
  
  void
  FormatterToXML_UTF16::outputDocTypeDecl(const XalanDOMChar*   name)
  {
        // "<!DOCTYPE "
        write(s_doctypeHeaderStartString, s_doctypeHeaderStartStringLength);
  
        write(name);
  
        if(length(m_doctypePublic) != 0)
        {
                // " PUBLIC \""
                write(s_doctypeHeaderPublicString, s_doctypeHeaderPublicStringLength);
                writeName(m_doctypePublic.c_str());
                write(XalanUnicode::charQuoteMark);
                write(XalanUnicode::charSpace);
                write(XalanUnicode::charQuoteMark);
        }
        else
        {
                // " SYSTEM \""
                write(s_doctypeHeaderSystemString, s_doctypeHeaderSystemStringLength);
        }
  
        writeName(m_doctypeSystem.c_str());
        write(XalanUnicode::charQuoteMark);
        write(XalanUnicode::charGreaterThanSign);
  
        outputLineSep();
  }
  
  
  
  bool
  FormatterToXML_UTF16::writeDefaultEntity(XalanDOMChar ch)
  {
        if (XalanUnicode::charLessThanSign == ch)
        {
                write(s_lessThanEntityString, s_lessThanEntityStringLength);
        }
        else if (XalanUnicode::charGreaterThanSign == ch)
        {
                write(s_greaterThanEntityString, s_greaterThanEntityStringLength);
        }
        else if (XalanUnicode::charAmpersand == ch)
        {
                write(s_ampersandEntityString, s_ampersandEntityStringLength);
        }
        else
        {
                return false;
        }
  
        return true;
  }
  
  
  
  
  
  
  void
  FormatterToXML_UTF16::writeDefaultEscape(XalanDOMChar ch)
  {
        if(!writeDefaultEntity(ch))
        {
                writeNormalizedChar(ch);
        }
  }
  
  
  
  bool
  FormatterToXML_UTF16::writeDefaultAttributeEntity(XalanDOMChar        ch)
  {
        if (writeDefaultEntity(ch) == true)
        {
                return true;
        }
        else if (XalanUnicode::charLF == ch) 
        {
                write(s_linefeedNCRString, s_linefeedNCRStringLength);
        }
        else if (XalanUnicode::charQuoteMark == ch) 
        {
                write(s_quoteEntityString, s_quoteEntityStringLength);
        }
        else
        {
                return false;
        }
  
        return true;
  }
  
  
  
  void
  FormatterToXML_UTF16::writeDefaultAttributeEscape(XalanDOMChar        ch)
  {
        if(!writeDefaultAttributeEntity(ch))
        {
                writeNormalizedChar(ch);
        }
  }
  
  
  
  void
  FormatterToXML_UTF16::flushWriter()
  {
        m_writer->flush();
  }
  
  
  
  void
  FormatterToXML_UTF16::setDocumentLocator(const LocatorType* const     /* locator */)
  {
  }
  
  
  
  void
  FormatterToXML_UTF16::startDocument()
  {
        m_needToOutputDocTypeDecl = true;
  
        if(m_shouldWriteXMLHeader == true)
        {
                // "<?xml version=\""
                write(s_xmlHeaderStartString, s_xmlHeaderStartStringLength);
  
                if (length(m_version) != 0)
                {
                        write(m_version);
                }
                else
                {
                        write(s_defaultVersionString, s_defaultVersionStringLength);
                }
  
                // "\" encoding=\""
                write(s_xmlHeaderEncodingString, s_xmlHeaderEncodingStringLength);
  
                write(s_utf16String);
  
                if (length(m_standalone) != 0)
                {
                        write(s_xmlHeaderStandaloneString, 
s_xmlHeaderStandaloneStringLength);
                        write(m_standalone);
                }
  
                write(s_xmlHeaderEndString, s_xmlHeaderEndStringLength);
  
                outputLineSep();
        }
  }
  
  
  
  void
  FormatterToXML_UTF16::endDocument()
  {
        flushBuffer();
  }
  
  
  
  void
  FormatterToXML_UTF16::startElement(
                        const XMLCh* const      name,
                        AttributeListType&      attrs)
  {
        if(true == m_needToOutputDocTypeDecl &&
           isEmpty(m_doctypeSystem) == false)
        {
                outputDocTypeDecl(name);
  
                m_needToOutputDocTypeDecl = false;
        }
  
        writeParentTagEnd();
  
        write(XalanUnicode::charLessThanSign);
        writeName(name);
  
        const unsigned int      nAttrs = attrs.getLength();
  
        for (unsigned int i = 0;  i < nAttrs ;  i++)
        {
                processAttribute(attrs.getName(i), attrs.getValue(i));
        }
  
        // Flag the current element as not yet having any children.
        openElementForChildren();
  }
  
  
  
  void
  FormatterToXML_UTF16::endElement(const XMLCh* const   name)
  {
        const bool      hasChildNodes = childNodesWereAdded();
  
        if (hasChildNodes == true) 
        {
                write(XalanUnicode::charLessThanSign);
                write(XalanUnicode::charSolidus);
                writeName(name);
        }
        else
        {
                if(m_spaceBeforeClose == true)
                {
                        write(XalanUnicode::charSpace);
                }
  
                write(XalanUnicode::charSolidus);
        }
  
        write(XalanUnicode::charGreaterThanSign);
  }
  
  
  
  void
  FormatterToXML_UTF16::processingInstruction(
                        const XMLCh* const      target,
                        const XMLCh* const      data)
  {
        // Use a fairly nasty hack to tell if the next node is supposed to be 
        // unescaped text.
        if(equals(target, length(target), s_piTarget, s_piTargetLength) == true &&
           equals(data, length(data), s_piData, s_piDataLength) == true)
        {
                m_nextIsRaw = true;
        }
        else    
        {
                writeParentTagEnd();
  
                write(XalanUnicode::charLessThanSign);
                write(XalanUnicode::charQuestionMark);
                writeName(target);
  
                const XalanDOMString::size_type         len = length(data);
  
                if ( len > 0 && !isXMLWhitespace(data[0]))
                {
                        write(XalanUnicode::charSpace);
                }
  
                writeNormalizedPIData(data, len);
  
                write(XalanUnicode::charQuestionMark);
                write(XalanUnicode::charGreaterThanSign);
  
                // If outside of an element, then put in a new line.  This whitespace
                // is not significant.
                if (m_elemStack.empty() == true)
                {
                        outputLineSep();
                }
        }
  }
  
  
  
  void
  FormatterToXML_UTF16::characters(
                        const XMLCh* const      chars,
                        const unsigned int      length)
  {
        if(length != 0)
        {
                if(m_nextIsRaw)
                {
                        m_nextIsRaw = false;
  
                        charactersRaw(chars, length);
                }
                else
                {
                        writeParentTagEnd();
  
                        unsigned int    i = 0;
                        unsigned int    firstIndex = 0;
  
                        while(i < length) 
                        {
                                const XalanDOMChar      ch = chars[i];
  
                                if (isContentSpecial(ch) == false)
                                {
                                        ++i;
                                }
                                else
                                {
                                        write(chars + firstIndex, i - firstIndex);
  
                                        writeDefaultEscape(chars[i++]);
  
                                        firstIndex = i;
                                }
                        }
  
                        write(chars + firstIndex, i - firstIndex);
                }
        }
  }
  
  
  
  void
  FormatterToXML_UTF16::charactersRaw(
                const XMLCh* const      chars,
                const unsigned int      length)
  {
        writeParentTagEnd();
  
        write(chars, length);
  }
  
  
  
  Writer*
  FormatterToXML_UTF16::getWriter() const
  {
        return m_writer;
  }
  
  
  
  const XalanDOMString&
  FormatterToXML_UTF16::getDoctypeSystem() const
  {
        return m_doctypeSystem;
  }
  
  
  
  const XalanDOMString&
  FormatterToXML_UTF16::getDoctypePublic() const
  {
        return m_doctypePublic;
  }
  
  
  
  const XalanDOMString&
  FormatterToXML_UTF16::getEncoding() const
  {
        return s_utf16String;
  }
  
  
  
  const XalanDOMString&
  FormatterToXML_UTF16::getMediaType() const
  {
        return m_mediaType;
  }
  
  
  
  void
  FormatterToXML_UTF16::writeAttrString(
                        const XalanDOMChar*                     theString,
                        XalanDOMString::size_type       theStringLength)
  {
        assert(theString != 0);
  
        XalanDOMString::size_type       i = 0;
        XalanDOMString::size_type       firstIndex = 0;
  
      while(i < theStringLength)
      {
                const XalanDOMChar      ch = theString[i];
  
                if (isAttributeSpecial(ch) == false)
                {
                        ++i;
                }
                else
                {
                        write(theString + firstIndex, i - firstIndex);
  
                        writeDefaultAttributeEscape(ch);
  
                        ++i;
  
                        firstIndex = i;
                }
      }
  
        write(theString + firstIndex, i - firstIndex);
  }
  
  
  
  void
  FormatterToXML_UTF16::writeCommentData(const XalanDOMChar*    data)
  {
        const XalanDOMString::size_type         len = length(data);
        XalanDOMChar                                            previousChar = 0;
  
        for (XalanDOMString::size_type i = 0; i < len; ++i)
        {
                const XalanDOMChar      currentChar = data[i];
  
                if (currentChar == XalanUnicode::charHyphenMinus &&
                        previousChar == XalanUnicode::charHyphenMinus)
                {
                        write(XalanUnicode::charSpace);
                }
  
                write(currentChar);
  
                previousChar = currentChar;
        }
                
        if (previousChar == XalanUnicode::charHyphenMinus)
        {
                write(XalanUnicode::charSpace);
        }
  }
  
  
  
  void
  FormatterToXML_UTF16::writeNormalizedChar(XalanDOMChar        ch)
  {
        if(XalanUnicode::charLF == ch)
        {
                outputLineSep();
        }
        else
        {
                write(ch);
        }
  }
  
  
  
  void
  FormatterToXML_UTF16::writeCDATAChars(
                        const XalanDOMChar                      ch[],
                        XalanDOMString::size_type       length)
  {
        XalanDOMString::size_type i = 0;
  
        while(i < length)
      {
                // If "]]>", which would close the CDATA appears in
                // the content, we have to put the first two characters
                // in the CDATA section, close the CDATA section, then
                // open a new one and add the last character.
                if (i < length - 2 &&
                        XalanUnicode::charRightSquareBracket == ch[i] &&
              XalanUnicode::charRightSquareBracket == ch[i + 1] &&
                        XalanUnicode::charGreaterThanSign == ch[ i + 2])
                {
                        // "]]]]><![CDATA[>"
                        write(XalanUnicode::charRightSquareBracket);
                        write(XalanUnicode::charRightSquareBracket);
  
                        write(s_cdataCloseString, s_cdataCloseStringLength);
                        write(s_cdataOpenString, s_cdataOpenStringLength);
  
                        write(XalanUnicode::charGreaterThanSign);
  
                        i += 3;
                }
                else
                {
                        writeNormalizedChar(ch[i++]);
                }
      }
  }
  
  
  
  void
  FormatterToXML_UTF16::entityReference(const XMLCh* const      name)
  {
        writeParentTagEnd();
          
        write(XalanUnicode::charAmpersand);
        writeName(name);
        write(XalanUnicode::charSemicolon);
  }
  
  
  
  void
  FormatterToXML_UTF16::ignorableWhitespace(
                        const XMLCh* const      chars,
                        const unsigned int      length)
  {
        if (length > 0)
        {
                characters(chars, length);
        }
  }
  
  
  
  void
  FormatterToXML_UTF16::resetDocument()
  {
        // I don't do anything with this yet.
  }
  
  
  
  void
  FormatterToXML_UTF16::comment(const XMLCh* const      data)
  {
        writeParentTagEnd();
  
        write(char(XalanUnicode::charLessThanSign));
        write(char(XalanUnicode::charExclamationMark));
        write(char(XalanUnicode::charHyphenMinus));
        write(char(XalanUnicode::charHyphenMinus));
  
        writeCommentData(data);
  
        write(char(XalanUnicode::charHyphenMinus));
        write(char(XalanUnicode::charHyphenMinus));
        write(char(XalanUnicode::charGreaterThanSign));
  }
  
  
  
  void
  FormatterToXML_UTF16::cdata(
                        const XMLCh* const      ch,
                        const unsigned int      length)
  {
        if(m_nextIsRaw == true)
        {
                m_nextIsRaw = false;
  
                charactersRaw(ch, length);
        }
        else
        {
                writeParentTagEnd();
  
                if(length > 0)
                {
                        write(s_cdataOpenString, s_cdataOpenStringLength);
  
                        writeCDATAChars(ch, length);
  
                        write(s_cdataCloseString, s_cdataCloseStringLength);
                }
        }
  }
  
  
  
  void
  FormatterToXML_UTF16::writeParentTagEnd()
  {
        if(!m_elemStack.empty())
        {
                // See if the parent element has already been flagged as having 
children.
                if(false == m_elemStack.back())
                {
                        write(char(XalanUnicode::charGreaterThanSign));
  
                        m_elemStack.back() = true;
                }
        }
  }
  
  
  
  void
  FormatterToXML_UTF16::openElementForChildren()
  {
        m_elemStack.push_back(false);
  }
  
  
  
  bool
  FormatterToXML_UTF16::childNodesWereAdded()
  {
        bool    fResult = false;
  
        if (m_elemStack.empty() == false)
        {
                fResult = m_elemStack.back();
  
                m_elemStack.pop_back();
        }
  
        return fResult;
  }
  
  
  
  void
  FormatterToXML_UTF16::processAttribute(
                        const XalanDOMChar*     name,
                        const XalanDOMChar*     value)
  {
        // We add a fake attribute to the source tree to
        // declare the xml prefix, so we filter it back out
        // here...
        // $$$ ToDo: It would be better if we didn't have to do
        // this here.
        if (equals(name, DOMServices::s_XMLNamespacePrefix) == false)
        {
                write(char(XalanUnicode::charSpace));
                writeName(name);
                write(char(XalanUnicode::charEqualsSign));
                write(char(XalanUnicode::charQuoteMark));
                writeAttrString(value, length(value));
                write(char(XalanUnicode::charQuoteMark));
        }
  }
  
  
  
  void
  FormatterToXML_UTF16::outputLineSep()
  {
        assert(m_newlineString != 0 && length(m_newlineString) == 
m_newlineStringLength);
  
        write(m_newlineString, m_newlineStringLength);
  }
  
  
  
  void
  FormatterToXML_UTF16::writeNormalizedPIData(
                        const XalanDOMChar*                     theData,
                        XalanDOMString::size_type       theLength)
  {
        // If there are any "?>" pairs in the string,
        // we have to normalize them to "? >", so they
        // won't be confused with the end tag.
  
        for (XalanDOMString::size_type i = 0; i < theLength; ++i)
        {
                const XalanDOMChar      theChar = theData[i];
  
                if (theChar == XalanUnicode::charQuestionMark &&
                        i + 1 < theLength &&
                        theData[i + 1] == XalanUnicode::charGreaterThanSign)
                {
                        write(char(XalanUnicode::charQuestionMark));
                        write(char(XalanUnicode::charSpace));
                }
                else
                {
                        write(theChar);
                }
        }
  }
  
  
  
  static XalanDOMString s_localUTF16String;
  
  
  
  const XalanDOMString& FormatterToXML_UTF16::s_utf16String = s_localUTF16String;
  
  
  
  void
  FormatterToXML_UTF16::initialize()
  {
        s_localUTF16String = XalanTranscodingServices::s_utf16String;
  }
  
  
  
  void
  FormatterToXML_UTF16::terminate()
  {
        XalanDOMString().swap(s_localUTF16String);
  }
  
  
  
  #define FXML_SIZE(str)        ((sizeof(str) / sizeof(str[0]) - 1))
  
  const XalanDOMChar    FormatterToXML_UTF16::s_doctypeHeaderStartString[] =
  {
        XalanUnicode::charLessThanSign,
        XalanUnicode::charExclamationMark,
        XalanUnicode::charLetter_D,
        XalanUnicode::charLetter_O,
        XalanUnicode::charLetter_C,
        XalanUnicode::charLetter_T,
        XalanUnicode::charLetter_Y,
        XalanUnicode::charLetter_P,
        XalanUnicode::charLetter_E,
        XalanUnicode::charSpace,
        XalanDOMChar(0)
  };
  
  const FormatterToXML_UTF16::size_type 
FormatterToXML_UTF16::s_doctypeHeaderStartStringLength =
                FXML_SIZE(s_doctypeHeaderStartString);
  
  const XalanDOMChar    FormatterToXML_UTF16::s_doctypeHeaderPublicString[] =
  {
        XalanUnicode::charSpace,
        XalanUnicode::charLetter_P,
        XalanUnicode::charLetter_U,
        XalanUnicode::charLetter_B,
        XalanUnicode::charLetter_L,
        XalanUnicode::charLetter_I,
        XalanUnicode::charLetter_C,
        XalanUnicode::charSpace,
        XalanUnicode::charQuoteMark,
        XalanDOMChar(0)
  };
  
  const FormatterToXML_UTF16::size_type 
FormatterToXML_UTF16::s_doctypeHeaderPublicStringLength =
                FXML_SIZE(s_doctypeHeaderPublicString);
  
  const XalanDOMChar    FormatterToXML_UTF16::s_doctypeHeaderSystemString[] =
  {
        XalanUnicode::charSpace,
        XalanUnicode::charLetter_S,
        XalanUnicode::charLetter_Y,
        XalanUnicode::charLetter_S,
        XalanUnicode::charLetter_T,
        XalanUnicode::charLetter_E,
        XalanUnicode::charLetter_M,
        XalanUnicode::charSpace,
        XalanUnicode::charQuoteMark,
        XalanDOMChar(0)
  };
  
  const FormatterToXML_UTF16::size_type         
FormatterToXML_UTF16::s_doctypeHeaderSystemStringLength =
                FXML_SIZE(s_doctypeHeaderSystemString);
  
  const XalanDOMChar    FormatterToXML_UTF16::s_xmlHeaderStartString[] =
  {
        XalanUnicode::charLessThanSign,
        XalanUnicode::charQuestionMark,
        XalanUnicode::charLetter_x,
        XalanUnicode::charLetter_m,
        XalanUnicode::charLetter_l,
        XalanUnicode::charSpace,
        XalanUnicode::charLetter_v,
        XalanUnicode::charLetter_e,
        XalanUnicode::charLetter_r,
        XalanUnicode::charLetter_s,
        XalanUnicode::charLetter_i,
        XalanUnicode::charLetter_o,
        XalanUnicode::charLetter_n,
        XalanUnicode::charEqualsSign,
        XalanUnicode::charQuoteMark,
        XalanDOMChar(0)
  };
  
  const FormatterToXML_UTF16::size_type         
FormatterToXML_UTF16::s_xmlHeaderStartStringLength =
                FXML_SIZE(s_xmlHeaderStartString);
  
  const XalanDOMChar    FormatterToXML_UTF16::s_xmlHeaderEncodingString[] =
  {
        XalanUnicode::charQuoteMark,
        XalanUnicode::charSpace,
        XalanUnicode::charLetter_e,
        XalanUnicode::charLetter_n,
        XalanUnicode::charLetter_c,
        XalanUnicode::charLetter_o,
        XalanUnicode::charLetter_d,
        XalanUnicode::charLetter_i,
        XalanUnicode::charLetter_n,
        XalanUnicode::charLetter_g,
        XalanUnicode::charEqualsSign,
        XalanUnicode::charQuoteMark,
        XalanDOMChar(0)
  };
  
  const FormatterToXML_UTF16::size_type         
FormatterToXML_UTF16::s_xmlHeaderEncodingStringLength =
                FXML_SIZE(s_xmlHeaderEncodingString);
  
  const XalanDOMChar    FormatterToXML_UTF16::s_xmlHeaderStandaloneString[] =
  {
        XalanUnicode::charQuoteMark,
        XalanUnicode::charSpace,
        XalanUnicode::charLetter_s,
        XalanUnicode::charLetter_t,
        XalanUnicode::charLetter_a,
        XalanUnicode::charLetter_n,
        XalanUnicode::charLetter_d,
        XalanUnicode::charLetter_a,
        XalanUnicode::charLetter_l,
        XalanUnicode::charLetter_o,
        XalanUnicode::charLetter_n,
        XalanUnicode::charLetter_e,
        XalanUnicode::charEqualsSign,
        XalanUnicode::charQuoteMark,
        XalanDOMChar(0)
  };
  
  const FormatterToXML_UTF16::size_type         
FormatterToXML_UTF16::s_xmlHeaderStandaloneStringLength =
                FXML_SIZE(s_xmlHeaderStandaloneString);
  
  const XalanDOMChar    FormatterToXML_UTF16::s_xmlHeaderEndString[] =
  {
        XalanUnicode::charQuoteMark,
        XalanUnicode::charQuestionMark,
        XalanUnicode::charGreaterThanSign,
        XalanDOMChar(0)
  };
  
  const FormatterToXML_UTF16::size_type         
FormatterToXML_UTF16::s_xmlHeaderEndStringLength =
                FXML_SIZE(s_xmlHeaderEndString);
  
  const XalanDOMChar    FormatterToXML_UTF16::s_defaultVersionString[] =
  {
        XalanUnicode::charDigit_1,
        XalanUnicode::charFullStop,
        XalanUnicode::charDigit_0,
        XalanDOMChar(0)
  };
  
  const FormatterToXML_UTF16::size_type         
FormatterToXML_UTF16::s_defaultVersionStringLength =
                FXML_SIZE(s_defaultVersionString);
  
  const XalanDOMChar    FormatterToXML_UTF16::s_cdataOpenString[] =
  {
        XalanUnicode::charLessThanSign,
        XalanUnicode::charExclamationMark,
        XalanUnicode::charLeftSquareBracket,
        XalanUnicode::charLetter_C,
        XalanUnicode::charLetter_D,
        XalanUnicode::charLetter_A,
        XalanUnicode::charLetter_T,
        XalanUnicode::charLetter_A,
        XalanUnicode::charLeftSquareBracket,
        XalanDOMChar(0)
  };
  
  const FormatterToXML_UTF16::size_type         
FormatterToXML_UTF16::s_cdataOpenStringLength =
                FXML_SIZE(s_cdataOpenString);
  
  const XalanDOMChar    FormatterToXML_UTF16::s_cdataCloseString[] =
  {
        XalanUnicode::charRightSquareBracket,
        XalanUnicode::charRightSquareBracket,
        XalanUnicode::charGreaterThanSign,
        XalanDOMChar(0)
  };
  
  const FormatterToXML_UTF16::size_type         
FormatterToXML_UTF16::s_cdataCloseStringLength =
                FXML_SIZE(s_cdataCloseString);
  
  
  const XalanDOMChar    FormatterToXML_UTF16::s_xhtmlDocTypeString[] =
  {
        XalanUnicode::charHyphenMinus,
        XalanUnicode::charSolidus,
        XalanUnicode::charSolidus,
        XalanUnicode::charLetter_W,
        XalanUnicode::charDigit_3,
        XalanUnicode::charLetter_C,
        XalanUnicode::charSolidus,
        XalanUnicode::charSolidus,
        XalanUnicode::charLetter_D,
        XalanUnicode::charLetter_T,
        XalanUnicode::charLetter_D,
        XalanUnicode::charSpace,
        XalanUnicode::charLetter_X,
        XalanUnicode::charLetter_H,
        XalanUnicode::charLetter_T,
        XalanUnicode::charLetter_M,
        XalanUnicode::charLetter_L,
        XalanDOMChar(0)
  };
  
  const FormatterToXML_UTF16::size_type         
FormatterToXML_UTF16::s_xhtmlDocTypeStringLength =
                FXML_SIZE(s_xhtmlDocTypeString);
  
  const XalanDOMChar    FormatterToXML_UTF16::s_lessThanEntityString[] =
  {
        XalanUnicode::charAmpersand,
        XalanUnicode::charLetter_l,
        XalanUnicode::charLetter_t,
        XalanUnicode::charSemicolon,
        XalanDOMChar(0)
  };
  
  const FormatterToXML_UTF16::size_type         
FormatterToXML_UTF16::s_lessThanEntityStringLength =
                FXML_SIZE(s_lessThanEntityString);
  
  const XalanDOMChar    FormatterToXML_UTF16::s_greaterThanEntityString[] =
  {
        XalanUnicode::charAmpersand,
        XalanUnicode::charLetter_g,
        XalanUnicode::charLetter_t,
        XalanUnicode::charSemicolon,
        XalanDOMChar(0)
  };
  
  const FormatterToXML_UTF16::size_type         
FormatterToXML_UTF16::s_greaterThanEntityStringLength =
                FXML_SIZE(s_greaterThanEntityString);
  
  const XalanDOMChar    FormatterToXML_UTF16::s_ampersandEntityString[] =
  {
        XalanUnicode::charAmpersand,
        XalanUnicode::charLetter_a,
        XalanUnicode::charLetter_m,
        XalanUnicode::charLetter_p,
        XalanUnicode::charSemicolon,
        XalanDOMChar(0)
  };
  
  const FormatterToXML_UTF16::size_type         
FormatterToXML_UTF16::s_ampersandEntityStringLength =
                FXML_SIZE(s_ampersandEntityString);
  
  const XalanDOMChar    FormatterToXML_UTF16::s_quoteEntityString[] =
  {
        XalanUnicode::charAmpersand,
        XalanUnicode::charLetter_q,
        XalanUnicode::charLetter_u,
        XalanUnicode::charLetter_o,
        XalanUnicode::charLetter_t,
        XalanUnicode::charSemicolon,
        XalanDOMChar(0)
  };
  
  const FormatterToXML_UTF16::size_type         
FormatterToXML_UTF16::s_quoteEntityStringLength =
                FXML_SIZE(s_quoteEntityString);
  
  const XalanDOMChar    FormatterToXML_UTF16::s_linefeedNCRString[] =
  {
        XalanUnicode::charAmpersand,
        XalanUnicode::charNumberSign,
        XalanUnicode::charDigit_1,
        XalanUnicode::charDigit_0,
        XalanUnicode::charSemicolon,
        XalanDOMChar(0)
  };
  
  const FormatterToXML_UTF16::size_type         
FormatterToXML_UTF16::s_linefeedNCRStringLength =
                FXML_SIZE(s_linefeedNCRString);
  
  
  
  XALAN_CPP_NAMESPACE_END
  
  
  
  1.1                  xml-xalan/c/src/xalanc/XMLSupport/FormatterToXML_UTF16.hpp
  
  Index: FormatterToXML_UTF16.hpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  #if !defined(FORMATTERTOXML_UTF16_HEADER_GUARD_1357924680)
  #define FORMATTERTOXML_UTF16_HEADER_GUARD_1357924680
  
  
  
  
  // Base include file.  Must be first.
  #include <xalanc/XMLSupport/XMLSupportDefinitions.hpp>
  
  
  
  #include <vector>
  
  
  
  #include <xalanc/XalanDOM/XalanDOMString.hpp>
  
  
  
  // Base class header file.
  #include <xalanc/PlatformSupport/FormatterListener.hpp>
  
  
  
  XALAN_CPP_NAMESPACE_BEGIN
  
  
  
  class Writer;
  
  
  
  /**
   * FormatterToXML_UTF16 formats SAX-style events into XML.
   */
  class XALAN_XMLSUPPORT_EXPORT FormatterToXML_UTF16 : public FormatterListener 
  {
  public:
  
        /**
         * Perform static initialization.  See class XMLSupportInit.
         */
        static void
        initialize();
   
        /**
         * Perform static shut down.  See class XMLSupportInit.
         */
        static void
        terminate();
  
        /**
         * Constructor
         *
         * @param writer            the writer.
         * @param version           the string to write for the XML version number.
         * @param mediaType         media type (MIME content type) of the data
         * @param doctypeSystem     system identifier to be used in the document
         *                          type declaration
         * @param doctypePublic     public identifier to be used in the document
         *                          type declaration
         * @param xmlDecl           true if the XSLT processor should output an XML
         *                          declaration
         * @param standalone        The string the XSLT processor should output for
         *                          the standalone document declaration
         */
        FormatterToXML_UTF16(
                        Writer&                                 writer,
                        const XalanDOMString&   version = XalanDOMString(),
                        const XalanDOMString&   mediaType = XalanDOMString(),
                        const XalanDOMString&   doctypeSystem = XalanDOMString(),
                        const XalanDOMString&   doctypePublic = XalanDOMString(),
                        bool                                    xmlDecl = true,
                        const XalanDOMString&   standalone = XalanDOMString());
  
        virtual
        ~FormatterToXML_UTF16();
  
  
        // These methods are inherited from FormatterListener ...
  
        virtual void
        setDocumentLocator(const LocatorType* const             locator);
  
        virtual void
        startDocument();
  
        virtual void
        endDocument();
  
        virtual void
        startElement(
                        const XMLCh* const      name,
                        AttributeListType&      attrs);
  
      virtual void
        endElement(const XMLCh* const   name);
  
      virtual void
        characters(
                        const XMLCh* const      chars,
                        const unsigned int      length);
  
      virtual void
        charactersRaw(
                        const XMLCh* const      chars,
                        const unsigned int      length);
  
        virtual void
        entityReference(const XMLCh* const      name);
  
        virtual void
        ignorableWhitespace(
                        const XMLCh* const      chars,
                        const unsigned int      length);
  
        virtual void
        processingInstruction(
                        const XMLCh* const      target,
                        const XMLCh* const      data);
  
  
      virtual void
        resetDocument();
  
        virtual void
        comment(const XMLCh* const      data);
  
        virtual void
        cdata(
                        const XMLCh* const      ch,
                        const unsigned int      length);
  
        virtual Writer*
        getWriter() const;
  
        virtual const XalanDOMString&
        getDoctypeSystem() const;
  
        virtual const XalanDOMString&
        getDoctypePublic() const;
  
        virtual const XalanDOMString&
        getEncoding() const;
  
        virtual const XalanDOMString&
        getMediaType() const;
  
        const XalanDOMString&
        getVersion() const
        {
                return m_version;
        }
  
        const XalanDOMString&
        getStandalone() const
        {
                return m_standalone;
        }
  
        bool
        getShouldWriteXMLHeader() const
        {
                return m_shouldWriteXMLHeader;
        }
  
        void
        setShouldWriteXMLHeader(bool    b)
        {
                m_shouldWriteXMLHeader = b;
        }
  
  #if defined(XALAN_NO_STD_NAMESPACE)
  #if defined(XALAN_USE_DEQUE_FOR_VECTOR_BOOL)
        typedef deque<bool>                     BoolStackType;
  #else
        typedef vector<bool>            BoolStackType;
  #endif
  #else
  #if defined(XALAN_USE_DEQUE_FOR_VECTOR_BOOL)
        typedef std::deque<bool>        BoolStackType;
  #else
        typedef std::vector<bool>       BoolStackType;
  #endif
  #endif
  
  protected:
  
        /** 
         * The writer.
         */
        Writer*                                 m_writer;
  
        /**
         * Output a line break.
         */
        void
        outputLineSep();
  
        /**
         * Escape and write a character.
         */
        void
        writeDefaultEscape(XalanDOMChar         ch);
  
        /**
         * Escape and write a character in an attribute.
         */
        void
        writeDefaultAttributeEscape(XalanDOMChar        ch);
  
        /**
         * Handle one of the default entities, return false if it 
         * is not a default entity.
         */
        bool
        writeDefaultEntity(XalanDOMChar         ch);
  
        /**
         * Handle one of the default entities, return false if it 
         * is not a default entity.
         */
        bool
        writeDefaultAttributeEntity(XalanDOMChar        ch);
  
        /**
         * Write the data for a comment
         * @param data The comment's data.
         */
        void
        writeCommentData(const XalanDOMChar*    data);
  
        void
        flushWriter();
  
        void
        openElementForChildren();
  
        bool
        childNodesWereAdded();
  
        /**
         * Check to see if a parent's ">" has been written, and, if 
         * it has not, write it.
         */
        void
        writeParentTagEnd();
  
        /**
         * Write a normalized character to the stream.
         * @param ch the character to write
         */
        void
        writeNormalizedChar(XalanDOMChar        ch);
  
        /**
         * Write characters for a CDATA section
         *
         * @param ch the string to write.
         * @param length the length of the string.
         */
        void
        writeCDATAChars(
                        const XalanDOMChar                      ch[],
                        XalanDOMString::size_type       length);
  
        /**
         * Write an attribute string.
         *
         * @param theString The string to write.
         * @param theStringLength The length of the string.
         */
        void
        writeAttrString(
                        const XalanDOMChar*                     theString,
                        XalanDOMString::size_type       theStringLength);
  
        /**
         * Throw an exception when an invalid
         * surrogate is encountered.
         * @param ch The first character in the surrogate
         */
        static void
        throwInvalidUTF16SurrogateException(XalanDOMChar        ch);
  
        /**
         * Throw an exception when an invalid
         * surrogate is encountered.
         * @param ch The first character in the surrogate
         * @param next The next character in the surrogate
         */
        static void
        throwInvalidUTF16SurrogateException(
                        XalanDOMChar    ch,
                        XalanDOMChar    next);
  
        /**
         * If true, XML header should be written to output.
         */
        bool            m_shouldWriteXMLHeader;
  
        /**
         * Flag to tell that we need to add the doctype decl, 
         * which we can't do until the first element is 
         * encountered.
         */
        bool            m_needToOutputDocTypeDecl;
    
        /**
         * Tell if the next text should be raw.
         */
        bool            m_nextIsRaw;
  
        /**
         * The System ID for the doc type.
         */
        const XalanDOMString    m_doctypeSystem;
  
        /**
         * The public ID for the doc type.
         */
        const XalanDOMString    m_doctypePublic;
  
  private:
  
        // These are not implemented.
        FormatterToXML_UTF16(const FormatterToXML_UTF16&);
  
        FormatterToXML_UTF16&
        operator=(const FormatterToXML_UTF16&);
  
        bool
        operator==(const FormatterToXML_UTF16&) const;
  
        void
        write(
                        const XalanDOMChar*             theChars,
                        size_type                               theLength);
  
        void
        writeName(const XalanDOMChar*   theChars);
  
        void
        write(const XalanDOMChar*       theChars)
        {
                write(theChars, XalanDOMString::length(theChars));
        }
  
        void
        write(XalanDOMChar      theChar)
        {
                write(&theChar, 1);
        }
  
        void
        write(const XalanDOMString&             theChars)
        {
                write(theChars.c_str(), theChars.length());
        }
  
        /**
         * Output the doc type declaration.
         *
         * @param name the name of the doctype.
         */
        void
        outputDocTypeDecl(const XalanDOMChar*   name);
  
        /**
         * Process an attribute.
         * @param name The name of the attribute.
         * @param value The value of the attribute.
         */
        void
        processAttribute(
                        const XalanDOMChar*             name,
                        const XalanDOMChar*             value);
  
        /**
         * Normalize the data in a PI, to replace any
         * "?>" pairs with "? >"
         * @param theData the data to normalize.
         */
        void
        writeNormalizedPIData(
                        const XalanDOMChar*                     theData,
                        XalanDOMString::size_type       theLength);
  
        void
        flushBuffer();
  
        // Data members...
        /**
         * Add space before '/>' for XHTML.
         */
        bool            m_spaceBeforeClose;
  
        /**
         * Tells the XML version, for writing out to the XML decl.
         */
        const XalanDOMString    m_version;
  
        /**
         * Text for standalone part of header.
         */
        const XalanDOMString    m_standalone;
  
        /**
         * The media type.  Not used right now.
         */
        const XalanDOMString    m_mediaType;
  
        typedef XalanDOMString::size_type       size_type;
  
        /**
         * The string "UTF-16".
         */
        static const XalanDOMString&    s_utf16String;
  
        /**
         * The string "<!DOCTYPE ".
         */
        static const XalanDOMChar       s_doctypeHeaderStartString[];
  
        static const size_type          s_doctypeHeaderStartStringLength;
  
        /**
         * The string " PUBLIC \"".
         */
        static const XalanDOMChar       s_doctypeHeaderPublicString[];
  
        static const size_type          s_doctypeHeaderPublicStringLength;
  
        /**
         * The string " SYSTEM \"".
         */
        static const XalanDOMChar       s_doctypeHeaderSystemString[];
  
        static const size_type          s_doctypeHeaderSystemStringLength;
  
        /**
         * The string "<?xml version=\"".
         */
        static const XalanDOMChar       s_xmlHeaderStartString[];
  
        static const size_type          s_xmlHeaderStartStringLength;
  
        /**
         * The string "\" encoding=\"".
         */
        static const XalanDOMChar       s_xmlHeaderEncodingString[];
  
        static const size_type          s_xmlHeaderEncodingStringLength;
  
        /**
         * The string "\" standalone=\"".
         */
        static const XalanDOMChar       s_xmlHeaderStandaloneString[];
  
        static const size_type          s_xmlHeaderStandaloneStringLength;
  
        /**
         * The string "\"?>".
         */
        static const XalanDOMChar       s_xmlHeaderEndString[];
  
        static const size_type          s_xmlHeaderEndStringLength;
  
        /**
         * The string "1.0".
         */
        static const XalanDOMChar       s_defaultVersionString[];
  
        static const size_type          s_defaultVersionStringLength;
  
        /**
         * The string "-//W3C//DTD XHTML".
         */
        static const XalanDOMChar       s_xhtmlDocTypeString[];
  
        static const size_type          s_xhtmlDocTypeStringLength;
  
        /**
         * The string "<![CDATA[".
         */
        static const XalanDOMChar       s_cdataOpenString[];
  
        static const size_type          s_cdataOpenStringLength;
  
        /**
         * The string "]]>".
         */
        static const XalanDOMChar       s_cdataCloseString[];
  
        static const size_type          s_cdataCloseStringLength;
  
        /**
         * The string "&lt;".
         */
        static const XalanDOMChar       s_lessThanEntityString[];
  
        static const size_type          s_lessThanEntityStringLength;
  
        /**
         * The string "&gt;".
         */
        static const XalanDOMChar       s_greaterThanEntityString[];
  
        static const size_type          s_greaterThanEntityStringLength;
  
        /**
         * The string "&amp;".
         */
        static const XalanDOMChar       s_ampersandEntityString[];
  
        static const size_type          s_ampersandEntityStringLength;
  
        /**
         * The string "&quot;".
         */
        static const XalanDOMChar       s_quoteEntityString[];
  
        static const size_type          s_quoteEntityStringLength;
  
        /**
         * The string "&#10;".
         */
        static const XalanDOMChar       s_linefeedNCRString[];
  
        static const size_type          s_linefeedNCRStringLength;
  
        /**
         * A stack of Boolean objects that tell if the given element 
         * has children.
         */
        BoolStackType   m_elemStack;
  
        /**
         * The string of characters that represents the newline
         */
        const XalanDOMChar*                     m_newlineString;
  
        /**
         * The length of the the string of characters that represents the newline
         */
        XalanDOMString::size_type       m_newlineStringLength;
  
  
        enum
        {
                        kNotSpecial = 0,
                        kContentSpecial = 1,    // A flag to indicate a value in 
s_specialChars applies to content
                        kAttributeSpecial = 2,  // A flag to indicate a value in 
s_specialChars applies to attributes
                        kBothSpecial = 3,               // A flag t0 indicate a value 
in s_specialChars applies to both content and attributes
                        kSpecialsSize = 0x80,   // The size of s_specialChars
                        kBufferSize = 512,              // The size of the buffer
        };
  
        static bool
        isContentSpecial(XalanDOMChar   theChar)
        {
                if ((theChar < kSpecialsSize) || (s_specialChars[theChar] & 
kContentSpecial))
                {
                        return true;
                }
                else
                {
                        return false;
                }
        }
  
        static bool
        isAttributeSpecial(XalanDOMChar         theChar)
        {
                if ((theChar < kSpecialsSize) && (s_specialChars[theChar] & 
kAttributeSpecial))
                {
                        return true;
                }
                else
                {
                        return false;
                }
        }
  
        static bool
        isUTF16HighSurrogate(XalanDOMChar       theChar)
        {
                return 0xD800u <= theChar && theChar <= 0xDBFFu ? true : false;
        }
  
        static bool
        isUTF16LowSurrogate(XalanDOMChar        theChar)
        {
                return 0xDC00u <= theChar && theChar <= 0xDFFFu ? true : false;
        }
  
        XalanDOMChar                            m_buffer[kBufferSize];
  
        XalanDOMChar*                           m_bufferPosition;
  
        size_type                                       m_bufferRemaining;
  
        static const XalanDOMChar       s_specialChars[];
  };
  
  
  
  XALAN_CPP_NAMESPACE_END
  
  
  
  #endif        // FORMATTERTOXML_UTF16_HEADER_GUARD_1357924680
  
  
  
  1.1                  xml-xalan/c/src/xalanc/XMLSupport/FormatterToXML_UTF8.cpp
  
  Index: FormatterToXML_UTF8.cpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *      notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *      notice, this list of conditions and the following disclaimer in
   *      the documentation and/or other materials provided with the
   *      distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *      if any, must include the following acknowledgment:  
   *             "This product includes software developed by the
   *              Apache Software Foundation (http://www.apache.org/)."
   *      Alternately, this acknowledgment may appear in the software itself,
   *      if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" and "Apache Software Foundation" must
   *      not be used to endorse or promote products derived from this
   *      software without prior written permission. For written 
   *      permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *      nor may "Apache" appear in their name, without prior written
   *      permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.        IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  
  // Class header file.
  #include "FormatterToXML_UTF8.hpp"
  
  
  
  #include <xercesc/sax/AttributeList.hpp>
  #include <xercesc/sax/SAXException.hpp>
  
  
  
  #include <xalanc/PlatformSupport/DOMStringHelper.hpp>
  #include <xalanc/PlatformSupport/DoubleSupport.hpp>
  #include <xalanc/PlatformSupport/Writer.hpp>
  #include <xalanc/PlatformSupport/XalanOutputStream.hpp>
  #include <xalanc/PlatformSupport/XalanTranscodingServices.hpp>
  #include <xalanc/PlatformSupport/XalanUnicode.hpp>
  
  
  
  #include <xalanc/DOMSupport/DOMServices.hpp>
  
  
  
  XALAN_CPP_NAMESPACE_BEGIN
  
  
  
  const XalanDOMChar    FormatterToXML_UTF8::s_specialChars[kSpecialsSize] =
  {
        kNotSpecial,            // 0
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kBothSpecial,           // 0xA -- linefeed  Special because we normalize as 
requested.
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,            // 0x10
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,            // 0x20
        kNotSpecial,
        kAttributeSpecial,      // 0x22 '"'
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kBothSpecial,           // 0x26 -- '&'
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,            // 0x30
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kNotSpecial,
        kBothSpecial,           // 0x3C '<'
        kNotSpecial,
        kBothSpecial            // 0x3E '>'
  };
  
  
  
  FormatterToXML_UTF8::FormatterToXML_UTF8(
                        Writer&                                 writer,
                        const XalanDOMString&   version,
                        const XalanDOMString&   mediaType,
                        const XalanDOMString&   doctypeSystem,
                        const XalanDOMString&   doctypePublic,
                        bool                                    xmlDecl,
                        const XalanDOMString&   standalone) :
        FormatterListener(OUTPUT_METHOD_XML),
        m_writer(&writer),
        m_shouldWriteXMLHeader(xmlDecl),
        m_needToOutputDocTypeDecl(true),
        m_nextIsRaw(false),
        m_doctypeSystem(doctypeSystem),
        m_doctypePublic(doctypePublic),
        m_spaceBeforeClose(false),
        m_version(version),
        m_standalone(standalone),
        m_mediaType(mediaType),
        m_elemStack(),
        m_newlineString(0),
        m_newlineStringLength(0),
        m_nameFunction(0),
        m_buffer(),
        m_bufferPosition(m_buffer),
        m_bufferRemaining(kBufferSize)
  {
        if(isEmpty(m_doctypePublic) == false)
        {
                if(startsWith(
                        m_doctypePublic,
                        s_xhtmlDocTypeString) == true)
                {
                        m_spaceBeforeClose = true;
                }
        }
  
        const XalanOutputStream* const  theStream = writer.getStream();
  
        if (theStream == 0)
        {
                m_newlineString = XalanOutputStream::defaultNewlineString();
        }
        else
        {
                m_newlineString = theStream->getNewlineString();
        }
  
        assert(m_newlineString != 0);
  
        m_newlineStringLength = length(m_newlineString);
  
        assert(m_newlineString != 0);
  
        if (m_version.empty() == true ||
                DoubleSupport::equal(DOMStringToDouble(m_version), 1.0) == true)
        {
                m_nameFunction = &FormatterToXML_UTF8::writeName1_0;
        }
        else
        {
                m_nameFunction = &FormatterToXML_UTF8::writeName1_1;
        }
  }
  
  
  
  FormatterToXML_UTF8::~FormatterToXML_UTF8()
  {
  }
  
  
  
  inline void
  FormatterToXML_UTF8::flushBuffer()
  {
        m_writer->write(m_buffer, 0, m_bufferPosition - m_buffer);
  
        m_bufferPosition = m_buffer;
        m_bufferRemaining = kBufferSize;
  }
  
  
  
  inline void
  FormatterToXML_UTF8::write(char               theChar)
  {
        assert(theChar < 128);
  
        if (m_bufferRemaining == 0)
        {
                flushBuffer();
        }
  
        *m_bufferPosition = theChar;
  
        ++m_bufferPosition;
        --m_bufferRemaining;
  }
  
  
  
  inline char
  bits19to21(unsigned int       theChar)
  {
        return char((theChar >> 18) & 0x7);
  }
  
  
  
  inline char
  bits13to18(unsigned int       theChar)
  {
        return char((theChar >> 12) & 0x1F);
  }
  
  
  
  inline char
  bits13to16(unsigned int       theChar)
  {
        return char((theChar >> 12) & 0xF);
  }
  
  
  
  inline char
  bits7to12(unsigned int        theChar)
  {
        return char((theChar >> 6) & 0x3f);
  }
  
  
  
  inline char
  bits7to11(unsigned int        theChar)
  {
        return char((theChar >> 6) & 0x1f);
  }
  
  
  
  inline char
  bits1to6(unsigned int theChar)
  {
        return char(theChar & 0x3f);
  }
  
  
  
  inline char
  leadingByteOf2(char           theBits)
  {
        return char(0xC0 + theBits);
  }
  
  
  
  inline char
  leadingByteOf3(char           theBits)
  {
        return char(0xE0 + theBits);
  }
  
  
  
  inline char
  leadingByteOf4(char           theBits)
  {
        return char(0xF0 + theBits);
  }
  
  
  
  inline char
  trailingByte(char     theBits)
  {
        return char(0x80 + theBits);
  }
  
  
  
  void
  FormatterToXML_UTF8::write(unsigned int               theChar)
  {
        if (theChar <= 0x7F)
        {
                write(char(theChar));
        }
        else if (theChar <= 0x7FF)
        {
                if (m_bufferRemaining < 2)
                {
                        flushBuffer();
                }
  
                *m_bufferPosition = leadingByteOf2(bits7to11(theChar));
                ++m_bufferPosition;
                *m_bufferPosition = trailingByte(bits1to6(theChar));
                ++m_bufferPosition;
  
                m_bufferRemaining -= 2;
        }
        else if (theChar <= 0xFFFF)
        {
                // We should never get a high or low surrogate here...
                assert(theChar < 0xD800 || theChar > 0xDBFF);
                assert(theChar < 0xDC00 || theChar > 0xDFFF);
  
                if (m_bufferRemaining < 3)
                {
                        flushBuffer();
                }
  
                *m_bufferPosition = leadingByteOf3(bits13to16(theChar));
                ++m_bufferPosition;
                *m_bufferPosition = trailingByte(bits7to12(theChar));
                ++m_bufferPosition;
                *m_bufferPosition = trailingByte(bits1to6(theChar));
                ++m_bufferPosition;
  
                m_bufferRemaining -= 3;
        }
        else if (theChar <= 0x10FFFF)
        {
                if (m_bufferRemaining < 4)
                {
                        flushBuffer();
                }
  
                *m_bufferPosition = leadingByteOf4(bits19to21(theChar));
                ++m_bufferPosition;
                *m_bufferPosition = trailingByte(bits13to18(theChar));
                ++m_bufferPosition;
                *m_bufferPosition = trailingByte(bits7to12(theChar));
                ++m_bufferPosition;
                *m_bufferPosition = trailingByte(bits1to6(theChar));
                ++m_bufferPosition;
  
                m_bufferRemaining -= 4;
        }
        else
        {
                XALAN_USING_XERCES(SAXException)
  
                const XalanDOMString    theMessage(TranscodeFromLocalCodePage("Invalid 
character detected: ") +
                                                                                   
UnsignedLongToHexDOMString(theChar));
  
                throw SAXException(c_wstr(theMessage));
        }
  }
  
  
  
  inline void
  FormatterToXML_UTF8::safeWriteContent(
                        const XalanDOMChar*             theChars,
                        size_type                               theLength)
  {
        for(size_type i = 0; i < theLength; ++i)
        {
                assert(isContentSpecial(theChars[i]) == false);
  
                write(char(theChars[i]));
        }
  }
  
  
  
  inline void
  FormatterToXML_UTF8::write(
                        const XalanDOMChar*             theChars,
                        size_type                               theLength)
  {
        for(size_type i = 0; i < theLength; ++i)
        {
                write(theChars[i]);
        }
  }
  
  
  
  inline unsigned int
  FormatterToXML_UTF8::decodeUTF16SurrogatePair(
                        XalanDOMChar    theHighSurrogate,
                        XalanDOMChar    theLowSurrogate)
  {
        assert(isUTF16HighSurrogate(theHighSurrogate) == true);
  
        if (isUTF16LowSurrogate(theLowSurrogate) == false)
        {
                throwInvalidUTF16SurrogateException(theHighSurrogate, theLowSurrogate);
        }
  
        return ((theHighSurrogate - 0xD800u) << 10) + theLowSurrogate - 0xDC00u + 
0x00010000u;
  }
  
  
  
  void
  FormatterToXML_UTF8::writeName1_0(const XalanDOMChar* theChars)
  {
        for(const XalanDOMChar* currentChar = theChars; *currentChar; ++currentChar)
        {
                assert(isUTF16HighSurrogate(*currentChar) == false);
  
                write(*currentChar);
        }
  }
  
  
  
  void
  FormatterToXML_UTF8::writeName1_1(const XalanDOMChar* theChars)
  {
        const XalanDOMChar*             currentChar = theChars;
        const XalanDOMChar*             firstChar = theChars;
  
        while(*currentChar)
        {
                if (isUTF16HighSurrogate(*currentChar) == false)
                {
                        ++currentChar;
                }
                else
                {
                        write(firstChar, currentChar - firstChar);
  
                        const XalanDOMChar      high = *currentChar;
                        const XalanDOMChar      low = *(++currentChar);
  
                        write(decodeUTF16SurrogatePair(high, low));
  
                        ++currentChar;
  
                        firstChar = currentChar;
                }
        }
  
        write(firstChar, currentChar - firstChar);
  }
  
  
  
  inline void
  FormatterToXML_UTF8::write(
                        const char*             theChars,
                        size_type               theLength)
  {
  #if defined(NDEBUG)
        if (theLength > sizeof(m_buffer))
        {
                flushBuffer();
  
                m_writer->write(theChars, 0, theLength);
        }
        else
        {
                if (m_bufferRemaining < theLength)
                {
                        flushBuffer();
                }
  
                for(size_type i = 0; i < theLength; ++i)
                {
                        *m_bufferPosition = theChars[i];
  
                        ++m_bufferPosition;
                }
  
                m_bufferRemaining -= theLength;
        }
  #else
        for(size_type i = 0; i < theLength; ++i)
        {
                write(theChars[i]);
        }
  #endif
  }
  
  
  
  void
  FormatterToXML_UTF8::outputDocTypeDecl(const XalanDOMChar*    name)
  {
        // "<!DOCTYPE "
        write(s_doctypeHeaderStartString, s_doctypeHeaderStartStringLength);
  
        write(name);
  
        if(length(m_doctypePublic) != 0)
        {
                // " PUBLIC \""
                write(s_doctypeHeaderPublicString, s_doctypeHeaderPublicStringLength);
                writeName(m_doctypePublic.c_str());
                write(char(XalanUnicode::charQuoteMark));
                write(char(XalanUnicode::charSpace));
                write(char(XalanUnicode::charQuoteMark));
        }
        else
        {
                // " SYSTEM \""
                write(s_doctypeHeaderSystemString, s_doctypeHeaderSystemStringLength);
        }
  
        writeName(m_doctypeSystem.c_str());
        write(char(XalanUnicode::charQuoteMark));
        write(char(XalanUnicode::charGreaterThanSign));
  
        outputLineSep();
  }
  
  
  
  XALAN_USING_XERCES(SAXException)
  
  void
  FormatterToXML_UTF8::throwInvalidUTF16SurrogateException(XalanDOMChar ch)
  {
        const XalanDOMString    theMessage(TranscodeFromLocalCodePage("Invalid UTF-16 
surrogate detected: ") +
                                                                           
UnsignedLongToHexDOMString(ch) +
                                                                           
TranscodeFromLocalCodePage(" ?"));
  
        throw SAXException(c_wstr(theMessage));
  }
  
  
  
  void
  FormatterToXML_UTF8::throwInvalidUTF16SurrogateException(
                        XalanDOMChar    ch,
                        XalanDOMChar    next)
  {
        const XalanDOMString    theMessage(TranscodeFromLocalCodePage("Invalid UTF-16 
surrogate detected: ") +
                                                                           
UnsignedLongToHexDOMString(ch) +
                                                                           
UnsignedLongToHexDOMString(next) +
                                                                           
TranscodeFromLocalCodePage(" ?"));
  
        throw SAXException(c_wstr(theMessage));
  }
  
  
  
  bool
  FormatterToXML_UTF8::writeDefaultEntity(XalanDOMChar  ch)
  {
        if (XalanUnicode::charLessThanSign == ch)
        {
                write(s_lessThanEntityString, s_lessThanEntityStringLength);
        }
        else if (XalanUnicode::charGreaterThanSign == ch)
        {
                write(s_greaterThanEntityString, s_greaterThanEntityStringLength);
        }
        else if (XalanUnicode::charAmpersand == ch)
        {
                write(s_ampersandEntityString, s_ampersandEntityStringLength);
        }
        else
        {
                return false;
        }
  
        return true;
  }
  
  
  
  
  
  
  XalanDOMString::size_type
  FormatterToXML_UTF8::writeDefaultEscape(
                        XalanDOMChar                            ch,
                        XalanDOMString::size_type       i,
                        const XalanDOMChar                      chars[],
                        XalanDOMString::size_type       len)
  {
        if(!writeDefaultEntity(ch))
        {
                i = writeNormalizedChar(ch, chars, i, len);
        }
  
        return i;
  }
  
  
  
  bool
  FormatterToXML_UTF8::writeDefaultAttributeEntity(XalanDOMChar ch)
  {
        if (writeDefaultEntity(ch) == true)
        {
                return true;
        }
        else if (XalanUnicode::charLF == ch) 
        {
                write(s_linefeedNCRString, s_linefeedNCRStringLength);
        }
        else if (XalanUnicode::charQuoteMark == ch) 
        {
                write(s_quoteEntityString, s_quoteEntityStringLength);
        }
        else
        {
                return false;
        }
  
        return true;
  }
  
  
  
  XalanDOMString::size_type
  FormatterToXML_UTF8::writeDefaultAttributeEscape(
                        XalanDOMChar                            ch,
                        XalanDOMString::size_type       i,
                        const XalanDOMChar                      chars[],
                        XalanDOMString::size_type       len)
  {
        if(!writeDefaultAttributeEntity(ch))
        {
                i = writeNormalizedChar(ch, chars, i, len);
        }
  
        return i;
  }
  
  
  
  void
  FormatterToXML_UTF8::flushWriter()
  {
        m_writer->flush();
  }
  
  
  
  void
  FormatterToXML_UTF8::setDocumentLocator(const LocatorType* const      /* locator */)
  {
  }
  
  
  
  void
  FormatterToXML_UTF8::startDocument()
  {
        m_needToOutputDocTypeDecl = true;
  
        if(m_shouldWriteXMLHeader == true)
        {
                // "<?xml version=\""
                write(s_xmlHeaderStartString, s_xmlHeaderStartStringLength);
  
                if (length(m_version) != 0)
                {
                        write(m_version);
                }
                else
                {
                        write(s_defaultVersionString, s_defaultVersionStringLength);
                }
  
                // "\" encoding=\""
                write(s_xmlHeaderEncodingString, s_xmlHeaderEncodingStringLength);
  
                write(s_utf8String);
  
                if (length(m_standalone) != 0)
                {
                        write(s_xmlHeaderStandaloneString, 
s_xmlHeaderStandaloneStringLength);
                        write(m_standalone);
                }
  
                write(s_xmlHeaderEndString, s_xmlHeaderEndStringLength);
  
                outputLineSep();
        }
  }
  
  
  
  void
  FormatterToXML_UTF8::endDocument()
  {
        flushBuffer();
  }
  
  
  
  void
  FormatterToXML_UTF8::startElement(
                        const XMLCh* const      name,
                        AttributeListType&      attrs)
  {
        if(true == m_needToOutputDocTypeDecl &&
           isEmpty(m_doctypeSystem) == false)
        {
                outputDocTypeDecl(name);
  
                m_needToOutputDocTypeDecl = false;
        }
  
        writeParentTagEnd();
  
        write(char(XalanUnicode::charLessThanSign));
        writeName(name);
  
        const unsigned int      nAttrs = attrs.getLength();
  
        for (unsigned int i = 0;  i < nAttrs ;  i++)
        {
                processAttribute(attrs.getName(i), attrs.getValue(i));
        }
  
        // Flag the current element as not yet having any children.
        openElementForChildren();
  }
  
  
  
  void
  FormatterToXML_UTF8::endElement(const XMLCh* const    name)
  {
        const bool      hasChildNodes = childNodesWereAdded();
  
        if (hasChildNodes == true) 
        {
                write(char(XalanUnicode::charLessThanSign));
                write(char(XalanUnicode::charSolidus));
                writeName(name);
        }
        else
        {
                if(m_spaceBeforeClose == true)
                {
                        write(char(XalanUnicode::charSpace));
                }
  
                write(char(XalanUnicode::charSolidus));
        }
  
        write(char(XalanUnicode::charGreaterThanSign));
  }
  
  
  
  void
  FormatterToXML_UTF8::processingInstruction(
                        const XMLCh* const      target,
                        const XMLCh* const      data)
  {
        // Use a fairly nasty hack to tell if the next node is supposed to be 
        // unescaped text.
        if(equals(target, length(target), s_piTarget, s_piTargetLength) == true &&
           equals(data, length(data), s_piData, s_piDataLength) == true)
        {
                m_nextIsRaw = true;
        }
        else    
        {
                writeParentTagEnd();
  
                write(char(XalanUnicode::charLessThanSign));
                write(char(XalanUnicode::charQuestionMark));
                writeName(target);
  
                const XalanDOMString::size_type         len = length(data);
  
                if ( len > 0 && !isXMLWhitespace(data[0]))
                {
                        write(char(XalanUnicode::charSpace));
                }
  
                writeNormalizedPIData(data, len);
  
                write(char(XalanUnicode::charQuestionMark));
                write(char(XalanUnicode::charGreaterThanSign));
  
                // If outside of an element, then put in a new line.  This whitespace
                // is not significant.
                if (m_elemStack.empty() == true)
                {
                        outputLineSep();
                }
        }
  }
  
  
  
  void
  FormatterToXML_UTF8::characters(
                        const XMLCh* const      chars,
                        const unsigned int      length)
  {
        if(length != 0)
        {
                if(m_nextIsRaw)
                {
                        m_nextIsRaw = false;
  
                        charactersRaw(chars, length);
                }
                else
                {
                        writeParentTagEnd();
  
                        unsigned int    i = 0;
                        unsigned int    firstIndex = 0;
  
                        while(i < length) 
                        {
                                const XalanDOMChar      ch = chars[i];
  
                                if (isContentSpecial(ch) == false)
                                {
                                        ++i;
                                }
                                else
                                {
                                        safeWriteContent(chars + firstIndex, i - 
firstIndex);
  
                                        i = writeDefaultEscape(chars[i], i, chars, 
length);
  
                                        ++i;
  
                                        firstIndex = i;
                                }
                        }
  
                        safeWriteContent(chars + firstIndex, i - firstIndex);
                }
        }
  }
  
  
  
  void
  FormatterToXML_UTF8::charactersRaw(
                const XMLCh* const      chars,
                const unsigned int      length)
  {
        writeParentTagEnd();
  
        write(chars, length);
  }
  
  
  
  Writer*
  FormatterToXML_UTF8::getWriter() const
  {
        return m_writer;
  }
  
  
  
  const XalanDOMString&
  FormatterToXML_UTF8::getDoctypeSystem() const
  {
        return m_doctypeSystem;
  }
  
  
  
  const XalanDOMString&
  FormatterToXML_UTF8::getDoctypePublic() const
  {
        return m_doctypePublic;
  }
  
  
  
  const XalanDOMString&
  FormatterToXML_UTF8::getEncoding() const
  {
        return s_utf8String;
  }
  
  
  
  const XalanDOMString&
  FormatterToXML_UTF8::getMediaType() const
  {
        return m_mediaType;
  }
  
  
  
  void
  FormatterToXML_UTF8::writeAttrString(
                        const XalanDOMChar*                     theString,
                        XalanDOMString::size_type       theStringLength)
  {
        assert(theString != 0);
  
        XalanDOMString::size_type       i = 0;
        XalanDOMString::size_type       firstIndex = 0;
  
      while(i < theStringLength)
      {
                const XalanDOMChar      ch = theString[i];
  
                if (isAttributeSpecial(ch) == false)
                {
                        ++i;
                }
                else
                {
                        safeWriteContent(theString + firstIndex, i - firstIndex);
  
                        i = writeDefaultAttributeEscape(ch, i, theString, 
theStringLength);
  
                        ++i;
  
                        firstIndex = i;
                }
      }
  
        safeWriteContent(theString + firstIndex, i - firstIndex);
  }
  
  
  
  void
  FormatterToXML_UTF8::writeCommentData(const XalanDOMChar*     data)
  {
        const XalanDOMString::size_type         len = length(data);
        XalanDOMChar                                            previousChar = 0;
  
        for (XalanDOMString::size_type i = 0; i < len; ++i)
        {
                const XalanDOMChar      currentChar = data[i];
  
                if (currentChar == XalanUnicode::charHyphenMinus &&
                        previousChar == XalanUnicode::charHyphenMinus)
                {
                        write(char(XalanUnicode::charSpace));
                }
  
                write(currentChar);
  
                previousChar = currentChar;
        }
                
        if (previousChar == XalanUnicode::charHyphenMinus)
        {
                write(char(XalanUnicode::charSpace));
        }
  }
  
  
  
  FormatterToXML_UTF8::size_type
  FormatterToXML_UTF8::writeNormalizedChar(
                        XalanDOMChar                            ch,
                        const XalanDOMChar                      chars[],
                        XalanDOMString::size_type       start,
                        XalanDOMString::size_type       length)
  {
        if (XalanUnicode::charLF == ch)
        {
                outputLineSep();
        }
        else if (isUTF16HighSurrogate(ch) == true)
        {
                if (start + 1 >= length)
                {
                        throwInvalidUTF16SurrogateException(ch);
                }
                else 
                {
                        write(decodeUTF16SurrogatePair(ch, chars[++start]));
                }
        }
        else
        {
                write(ch);
        }
  
        return start;
  }
  
  
  
  void
  FormatterToXML_UTF8::writeCDATAChars(
                        const XalanDOMChar                      ch[],
                        XalanDOMString::size_type       length)
  {
        XalanDOMString::size_type i = 0;
  
        while(i < length)
      {
                // If "]]>", which would close the CDATA appears in
                // the content, we have to put the first two characters
                // in the CDATA section, close the CDATA section, then
                // open a new one and add the last character.
                if (i < length - 2 &&
                        XalanUnicode::charRightSquareBracket == ch[i] &&
              XalanUnicode::charRightSquareBracket == ch[i + 1] &&
                        XalanUnicode::charGreaterThanSign == ch[ i + 2])
                {
                        // "]]]]><![CDATA[>"
                        write(char(XalanUnicode::charRightSquareBracket));
                        write(char(XalanUnicode::charRightSquareBracket));
  
                        write(s_cdataCloseString, s_cdataCloseStringLength);
                        write(s_cdataOpenString, s_cdataOpenStringLength);
  
                        write(char(XalanUnicode::charGreaterThanSign));
  
                        i += 3;
                }
                else
                {
                        i = writeNormalizedChar(ch[i], ch, i, length);
  
                        ++i;
                }
      }
  }
  
  
  
  void
  FormatterToXML_UTF8::entityReference(const XMLCh* const       name)
  {
        writeParentTagEnd();
          
        write(char(XalanUnicode::charAmpersand));
        writeName(name);
        write(char(XalanUnicode::charSemicolon));
  }
  
  
  
  void
  FormatterToXML_UTF8::ignorableWhitespace(
                        const XMLCh* const      chars,
                        const unsigned int      length)
  {
        if (length > 0)
        {
                characters(chars, length);
        }
  }
  
  
  
  void
  FormatterToXML_UTF8::resetDocument()
  {
        // I don't do anything with this yet.
  }
  
  
  
  void
  FormatterToXML_UTF8::comment(const XMLCh* const       data)
  {
        writeParentTagEnd();
  
        write(char(XalanUnicode::charLessThanSign));
        write(char(XalanUnicode::charExclamationMark));
        write(char(XalanUnicode::charHyphenMinus));
        write(char(XalanUnicode::charHyphenMinus));
  
        writeCommentData(data);
  
        write(char(XalanUnicode::charHyphenMinus));
        write(char(XalanUnicode::charHyphenMinus));
        write(char(XalanUnicode::charGreaterThanSign));
  }
  
  
  
  void
  FormatterToXML_UTF8::cdata(
                        const XMLCh* const      ch,
                        const unsigned int      length)
  {
        if(m_nextIsRaw == true)
        {
                m_nextIsRaw = false;
  
                charactersRaw(ch, length);
        }
        else
        {
                writeParentTagEnd();
  
                if(length > 0)
                {
                        write(s_cdataOpenString, s_cdataOpenStringLength);
  
                        writeCDATAChars(ch, length);
  
                        write(s_cdataCloseString, s_cdataCloseStringLength);
                }
        }
  }
  
  
  
  void
  FormatterToXML_UTF8::writeParentTagEnd()
  {
        if(!m_elemStack.empty())
        {
                // See if the parent element has already been flagged as having 
children.
                if(false == m_elemStack.back())
                {
                        write(char(XalanUnicode::charGreaterThanSign));
  
                        m_elemStack.back() = true;
                }
        }
  }
  
  
  
  void
  FormatterToXML_UTF8::openElementForChildren()
  {
        m_elemStack.push_back(false);
  }
  
  
  
  bool
  FormatterToXML_UTF8::childNodesWereAdded()
  {
        bool    fResult = false;
  
        if (m_elemStack.empty() == false)
        {
                fResult = m_elemStack.back();
  
                m_elemStack.pop_back();
        }
  
        return fResult;
  }
  
  
  
  void
  FormatterToXML_UTF8::processAttribute(
                        const XalanDOMChar*     name,
                        const XalanDOMChar*     value)
  {
        // We add a fake attribute to the source tree to
        // declare the xml prefix, so we filter it back out
        // here...
        // $$$ ToDo: It would be better if we didn't have to do
        // this here.
        if (equals(name, DOMServices::s_XMLNamespacePrefix) == false)
        {
                write(char(XalanUnicode::charSpace));
                writeName(name);
                write(char(XalanUnicode::charEqualsSign));
                write(char(XalanUnicode::charQuoteMark));
                writeAttrString(value, length(value));
                write(char(XalanUnicode::charQuoteMark));
        }
  }
  
  
  
  void
  FormatterToXML_UTF8::outputLineSep()
  {
        assert(m_newlineString != 0 && length(m_newlineString) == 
m_newlineStringLength);
  
        write(m_newlineString, m_newlineStringLength);
  }
  
  
  
  void
  FormatterToXML_UTF8::writeNormalizedPIData(
                        const XalanDOMChar*                     theData,
                        XalanDOMString::size_type       theLength)
  {
        // If there are any "?>" pairs in the string,
        // we have to normalize them to "? >", so they
        // won't be confused with the end tag.
  
        for (XalanDOMString::size_type i = 0; i < theLength; ++i)
        {
                const XalanDOMChar      theChar = theData[i];
  
                if (theChar == XalanUnicode::charQuestionMark &&
                        i + 1 < theLength &&
                        theData[i + 1] == XalanUnicode::charGreaterThanSign)
                {
                        write(char(XalanUnicode::charQuestionMark));
                        write(char(XalanUnicode::charSpace));
                }
                else
                {
                        write(theChar);
                }
        }
  }
  
  
  
  static XalanDOMString s_localUTF8String;
  
  
  
  const XalanDOMString& FormatterToXML_UTF8::s_utf8String = s_localUTF8String;
  
  
  
  void
  FormatterToXML_UTF8::initialize()
  {
        s_localUTF8String = XalanTranscodingServices::s_utf8String;
  }
  
  
  
  void
  FormatterToXML_UTF8::terminate()
  {
        XalanDOMString().swap(s_localUTF8String);
  }
  
  
  
  #define FXML_SIZE(str)        ((sizeof(str) / sizeof(str[0]) - 1))
  
  const char    FormatterToXML_UTF8::s_doctypeHeaderStartString[] =
  {
        char(XalanUnicode::charLessThanSign),
        char(XalanUnicode::charExclamationMark),
        char(XalanUnicode::charLetter_D),
        char(XalanUnicode::charLetter_O),
        char(XalanUnicode::charLetter_C),
        char(XalanUnicode::charLetter_T),
        char(XalanUnicode::charLetter_Y),
        char(XalanUnicode::charLetter_P),
        char(XalanUnicode::charLetter_E),
        char(XalanUnicode::charSpace),
        char(0)
  };
  
  const FormatterToXML_UTF8::size_type  
FormatterToXML_UTF8::s_doctypeHeaderStartStringLength =
                FXML_SIZE(s_doctypeHeaderStartString);
  
  const char    FormatterToXML_UTF8::s_doctypeHeaderPublicString[] =
  {
        char(XalanUnicode::charSpace),
        char(XalanUnicode::charLetter_P),
        char(XalanUnicode::charLetter_U),
        char(XalanUnicode::charLetter_B),
        char(XalanUnicode::charLetter_L),
        char(XalanUnicode::charLetter_I),
        char(XalanUnicode::charLetter_C),
        char(XalanUnicode::charSpace),
        char(XalanUnicode::charQuoteMark),
        char(0)
  };
  
  const FormatterToXML_UTF8::size_type  
FormatterToXML_UTF8::s_doctypeHeaderPublicStringLength =
                FXML_SIZE(s_doctypeHeaderPublicString);
  
  const char    FormatterToXML_UTF8::s_doctypeHeaderSystemString[] =
  {
        char(XalanUnicode::charSpace),
        char(XalanUnicode::charLetter_S),
        char(XalanUnicode::charLetter_Y),
        char(XalanUnicode::charLetter_S),
        char(XalanUnicode::charLetter_T),
        char(XalanUnicode::charLetter_E),
        char(XalanUnicode::charLetter_M),
        char(XalanUnicode::charSpace),
        char(XalanUnicode::charQuoteMark),
        char(0)
  };
  
  const FormatterToXML_UTF8::size_type          
FormatterToXML_UTF8::s_doctypeHeaderSystemStringLength =
                FXML_SIZE(s_doctypeHeaderSystemString);
  
  const char    FormatterToXML_UTF8::s_xmlHeaderStartString[] =
  {
        char(XalanUnicode::charLessThanSign),
        char(XalanUnicode::charQuestionMark),
        char(XalanUnicode::charLetter_x),
        char(XalanUnicode::charLetter_m),
        char(XalanUnicode::charLetter_l),
        char(XalanUnicode::charSpace),
        char(XalanUnicode::charLetter_v),
        char(XalanUnicode::charLetter_e),
        char(XalanUnicode::charLetter_r),
        char(XalanUnicode::charLetter_s),
        char(XalanUnicode::charLetter_i),
        char(XalanUnicode::charLetter_o),
        char(XalanUnicode::charLetter_n),
        char(XalanUnicode::charEqualsSign),
        char(XalanUnicode::charQuoteMark),
        char(0)
  };
  
  const FormatterToXML_UTF8::size_type          
FormatterToXML_UTF8::s_xmlHeaderStartStringLength =
                FXML_SIZE(s_xmlHeaderStartString);
  
  const char    FormatterToXML_UTF8::s_xmlHeaderEncodingString[] =
  {
        char(XalanUnicode::charQuoteMark),
        char(XalanUnicode::charSpace),
        char(XalanUnicode::charLetter_e),
        char(XalanUnicode::charLetter_n),
        char(XalanUnicode::charLetter_c),
        char(XalanUnicode::charLetter_o),
        char(XalanUnicode::charLetter_d),
        char(XalanUnicode::charLetter_i),
        char(XalanUnicode::charLetter_n),
        char(XalanUnicode::charLetter_g),
        char(XalanUnicode::charEqualsSign),
        char(XalanUnicode::charQuoteMark),
        char(0)
  };
  
  const FormatterToXML_UTF8::size_type          
FormatterToXML_UTF8::s_xmlHeaderEncodingStringLength =
                FXML_SIZE(s_xmlHeaderEncodingString);
  
  const char    FormatterToXML_UTF8::s_xmlHeaderStandaloneString[] =
  {
        char(XalanUnicode::charQuoteMark),
        char(XalanUnicode::charSpace),
        char(XalanUnicode::charLetter_s),
        char(XalanUnicode::charLetter_t),
        char(XalanUnicode::charLetter_a),
        char(XalanUnicode::charLetter_n),
        char(XalanUnicode::charLetter_d),
        char(XalanUnicode::charLetter_a),
        char(XalanUnicode::charLetter_l),
        char(XalanUnicode::charLetter_o),
        char(XalanUnicode::charLetter_n),
        char(XalanUnicode::charLetter_e),
        char(XalanUnicode::charEqualsSign),
        char(XalanUnicode::charQuoteMark),
        char(0)
  };
  
  const FormatterToXML_UTF8::size_type          
FormatterToXML_UTF8::s_xmlHeaderStandaloneStringLength =
                FXML_SIZE(s_xmlHeaderStandaloneString);
  
  const char    FormatterToXML_UTF8::s_xmlHeaderEndString[] =
  {
        char(XalanUnicode::charQuoteMark),
        char(XalanUnicode::charQuestionMark),
        char(XalanUnicode::charGreaterThanSign),
        char(0)
  };
  
  const FormatterToXML_UTF8::size_type          
FormatterToXML_UTF8::s_xmlHeaderEndStringLength =
                FXML_SIZE(s_xmlHeaderEndString);
  
  const char    FormatterToXML_UTF8::s_defaultVersionString[] =
  {
        char(XalanUnicode::charDigit_1),
        char(XalanUnicode::charFullStop),
        char(XalanUnicode::charDigit_0),
        char(0)
  };
  
  const FormatterToXML_UTF8::size_type          
FormatterToXML_UTF8::s_defaultVersionStringLength =
                FXML_SIZE(s_defaultVersionString);
  
  const char    FormatterToXML_UTF8::s_cdataOpenString[] =
  {
        char(XalanUnicode::charLessThanSign),
        char(XalanUnicode::charExclamationMark),
        char(XalanUnicode::charLeftSquareBracket),
        char(XalanUnicode::charLetter_C),
        char(XalanUnicode::charLetter_D),
        char(XalanUnicode::charLetter_A),
        char(XalanUnicode::charLetter_T),
        char(XalanUnicode::charLetter_A),
        char(XalanUnicode::charLeftSquareBracket),
        char(0)
  };
  
  const FormatterToXML_UTF8::size_type          
FormatterToXML_UTF8::s_cdataOpenStringLength =
                FXML_SIZE(s_cdataOpenString);
  
  const char    FormatterToXML_UTF8::s_cdataCloseString[] =
  {
        char(XalanUnicode::charRightSquareBracket),
        char(XalanUnicode::charRightSquareBracket),
        char(XalanUnicode::charGreaterThanSign),
        char(0)
  };
  
  const FormatterToXML_UTF8::size_type          
FormatterToXML_UTF8::s_cdataCloseStringLength =
                FXML_SIZE(s_cdataCloseString);
  
  
  const char    FormatterToXML_UTF8::s_xhtmlDocTypeString[] =
  {
        char(XalanUnicode::charHyphenMinus),
        char(XalanUnicode::charSolidus),
        char(XalanUnicode::charSolidus),
        char(XalanUnicode::charLetter_W),
        char(XalanUnicode::charDigit_3),
        char(XalanUnicode::charLetter_C),
        char(XalanUnicode::charSolidus),
        char(XalanUnicode::charSolidus),
        char(XalanUnicode::charLetter_D),
        char(XalanUnicode::charLetter_T),
        char(XalanUnicode::charLetter_D),
        char(XalanUnicode::charSpace),
        char(XalanUnicode::charLetter_X),
        char(XalanUnicode::charLetter_H),
        char(XalanUnicode::charLetter_T),
        char(XalanUnicode::charLetter_M),
        char(XalanUnicode::charLetter_L),
        char(0)
  };
  
  const FormatterToXML_UTF8::size_type          
FormatterToXML_UTF8::s_xhtmlDocTypeStringLength =
                FXML_SIZE(s_xhtmlDocTypeString);
  
  const char    FormatterToXML_UTF8::s_lessThanEntityString[] =
  {
        char(XalanUnicode::charAmpersand),
        char(XalanUnicode::charLetter_l),
        char(XalanUnicode::charLetter_t),
        char(XalanUnicode::charSemicolon),
        char(0)
  };
  
  const FormatterToXML_UTF8::size_type          
FormatterToXML_UTF8::s_lessThanEntityStringLength =
                FXML_SIZE(s_lessThanEntityString);
  
  const char    FormatterToXML_UTF8::s_greaterThanEntityString[] =
  {
        char(XalanUnicode::charAmpersand),
        char(XalanUnicode::charLetter_g),
        char(XalanUnicode::charLetter_t),
        char(XalanUnicode::charSemicolon),
        char(0)
  };
  
  const FormatterToXML_UTF8::size_type          
FormatterToXML_UTF8::s_greaterThanEntityStringLength =
                FXML_SIZE(s_greaterThanEntityString);
  
  const char    FormatterToXML_UTF8::s_ampersandEntityString[] =
  {
        char(XalanUnicode::charAmpersand),
        char(XalanUnicode::charLetter_a),
        char(XalanUnicode::charLetter_m),
        char(XalanUnicode::charLetter_p),
        char(XalanUnicode::charSemicolon),
        char(0)
  };
  
  const FormatterToXML_UTF8::size_type          
FormatterToXML_UTF8::s_ampersandEntityStringLength =
                FXML_SIZE(s_ampersandEntityString);
  
  const char    FormatterToXML_UTF8::s_quoteEntityString[] =
  {
        char(XalanUnicode::charAmpersand),
        char(XalanUnicode::charLetter_q),
        char(XalanUnicode::charLetter_u),
        char(XalanUnicode::charLetter_o),
        char(XalanUnicode::charLetter_t),
        char(XalanUnicode::charSemicolon),
        char(0)
  };
  
  const FormatterToXML_UTF8::size_type          
FormatterToXML_UTF8::s_quoteEntityStringLength =
                FXML_SIZE(s_quoteEntityString);
  
  const char    FormatterToXML_UTF8::s_linefeedNCRString[] =
  {
        char(XalanUnicode::charAmpersand),
        char(XalanUnicode::charNumberSign),
        char(XalanUnicode::charDigit_1),
        char(XalanUnicode::charDigit_0),
        char(XalanUnicode::charSemicolon),
        char(0)
  };
  
  const FormatterToXML_UTF8::size_type          
FormatterToXML_UTF8::s_linefeedNCRStringLength =
                FXML_SIZE(s_linefeedNCRString);
  
  
  
  XALAN_CPP_NAMESPACE_END
  
  
  
  1.1                  xml-xalan/c/src/xalanc/XMLSupport/FormatterToXML_UTF8.hpp
  
  Index: FormatterToXML_UTF8.hpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:  
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written 
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  #if !defined(FORMATTERTOXML_UTF8_HEADER_GUARD_1357924680)
  #define FORMATTERTOXML_UTF8_HEADER_GUARD_1357924680
  
  
  
  
  // Base include file.  Must be first.
  #include <xalanc/XMLSupport/XMLSupportDefinitions.hpp>
  
  
  
  #include <vector>
  
  
  
  #include <xalanc/XalanDOM/XalanDOMString.hpp>
  
  
  
  // Base class header file.
  #include <xalanc/PlatformSupport/FormatterListener.hpp>
  
  
  
  XALAN_CPP_NAMESPACE_BEGIN
  
  
  
  class Writer;
  
  
  
  /**
   * FormatterToXML_UTF8 formats SAX-style events into XML.
   */
  class XALAN_XMLSUPPORT_EXPORT FormatterToXML_UTF8 : public FormatterListener 
  {
  public:
  
        /**
         * Perform static initialization.  See class XMLSupportInit.
         */
        static void
        initialize();
   
        /**
         * Perform static shut down.  See class XMLSupportInit.
         */
        static void
        terminate();
  
        /**
         * Constructor
         *
         * @param writer            the writer.
         * @param version           the string to write for the XML version number.
         * @param mediaType         media type (MIME content type) of the data
         * @param doctypeSystem     system identifier to be used in the document
         *                          type declaration
         * @param doctypePublic     public identifier to be used in the document
         *                          type declaration
         * @param xmlDecl           true if the XSLT processor should output an XML
         *                          declaration
         * @param standalone        The string the XSLT processor should output for
         *                          the standalone document declaration
         */
        FormatterToXML_UTF8(
                        Writer&                                 writer,
                        const XalanDOMString&   version = XalanDOMString(),
                        const XalanDOMString&   mediaType = XalanDOMString(),
                        const XalanDOMString&   doctypeSystem = XalanDOMString(),
                        const XalanDOMString&   doctypePublic = XalanDOMString(),
                        bool                                    xmlDecl = true,
                        const XalanDOMString&   standalone = XalanDOMString());
  
        virtual
        ~FormatterToXML_UTF8();
  
  
        // These methods are inherited from FormatterListener ...
  
        virtual void
        setDocumentLocator(const LocatorType* const             locator);
  
        virtual void
        startDocument();
  
        virtual void
        endDocument();
  
        virtual void
        startElement(
                        const XMLCh* const      name,
                        AttributeListType&      attrs);
  
      virtual void
        endElement(const XMLCh* const   name);
  
      virtual void
        characters(
                        const XMLCh* const      chars,
                        const unsigned int      length);
  
      virtual void
        charactersRaw(
                        const XMLCh* const      chars,
                        const unsigned int      length);
  
        virtual void
        entityReference(const XMLCh* const      name);
  
        virtual void
        ignorableWhitespace(
                        const XMLCh* const      chars,
                        const unsigned int      length);
  
        virtual void
        processingInstruction(
                        const XMLCh* const      target,
                        const XMLCh* const      data);
  
  
      virtual void
        resetDocument();
  
        virtual void
        comment(const XMLCh* const      data);
  
        virtual void
        cdata(
                        const XMLCh* const      ch,
                        const unsigned int      length);
  
        virtual Writer*
        getWriter() const;
  
        virtual const XalanDOMString&
        getDoctypeSystem() const;
  
        virtual const XalanDOMString&
        getDoctypePublic() const;
  
        virtual const XalanDOMString&
        getEncoding() const;
  
        virtual const XalanDOMString&
        getMediaType() const;
  
        const XalanDOMString&
        getVersion() const
        {
                return m_version;
        }
  
        const XalanDOMString&
        getStandalone() const
        {
                return m_standalone;
        }
  
        bool
        getShouldWriteXMLHeader() const
        {
                return m_shouldWriteXMLHeader;
        }
  
        void
        setShouldWriteXMLHeader(bool    b)
        {
                m_shouldWriteXMLHeader = b;
        }
  
  #if defined(XALAN_NO_STD_NAMESPACE)
  #if defined(XALAN_USE_DEQUE_FOR_VECTOR_BOOL)
        typedef deque<bool>                     BoolStackType;
  #else
        typedef vector<bool>            BoolStackType;
  #endif
  #else
  #if defined(XALAN_USE_DEQUE_FOR_VECTOR_BOOL)
        typedef std::deque<bool>        BoolStackType;
  #else
        typedef std::vector<bool>       BoolStackType;
  #endif
  #endif
  
  protected:
  
        /** 
         * The writer.
         */
        Writer*                                 m_writer;
  
        /**
         * Output a line break.
         */
        void
        outputLineSep();
  
        /**
         * Escape and write a character.
         */
        XalanDOMString::size_type
        writeDefaultEscape(
                        XalanDOMChar                            ch,
                        XalanDOMString::size_type       i,
                        const XalanDOMChar                      chars[],
                        XalanDOMString::size_type       len);
  
        /**
         * Escape and write a character in an attribute.
         */
        XalanDOMString::size_type
        writeDefaultAttributeEscape(
                        XalanDOMChar                            ch,
                        XalanDOMString::size_type       i,
                        const XalanDOMChar                      chars[],
                        XalanDOMString::size_type       len);
  
        /**
         * Handle one of the default entities, return false if it 
         * is not a default entity.
         */
        bool
        writeDefaultEntity(XalanDOMChar         ch);
  
        /**
         * Handle one of the default entities, return false if it 
         * is not a default entity.
         */
        bool
        writeDefaultAttributeEntity(XalanDOMChar        ch);
  
        /**
         * Write the data for a comment
         * @param data The comment's data.
         */
        void
        writeCommentData(const XalanDOMChar*    data);
  
        void
        flushWriter();
  
        void
        openElementForChildren();
  
        bool
        childNodesWereAdded();
  
        /**
         * Check to see if a parent's ">" has been written, and, if 
         * it has not, write it.
         */
        void
        writeParentTagEnd();
  
        /**
         * Write a normalized character to the stream.
         * @param ch the string to write.
         * @param start the start offset into the string.
         * @param length the length of the string.
         */
        size_type
        writeNormalizedChar(
                        XalanDOMChar                            ch,
                        const XalanDOMChar                      chars[],
                        XalanDOMString::size_type       start,
                        XalanDOMString::size_type       length);
  
        /**
         * Write characters for a CDATA section
         *
         * @param ch the string to write.
         * @param length the length of the string.
         */
        void
        writeCDATAChars(
                        const XalanDOMChar                      ch[],
                        XalanDOMString::size_type       length);
  
        /**
         * Write an attribute string.
         *
         * @param theString The string to write.
         * @param theStringLength The length of the string.
         */
        void
        writeAttrString(
                        const XalanDOMChar*                     theString,
                        XalanDOMString::size_type       theStringLength);
  
        /**
         * Throw an exception when an invalid
         * surrogate is encountered.
         * @param ch The first character in the surrogate
         */
        static void
        throwInvalidUTF16SurrogateException(XalanDOMChar        ch);
  
        /**
         * Throw an exception when an invalid
         * surrogate is encountered.
         * @param ch The first character in the surrogate
         * @param next The next character in the surrogate
         */
        static void
        throwInvalidUTF16SurrogateException(
                        XalanDOMChar    ch,
                        XalanDOMChar    next);
  
        /**
         * If true, XML header should be written to output.
         */
        bool            m_shouldWriteXMLHeader;
  
        /**
         * Flag to tell that we need to add the doctype decl, 
         * which we can't do until the first element is 
         * encountered.
         */
        bool            m_needToOutputDocTypeDecl;
    
        /**
         * Tell if the next text should be raw.
         */
        bool            m_nextIsRaw;
  
        /**
         * The System ID for the doc type.
         */
        const XalanDOMString    m_doctypeSystem;
  
        /**
         * The public ID for the doc type.
         */
        const XalanDOMString    m_doctypePublic;
  
  private:
  
        // These are not implemented.
        FormatterToXML_UTF8(const FormatterToXML_UTF8&);
  
        FormatterToXML_UTF8&
        operator=(const FormatterToXML_UTF8&);
  
        bool
        operator==(const FormatterToXML_UTF8&) const;
  
        void
        safeWriteContent(
                        const XalanDOMChar*             theChars,
                        size_type                               theLength);
  
        void
        write(
                        const XalanDOMChar*             theChars,
                        size_type                               theLength);
  
        void
        writeName1_0(const XalanDOMChar*        theChars);
  
        void
        writeName1_1(const XalanDOMChar*        theChars);
  
        void
        write(const XalanDOMChar*       theChars)
        {
                write(theChars, XalanDOMString::length(theChars));
        }
  
        void
        write(XalanDOMChar      theChar)
        {
                write((unsigned int)theChar);
        }
  
        void
        write(unsigned int      theChar);
  
        void
        write(const XalanDOMString&             theChars)
        {
                write(theChars.c_str(), theChars.length());
        }
  
        void
        write(char      theChar);
  
        void
        write(
                        const char*             theChars,
                        size_type               theLength);
  
        void
        write(const char*       theChars)
        {
                write(theChars, XalanDOMString::length(theChars));
        }
  
        /**
         * Output the doc type declaration.
         *
         * @param name the name of the doctype.
         */
        void
        outputDocTypeDecl(const XalanDOMChar*   name);
  
        /**
         * Process an attribute.
         * @param name The name of the attribute.
         * @param value The value of the attribute.
         */
        void
        processAttribute(
                        const XalanDOMChar*             name,
                        const XalanDOMChar*             value);
  
        /**
         * Normalize the data in a PI, to replace any
         * "?>" pairs with "? >"
         * @param theData the data to normalize.
         */
        void
        writeNormalizedPIData(
                        const XalanDOMChar*                     theData,
                        XalanDOMString::size_type       theLength);
  
        void
        flushBuffer();
  
        // Data members...
        /**
         * Add space before '/>' for XHTML.
         */
        bool            m_spaceBeforeClose;
  
        /**
         * Tells the XML version, for writing out to the XML decl.
         */
        const XalanDOMString    m_version;
  
        /**
         * Text for standalone part of header.
         */
        const XalanDOMString    m_standalone;
  
        /**
         * The media type.  Not used right now.
         */
        const XalanDOMString    m_mediaType;
  
        typedef XalanDOMString::size_type       size_type;
  
        /**
         * The string "UTF-8".
         */
        static const XalanDOMString&    s_utf8String;
  
        /**
         * The string "<!DOCTYPE ".
         */
        static const char               s_doctypeHeaderStartString[];
  
        static const size_type  s_doctypeHeaderStartStringLength;
  
        /**
         * The string " PUBLIC \"".
         */
        static const char               s_doctypeHeaderPublicString[];
  
        static const size_type  s_doctypeHeaderPublicStringLength;
  
        /**
         * The string " SYSTEM \"".
         */
        static const char               s_doctypeHeaderSystemString[];
  
        static const size_type  s_doctypeHeaderSystemStringLength;
  
        /**
         * The string "<?xml version=\"".
         */
        static const char               s_xmlHeaderStartString[];
  
        static const size_type  s_xmlHeaderStartStringLength;
  
        /**
         * The string "\" encoding=\"".
         */
        static const char               s_xmlHeaderEncodingString[];
  
        static const size_type  s_xmlHeaderEncodingStringLength;
  
        /**
         * The string "\" standalone=\"".
         */
        static const char               s_xmlHeaderStandaloneString[];
  
        static const size_type  s_xmlHeaderStandaloneStringLength;
  
        /**
         * The string "\"?>".
         */
        static const char               s_xmlHeaderEndString[];
  
        static const size_type  s_xmlHeaderEndStringLength;
  
        /**
         * The string "1.0".
         */
        static const char               s_defaultVersionString[];
  
        static const size_type  s_defaultVersionStringLength;
  
        /**
         * The string "-//W3C//DTD XHTML".
         */
        static const char               s_xhtmlDocTypeString[];
  
        static const size_type  s_xhtmlDocTypeStringLength;
  
        /**
         * The string "<![CDATA[".
         */
        static const char               s_cdataOpenString[];
  
        static const size_type  s_cdataOpenStringLength;
  
        /**
         * The string "]]>".
         */
        static const char               s_cdataCloseString[];
  
        static const size_type  s_cdataCloseStringLength;
  
        /**
         * The string "&lt;".
         */
        static const char               s_lessThanEntityString[];
  
        static const size_type  s_lessThanEntityStringLength;
  
        /**
         * The string "&gt;".
         */
        static const char               s_greaterThanEntityString[];
  
        static const size_type  s_greaterThanEntityStringLength;
  
        /**
         * The string "&amp;".
         */
        static const char               s_ampersandEntityString[];
  
        static const size_type  s_ampersandEntityStringLength;
  
        /**
         * The string "&quot;".
         */
        static const char               s_quoteEntityString[];
  
        static const size_type  s_quoteEntityStringLength;
  
        /**
         * The string "&#10;".
         */
        static const char               s_linefeedNCRString[];
  
        static const size_type  s_linefeedNCRStringLength;
  
        /**
         * A stack of Boolean objects that tell if the given element 
         * has children.
         */
        BoolStackType   m_elemStack;
  
        /**
         * The string of characters that represents the newline
         */
        const XalanDOMChar*                     m_newlineString;
  
        /**
         * The length of the the string of characters that represents the newline
         */
        XalanDOMString::size_type       m_newlineStringLength;
  
        typedef void (FormatterToXML_UTF8::*NameFunctionType)(const XalanDOMChar*);
  
        NameFunctionType                        m_nameFunction;
  
        void
        writeName(const XalanDOMChar*   theChars)
        {
                assert(m_nameFunction != 0);
  
                (this->*m_nameFunction)(theChars);
        }
  
        enum
        {
                        kNotSpecial = 0,
                        kContentSpecial = 1,    // A flag to indicate a value in 
s_specialChars applies to content
                        kAttributeSpecial = 2,  // A flag to indicate a value in 
s_specialChars applies to attributes
                        kBothSpecial = 3,               // A flag t0 indicate a value 
in s_specialChars applies to both content and attributes
                        kSpecialsSize = 0x80,   // The size of s_specialChars
                        kBufferSize = 512,              // The size of the buffer
        };
  
        static bool
        isContentSpecial(XalanDOMChar   theChar)
        {
                if ((theChar >= kSpecialsSize) || (s_specialChars[theChar] & 
kContentSpecial))
                {
                        return true;
                }
                else
                {
                        return false;
                }
        }
  
        static bool
        isAttributeSpecial(XalanDOMChar         theChar)
        {
                if ((theChar >= kSpecialsSize) || (s_specialChars[theChar] & 
kAttributeSpecial))
                {
                        return true;
                }
                else
                {
                        return false;
                }
        }
  
        static bool
        isUTF16HighSurrogate(XalanDOMChar       theChar)
        {
                return 0xD800u <= theChar && theChar <= 0xDBFFu ? true : false;
        }
  
        static bool
        isUTF16LowSurrogate(XalanDOMChar        theChar)
        {
                return 0xDC00u <= theChar && theChar <= 0xDFFFu ? true : false;
        }
  
        static unsigned int
        decodeUTF16SurrogatePair(
                        XalanDOMChar    theHighSurrogate,
                        XalanDOMChar    theLowSurrogate);
  
        char                                            m_buffer[kBufferSize];
  
        char*                                           m_bufferPosition;
  
        size_type                                       m_bufferRemaining;
  
        static const XalanDOMChar       s_specialChars[];
  };
  
  
  
  XALAN_CPP_NAMESPACE_END
  
  
  
  #endif        // FORMATTERTOXML_UTF8_HEADER_GUARD_1357924680
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to