/* $Id: io.h 5149 2010-03-24 23:37:18Z abehm $ Copyright (C) 2010 by The Regents of the University of California Redistribution of this file is permitted under the terms of the BSD license. Date: 06/27/2008 Author: Rares Vernica */ #ifndef _io_h_ #define _io_h_ #include #include #include #include #include #include "range.h" #include "util/debug.h" template class out { T data; public: out(T data = T()): data(data) {} operator T() const { return data; } friend std::ostream& operator<<(std::ostream &output, const out &b) { return output << b.data; } }; // -- - read/write a binary string from/to stream - -- std::istream& read_binary_string(std::istream &in, std::string &str); std::ostream& write_binary_string(std::ostream &out, const std::string &str); // -- - for use with copy-like functions for read/write - -- // e.g., copy(begin, end, ostream_iterator >(file)); template class binary_io { T data; public: binary_io(T data = T()): data(data) {} operator T() const { return data; } friend std::istream& operator>>(std::istream &in, binary_io &b) { return in.read(reinterpret_cast(&b.data), sizeof(T)); } friend std::ostream& operator<<(std::ostream &out, const binary_io &b) { return out.write(reinterpret_cast(&b.data), sizeof(T)); } }; template<> class binary_io { std::string data; public: binary_io(std::string data = std::string()): data(data) {} operator std::string() const { return data; } friend std::istream& operator>>(std::istream &in, binary_io &b) { return read_binary_string(in, b.data); } friend std::ostream& operator<<(std::ostream &out, const binary_io &b) { return write_binary_string(out, b.data); } }; template class binary_io > { range data; public: binary_io(range value = range()): data(value) {} operator range() const { return data; } friend std::istream& operator>>(std::istream &in, binary_io &b) { in.read(reinterpret_cast(&b.data._begin), sizeof(T)); return in.read(reinterpret_cast(&b.data.end), sizeof(T)); } friend std::ostream& operator<<(std::ostream &out, const binary_io &b) { out.write(reinterpret_cast(&b.data._begin), sizeof(T)); return out.write(reinterpret_cast(&b.data._end), sizeof(T)); } }; template std::istream& text_io_read(std::istream &in, T &d) { return in >> d; } template<> std::istream& text_io_read(std::istream &in, std::string &d); template class text_io { T data; public: text_io(T value = T()): data(value) {} operator T() const { return data; } friend std::istream& operator>>(std::istream &in, text_io &b) { return text_io_read(in, b.data); } friend std::ostream& operator<<(std::ostream &out, const text_io &b) { return out << b.data << std::endl; } }; template struct text_reader { std::istream ∈ text_reader(std::istream &in): in(in) {} void operator()(T& e) { in >> e; } }; // -- - for use with foreach-like functions for read - -- // usefull when we don't want to read the entire file // we do as many reds as elements in the container // e.g., for_each(begin, end, binary_reader(file)) template struct binary_reader { std::istream ∈ binary_reader(std::istream &in): in(in) {} void operator()(T &e) { in.read(reinterpret_cast(&e), sizeof(T)); } }; template<> struct binary_reader { std::istream ∈ binary_reader(std::istream &in): in(in) {} void operator()(std::string &e) { read_binary_string(in, e); } }; template struct binary_reader > { std::istream ∈ binary_reader(std::istream &in): in(in) {} void operator()(range &e) { in.read(reinterpret_cast(&e._begin), sizeof(T)); in.read(reinterpret_cast(&e._end), sizeof(T)); } }; template struct binary_writer { std::ostream &out; binary_writer(std::ostream &out): out(out) {} void operator()(T &e) { out.write(reinterpret_cast(&e), sizeof(T)); } }; template void readTextFile(const std::string &filename, OutputIterator out) { std::ifstream file(filename.c_str(), std::ios::in); if (!file) { std::cerr << "can't open input file \"" << filename << "\"" << std::endl; exit(EXIT_FAILURE); } READING_FILE(filename); copy( std::istream_iterator >(file), std::istream_iterator >(), out); READING_DONE(); } template void readBinaryFile(const std::string &filename, OutputIterator out) { std::ifstream file(filename.c_str(), std::ios::in | std::ios::binary); if (!file) { std::cerr << "can't open input file \"" << filename << "\"" << std::endl; exit(EXIT_FAILURE); } READING_FILE(filename); copy( std::istream_iterator >(file), std::istream_iterator >(), out); READING_DONE(); } template void writeTextFile( const std::string &filename, InputIterator in, InputIterator in_end) { std::ofstream file(filename.c_str(), std::ios::out); if (!file) { std::cerr << "can't open output file \"" << filename << "\"" << std::endl; exit(EXIT_FAILURE); } WRITING_FILE(filename); copy(in, in_end, std::ostream_iterator >(file)); WRITING_DONE(); } template void writeBinaryFile( const std::string &filename, InputIterator in, InputIterator in_end) { std::ofstream file(filename.c_str(), std::ios::out | std::ios::binary); if (!file) { std::cerr << "can't open output file \"" << filename << "\"" << std::endl; exit(EXIT_FAILURE); } WRITING_FILE(filename); copy(in, in_end, std::ostream_iterator >(file)); WRITING_DONE(); } // -- - more code - -- /* bool existFile(const string &filename) { std::ifstream file(filename.c_str(), std::ios::in); if (!file) return false; file.close(); return true; } */ /* template class binary_input_iterator: public std::iterator { private: std::istream *i_ptr; T d; public: binary_input_iterator(): i_ptr(0) {} binary_input_iterator(std::istream& i): i_ptr(&i) { read(); } bool operator==(const binary_input_iterator &j) const { return i_ptr == j.i_ptr || i_ptr == 0 && (! *j.i_ptr || j.i_ptr->eof()) || (! *i_ptr || i_ptr->eof()) && j.i_ptr == 0; } bool operator!=(const binary_input_iterator &j) const { return !operator==(j); } const binary_input_iterator& operator++() { read(); return *this; } binary_input_iterator operator++(int) { read(); return *this; } T operator*() { return d; } private: void read() { i_ptr->read(reinterpret_cast(&d), sizeof(T)); } }; template class binary_output_iterator: public std::iterator { std::ostream *o_ptr; public: binary_output_iterator(std::ostream& i): o_ptr(&i) {} const binary_output_iterator& operator++() const { return *this; } binary_output_iterator& operator*() { return *this; } binary_output_iterator& operator=(const T & d) { o_ptr->write(reinterpret_cast(&d), sizeof(T)); return *this; } }; */ #endif // _io_h_