lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [4799] Refactor, moving read() and write() to the base cla


From: Greg Chicares
Subject: [lmi-commits] [4799] Refactor, moving read() and write() to the base class
Date: Sun, 21 Mar 2010 13:42:22 +0000

Revision: 4799
          http://svn.sv.gnu.org/viewvc/?view=rev&root=lmi&revision=4799
Author:   chicares
Date:     2010-03-21 13:42:22 +0000 (Sun, 21 Mar 2010)
Log Message:
-----------
Refactor, moving read() and write() to the base class

Modified Paths:
--------------
    lmi/trunk/ChangeLog
    lmi/trunk/antediluvian_stubs.cpp
    lmi/trunk/input.hpp
    lmi/trunk/input_xml_io.cpp
    lmi/trunk/mec_input.cpp
    lmi/trunk/mec_input.hpp
    lmi/trunk/mec_state.cpp
    lmi/trunk/mec_state.hpp
    lmi/trunk/xml_serializable.hpp
    lmi/trunk/xml_serializable.tpp

Modified: lmi/trunk/ChangeLog
===================================================================
--- lmi/trunk/ChangeLog 2010-03-21 12:40:30 UTC (rev 4798)
+++ lmi/trunk/ChangeLog 2010-03-21 13:42:22 UTC (rev 4799)
@@ -24465,23 +24465,87 @@
   xml_serializable.hpp [new file]
 Rename 'streamable.?pp' to 'xml_serializable.?pp'.
 
-20100321T1056Z <address@hidden> [761]
+20100319T1243Z <address@hidden> [761]
 
+  input.hpp
+  input_xml_io.cpp
+  mec_input.cpp
+  mec_input.hpp
+  mec_state.cpp
+  mec_state.hpp
+Rename redintegration functions.
+
+20100319T1323Z <address@hidden> [761]
+
+  input.hpp
+  input_xml_io.cpp
+  mec_input.cpp
+  mec_input.hpp
+  mec_state.cpp
+  mec_state.hpp
+Make a free function a member. Usually, the opposite would be better,
+but soon this function will become virtual.
+
+20100319T1351Z <address@hidden> [761]
+
+  input.hpp
+  input_xml_io.cpp
+  mec_input.cpp
+  mec_input.hpp
+  mec_state.cpp
+  mec_state.hpp
+Refactor. The purpose is to make the implementations of read() and
+write() identical in all three classes, and thus to make refactoring
+them trivial.
+
+20100321T1133Z <address@hidden> [761]
+
   configure.ac
 Use AM_SILENT_RULES if available, for cleaner make output.
 
-20100321T1059Z <address@hidden> [761]
+20100321T1133Z <address@hidden> [761]
 
   Makefile.am
 Fix duplicate definition of test_input_LDADD.
 
-20100321T1102Z <address@hidden> [761]
+20100321T1133Z <address@hidden> [761]
 
   ihs_pios.hpp
 GCC 4.4 compilation fix.
 
-20100321T1110Z <address@hidden> [761]
+20100321T1133Z <address@hidden> [761]
 
   Makefile.am
 Include .[tx]pp files in noinst_HEADERS.
 
+20100321T1240Z <address@hidden> [761]
+
+  Makefile.am
+  antediluvian_stubs.cpp
+  input.cpp
+  input.hpp
+  input_xml_io.cpp
+  mec_input.cpp
+  mec_input.hpp
+  mec_state.cpp
+  mec_state.hpp
+  objects.make
+  xml_serializable.cpp [expunged]
+  xml_serializable.hpp
+  xml_serializable.tpp [new file]
+Use CRTP, preferring nonvirtual inheritance. This requires renaming
+'xml_serializable.cpp' to 'xml_serializable.tpp'.
+
+20100321T1342Z <address@hidden> [761]
+
+  antediluvian_stubs.cpp
+  input.hpp
+  input_xml_io.cpp
+  mec_input.cpp
+  mec_input.hpp
+  mec_state.cpp
+  mec_state.hpp
+  xml_serializable.hpp
+  xml_serializable.tpp
+Refactor, moving read() and write() to the base class.
+

