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

// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com . 
// Use, modification and distribution is subject to 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.

#if (defined _MSC_VER) && (_MSC_VER == 1200)
#  pragma warning (disable : 4786) // too long name, harmless warning
#endif

#include <istream>
#include <algorithm>
#include <boost/config.hpp> // BOOST_DEDUCED_TYPENAME

#ifdef BOOST_MSVC
#  pragma warning(push)
#  pragma warning(disable : 4511 4512)
#endif

// spirit stuff
#include <boost/spirit/core/composite/operators.hpp>
#include <boost/spirit/core/composite/actions.hpp>
#include <boost/spirit/core/primitives/numerics.hpp>

#ifdef BOOST_MSVC
#pragma warning(pop)
#endif

// for head_iterator test
//#include <boost/bind.hpp> 
#include <boost/function.hpp>
#include <boost/serialization/pfto.hpp>

#include <boost/io/ios_state.hpp>
#include <boost/serialization/throw_exception.hpp>
#include <boost/archive/impl/basic_xml_grammar.hpp>
#include <boost/archive/xml_archive_exception.hpp>
#include <boost/archive/basic_xml_archive.hpp>
#include <boost/archive/iterators/xml_unescape.hpp>

using namespace boost::spirit;

namespace boost {
namespace archive {

/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
// template code for basic_xml_grammar of both wchar_t and char types

namespace xml { // anonymous

#ifdef BOOST_MSVC
#  pragma warning(push)
#  pragma warning(disable : 4511 4512)
#endif

template<class T>
struct assign_impl {
    T & t;
    void operator()(const T t_) const {
        t = t_;
    }
    assign_impl(T &  t_)
        : t(t_)
    {}
};

template<>
struct assign_impl<std::string> {
    std::string & t;
    void operator()(
        std::string::const_iterator b, 
        std::string::const_iterator e
    ) const {
        t.resize(0);
        while(b != e){
            t += * b;
            ++b;
        }
    }
    assign_impl<std::string> & operator=(
        assign_impl<std::string> & rhs
    );
    assign_impl(std::string & t_)
        : t(t_)
    {}
};

#ifndef BOOST_NO_STD_WSTRING
template<>
struct assign_impl<std::wstring> {
    std::wstring & t;
    void operator()(
        std::wstring::const_iterator b, 
        std::wstring::const_iterator e
    ) const {
        t.resize(0);
        while(b != e){
            t += * b;
            ++b;
        }
    }
    assign_impl(std::wstring & t_)
        : t(t_)
    {}
};
#endif

template<class T>
assign_impl<T> assign_object(T &t){
    return assign_impl<T>(t);
} 

struct assign_level {
    tracking_type & tracking_level;
    void operator()(const unsigned int tracking_level_) const {
        tracking_level = (0 == tracking_level_) ? false : true;
    }
    assign_level(tracking_type &  tracking_level_)
        : tracking_level(tracking_level_)
    {}
};

template<class String, class Iterator>
struct append_string {
    String & contents;
    void operator()(Iterator start, Iterator end) const {
    #if 0
        typedef boost::archive::iterators::xml_unescape<Iterator> translator;
        contents.append(
            translator(BOOST_MAKE_PFTO_WRAPPER(start)), 
            translator(BOOST_MAKE_PFTO_WRAPPER(end))
        );
    #endif
        contents.append(start, end);
    }
    append_string(String & contents_)
        : contents(contents_)
    {}
};

template<class String>
struct append_char {
    String & contents;
    void operator()(const unsigned int char_value) const {
        const BOOST_DEDUCED_TYPENAME String::value_type z = char_value;
        contents += z;
    }
    append_char(String & contents_)
        : contents(contents_)
    {}
};

template<class String, unsigned int c>
struct append_lit {
    String & contents;
    template<class X, class Y>
    void operator()(const X & /*x*/, const Y & /*y*/) const {
        const BOOST_DEDUCED_TYPENAME String::value_type z = c;
        contents += z;
    }
    append_lit(String & contents_)
        : contents(contents_)
    {}
};

#ifdef BOOST_MSVC
#pragma warning(pop)
#endif

} // namespace anonymous

template<class CharType>
bool basic_xml_grammar<CharType>::my_parse(
    BOOST_DEDUCED_TYPENAME basic_xml_grammar<CharType>::IStream & is,
    const rule_t & rule_,
    CharType delimiter
) const {
    if(is.fail()){
        boost::serialization::throw_exception(
            archive_exception(archive_exception::input_stream_error)
        );
    }
    
    boost::io::ios_flags_saver ifs(is);
    is >> std::noskipws;

    std::basic_string<CharType> arg;
    
    CharType val;
    do{
        BOOST_DEDUCED_TYPENAME basic_xml_grammar<CharType>::IStream::int_type
            result = is.get();
        if(is.fail())
            return false;
        val = static_cast<CharType>(result);
        arg += val;
    }
    while(val != delimiter);
    
    // read just one more character.  This will be the newline after the tag
    // this is so that the next operation will return fail if the archive
    // is terminated.  This will permit the archive to be used for debug
    // and transaction data logging in the standard way.
    
    parse_info<BOOST_DEDUCED_TYPENAME std::basic_string<CharType>::iterator> 
        result = boost::spirit::parse(arg.begin(), arg.end(), rule_);
    return result.hit;
}

template<class CharType>
bool basic_xml_grammar<CharType>::parse_start_tag(
    BOOST_DEDUCED_TYPENAME basic_xml_grammar<CharType>::IStream & is
){
    rv.class_name.resize(0);
    return my_parse(is, STag);
}

template<class CharType>
bool basic_xml_grammar<CharType>::parse_end_tag(IStream & is) const {
    return my_parse(is, ETag);
}

template<class CharType>
bool basic_xml_grammar<CharType>::parse_string(IStream & is, StringType & s){
    rv.contents.resize(0);
    bool result = my_parse(is, content, '<');
    // note: unget caused a problem with dinkumware.  replace with
 // is.unget();
    // putback another dilimiter instead
    is.putback('<');
    if(result)
        s = rv.contents;
    return result;
}

template<class CharType>
basic_xml_grammar<CharType>::basic_xml_grammar(){
    init_chset();

    S =
        +(Sch)
    ;

    // refactoring to workaround template depth on darwin
    NameHead = (Letter | '_' | ':');
    NameTail = *NameChar ;
    Name =
      NameHead >> NameTail
    ;

    Eq =
        !S >> '=' >> !S
    ;

    AttributeList = 
        *(S >> Attribute)
    ;
    
    STag =
        !S
        >> '<'
        >> Name  [xml::assign_object(rv.object_name)]
        >> AttributeList
        >> !S
        >> '>'
    ;

    ETag =
        !S
        >> "</"
        >> Name [xml::assign_object(rv.object_name)]
        >> !S 
        >> '>'
    ;

    // refactoring to workaround template depth on darwin
    CharDataChars = +(anychar_p - chset_p(L"&<"));
    CharData =  
        CharDataChars [
            xml::append_string<
                StringType, 
                BOOST_DEDUCED_TYPENAME std::basic_string<CharType>::const_iterator
            >(rv.contents)
        ]
    ;

    // slight factoring works around ICE in msvc 6.0
    CharRef1 = 
        str_p(L"&#") >> uint_p [xml::append_char<StringType>(rv.contents)] >> L';'
    ;
    CharRef2 =
        str_p(L"&#x") >> hex_p [xml::append_char<StringType>(rv.contents)] >> L';'
    ;
    CharRef = CharRef1 | CharRef2 ;

    AmpRef = str_p(L"&amp;")[xml::append_lit<StringType, L'&'>(rv.contents)];
    LTRef = str_p(L"&lt;")[xml::append_lit<StringType, L'<'>(rv.contents)];
    GTRef = str_p(L"&gt;")[xml::append_lit<StringType, L'>'>(rv.contents)];
    AposRef = str_p(L"&apos;")[xml::append_lit<StringType, L'\''>(rv.contents)];
    QuoteRef = str_p(L"&quot;")[xml::append_lit<StringType, L'"'>(rv.contents)];

    Reference =
        AmpRef
        | LTRef
        | GTRef
        | AposRef
        | QuoteRef
        | CharRef
    ;

    content = 
        L"<" // should be end_p
        | +(Reference | CharData) >> L"<"
    ;

    ClassIDAttribute = 
        str_p(BOOST_ARCHIVE_XML_CLASS_ID()) >> NameTail
        >> Eq 
        >> L'"'
        >> int_p [xml::assign_object(rv.class_id)]
        >> L'"'
      ;

    ObjectIDAttribute = (
        str_p(BOOST_ARCHIVE_XML_OBJECT_ID()) 
        | 
        str_p(BOOST_ARCHIVE_XML_OBJECT_REFERENCE()) 
        )
        >> NameTail
        >> Eq 
        >> L'"'
        >> L'_'
        >> uint_p [xml::assign_object(rv.object_id)]
        >> L'"'
    ;
        
    AmpName = str_p(L"&amp;")[xml::append_lit<StringType, L'&'>(rv.class_name)];
    LTName = str_p(L"&lt;")[xml::append_lit<StringType, L'<'>(rv.class_name)];
    GTName = str_p(L"&gt;")[xml::append_lit<StringType, L'>'>(rv.class_name)];
    ClassNameChar = 
        AmpName
        | LTName
        | GTName
        | (anychar_p - chset_p(L"\"")) [xml::append_char<StringType>(rv.class_name)]
    ;
    
    ClassName =
        * ClassNameChar
    ;
    
    ClassNameAttribute = 
        str_p(BOOST_ARCHIVE_XML_CLASS_NAME()) 
        >> Eq 
        >> L'"'
        >> ClassName
        >> L'"'
    ;

    TrackingAttribute = 
        str_p(BOOST_ARCHIVE_XML_TRACKING())
        >> Eq
        >> L'"'
        >> uint_p [xml::assign_level(rv.tracking_level)]
        >> L'"'
    ;

    VersionAttribute = 
        str_p(BOOST_ARCHIVE_XML_VERSION())
        >> Eq
        >> L'"'
        >> uint_p [xml::assign_object(rv.version)]
        >> L'"'
    ;

    UnusedAttribute = 
        Name
        >> Eq
        >> L'"'
        >> !CharData
        >> L'"'
    ;

    Attribute =
        ClassIDAttribute
        | ObjectIDAttribute
        | ClassNameAttribute
        | TrackingAttribute
        | VersionAttribute
        | UnusedAttribute
    ;

    XMLDeclChars = *(anychar_p - chset_p(L"?>"));
    XMLDecl =
        !S
        >> str_p(L"<?xml")
        >> S
        >> str_p(L"version")
        >> Eq
        >> str_p(L"\"1.0\"")
        >> XMLDeclChars
        >> !S
        >> str_p(L"?>")
    ;

    DocTypeDeclChars = *(anychar_p - chset_p(L">"));
    DocTypeDecl =
        !S
        >> str_p(L"<!DOCTYPE")
        >> DocTypeDeclChars
        >> L'>'
    ;

    SignatureAttribute = 
        str_p(L"signature") 
        >> Eq 
        >> L'"'
        >> Name [xml::assign_object(rv.class_name)]
        >> L'"'
    ;
    
    SerializationWrapper =
        !S
        >> str_p(L"<boost_serialization")
        >> S
        >> SignatureAttribute
        >> S
        >> VersionAttribute
        >> !S
        >> L'>'
    ;
}

template<class CharType>
void basic_xml_grammar<CharType>::init(IStream & is){
    init_chset();
    if(! my_parse(is, XMLDecl))
        boost::serialization::throw_exception(
            xml_archive_exception(xml_archive_exception::xml_archive_parsing_error)
        );
    if(! my_parse(is, DocTypeDecl))
        boost::serialization::throw_exception(
            xml_archive_exception(xml_archive_exception::xml_archive_parsing_error)
        );
    if(! my_parse(is, SerializationWrapper))
        boost::serialization::throw_exception(
            xml_archive_exception(xml_archive_exception::xml_archive_parsing_error)
        );
    if(! std::equal(rv.class_name.begin(), rv.class_name.end(), BOOST_ARCHIVE_SIGNATURE()))
        boost::serialization::throw_exception(
            archive_exception(archive_exception::invalid_signature)
        );
}

template<class CharType>
void basic_xml_grammar<CharType>::windup(IStream & is){
    if(is.fail())
        return;
    // uh-oh - don't throw exception from code called by a destructor !
    // so just ignore any failure.
    my_parse(is, ETag);
}

} // namespace archive
} // namespace boost
