lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [5468] Add binary-to-xml migration tool


From: Greg Chicares
Subject: [lmi-commits] [5468] Add binary-to-xml migration tool
Date: Sun, 27 May 2012 16:15:12 +0000

Revision: 5468
          http://svn.sv.gnu.org/viewvc/?view=rev&root=lmi&revision=5468
Author:   chicares
Date:     2012-05-27 16:15:12 +0000 (Sun, 27 May 2012)
Log Message:
-----------
Add binary-to-xml migration tool

Added Paths:
-----------
    lmi/trunk/soa2xml.cpp
    lmi/trunk/soa_helpers.hpp

Added: lmi/trunk/soa2xml.cpp
===================================================================
--- lmi/trunk/soa2xml.cpp                               (rev 0)
+++ lmi/trunk/soa2xml.cpp       2012-05-27 16:15:12 UTC (rev 5468)
@@ -0,0 +1,180 @@
+
+#include "soa_helpers.hpp"
+
+#include "actuarial_table.hpp"
+#include "value_cast.hpp"
+
+#include <xmlwrapp/attributes.h>
+#include <xmlwrapp/document.h>
+#include <xmlwrapp/node.h>
+
+#include <ios>
+#include <istream>
+
+/************************************************************************
+ misc helpers
+ ************************************************************************/
+
+template<typename T>
+inline const char *as_str(T x)
+{
+    static std::string tmp;
+    tmp = value_cast<std::string>(x);
+    return tmp.c_str();
+}
+
+
+/************************************************************************
+ conversion code
+ ************************************************************************/
+
+xml::node xml_for_aggregate_table(soa_actuarial_table const& t)
+{
+    xml::node n("aggregate");
+
+    std::vector<double> const values =
+        t.values(t.min_age(), t.max_age() - t.min_age() + 1);
+
+    for(int i = 0; i < values.size(); i++)
+        {
+        xml::node v("value", as_str(values[i]));
+        v.get_attributes().insert("age", as_str(t.min_age() + i));
+        n.insert(v);
+        }
+
+    return n;
+}
+
+xml::node xml_for_duration_table(soa_actuarial_table const& t)
+{
+    xml::node n("duration");
+
+    std::vector<double> const values =
+        t.values(t.min_age(), t.max_age() - t.min_age() + 1);
+
+    for(int i = 0; i < values.size(); i++)
+        {
+        xml::node v("value", as_str(values[i]));
+        n.insert(v);
+        }
+
+    return n;
+}
+
+xml::node xml_for_select_and_ultimate_table(soa_actuarial_table const& t)
+{
+    xml::node n("select-and-ultimate");
+
+    xml::node n_select("select");
+    xml::node n_ultimate("ultimate");
+
+    // Write the <select> portion:
+    n_select.get_attributes().insert("period", as_str(t.select_period()));
+    for(int age = t.min_age(); age <= t.max_select_age(); age++)
+        {
+            std::vector<double> data = t.values(age, t.select_period());
+            xml::node n_row("row");
+            n_row.get_attributes().insert("age", as_str(age));
+            for (int s = 0; s < t.select_period(); s++)
+                {
+                xml::node v("value", as_str(data[s]));
+                n_row.insert(v);
+                }
+
+            n_select.insert(n_row);
+        }
+
+    // Write the <ultimate> portion:
+    for(int age = t.min_age(); age <= t.max_select_age(); age++)
+        {
+        std::vector<double> data = t.values(age, t.select_period() + 1);
+        xml::node v("value", as_str(data.back()));
+        v.get_attributes().insert("age", as_str(age + t.select_period()));
+        n_ultimate.insert(v);
+        }
+    for(int age = t.max_select_age() + t.select_period() + 1; age <= 
t.max_age(); age++)
+        {
+        std::vector<double> data = t.values(age, 1);
+        xml::node v("value", as_str(data.back()));
+        v.get_attributes().insert("age", as_str(age));
+        n_ultimate.insert(v);
+        }
+
+    n.insert(n_select);
+    n.insert(n_ultimate);
+
+    return n;
+}
+
+
+void export_single_table(char const* filename, int index, char const* 
description)
+{
+    fs::path table_path(filename);
+    soa_actuarial_table table(filename, index);
+
+    std::cout
+        << table.table_type()
+        << " table #"
+        << index
+        << ":\t"
+        << description
+        << std::endl;
+
+    xml::node root("table");
+    root.insert(xml::node("description", description));
+
+    switch(table.table_type())
+        {
+        case 'A':
+            root.insert(xml_for_aggregate_table(table));
+            break;
+
+        case 'D':
+            root.insert(xml_for_duration_table(table));
+            break;
+
+        case 'S':
+            root.insert(xml_for_select_and_ultimate_table(table));
+            break;
+
+        default:
+            error(boost::format("Unknown table type '%1%'.") % 
table.table_type());
+       }
+
+    xml::document doc(root);
+
+    char xmlsuffix[64];
+    sprintf(xmlsuffix, "_%d.xtable", index);
+    std::string const xmlfile = fs::basename(table_path) + xmlsuffix;
+    doc.save_to_file(xmlfile.c_str());
+}
+
+void export_soa_file(char const* filename)
+{
+    const std::vector<soa_record_info> tables = list_soa_file_tables(filename);
+
+    for(std::vector<soa_record_info>::const_iterator i = tables.begin()
+        ;i != tables.end()
+        ;++i)
+        {
+        export_single_table(filename, i->index, i->name.c_str());
+        }
+}
+
+
+int main(int argc, char *argv[])
+{
+    try
+    {
+        for(int i = 1; i < argc; i++)
+            {
+            export_soa_file(argv[i]);
+            }
+        return 0;
+    }
+    catch ( const std::exception& e )
+    {
+        std::cerr << "Error: " << e.what() << std::endl;
+        return 1;
+    }
+}