Modified: lmi/trunk/antediluvian_stubs.cpp
===================================================================
--- lmi/trunk/antediluvian_stubs.cpp    2010-03-21 12:40:30 UTC (rev 4798)
+++ lmi/trunk/antediluvian_stubs.cpp    2010-03-21 13:42:22 UTC (rev 4799)
@@ -64,12 +64,6 @@
 mec_state::~mec_state()
 {}
 
-void mec_state::read(xml::element const&)
-{}
-
-void mec_state::write(xml::element&) const
-{}
-
 int mec_state::class_version() const
 {
     return 0;
@@ -81,3 +75,28 @@
     return s;
 }
 
+bool mec_state::is_detritus(std::string const&) const
+{
+    return false;
+}
+
+std::string mec_state::redintegrate_ex_ante
+    (int
+    ,std::string const&
+    ,std::string const&
+    ) const
+{
+    static std::string const s("");
+    return s;
+}
+
+void mec_state::redintegrate_ex_post
+    (int
+    ,std::map<std::string, std::string>
+    ,std::list<std::string>
+    )
+{}
+
+void mec_state::redintegrate_ad_terminum()
+{}
+

Modified: lmi/trunk/input.hpp
===================================================================
--- lmi/trunk/input.hpp 2010-03-21 12:40:30 UTC (rev 4798)
+++ lmi/trunk/input.hpp 2010-03-21 13:42:22 UTC (rev 4799)
@@ -46,7 +46,6 @@
 #include <boost/operators.hpp>
 #include <boost/scoped_ptr.hpp>
 
-#include <list>
 #include <map>
 #include <string>
 #include <vector>
@@ -170,24 +169,20 @@
         );
 
     // Class 'xml_serializable' required implementation.
-    virtual void read (xml::element const&);
-    virtual void write(xml::element&) const;
-    virtual int class_version() const;
+    virtual int         class_version() const;
     virtual std::string xml_root_name() const;
-
-    // Backward compatibility.
-    bool is_detritus(std::string const&);
-    std::string redintegrate_ex_ante
+    virtual bool        is_detritus(std::string const&) const;
+    virtual std::string redintegrate_ex_ante
         (int                file_version
         ,std::string const& name
         ,std::string const& value
         ) const;
-    void        redintegrate_ex_post
+    virtual void        redintegrate_ex_post
         (int                                file_version
         ,std::map<std::string, std::string> detritus_map
         ,std::list<std::string>             residuary_names
         );
-    void        redintegrate_ad_terminum();
+    virtual void        redintegrate_ad_terminum();
 
     // MvcModel required implementation.
     virtual void DoAdaptExternalities();

Modified: lmi/trunk/input_xml_io.cpp
===================================================================
--- lmi/trunk/input_xml_io.cpp  2010-03-21 12:40:30 UTC (rev 4798)
+++ lmi/trunk/input_xml_io.cpp  2010-03-21 13:42:22 UTC (rev 4799)
@@ -32,13 +32,9 @@
 #include "alert.hpp"
 #include "calendar_date.hpp"
 #include "global_settings.hpp"
-#include "miscellany.hpp"
-#include "value_cast.hpp"
-#include "xml_lmi.hpp"
+#include "miscellany.hpp" // lmi_array_size()
 
-#include <xmlwrapp/nodes_view.h>
-
-#include <algorithm> // std::find()
+#include <algorithm>      // std::find(), std::min()
 #include <stdexcept>
 
 template class xml_serializable<Input>;
@@ -66,108 +62,6 @@
 }
 } // Unnamed namespace.
 
