binaryIO.cc
Go to the documentation of this file.
00001 /* binaryIO.cc
00002  */
00003 #include "osl/misc/binaryIO.h"
00004 #include "osl/oslConfig.h"
00005 #include <boost/serialization/serialization.hpp>
00006 #include <boost/serialization/vector.hpp>
00007 #include <boost/archive/text_iarchive.hpp>
00008 #include <boost/archive/text_oarchive.hpp>
00009 #include <boost/iostreams/filtering_streambuf.hpp>
00010 #include <boost/iostreams/filter/bzip2.hpp>
00011 #include <iostream>
00012 
00013 namespace osl
00014 {
00015   namespace
00016   {
00017     const size_t split_limit = 8*1024;
00018     template <class T>
00019     void write_vector(std::ostream& os, const std::vector<T>& data)
00020     {
00021       boost::iostreams::filtering_streambuf<boost::iostreams::output> filter;
00022       filter.push(boost::iostreams::bzip2_compressor());
00023       filter.push(os);
00024       std::ostream out(&filter);
00025     
00026       boost::archive::text_oarchive oa(out);
00027       if (data.size() <= split_limit) {
00028         oa << data;
00029       }
00030       else {
00031         for (size_t p=0; p<data.size(); p+=split_limit) {
00032           std::vector<T> tmp(data.begin()+p,
00033                              data.begin()+std::min(p+split_limit,
00034                                                    data.size()));
00035           oa << tmp;
00036         }
00037       }
00038     }
00039   }
00040 }
00041 
00042 void osl::misc::BinaryWriter::
00043 write(std::ostream& os, const std::vector<int>& data)
00044 {
00045   write_vector(os, data);
00046 }
00047 void osl::misc::BinaryWriter::
00048 write(std::ostream& os, const std::vector<double>& data)
00049 {
00050   write_vector(os, data);
00051 }
00052 
00053 
00054 template <class T>
00055 osl::misc::BinaryReader<T>::BinaryReader(std::istream& is)
00056   : state(new State(is))
00057 {
00058 }
00059 template <class T>
00060 osl::misc::BinaryReader<T>::~BinaryReader()
00061 {
00062 }
00063 
00064 template <class T>
00065 struct osl::misc::BinaryReader<T>::State
00066 {
00067   boost::iostreams::filtering_streambuf<boost::iostreams::input> filter;
00068   boost::scoped_ptr<std::istream> in;
00069   boost::scoped_ptr<boost::archive::text_iarchive> ia;
00070   explicit State(std::istream &is)
00071   {
00072     if (!is)
00073       return;
00074     filter.push(boost::iostreams::bzip2_decompressor());
00075     filter.push(is);
00076     in.reset(new std::istream(&filter));
00077     ia.reset(new boost::archive::text_iarchive(*in));
00078   }
00079   bool read_vector(std::vector<T>& data)
00080   {
00081     if (! in || ! *in)
00082       return false;
00083     return (*ia) >> data, *in;
00084   }
00085 };
00086 
00087 template <class T>
00088 bool osl::misc::BinaryReader<T>::
00089 read(std::vector<T>& data)
00090 {
00091   return state->read_vector(data);
00092 }
00093 
00094 template <class T>
00095 size_t osl::misc::BinaryReader<T>::blockSize()
00096 {
00097   return split_limit;
00098 }
00099 
00100 
00101 template <class T>
00102 struct osl::misc::BinaryElementReader<T>::State
00103 {
00104   BinaryReader<T> reader;
00105   std::vector<T> data;
00106   size_t cur;
00107   bool failed;
00108   explicit State(std::istream& is) : reader(is), cur(0), failed(!is)
00109   {
00110   }
00111   bool hasNext() 
00112   {
00113     tryRead();
00114     return cur < data.size();
00115   }
00116   T read()
00117   {
00118     if (! hasNext())
00119       throw std::logic_error("no data in BinaryReader::read");
00120     return data[cur++];
00121   }
00122   void tryRead()
00123   {
00124     if (cur < data.size())
00125       return;
00126     data.clear();
00127     cur = 0;
00128     try {
00129       failed = ! reader.read(data);
00130     } catch (boost::archive::archive_exception& e) {
00131       if (OslConfig::verbose() || 1)
00132         std::cerr << "read failed in BinaryReader " << e.what();
00133       cur = data.size();
00134       failed = true;
00135     }
00136   }
00137 };
00138   
00139 template <class T>
00140 osl::misc::BinaryElementReader<T>::BinaryElementReader(std::istream& is)
00141   : state(new State(is))
00142 {
00143 }
00144 template <class T>
00145 osl::misc::BinaryElementReader<T>::~BinaryElementReader()
00146 {
00147 }
00148 template <class T>
00149 bool osl::misc::BinaryElementReader<T>::
00150 hasNext() const
00151 {
00152   return state->hasNext();
00153 }
00154 template <class T>
00155 bool osl::misc::BinaryElementReader<T>::
00156 failed() const
00157 {
00158   return state->failed;
00159 }
00160 template <class T>
00161 T osl::misc::BinaryElementReader<T>::read()
00162 {
00163   return state->read();
00164 }
00165 
00166 
00167 template class osl::misc::BinaryReader<int>;
00168 template class osl::misc::BinaryReader<double>;
00169 template class osl::misc::BinaryElementReader<int>;
00170 template class osl::misc::BinaryElementReader<double>;
00171 
00172 // ;;; Local Variables:
00173 // ;;; mode:c++
00174 // ;;; c-basic-offset:2
00175 // ;;; End:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines