[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [lmi-commits] [5468] Add binary-to-xml migration tool,
Greg Chicares <=