Property changes on: lmi/trunk/soa2xml.cpp
___________________________________________________________________
Added: svn:keywords
   + Id

Added: lmi/trunk/soa_helpers.hpp
===================================================================
--- lmi/trunk/soa_helpers.hpp                           (rev 0)
+++ lmi/trunk/soa_helpers.hpp   2012-05-27 16:15:12 UTC (rev 5468)
@@ -0,0 +1,87 @@
+
+#include "actuarial_table.hpp"
+#include "miscellany.hpp"
+#include "path_utility.hpp" // fs::path inserter
+
+#include <boost/cstdint.hpp>
+#include <boost/filesystem/convenience.hpp>
+#include <boost/filesystem/fstream.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/format.hpp>
+#include <boost/static_assert.hpp>
+
+#include <climits>   // CHAR_BIT
+
+/************************************************************************
+ misc helpers
+ ************************************************************************/
+
+inline void error(const boost::format& fmt)
+{
+    throw std::runtime_error(fmt.str());
+}
+
+
+/************************************************************************
+ SOA actuarial table format helpers
+ ************************************************************************/
+
+struct soa_record_info
+{
+    int         index;
+    std::string name;
+};
+
+std::vector<soa_record_info> list_soa_file_tables(const char *filename)
+{
+    std::vector<soa_record_info> v;
+
+    fs::path index_path(filename);
+    index_path = fs::change_extension(index_path, ".ndx");
+    fs::ifstream index_ifs(index_path, ios_in_binary());
+    if(!index_ifs)
+        {
+        error(boost::format("File '%1%' is required but could not be found.") 
% index_path);
+        }
+
+    // Index records have fixed length:
+    //   4-byte integer:     table number
+    //   50-byte char array: table name
+    //   4-byte integer:     byte offset into '.dat' file
+    // Table numbers are not necessarily consecutive or sorted.
+
+    // SOA !! Assert endianness too? SOA tables are not portable;
+    // probably they can easily be read only on x86 hardware.
+
+    BOOST_STATIC_ASSERT(8 == CHAR_BIT);
+    BOOST_STATIC_ASSERT(4 == sizeof(int));
+    BOOST_STATIC_ASSERT(2 == sizeof(short int));
+
+    int const index_record_length(58);
+    char index_record[index_record_length] = {0};
+
+    BOOST_STATIC_ASSERT(sizeof(boost::int32_t) <= sizeof(int));
+    while(index_ifs)
+        {
+        index_ifs.read(index_record, index_record_length);
+        if(index_record_length != index_ifs.gcount())
+            {
+            if(!index_ifs)
+                break;
+            error(
+                boost::format("Table index file file '%1%': attempted to read 
%2% bytes, but got %3% bytes instead.")
+                % index_path
+                % index_record_length
+                % index_ifs
+                );
+            }
+
+        soa_record_info rec;
+        rec.index = *reinterpret_cast<boost::int32_t*>(index_record);
+        rec.name.assign(index_record + 4);
+        v.push_back(rec);
+        }
+
+    return v;
+}
+


Property changes on: lmi/trunk/soa_helpers.hpp
___________________________________________________________________
Added: svn:keywords
   + Id




reply via email to

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