/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// basic_xml_oarchive.ipp:

// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

//  See http://www.boost.org for updates, documentation, and revision history.

#include <algorithm>
#include <cstddef> // NULL
#include <cstring>
#if defined(BOOST_NO_STDC_NAMESPACE) && ! defined(__LIBCOMO__)
namespace std{
    using ::strlen;
} // namespace std
#endif

#include <boost/archive/basic_xml_archive.hpp>
#include <boost/archive/basic_xml_oarchive.hpp>
#include <boost/archive/xml_archive_exception.hpp>
#include <boost/detail/no_exceptions_support.hpp>

namespace boost {
namespace archive {

namespace detail {
template<class CharType>
struct XML_name {
    void operator()(CharType t) const{
        const unsigned char lookup_table[] = {
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0, // -.
            1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 0-9
            0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // A-
            1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1, // -Z _
            0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // a-
            1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, // -z
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
            0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
        };
        if((unsigned)t > 127)
            return;
        if(0 == lookup_table[(unsigned)t])
            boost::serialization::throw_exception(
                xml_archive_exception(
                    xml_archive_exception::xml_archive_tag_name_error
                )
            );
    }
};

} // namespace detail

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// implemenations of functions common to both types of xml output

template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::write_attribute(
    const char *attribute_name,
    int t,
    const char *conjunction
){
    this->This()->put(' ');
    this->This()->put(attribute_name);
    this->This()->put(conjunction);
    this->This()->save(t);
    this->This()->put('"');
}

template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::write_attribute(
    const char *attribute_name,
    const char *key
){
    this->This()->put(' ');
    this->This()->put(attribute_name);
    this->This()->put("=\"");
    this->This()->save(key);
    this->This()->put('"');
}

template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::indent(){
    int i;
    for(i = depth; i-- > 0;)
        this->This()->put('\t');
}

template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_start(const char *name)
{
    if(NULL == name)
        return;

    // be sure name has no invalid characters
    std::for_each(name, name + std::strlen(name), detail::XML_name<const char>());

    end_preamble();
    if(depth > 0){
        this->This()->put('\n');
        indent();
    }
    ++depth;
    this->This()->put('<');
    this->This()->save(name);
    pending_preamble = true;
    indent_next = false;
}

template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_end(const char *name)
{
    if(NULL == name)
        return;

    // be sure name has no invalid characters
    std::for_each(name, name + std::strlen(name), detail::XML_name<const char>());

    end_preamble();
    --depth;
    if(indent_next){
        this->This()->put('\n');
        indent();
    }
    indent_next = true;
    this->This()->put("</");
    this->This()->save(name);
    this->This()->put('>');
    if(0 == depth)
        this->This()->put('\n');
}

template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::end_preamble(){
    if(pending_preamble){
        this->This()->put('>');
        pending_preamble = false;
    }
}
#if 0
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(const object_id_type & t, int)
{
    int i = t.t; // extra .t is for borland
    write_attribute(BOOST_ARCHIVE_XML_OBJECT_ID(), i, "=\"_");
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(
    const object_reference_type & t,
    int
){
    int i = t.t; // extra .t is for borland
    write_attribute(BOOST_ARCHIVE_XML_OBJECT_REFERENCE(), i, "=\"_");
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(const version_type & t, int)
{
    int i = t.t; // extra .t is for borland
    write_attribute(BOOST_ARCHIVE_XML_VERSION(), i);
}
#endif

template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(const object_id_type & t, int)
{
    // borland doesn't do conversion of STRONG_TYPEDEFs very well
    const unsigned int i = t;
    write_attribute(BOOST_ARCHIVE_XML_OBJECT_ID(), i, "=\"_");
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(
    const object_reference_type & t,
    int
){
    const unsigned int i = t;
    write_attribute(BOOST_ARCHIVE_XML_OBJECT_REFERENCE(), i, "=\"_");
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(const version_type & t, int)
{
    const unsigned int i = t;
    write_attribute(BOOST_ARCHIVE_XML_VERSION(), i);
}

template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(const class_id_type & t, int)
{
    write_attribute(BOOST_ARCHIVE_XML_CLASS_ID(), t);
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(
    const class_id_reference_type & t,
    int
){
    write_attribute(BOOST_ARCHIVE_XML_CLASS_ID_REFERENCE(), t);
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(
    const class_id_optional_type & t,
    int
){
    write_attribute(BOOST_ARCHIVE_XML_CLASS_ID(), t);
}
template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(const class_name_type & t, int)
{
    const char * key = t;
    if(NULL == key)
        return;
    write_attribute(BOOST_ARCHIVE_XML_CLASS_NAME(), key);
}

template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::save_override(const tracking_type & t, int)
{
    write_attribute(BOOST_ARCHIVE_XML_TRACKING(), t.t);
}

template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(void)
basic_xml_oarchive<Archive>::init(){
    // xml header
    this->This()->put("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?>\n");
    this->This()->put("<!DOCTYPE boost_serialization>\n");
    // xml document wrapper - outer root
    this->This()->put("<boost_serialization");
    write_attribute("signature", BOOST_ARCHIVE_SIGNATURE());
    write_attribute("version", BOOST_ARCHIVE_VERSION());
    this->This()->put(">\n");
}

template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
basic_xml_oarchive<Archive>::basic_xml_oarchive(unsigned int flags) :
    detail::common_oarchive<Archive>(flags),
    depth(0),
    indent_next(false),
    pending_preamble(false)
{
}

template<class Archive>
BOOST_ARCHIVE_OR_WARCHIVE_DECL(BOOST_PP_EMPTY())
basic_xml_oarchive<Archive>::~basic_xml_oarchive(){
    if(0 == (this->get_flags() & no_header)){
        BOOST_TRY{
                this->This()->put("</boost_serialization>\n");
        }
        BOOST_CATCH(...){}
        BOOST_CATCH_END
    }
}

} // namespace archive
} // namespace boost
