Go to the documentation of this file.00001
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
00173
00174
00175