-//============================================================================
-void Input::read(xml::element const& x)
-{
-    if(xml_root_name() != x.get_name())
-        {
-        fatal_error()
-            << "XML node name is '"
-            << x.get_name()
-            << "' but '"
-            << xml_root_name()
-            << "' was expected."
-            << LMI_FLUSH
-            ;
-        }
-
-    std::string file_version_string;
-    if(!xml_lmi::get_attr(x, "version", file_version_string))
-        {
-        fatal_error()
-            << "XML tag <"
-            << xml_root_name()
-            << "> lacks required version attribute."
-            << LMI_FLUSH
-            ;
-        }
-    int file_version = value_cast<int>(file_version_string);
-
-// COMPILER !! Borland doesn't find operator==() in ns xml.
-#ifdef __BORLANDC__
-using namespace xml;
-#endif // __BORLANDC__
-
-    std::map<std::string, std::string> detritus_map;
-
-    std::list<std::string> residuary_names;
-    std::copy
-        (member_names().begin()
-        ,member_names().end()
-        ,std::back_inserter(residuary_names)
-        );
-    std::list<std::string>::iterator current_member;
-
-    xml::const_nodes_view const elements(x.elements());
-    typedef xml::const_nodes_view::const_iterator cnvi;
-    for(cnvi child = elements.begin(); child != elements.end(); ++child)
-        {
-        std::string node_tag(child->get_name());
-        current_member = std::find
-            (residuary_names.begin()
-            ,residuary_names.end()
-            ,node_tag
-            );
-        if(residuary_names.end() != current_member)
-            {
-            operator[](node_tag) = redintegrate_ex_ante
-                (file_version
-                ,node_tag
-                ,xml_lmi::get_content(*child)
-                );
-            residuary_names.erase(current_member);
-            }
-        else if(is_detritus(node_tag))
-            {
-            // Hold certain obsolete entities that must be translated.
-            detritus_map[node_tag] = xml_lmi::get_content(*child);
-            }
-        else
-            {
-            warning()
-                << "XML tag '"
-                << node_tag
-                << "' not recognized by this version of the program."
-                << LMI_FLUSH
-                ;
-            }
-        }
-
-    redintegrate_ex_post(file_version, detritus_map, residuary_names);
-
-    redintegrate_ad_terminum();
-}
-
-//============================================================================
-void Input::write(xml::element& x) const
-{
-    xml::element root(xml_root_name().c_str());
-
-// XMLWRAPP !! There's no way to set an integer attribute.
-    std::string const version(value_cast<std::string>(class_version()));
-    xml_lmi::set_attr(root, "version", version.c_str());
-
-    std::vector<std::string>::const_iterator i;
-    for(i = member_names().begin(); i != member_names().end(); ++i)
-        {
-        std::string node_tag(*i);
-        std::string value = operator[](*i).str();
-        root.push_back(xml::element(node_tag.c_str(), value.c_str()));
-        }
-
-    x.push_back(root);
-}
-
 /// Serial number of this class's xml version.
 ///
 /// version 0: [prior to the lmi epoch]
@@ -197,7 +91,7 @@
 /// are recognized and ignored. If they're resurrected in a later
 /// version, then they aren't ignored.
 
-bool Input::is_detritus(std::string const& s)
+bool Input::is_detritus(std::string const& s) const
 {
     static std::string const a[] =
         {"AgentFirstName"                // Single name instead.

Modified: lmi/trunk/mec_input.cpp
===================================================================
--- lmi/trunk/mec_input.cpp     2010-03-21 12:40:30 UTC (rev 4798)
+++ lmi/trunk/mec_input.cpp     2010-03-21 13:42:22 UTC (rev 4799)
@@ -35,17 +35,11 @@
 #include "global_settings.hpp"
 #include "input_seq_helpers.hpp"
 #include "miscellany.hpp" // lmi_array_size()
-#include "xml_lmi.hpp"
 
-#include <xmlwrapp/nodes_view.h>
-
-#include <algorithm>
+#include <algorithm>      // std::find(), std::max()
 #include <limits>
-#include <list>
-#include <map>
 #include <sstream>
-#include <string>
-#include <vector>
+#include <utility>        // std::pair
 
 template class xml_serializable<mec_input>;
 
@@ -609,106 +603,6 @@
         );
 }
 
