Index: trunk/lttoolbox/lttoolbox/Makefile.am =================================================================== --- trunk/lttoolbox/lttoolbox/Makefile.am (revision 71730) +++ trunk/lttoolbox/lttoolbox/Makefile.am (revision 71731) @@ -1,8 +1,8 @@ h_sources = alphabet.h att_compiler.h buffer.h compiler.h compression.h \ - entry_token.h expander.h fst_processor.h lt_locale.h ltstr.h \ - match_exe.h match_node.h match_state.h my_stdio.h node.h \ - pattern_list.h regexp_compiler.h sorted_vector.h state.h \ + deserialiser.h entry_token.h expander.h fst_processor.h lt_locale.h \ + ltstr.h match_exe.h match_node.h match_state.h my_stdio.h node.h \ + pattern_list.h regexp_compiler.h serialiser.h sorted_vector.h state.h \ transducer.h trans_exe.h xml_parse_util.h exception.h tmx_compiler.h cc_sources = alphabet.cc att_compiler.cc compiler.cc compression.cc entry_token.cc \ expander.cc fst_processor.cc lt_locale.cc match_exe.cc \ Index: trunk/lttoolbox/lttoolbox/alphabet.cc =================================================================== --- trunk/lttoolbox/lttoolbox/alphabet.cc (revision 71730) +++ trunk/lttoolbox/lttoolbox/alphabet.cc (revision 71731) @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include @@ -171,6 +173,30 @@ } void +Alphabet::serialise(std::ostream &serialised) const +{ + Serialiser >::serialise(slexicinv, serialised); + Serialiser > >::serialise(spairinv, serialised); +} + +void +Alphabet::deserialise(std::istream &serialised) +{ + slexicinv.clear(); + slexic.clear(); + spairinv.clear(); + spair.clear(); + slexicinv = Deserialiser >::deserialise(serialised); + for (size_t i = 0; i < slexicinv.size(); i++) { + slexic[slexicinv[i]] = i; + } + spairinv = Deserialiser > >::deserialise(serialised); + for (size_t i = 0; i < slexicinv.size(); i++) { + spair[spairinv[i]] = i; + } +} + +void Alphabet::writeSymbol(int const symbol, FILE *output) const { if(symbol < 0) Index: trunk/lttoolbox/lttoolbox/alphabet.h =================================================================== --- trunk/lttoolbox/lttoolbox/alphabet.h (revision 71730) +++ trunk/lttoolbox/lttoolbox/alphabet.h (revision 71731) @@ -133,6 +133,9 @@ */ void read(FILE *input); + void serialise(std::ostream &serialised) const; + void deserialise(std::istream &serialised); + /** * Write a symbol enclosed by angle brackets in the output stream. * @param symbol symbol code. Index: trunk/lttoolbox/lttoolbox/deserialiser.h =================================================================== --- trunk/lttoolbox/lttoolbox/deserialiser.h (nonexistent) +++ trunk/lttoolbox/lttoolbox/deserialiser.h (revision 71731) @@ -0,0 +1,185 @@ +// Copyright (C) 2005 Universitat d'Alacant / Universidad de Alicante +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, see . + +#ifndef DESERIALISER_H +#define DESERIALISER_H + +#include "exception.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +template +struct remove_const +{ + typedef T type; +}; +template +struct remove_const +{ + typedef T type; +}; + +template class Deserialiser; + +template +class Deserialiser > { +public: + inline static std::basic_string + deserialise(std::istream &Stream_); +}; + +template +class Deserialiser > { +public: + inline static std::pair + deserialise(std::istream &Stream_); +}; + +template <> class Deserialiser { +public: + inline static signed int deserialise(std::istream &Stream_); +}; + +template <> class Deserialiser { +public: + inline static size_t deserialise(std::istream &Stream_); +}; + +template <> class Deserialiser { +public: + inline static wchar_t deserialise(std::istream &Stream_); +}; + +template <> class Deserialiser { +public: + inline static char deserialise(std::istream &Stream_); +}; + +template<> class Deserialiser { +public: + inline static double deserialise(std::istream &Stream_); +}; + +template +class Deserialiser { +public: + inline static Container deserialise(std::istream &Stream_); +}; + +template +std::basic_string +Deserialiser >::deserialise( + std::istream &Stream_) { + std::size_t SerialisedValueCount = + Deserialiser::deserialise(Stream_); + std::basic_string SerialisedType_; + + for (; SerialisedValueCount != 0; --SerialisedValueCount) { + SerialisedType_.push_back(Deserialiser::deserialise(Stream_)); + } + + return SerialisedType_; +} + +template +std::pair +Deserialiser >::deserialise( + std::istream &Stream_) { + first_type a = Deserialiser::type>::deserialise(Stream_); + second_type b = Deserialiser::type>::deserialise(Stream_); + return std::make_pair(a, b); +} + +template +integer_type int_deserialise(std::istream &Stream_) { + try { + integer_type SerialisedType_ = 0; + unsigned char SerialisedTypeSize = Stream_.get(); + + if (!Stream_) + throw DeserialisationException("can't deserialise size"); + + for (; SerialisedTypeSize != 0;) { + SerialisedType_ += + static_cast(Stream_.get()) + << std::numeric_limits::digits * --SerialisedTypeSize; + + if (!Stream_) + throw DeserialisationException("can't deserialise byte"); + } + + return SerialisedType_; + } catch (const std::exception &exc) { + std::stringstream what_; + what_ << "can't deserialise " << sizeof(integer_type) << " byte integer type: " << exc.what(); + throw DeserialisationException(what_.str().c_str()); + } +} + +signed int Deserialiser::deserialise(std::istream &Stream_) { + // Assumes size_t >= int and signed int != size_t + return Deserialiser::deserialise(Stream_); +} + +size_t Deserialiser::deserialise(std::istream &Stream_) { + // Assumes size_t == uint64_t, ie it is fixed across platforms + return int_deserialise(Stream_); +} + +wchar_t Deserialiser::deserialise(std::istream &Stream_) { + return int_deserialise(Stream_); +} + +char Deserialiser::deserialise(std::istream &Stream_) { + return int_deserialise(Stream_); +} + +double Deserialiser::deserialise(std::istream &Stream_) { + union { + uint64_t i; + double d; + } u; + u.i = Deserialiser::deserialise(Stream_); + return u.d; +} + +template +Container +Deserialiser::deserialise(std::istream &Stream_) { + std::size_t SerialisedValueCount = + Deserialiser::deserialise(Stream_); + typename remove_const::type SerialisedType_; + std::insert_iterator::type> insert_it = + std::inserter(SerialisedType_, SerialisedType_.begin()); + + for (; SerialisedValueCount != 0; --SerialisedValueCount) { + *(insert_it++) = Deserialiser::deserialise(Stream_); + } + + return SerialisedType_; +} + +#endif // DESERIALISER_H Index: trunk/lttoolbox/lttoolbox/exception.h =================================================================== --- trunk/lttoolbox/lttoolbox/exception.h (revision 71730) +++ trunk/lttoolbox/lttoolbox/exception.h (revision 71731) @@ -42,4 +42,19 @@ std::string msg; }; +class IOException : public Exception { +public: + IOException(const char* _msg) throw () : Exception(_msg) {}; +}; + +class SerialisationException : public IOException { +public: + SerialisationException(const char* _msg) throw () : IOException(_msg) {}; +}; + +class DeserialisationException : public IOException { +public: + DeserialisationException(const char* _msg) throw () : IOException(_msg) {}; +}; + #endif Index: trunk/lttoolbox/lttoolbox/pattern_list.cc =================================================================== --- trunk/lttoolbox/lttoolbox/pattern_list.cc (revision 71730) +++ trunk/lttoolbox/lttoolbox/pattern_list.cc (revision 71731) @@ -16,6 +16,8 @@ */ #include #include +#include +#include #include #include @@ -399,6 +401,22 @@ } } +void +PatternList::serialise(std::ostream &serialised) const +{ + alphabet.serialise(serialised); + transducer.serialise(serialised); + Serialiser >::serialise(final_type, serialised); +} + +void +PatternList::deserialise(std::istream &serialised) +{ + alphabet.deserialise(serialised); + transducer.deserialise(serialised); + final_type = Deserialiser >::deserialise(serialised); +} + MatchExe * PatternList::newMatchExe() { Index: trunk/lttoolbox/lttoolbox/pattern_list.h =================================================================== --- trunk/lttoolbox/lttoolbox/pattern_list.h (revision 71730) +++ trunk/lttoolbox/lttoolbox/pattern_list.h (revision 71731) @@ -136,6 +136,9 @@ * @param output the output stream */ void write(FILE *output); + + void serialise(std::ostream &serialised) const; + void deserialise(std::istream &serialised); /** * Create a new MatchExe from PatternList, must be freed with 'delete' Index: trunk/lttoolbox/lttoolbox/serialiser.h =================================================================== --- trunk/lttoolbox/lttoolbox/serialiser.h (nonexistent) +++ trunk/lttoolbox/lttoolbox/serialiser.h (revision 71731) @@ -0,0 +1,216 @@ +// Copyright (C) 2005 Universitat d'Alacant / Universidad de Alicante +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, see . + +#ifndef SERIALISER_H +#define SERIALISER_H + +#include "exception.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { +template +static unsigned char compressedSize(const SerialisedType &SerialisedType_) { + unsigned char compressedSize_ = 0; + + // Have to be careful here, if we shift >> 64 it's the same as >> 0 so make + // sure only to shift up to >> 56 + for (; (SerialisedType_ >> + std::numeric_limits::digits * compressedSize_ > 255); + ++compressedSize_) { + } + ++compressedSize_; + + return compressedSize_; +} + +template class Serialiser; + +template +class Serialiser > { +public: + inline static void + serialise(const std::basic_string &SerialisedType_, + std::ostream &Output); +}; + +template +class Serialiser > { +public: + inline static void + serialise(const std::pair &SerialisedType_, + std::ostream &Output); +}; + +template <> class Serialiser { +public: + inline static void serialise(const signed int &SerialisedType_, + std::ostream &Output); +}; + +template <> class Serialiser { +public: + inline static void serialise(const size_t &SerialisedType_, + std::ostream &Output); +}; + +template <> class Serialiser { +public: + inline static void serialise(const wchar_t &SerialisedType_, + std::ostream &Output); +}; + +template <> class Serialiser { +public: + inline static void serialise(const char &SerialisedType_, + std::ostream &Output); +}; + +template<> class Serialiser { +public: + inline static void serialise(const double &SerialisedType_, + std::ostream &Output); +}; + +template +class Serialiser { +public: + inline static void serialise(const Container &SerialisedType_, + std::ostream &Output); +}; +} + +template +inline void serialise(const SerialisedType &SerialisedType_, + std::ostream &Output) { + Serialiser::serialise(SerialisedType_, Output); +} + +template +void Serialiser >::serialise( + const std::basic_string &SerialisedType_, + std::ostream &Output) { + ::serialise(SerialisedType_.size(), Output); + + for (typename std::basic_string::const_iterator + SerialisedType_iterator = SerialisedType_.begin(); + // Call .end() each iteration to save memory. + SerialisedType_iterator != SerialisedType_.end(); + ++SerialisedType_iterator) { + ::serialise(*SerialisedType_iterator, Output); + } +} + +template +void Serialiser >::serialise( + const std::pair &SerialisedType_, + std::ostream &Output) { + ::serialise(SerialisedType_.first, Output); + ::serialise(SerialisedType_.second, Output); +} + +template +void int_serialise(const integer_type &SerialisedType_, + std::ostream &Output) { + try { + Output.put(compressedSize(SerialisedType_)); + + if (!Output) { + std::stringstream what_; + what_ << "can't serialise size " << std::hex + << /* [1] */ +compressedSize(SerialisedType_) << std::dec; + throw SerialisationException(what_.str().c_str()); + } + + for (unsigned char CompressedSize = compressedSize(SerialisedType_); + CompressedSize != 0; Output.put(static_cast( + SerialisedType_ >> + std::numeric_limits::digits * --CompressedSize))) { + if (!Output) { + std::stringstream what_; + what_ << "can't serialise byte " << std::hex + << /* [1] */ +static_cast( + SerialisedType_ >> + std::numeric_limits::digits * + CompressedSize) << std::dec; + throw SerialisationException(what_.str().c_str()); + } + } + } catch (const SerialisationException &exc) { + std::stringstream what_; + what_ << "can't serialise const " << sizeof(integer_type) << " byte integer type: " + << exc.what(); + throw SerialisationException(what_.str().c_str()); + } +} + +void Serialiser::serialise(const signed int &SerialisedType_, + std::ostream &Output) { + // Assumes size_t >= int and signed int != size_t + Serialiser::serialise(SerialisedType_, Output); +} + +void Serialiser::serialise(const size_t &SerialisedType_, + std::ostream &Output) { + // Assumes size_t == uint64_t, ie it is fixed across platforms + int_serialise(SerialisedType_, Output); +} + +void Serialiser::serialise(const wchar_t &SerialisedType_, + std::ostream &Output) { + int_serialise(SerialisedType_, Output); +} + +void Serialiser::serialise(const char &SerialisedType_, + std::ostream &Output) { + int_serialise(SerialisedType_, Output); +} + +void Serialiser::serialise(const double &SerialisedType_, + std::ostream &Output) { + union { + uint64_t i; + double d; + } u; + u.d = SerialisedType_; + Serialiser::serialise(u.i, Output); +} + +template +void Serialiser::serialise( + const Container &SerialisedType_, std::ostream &Output) { + ::serialise(SerialisedType_.size(), Output); + + for (typename Container::const_iterator value_type_ = + SerialisedType_.begin(); + // Call .end() each iteration to save memory. + value_type_ != SerialisedType_.end(); ++value_type_) { + ::serialise(*value_type_, Output); + } +} + +// [1] operator+ promotes its operand to a printable integral type. + +#endif // SERIALISER_H Index: trunk/lttoolbox/lttoolbox/stdint_shim.h =================================================================== --- trunk/lttoolbox/lttoolbox/stdint_shim.h (nonexistent) +++ trunk/lttoolbox/lttoolbox/stdint_shim.h (revision 71731) @@ -0,0 +1,6 @@ +#ifdef _MSC_VER +typedef unsigned __int64 uint64_t; +typedef signed __int64 int64_t; +#else +#include +#endif Index: trunk/lttoolbox/lttoolbox/transducer.cc =================================================================== --- trunk/lttoolbox/lttoolbox/transducer.cc (revision 71730) +++ trunk/lttoolbox/lttoolbox/transducer.cc (revision 71731) @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include @@ -561,6 +563,22 @@ } void +Transducer::serialise(std::ostream &serialised) const +{ + Serialiser::serialise(initial, serialised); + Serialiser >::serialise(finals, serialised); + Serialiser > >::serialise(transitions, serialised); +} + +void +Transducer::deserialise(std::istream &serialised) +{ + initial = Deserialiser::deserialise(serialised); + finals = Deserialiser >::deserialise(serialised); + transitions = Deserialiser > >::deserialise(serialised); +} + +void Transducer::copy(Transducer const &t) { initial = t.initial; Index: trunk/lttoolbox/lttoolbox/transducer.h =================================================================== --- trunk/lttoolbox/lttoolbox/transducer.h (revision 71730) +++ trunk/lttoolbox/lttoolbox/transducer.h (revision 71731) @@ -278,6 +278,9 @@ */ void read(FILE *input, int const decalage = 0); + void serialise(std::ostream &serialised) const; + void deserialise(std::istream &serialised); + /** * Insert another transducer into this, unifying source and targets. * Does not minimize.