//---------------------------------------------------------------------------
//
//     File:         DOMSerializer.h
//     Description:  Class to serialize a DOM to a stream. Largely taken from
//                   the Xerces-c DOMPrint example
//                   Works with Xerces-C 1.4
//
//     Rev:          $Id: DOMSerializer.h,v 1.1 2001/04/05 13:04:39 evert Exp $
//     Created:      2001/03/30
//     Author:       Evert Haasdijk
//     mail:         evert@ZukkeSpijkers.nl
//
//---------------------------------------------------------------------------
#ifndef DOMSerializerH
#define DOMSerializerH
//---------------------------------------------------------------------------

/*
 * 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.
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------

#include <util/PlatformUtils.hpp>
#include <util/XMLString.hpp>
#include <util/XMLUniDefs.hpp>
#include <framework/XMLFormatter.hpp>
#include <util/TranscodingException.hpp>
#include <dom/DOM_DOMException.hpp>
#include <dom/DOM.hpp>
#include <dom/DOMString.hpp>

#include <string>
#include <ostream>
#include <stdlib>


// ---------------------------------------------------------------------------
/// XMLFormatTarget-derived class for use with the DOMSerializer.
class DOMSerializerFormatTarget : public XMLFormatTarget
{
public:
    /**
      Constructor.

      @param os reference to the stream to write to.
    */
    DOMSerializerFormatTarget(std::ostream& os);

    /// Destructor
    ~DOMSerializerFormatTarget();

    ///  Implementations of the format target interface
    void writeChars(const XMLByte* const toWrite,
                    const unsigned int count,
                    XMLFormatter * const formatter);

    std::ostream& stream(void);

private:
    //@name:  Unimplemented methods.
    //@{
    /// copy constructor
    DOMSerializerFormatTarget(const DOMSerializerFormatTarget& other);
    /// assignement operator
    void operator=(const DOMSerializerFormatTarget& rhs);
    //@}

    /// reference to the stream to write to
    std::ostream& os_;
};

// ---------------------------------------------------------------------------

/**
  Serializes an in-memory DOM to a stream.
*/
class DOMSerializer
{
  public:
    /// Default encoding for output - 'UTF-8'
    static const std::string defaultEncoding_;
    /**
      Constructor.

      @param encoding const reference to a string denoting the encoding.
             Defaults to 'UTF-8'.
    */
    DOMSerializer(const std::string& encoding = defaultEncoding_);

    /// serialize the node and its descendants to the target
    void serialize(DOMSerializerFormatTarget* target, const DOM_Node& node);

  private:

    /**
      Stream out a DOM node, and, recursively, all of its children. This
      function is the heart of writing a DOM tree out as XML source. Give it
      a document node and it will do the whole thing.
    */
    std::ostream& doSerialize(std::ostream& target, const DOM_Node& toWrite);

    static const XMLCh  gEndElement[];
    static const XMLCh  gEndPI[];
    static const XMLCh  gStartPI[];
    static const XMLCh  gXMLDecl1[];
    static const XMLCh  gXMLDecl2[];
    static const XMLCh  gXMLDecl3[];
    static const XMLCh  gXMLDecl4[];
    static const XMLCh  gStartCDATA[];
    static const XMLCh  gEndCDATA[];
    static const XMLCh  gStartComment[];
    static const XMLCh  gEndComment[];
    static const XMLCh  gStartDoctype[];
    static const XMLCh  gPublic[];
    static const XMLCh  gSystem[];
    static const XMLCh  gStartEntity[];
    static const XMLCh  gNotation[];

    XMLFormatter* formatter_;

    std::string encoding_;
};

// ---------------------------------------------------------------------------
/**
  ostream << DOM_Node

  Serialize a DOM Node to stream s. Uses UTF-8 encoding.
*/
std::ostream& operator<< (std::ostream& s, const DOM_Node& node);


// ---------------------------------------------------------------------------
/**
  ostream << DOMString

  Stream out a DOM string. Doing this requires that we first transcode
  to char * form in the default code page for the system.
*/
std::ostream& operator<< (std::ostream& target, const DOMString& s);

XMLFormatter& operator<< (XMLFormatter& strm, const DOMString& s);

#endif