-void mec_input::read(xml::element const& x)
-{
-    if(xml_root_name() != x.get_name())
-        {
-        fatal_error()
-            << "XML node name is '"
-            << x.get_name()
-            << "' but '"
-            << xml_root_name()
-            << "' was expected."
-            << LMI_FLUSH
-            ;
-        }
-
-    std::string file_version_string;
-    if(!xml_lmi::get_attr(x, "version", file_version_string))
-        {
-        fatal_error()
-            << "XML tag <"
-            << xml_root_name()
-            << "> lacks required version attribute."
-            << LMI_FLUSH
-            ;
-        }
-    int file_version = value_cast<int>(file_version_string);
-
-// COMPILER !! Borland doesn't find operator==() in ns xml.
-#ifdef __BORLANDC__
-using namespace xml;
-#endif // __BORLANDC__
-
-    std::map<std::string, std::string> detritus_map;
-
-    std::list<std::string> residuary_names;
-    std::copy
-        (member_names().begin()
-        ,member_names().end()
-        ,std::back_inserter(residuary_names)
-        );
-    std::list<std::string>::iterator current_member;
-
-    xml::const_nodes_view const elements(x.elements());
-    typedef xml::const_nodes_view::const_iterator cnvi;
-    for(cnvi child = elements.begin(); child != elements.end(); ++child)
-        {
-        std::string node_tag(child->get_name());
-        current_member = std::find
-            (residuary_names.begin()
-            ,residuary_names.end()
-            ,node_tag
-            );
-        if(residuary_names.end() != current_member)
-            {
-            operator[](node_tag) = redintegrate_ex_ante
-                (file_version
-                ,node_tag
-                ,xml_lmi::get_content(*child)
-                );
-            residuary_names.erase(current_member);
-            }
-        else if(is_detritus(node_tag))
-            {
-            // Hold certain obsolete entities that must be translated.
-            detritus_map[node_tag] = xml_lmi::get_content(*child);
-            }
-        else
-            {
-            warning()
-                << "XML tag '"
-                << node_tag
-                << "' not recognized by this version of the program."
-                << LMI_FLUSH
-                ;
-            }
-        }
-
-    redintegrate_ex_post(file_version, detritus_map, residuary_names);
-
-    redintegrate_ad_terminum();
-}
-
-void mec_input::write(xml::element& x) const
-{
-    xml::element root(xml_root_name().c_str());
-
-// XMLWRAPP !! There's no way to set an integer attribute.
-    std::string const version(value_cast<std::string>(class_version()));
-    xml_lmi::set_attr(root, "version", version.c_str());
-
-    std::vector<std::string>::const_iterator i;
-    for(i = member_names().begin(); i != member_names().end(); ++i)
-        {
-        std::string node_tag(*i);
-        std::string value = operator[](*i).str();
-        root.push_back(xml::element(node_tag.c_str(), value.c_str()));
-        }
-
-    x.push_back(root);
-}
-
 /// Serial number of this class's xml version.
 ///
 /// version 0: 20090627T2249Z
@@ -727,7 +621,7 @@
 /// are recognized and ignored. If they're resurrected in a later
 /// version, then they aren't ignored.
 
