@@ -20,10 +20,33 @@ namespace xt
2020{
2121 namespace detail
2222 {
23- template <typename T>
24- inline xt::svector<T> load_bin_file (std::istream& stream, bool as_big_endian)
23+ // load_bin "overload" for file-like objects
24+ // we check that `fclose` can be called on them!
25+ template <typename T, class I >
26+ auto load_bin_imp (I& file, std::string& buffer)
27+ -> decltype(fclose(file), void())
2528 {
26- std::string buffer{std::istreambuf_iterator<char >{stream}, {}};
29+ fseek (file, 0 , SEEK_END);
30+ std::size_t size = ftell (file);
31+ buffer.resize (size);
32+ rewind (file);
33+ fread (&buffer[0 ], 1 , size, file);
34+ }
35+
36+ // load_bin "overload" for stream-like objects
37+ // we check that they have a `tellg` method!
38+ template <typename T, class I >
39+ auto load_bin_imp (I& stream, std::string& buffer)
40+ -> decltype(stream.tellg(), void())
41+ {
42+ buffer = {std::istreambuf_iterator<char >{stream}, {}};
43+ }
44+
45+ template <typename T, class I >
46+ inline xt::svector<T> load_bin (I& stream, bool as_big_endian)
47+ {
48+ std::string buffer;
49+ load_bin_imp<T>(stream, buffer);
2750 std::size_t uncompressed_size = buffer.size () / sizeof (T);
2851 xt::svector<T> uncompressed_buffer (uncompressed_size);
2952 std::copy ((const T*)(buffer.data ()), (const T*)(buffer.data ()) + uncompressed_size, uncompressed_buffer.begin ());
@@ -34,8 +57,28 @@ namespace xt
3457 return uncompressed_buffer;
3558 }
3659
60+ // dump_bin "overload" for file-like objects
61+ // we check that `fclose` can be called on them!
62+ template <class O >
63+ auto dump_bin_imp (O& file, const char * uncompressed_buffer, std::size_t uncompressed_size)
64+ -> decltype(fclose(file), void())
65+ {
66+ fwrite (uncompressed_buffer, 1 , uncompressed_size, file);
67+ fflush (file);
68+ }
69+
70+ // dump_bin "overload" for stream-like objects
71+ // we check that they have a `tellp` method!
72+ template <class O >
73+ auto dump_bin_imp (O& stream, const char * uncompressed_buffer, std::size_t uncompressed_size)
74+ -> decltype(stream.tellp(), void())
75+ {
76+ stream.write (uncompressed_buffer, std::streamsize (uncompressed_size));
77+ stream.flush ();
78+ }
79+
3780 template <class O , class E >
38- inline void dump_bin_stream (O& stream, const xexpression<E>& e, bool as_big_endian)
81+ inline void dump_bin (O& stream, const xexpression<E>& e, bool as_big_endian)
3982 {
4083 using value_type = typename E::value_type;
4184 const E& ex = e.derived_cast ();
@@ -56,21 +99,26 @@ namespace xt
5699 {
57100 uncompressed_buffer = reinterpret_cast <const char *>(eval_ex.data ());
58101 }
59- stream.write (uncompressed_buffer, std::streamsize (uncompressed_size));
60- stream.flush ();
102+ dump_bin_imp (stream, uncompressed_buffer, uncompressed_size);
61103 }
62104 } // namespace detail
63105
106+ template <typename E, class O >
107+ inline void dump_bin (O& stream, const xexpression<E>& e, bool as_big_endian=is_big_endian())
108+ {
109+ detail::dump_bin (stream, e, as_big_endian);
110+ }
111+
64112 /* *
65113 * Save xexpression to binary format
66114 *
67115 * @param stream An output stream to which to dump the data
68116 * @param e the xexpression
69117 */
70118 template <typename E>
71- inline void dump_bin (std::ostream & stream, const xexpression<E>& e, bool as_big_endian=is_big_endian())
119+ inline void dump_bin (std::ofstream & stream, const xexpression<E>& e, bool as_big_endian=is_big_endian())
72120 {
73- detail::dump_bin_stream (stream, e, as_big_endian);
121+ detail::dump_bin (stream, e, as_big_endian);
74122 }
75123
76124 /* *
@@ -87,7 +135,7 @@ namespace xt
87135 {
88136 std::runtime_error (" IO Error: failed to open file" );
89137 }
90- detail::dump_bin_stream (stream, e, as_big_endian);
138+ detail::dump_bin (stream, e, as_big_endian);
91139 }
92140
93141 /* *
@@ -99,7 +147,7 @@ namespace xt
99147 inline std::string dump_bin (const xexpression<E>& e, bool as_big_endian=is_big_endian())
100148 {
101149 std::stringstream stream;
102- detail::dump_bin_stream (stream, e, as_big_endian);
150+ detail::dump_bin (stream, e, as_big_endian);
103151 return stream.str ();
104152 }
105153
@@ -112,10 +160,10 @@ namespace xt
112160 * Fortran format
113161 * @return xarray with contents from binary file
114162 */
115- template <typename T, layout_type L = layout_type::dynamic>
116- inline auto load_bin (std::istream & stream, bool as_big_endian=is_big_endian())
163+ template <typename T, layout_type L = layout_type::dynamic, class I >
164+ inline auto load_bin (I & stream, bool as_big_endian=is_big_endian())
117165 {
118- xt::svector<T> uncompressed_buffer = detail::load_bin_file <T>(stream, as_big_endian);
166+ xt::svector<T> uncompressed_buffer = detail::load_bin <T>(stream, as_big_endian);
119167 std::vector<std::size_t > shape = {uncompressed_buffer.size ()};
120168 auto array = adapt (std::move (uncompressed_buffer), shape);
121169 return array;
@@ -170,8 +218,8 @@ namespace xt
170218 }
171219 };
172220
173- template <class E >
174- void load_file (std::istream & stream, xexpression<E>& e, const xio_binary_config& config)
221+ template <class E , class I >
222+ void load_file (I & stream, xexpression<E>& e, const xio_binary_config& config)
175223 {
176224 E& ex = e.derived_cast ();
177225 auto shape = ex.shape ();
@@ -186,8 +234,8 @@ namespace xt
186234 }
187235 }
188236
189- template <class E >
190- void dump_file (std::ostream & stream, const xexpression<E> &e, const xio_binary_config& config)
237+ template <class E , class O >
238+ void dump_file (O & stream, const xexpression<E> &e, const xio_binary_config& config)
191239 {
192240 dump_bin (stream, e, config.big_endian );
193241 }
0 commit comments