-bool mec_input::is_detritus(std::string const& s)
+bool mec_input::is_detritus(std::string const& s) const
 {
     static std::string const a[] =
         {"EffectiveDateToday"

Modified: lmi/trunk/mec_input.hpp
===================================================================
--- lmi/trunk/mec_input.hpp     2010-03-21 12:40:30 UTC (rev 4798)
+++ lmi/trunk/mec_input.hpp     2010-03-21 13:42:22 UTC (rev 4799)
@@ -46,8 +46,6 @@
 #include <boost/operators.hpp>
 #include <boost/scoped_ptr.hpp>
 
-#include <list>
-#include <map>
 #include <string>
 #include <vector>
 
@@ -104,24 +102,20 @@
     void AscribeMembers();
 
     // Class 'xml_serializable' required implementation.
-    virtual void read (xml::element const&);
-    virtual void write(xml::element&) const;
-    virtual int class_version() const;
+    virtual int         class_version() const;
     virtual std::string xml_root_name() const;
-
-    // Backward compatibility.
-    bool is_detritus(std::string const&);
-    std::string redintegrate_ex_ante
+    virtual bool        is_detritus(std::string const&) const;
+    virtual std::string redintegrate_ex_ante
         (int                file_version
         ,std::string const& name
         ,std::string const& value
         ) const;
-    void        redintegrate_ex_post
+    virtual void        redintegrate_ex_post
         (int                                file_version
         ,std::map<std::string, std::string> detritus_map
         ,std::list<std::string>             residuary_names
         );
-    void        redintegrate_ad_terminum();
+    virtual void        redintegrate_ad_terminum();
 
     // MvcModel required implementation.
     virtual void DoAdaptExternalities();

Modified: lmi/trunk/mec_state.cpp
===================================================================
--- lmi/trunk/mec_state.cpp     2010-03-21 12:40:30 UTC (rev 4798)
+++ lmi/trunk/mec_state.cpp     2010-03-21 13:42:22 UTC (rev 4799)
@@ -36,10 +36,7 @@
 
 #include <boost/filesystem/fstream.hpp>
 
-#include <xmlwrapp/nodes_view.h>
-
 #include <algorithm>      // std::find()
-#include <iterator>       // std::back_inserter
 #include <limits>
 #include <sstream>
 #include <vector>
@@ -386,106 +383,6 @@
     ascribe("Q6_max_non_mec_prem"      , &mec_state::Q6_max_non_mec_prem      
);
 }
 
-void mec_state::read(xml::element const& x)
-{
-    if(xml_root_name() != x.get_name())
-        {
-        fatal_error()
-            << "XML node name is '"
-            << x.get_name()
-            << "' but '"
-            << xml_root_name()
-            << "' was expected."
-            << LMI_FLUSH
-            ;
-        }
-
-    std::string file_version_string;
-    if(!xml_lmi::get_attr(x, "version", file_version_string))
-        {
-        fatal_error()
-            << "XML tag <"
-            << xml_root_name()
-            << "> lacks required version attribute."
-            << LMI_FLUSH
-            ;
-        }
-    int file_version = value_cast<int>(file_version_string);
-
-// COMPILER !! Borland doesn't find operator==() in ns xml.
-#ifdef __BORLANDC__
-using namespace xml;
-#endif // __BORLANDC__
-
-    std::map<std::string, std::string> detritus_map;
-
-    std::list<std::string> residuary_names;
-    std::copy
-        (member_names().begin()
-        ,member_names().end()
-        ,std::back_inserter(residuary_names)
-        );
-    std::list<std::string>::iterator current_member;
-
-    xml::const_nodes_view const elements(x.elements());
-    typedef xml::const_nodes_view::const_iterator cnvi;
-    for(cnvi child = elements.begin(); child != elements.end(); ++child)
-        {
-        std::string node_tag(child->get_name());
-        current_member = std::find
-            (residuary_names.begin()
-            ,residuary_names.end()
-            ,node_tag
-            );
-        if(residuary_names.end() != current_member)
-            {
-            operator[](node_tag) = redintegrate_ex_ante
-                (file_version
-                ,node_tag
-                ,xml_lmi::get_content(*child)
-                );
-            residuary_names.erase(current_member);
-            }
-        else if(is_detritus(node_tag))
-            {
-            // Hold certain obsolete entities that must be translated.
-            detritus_map[node_tag] = xml_lmi::get_content(*child);
-            }
-        else
-            {
-            warning()
-                << "XML tag '"
-                << node_tag
-                << "' not recognized by this version of the program."
-                << LMI_FLUSH
-                ;
-            }
-        }
-
-    redintegrate_ex_post(file_version, detritus_map, residuary_names);
-
-    redintegrate_ad_terminum();
-}
-
-void mec_state::write(xml::element& x) const
-{
-    xml::element root(xml_root_name().c_str());
-
-// XMLWRAPP !! There's no way to set an integer attribute.
-    std::string const version(value_cast<std::string>(class_version()));
-    xml_lmi::set_attr(root, "version", version.c_str());
-
-    std::vector<std::string>::const_iterator i;
-    for(i = member_names().begin(); i != member_names().end(); ++i)
-        {
-        std::string node_tag(*i);
-        std::string value = operator[](*i).str();
-        root.push_back(xml::element(node_tag.c_str(), value.c_str()));
-        }
-
-    x.push_back(root);
-}
-
 /// Serial number of this class's xml version.
 ///
 /// version 0: 20090728T1324Z
@@ -504,7 +401,7 @@
 /// are recognized and ignored. If they're resurrected in a later
 /// version, then they aren't ignored.
 
-bool mec_state::is_detritus(std::string const& s)
+bool mec_state::is_detritus(std::string const& s) const
 {
     static std::string const a[] =
         {"Remove this string when adding the first removed entity."

Modified: lmi/trunk/mec_state.hpp
===================================================================
--- lmi/trunk/mec_state.hpp     2010-03-21 12:40:30 UTC (rev 4798)
+++ lmi/trunk/mec_state.hpp     2010-03-21 13:42:22 UTC (rev 4799)
@@ -34,8 +34,6 @@
 #include <boost/filesystem/path.hpp>
 #include <boost/operators.hpp>
 
-#include <list>
-#include <map>
 #include <string>
 
 /// Transient state of MEC testing.
@@ -70,24 +68,20 @@
     void AscribeMembers();
 
     // Class 'xml_serializable' required implementation.
-    virtual void read (xml::element const&);
-    virtual void write(xml::element&) const;
-    virtual int class_version() const;
+    virtual int         class_version() const;
     virtual std::string xml_root_name() const;
-
-    // Backward compatibility.
-    bool is_detritus(std::string const&);
-    std::string redintegrate_ex_ante
+    virtual bool        is_detritus(std::string const&) const;
+    virtual std::string redintegrate_ex_ante
         (int                file_version
         ,std::string const& name
         ,std::string const& value
         ) const;
-    void        redintegrate_ex_post
+    virtual void        redintegrate_ex_post
         (int                                file_version
         ,std::map<std::string, std::string> detritus_map
         ,std::list<std::string>             residuary_names
         );
-    void        redintegrate_ad_terminum();
+    virtual void        redintegrate_ad_terminum();
 
     int    B0_deduced_policy_year;
     int    B1_deduced_contract_year;

Modified: lmi/trunk/xml_serializable.hpp
===================================================================
--- lmi/trunk/xml_serializable.hpp      2010-03-21 12:40:30 UTC (rev 4798)
+++ lmi/trunk/xml_serializable.hpp      2010-03-21 13:42:22 UTC (rev 4799)
@@ -29,6 +29,8 @@
 #include "so_attributes.hpp"
 #include "xml_lmi_fwd.hpp"
 
+#include <list>
+#include <map>
 #include <string>
 
 /// Derive from this mixin class to use its xml serialization.
@@ -41,12 +43,24 @@
   public:
     virtual ~xml_serializable();
 
-    virtual void read (xml::element const&) = 0;
-    virtual void write(xml::element&) const = 0;
+    void read (xml::element const&);
+    void write(xml::element&) const;
 
   private:
-    virtual int class_version() const = 0;
+    virtual int         class_version() const = 0;
     virtual std::string xml_root_name() const = 0;
+    virtual bool        is_detritus(std::string const&) const = 0;
+    virtual std::string redintegrate_ex_ante
+        (int                file_version
+        ,std::string const& name
+        ,std::string const& value
+        ) const = 0;
+    virtual void        redintegrate_ex_post
+        (int                                file_version
+        ,std::map<std::string, std::string> detritus_map
+        ,std::list<std::string>             residuary_names
+        ) = 0;
+    virtual void        redintegrate_ad_terminum() = 0;
 };
 
 template<typename T>

Modified: lmi/trunk/xml_serializable.tpp
===================================================================
--- lmi/trunk/xml_serializable.tpp      2010-03-21 12:40:30 UTC (rev 4798)
+++ lmi/trunk/xml_serializable.tpp      2010-03-21 13:42:22 UTC (rev 4799)
@@ -28,8 +28,142 @@
 
 #include "xml_serializable.hpp"
 
+#include "alert.hpp"
+#include "any_member.hpp" // MemberSymbolTable<>
+#include "value_cast.hpp"
+#include "xml_lmi.hpp"
+
+#if !defined __BORLANDC__
+#   include <boost/static_assert.hpp>
+#   include <boost/type_traits.hpp>
+#else  // defined __BORLANDC__
+#   define BOOST_STATIC_ASSERT(deliberately_ignored) class IgNoRe
+#endif // defined __BORLANDC__
+
+#include <xmlwrapp/nodes_view.h>
+
+#include <algorithm>      // std::copy(), std::find()
+#include <iterator>       // std::back_inserter
+#include <vector>
+
 template<typename T>
 xml_serializable<T>::~xml_serializable()
 {
+    // Assert that static_cast<T cv&> doesn't engender undefined
+    // behavior, and that the base class provides the expected
+    // operator[]() and member_names() functions.
+    //
+    // Double parentheses: don't parse comma as a macro parameter separator.
+    BOOST_STATIC_ASSERT
+        ((
+           boost::is_base_and_derived<xml_serializable <T>,T>::value
+        && boost::is_base_and_derived<MemberSymbolTable<T>,T>::value
+        ));
 }
 
+template<typename T>
+void xml_serializable<T>::read(xml::element const& x)
+{
+    T& t = static_cast<T&>(*this);
+
+    if(xml_root_name() != x.get_name())
+        {
+        fatal_error()
+            << "XML node name is '"
+            << x.get_name()
+            << "' but '"
+            << xml_root_name()
+            << "' was expected."
+            << LMI_FLUSH
+            ;
+        }
+
+    std::string file_version_string;
+    if(!xml_lmi::get_attr(x, "version", file_version_string))
+        {
+        fatal_error()
+            << "XML tag <"
+            << xml_root_name()
+            << "> lacks required version attribute."
+            << LMI_FLUSH
+            ;
+        }
+    int file_version = value_cast<int>(file_version_string);
+
+// COMPILER !! Borland doesn't find operator==() in ns xml.
+#ifdef __BORLANDC__
+using namespace xml;
+#endif // __BORLANDC__
+
+    std::map<std::string, std::string> detritus_map;
+
+    std::list<std::string> residuary_names;
+    std::copy
+        (t.member_names().begin()
+        ,t.member_names().end()
+        ,std::back_inserter(residuary_names)
+        );
+    std::list<std::string>::iterator current_member;
+
+    xml::const_nodes_view const elements(x.elements());
+    typedef xml::const_nodes_view::const_iterator cnvi;
+    for(cnvi child = elements.begin(); child != elements.end(); ++child)
+        {
+        std::string node_tag(child->get_name());
+        current_member = std::find
+            (residuary_names.begin()
+            ,residuary_names.end()
+            ,node_tag
+            );
+        if(residuary_names.end() != current_member)
+            {
+            t[node_tag] = redintegrate_ex_ante
+                (file_version
+                ,node_tag
+                ,xml_lmi::get_content(*child)
+                );
+            residuary_names.erase(current_member);
+            }
+        else if(is_detritus(node_tag))
+            {
+            // Hold certain obsolete entities that must be translated.
+            detritus_map[node_tag] = xml_lmi::get_content(*child);
+            }
+        else
+            {
+            warning()
+                << "XML tag '"
+                << node_tag
+                << "' not recognized by this version of the program."
+                << LMI_FLUSH
+                ;
+            }
+        }
+
+    redintegrate_ex_post(file_version, detritus_map, residuary_names);
+
+    redintegrate_ad_terminum();
+}
+
+template<typename T>
+void xml_serializable<T>::write(xml::element& x) const
+{
+    T const& t = static_cast<T const&>(*this);
+
+    xml::element root(xml_root_name().c_str());
+
+// XMLWRAPP !! There's no way to set an integer attribute.
+    std::string const version(value_cast<std::string>(class_version()));
+    xml_lmi::set_attr(root, "version", version.c_str());
+
+    std::vector<std::string>::const_iterator i;
+    for(i = t.member_names().begin(); i != t.member_names().end(); ++i)
+        {
+        std::string node_tag(*i);
+        std::string value = t[node_tag].str();
+        root.push_back(xml::element(node_tag.c_str(), value.c_str()));
+        }
+
+    x.push_back(root);
+}
+





reply via email to

[Prev in Thread] Current Thread [Next in Thread]