/*---------------------------------------------------------------------------* * IT++ * *---------------------------------------------------------------------------* * Copyright (c) 1995-2004 by Tony Ottosson, Thomas Eriksson, Pål Frenger, * * Tobias Ringström, and Jonas Samuelsson. * * * * Permission to use, copy, modify, and distribute this software and its * * documentation under the terms of the GNU General Public License is hereby * * granted. No representations are made about the suitability of this * * software for any purpose. It is provided "as is" without expressed or * * implied warranty. See the GNU General Public License for more details. * *---------------------------------------------------------------------------*/ /*! \file \brief Implementation of classes for the IT++ file format. \author Tobias Ringström and Tony Ottosson 1.13 2004/10/29 10:54:52 */ #include "base/itfile.h" using std::string; using std::streampos; using std::ios; using std::cout; using std::endl; namespace itpp { char it_file_base::file_magic[4] = { 'I', 'T', '+', '+' }; char it_file_base::file_version = 2; it_ifile::it_ifile() { } it_ifile::it_ifile(const std::string &name) { open(name); } void it_ifile::open(const std::string &name) { if (!exist(name)) throw Error("File does not exist"); s.open_readonly(name); if (!read_check_file_header()) { s.close(); throw Error("Corrupt file"); } } void it_ifile::close() { s.close(); } void it_ifile::seek(const std::string &name) { data_header h; streampos p; s.clear(); s.seekg(sizeof(file_header)); while (true) { p = s.tellg(); read_data_header(h); if (s.eof()) { s.clear(); throw Error("Variable '"+name+"' not found"); } if (h.type != "" && h.name == name) { s.seekg(p); break; } s.seekg(p + static_cast(h.block_bytes)); } } bool it_ifile::seek(int n) { data_header h; streampos p; s.clear(); s.seekg(sizeof(file_header)); for (int i=0; i<=n; i++) { p = s.tellg(); // changed from tellp() since probably an error read_data_header(h); if (s.eof()) { s.clear(); return false; } if (h.type == "") i--; s.seekg(i==n ? p : p+static_cast(h.block_bytes)); } return true; } void it_ifile::info(string &name, string &type, int &bytes) { data_header h; streampos p; p = s.tellg(); // changed from tellp() read_data_header(h); s.seekg(p); name = h.name; type = h.type; bytes = h.data_bytes; } bool it_ifile::read_check_file_header() { file_header h; memset(&h, 0, sizeof(h)); // Clear the struct s.read(reinterpret_cast(&h), sizeof(h)); return (memcmp(h.magic, file_magic, 4) == 0 && (h.version <= file_version) ); } void it_ifile::read_data_header(data_header &h) { streampos p=s.tellg(); s.clear(); s >> h.endianity; if (s.eof()) return; s.set_endianity(static_cast(h.endianity)); s >> h.hdr_bytes; s >> h.data_bytes; s >> h.block_bytes; s >> h.name; s >> h.type; s.seekg(p + static_cast(h.hdr_bytes)); } void it_ifile::low_level_read(bin &x) { s >> x; } void it_ifile::low_level_read(short &x) { s >> x; } void it_ifile::low_level_read(int &x) { s >> x; } /* void it_ifile::low_level_read(long_long &x) { s >> x; } */ void it_ifile::low_level_read(float &x) { s >> x; } void it_ifile::low_level_read(double &x) { s >> x; } void it_ifile::low_level_read(complex &x) { float x_real, x_imag; s >> x_real; s >> x_imag; x = complex(x_real, x_imag); } void it_ifile::low_level_read(complex &x) { double x_real, x_imag; s >> x_real; s >> x_imag; x = complex(x_real, x_imag); } void it_ifile::low_level_read_lo(vec &v) { int i; float val; s >> i; v.set_size(i, false); for (i=0; i> val; v(i) = static_cast(val); } } void it_ifile::low_level_read_hi(vec &v) { int i; double val; s >> i; v.set_size(i, false); for (i=0; i> val; v(i) = static_cast(val); } } void it_ifile::low_level_read(ivec &v) { int i; s >> i; v.set_size(i, false); for (i=0; i> v(i); } void it_ifile::low_level_read(bvec &v) { int i; s >> i; v.set_size(i, false); for (i=0; i> v(i); } void it_ifile::low_level_read_lo(cvec &v) { int i; float val_real, val_imag; s >> i; v.set_size(i, false); for (i=0; i> val_real; s >> val_imag; v(i) = complex(val_real, val_imag); } } void it_ifile::low_level_read_hi(cvec &v) { int i; double val_real, val_imag; s >> i; v.set_size(i, false); for (i=0; i> val_real; s >> val_imag; v(i) = complex(val_real, val_imag); } } void it_ifile::low_level_read(string &str) { int i, j; char val; str = ""; s >> i; for (j=0; j> val; str += val; } } void it_ifile::low_level_read_lo(mat &m) { int i, j; float val; s >> i >> j; m.set_size(i, j, false); for (j=0; j> val; m(i,j) = static_cast(val); } } void it_ifile::low_level_read_hi(mat &m) { int i, j; double val; s >> i >> j; m.set_size(i, j, false); for (j=0; j> val; m(i,j) = static_cast(val); } } void it_ifile::low_level_read(imat &m) { int i, j; s >> i >> j; m.set_size(i, j, false); for (j=0; j> m(i,j); } void it_ifile::low_level_read(bmat &m) { int i, j; s >> i >> j; m.set_size(i, j, false); for (j=0; j> m(i,j); } void it_ifile::low_level_read_lo(cmat &m) { int i, j; float val_real, val_imag; s >> i >> j; m.set_size(i, j, false); for (j=0; j> val_real; s >> val_imag; m(i,j) = complex(val_real, val_imag); } } void it_ifile::low_level_read_hi(cmat &m) { int i, j; double val_real, val_imag; s >> i >> j; m.set_size(i, j, false); for (j=0; j> val_real; s >> val_imag; m(i,j) = complex(val_real, val_imag); } } void it_ifile::low_level_read_lo(Array &v) { int i; float val; s >> i; v.set_size(i, false); for (i=0; i> val; v(i) = val; } } void it_ifile::low_level_read_lo(Array &v) { int i; float val; s >> i; v.set_size(i, false); for (i=0; i> val; v(i) = static_cast(val); } } void it_ifile::low_level_read_hi(Array &v) { int i; double val; s >> i; v.set_size(i, false); for (i=0; i> val; v(i) = static_cast(val); } } void it_ifile::low_level_read(Array &v) { int i; s >> i; v.set_size(i, false); for (i=0; i> v(i); } void it_ifile::low_level_read(Array &v) { int i; s >> i; v.set_size(i, false); for (i=0; i> v(i); } void it_ifile::low_level_read_lo(Array > &v) { int i; float val_real, val_imag; s >> i; v.set_size(i, false); for (i=0; i> val_real; s >> val_imag; v(i) = complex(val_real, val_imag); } } void it_ifile::low_level_read_lo(Array > &v) { int i; float val_real, val_imag; s >> i; v.set_size(i, false); for (i=0; i> val_real; s >> val_imag; v(i) = complex(val_real, val_imag); } } void it_ifile::low_level_read_hi(Array > &v) { int i; double val_real, val_imag; s >> i; v.set_size(i, false); for (i=0; i> val_real; s >> val_imag; v(i) = complex(val_real, val_imag); } } it_file::it_file() { low_prec = false; next_name = ""; } it_file::it_file(const std::string &name, bool trunc) { low_prec = false; next_name = ""; open(name, trunc); } void it_file::open(const std::string &name, bool trunc) { if (!exist(name)) trunc = true; s.open(name, trunc); if (trunc) write_file_header(); else if (!read_check_file_header()) { s.close(); throw Error("Corrupt file"); } } void it_file::close() { s.close(); } void it_file::flush() { s.flush(); } void it_file::write_file_header() { s.write(file_magic, 4); s << file_version; } void it_file::write_data_header(const std::string &type, it_u32 size) { if (next_name == "") throw Error("Try to write without a name"); write_data_header(type, next_name, size); next_name = ""; } void it_file::write_data_header(const std::string &type, const std::string &name, it_u32 size) { data_header h1, h2; streampos p; int availpos=0; bool removed=false; int skip; h1.endianity = s.get_native_endianity(); h1.hdr_bytes = 1 + 3*4 + type.size()+1 + name.size()+1; h1.data_bytes = size; h1.block_bytes = h1.hdr_bytes + h1.data_bytes; h1.name = name; h1.type = type; if (exists(name)) remove(); // Try to find an empty space s.clear(); s.seekg(sizeof(file_header)); while (true) { p = s.tellp(); read_data_header(h2); if (s.eof()) { s.clear(); break; } skip = h2.block_bytes; if (h2.type != "" && h2.name == name) { s.seekg(p); remove(); s.seekg(p); read_data_header(h2); removed = true; if (availpos != 0) break; } if (availpos == 0) { if (h2.type == "" && h2.block_bytes >= h1.block_bytes) { h1.block_bytes = h2.block_bytes; availpos = p; } else if (h2.block_bytes-h2.hdr_bytes-h2.data_bytes >= h1.block_bytes) { h1.block_bytes = h2.block_bytes - h2.hdr_bytes - h2.data_bytes - h1.block_bytes; h2.block_bytes = h2.hdr_bytes + h2.data_bytes; s.seekp(p); write_data_header_here(h2); availpos = static_cast(p) + h2.block_bytes; if (removed) break; } } s.seekg(p + static_cast(skip)); } if (availpos != 0) s.seekp(availpos); else s.seekp(0, ios::end); write_data_header_here(h1); } void it_file::write_data_header_here(const data_header &h) { s.set_endianity(static_cast(h.endianity)); s << h.endianity << h.hdr_bytes << h.data_bytes << h.block_bytes << h.name << h.type; } void it_file::remove(const std::string &name) { seek(name); remove(); } void it_file::remove() { data_header h; streampos p; p = s.tellp(); read_data_header(h); h.type = ""; h.name = ""; h.hdr_bytes = 1 + 3*4 + 1 + 1; h.data_bytes = 0; s.seekp(p); write_data_header_here(h); s.seekp(p + static_cast(h.block_bytes)); } bool it_file::exists(const std::string &name) { try { seek(name); } catch (...) { // Assume a "Not found" message return false; } return true; } void it_file::pack() { cout << "pack() is not implemented!" << endl; } void it_file::low_level_write(bin x) { s << x; } void it_file::low_level_write(short x) { s << x; } void it_file::low_level_write(int x) { s << x; } void it_file::low_level_write(float x) { s << x; } void it_file::low_level_write(double x) { s << x; } void it_file::low_level_write(const complex &x) { s << x.real(); s << x.imag(); } void it_file::low_level_write(const complex &x) { s << x.real(); s << x.imag(); } void it_file::low_level_write(const vec &v) { if (get_low_precision()) { s << v.size(); for (int i=0; i(v(i)); } else { s << v.size(); for (int i=0; i(v(i)); } } void it_file::low_level_write(const ivec &v) { s << v.size(); for (int i=0; i(v(i).real()); s << static_cast(v(i).imag()); } } else { s << v.size(); for (int i=0; i(v(i).real()); s << static_cast(v(i).imag()); } } } void it_file::low_level_write(const std::string &str) { s << str.size(); for (int i=0; i<(int)str.size(); i++) s << str[i]; } void it_file::low_level_write(const mat &m) { int i, j; if (get_low_precision()) { s << m.rows() << m.cols(); for (j=0; j(m(i,j)); } else { s << m.rows() << m.cols(); for (j=0; j(m(i,j)); } } void it_file::low_level_write(const imat &m) { int i, j; s << m.rows() << m.cols(); for (j=0; j(m(i,j).real()); s << static_cast(m(i,j).imag()); } } else { s << m.rows() << m.cols(); for (j=0; j(m(i,j).real()); s << static_cast(m(i,j).imag()); } } } void it_file::low_level_write(const Array &v) { s << v.size(); for (int i=0; i &v) { if (get_low_precision()) { s << v.size(); for (int i=0; i(v(i)); } else { s << v.size(); for (int i=0; i(v(i)); } } void it_file::low_level_write(const Array &v) { s << v.size(); for (int i=0; i &v) { s << v.size(); for (int i=0; i > &v) { s << v.size(); for (int i=0; i > &v) { if (get_low_precision()) { s << v.size(); for (int i=0; i(v(i).real()); s << static_cast(v(i).imag()); } } else { s << v.size(); for (int i=0; i(v(i).real()); s << static_cast(v(i).imag()); } } } it_ifile &operator>>(it_ifile &f, bin &x) { it_file::data_header h; f.read_data_header(h); if (h.type == "bin") f.low_level_read(x); else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, short &x) { it_file::data_header h; f.read_data_header(h); if (h.type == "int16") f.low_level_read(x); else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, int &x) { it_file::data_header h; f.read_data_header(h); if (h.type == "int32") f.low_level_read(x); else if (h.type == "int16") { short x16; f.low_level_read(x16); x = x16; } else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, double &x) { it_file::data_header h; f.read_data_header(h); if (h.type == "float64") f.low_level_read(x); else if (h.type == "float32") { float f32; f.low_level_read(f32); x = f32; } else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, float &x) { it_file::data_header h; f.read_data_header(h); if (h.type == "float32") f.low_level_read(x); else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, complex &x) { it_file::data_header h; f.read_data_header(h); if (h.type == "float32_complex") { complex f32_c; f.low_level_read(f32_c); x = f32_c; } else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, complex &x) { it_file::data_header h; f.read_data_header(h); if (h.type == "float64_complex") f.low_level_read(x); else if (h.type == "float32_complex") { complex f32_c; f.low_level_read(f32_c); x = f32_c; } else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, vec &v) { it_ifile::data_header h; f.read_data_header(h); if (h.type == "fvec") f.low_level_read_lo(v); else if (h.type == "dvec") f.low_level_read_hi(v); else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, ivec &v) { it_file::data_header h; f.read_data_header(h); if (h.type == "ivec") f.low_level_read(v); else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, bvec &v) { it_file::data_header h; f.read_data_header(h); if (h.type == "bvec") f.low_level_read(v); else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, cvec &v) { it_file::data_header h; f.read_data_header(h); if (h.type == "fcvec") f.low_level_read_lo(v); else if (h.type == "dcvec") f.low_level_read_hi(v); else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, string &str) { it_file::data_header h; f.read_data_header(h); if (h.type == "string") f.low_level_read(str); else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, mat &m) { it_file::data_header h; f.read_data_header(h); if (h.type == "fmat") f.low_level_read_lo(m); else if (h.type == "dmat") f.low_level_read_hi(m); else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, imat &m) { it_file::data_header h; f.read_data_header(h); if (h.type == "imat") f.low_level_read(m); else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, bmat &m) { it_file::data_header h; f.read_data_header(h); if (h.type == "bmat") f.low_level_read(m); else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, cmat &m) { it_file::data_header h; f.read_data_header(h); if (h.type == "fcmat") f.low_level_read_lo(m); else if (h.type == "dcmat") f.low_level_read_hi(m); else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, Array &v) { it_file::data_header h; f.read_data_header(h); if (h.type == "fArray") f.low_level_read_lo(v); else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, Array &v) { it_file::data_header h; f.read_data_header(h); if (h.type == "fArray") f.low_level_read_lo(v); else if (h.type == "dArray") f.low_level_read_hi(v); else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, Array &v) { it_file::data_header h; f.read_data_header(h); if (h.type == "iArray") f.low_level_read(v); else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, Array &v) { it_file::data_header h; f.read_data_header(h); if (h.type == "bArray") f.low_level_read(v); else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, Array > &v) { it_file::data_header h; f.read_data_header(h); if (h.type == "fcArray") f.low_level_read_lo(v); else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, Array > &v) { it_file::data_header h; f.read_data_header(h); if (h.type == "fcArray") f.low_level_read_lo(v); else if (h.type == "dcArray") f.low_level_read_hi(v); else throw it_file_base::Error("Wrong type"); return f; } it_ifile &operator>>(it_ifile &f, Array &v) { it_file::data_header h; f.read_data_header(h); if (h.type == "vecArray") { int n; f.low_level_read(n); v.set_size(n, false); for (int i=0; i>(it_ifile &f, Array &v) { it_file::data_header h; f.read_data_header(h); if (h.type == "ivecArray") { int n; f.low_level_read(n); v.set_size(n, false); for (int i=0; i>(it_ifile &f, Array &v) { it_file::data_header h; f.read_data_header(h); if (h.type == "bvecArray") { int n; f.low_level_read(n); v.set_size(n, false); for (int i=0; i>(it_ifile &f, Array &v) { it_file::data_header h; f.read_data_header(h); if (h.type == "cvecArray") { int n; f.low_level_read(n); v.set_size(n, false); for (int i=0; i>(it_ifile &f, Array &v) { it_file::data_header h; f.read_data_header(h); if (h.type == "stringArray") { int n; f.low_level_read(n); v.set_size(n, false); for (int i=0; i>(it_ifile &f, Array &v) { it_file::data_header h; f.read_data_header(h); if (h.type == "matArray") { int n; f.low_level_read(n); v.set_size(n, false); for (int i=0; i>(it_ifile &f, Array &v) { it_file::data_header h; f.read_data_header(h); if (h.type == "imatArray") { int n; f.low_level_read(n); v.set_size(n, false); for (int i=0; i>(it_ifile &f, Array &v) { it_file::data_header h; f.read_data_header(h); if (h.type == "bmatArray") { int n; f.low_level_read(n); v.set_size(n, false); for (int i=0; i>(it_ifile &f, Array &v) { it_file::data_header h; f.read_data_header(h); if (h.type == "cmatArray") { int n; f.low_level_read(n); v.set_size(n, false); for (int i=0; i x) { f.write_data_header("float32_complex", 2*sizeof(float)); f.low_level_write(x); return f; } it_file &operator<<(it_file &f, complex x) { f.write_data_header("float64_complex", 2*sizeof(double)); f.low_level_write(x); return f; } it_file &operator<<(it_file &f, const vec &v) { if (f.get_low_precision()) f.write_data_header("fvec", sizeof(int) + v.size() * sizeof(float)); else f.write_data_header("dvec", sizeof(int) + v.size() * sizeof(double)); f.low_level_write(v); return f; } it_file &operator<<(it_file &f, const ivec &v) { f.write_data_header("ivec", (1 + v.size()) * sizeof(int)); f.low_level_write(v); return f; } it_file &operator<<(it_file &f, const bvec &v) { f.write_data_header("bvec", sizeof(int) + v.size() * sizeof(bin) ); f.low_level_write(v); return f; } it_file &operator<<(it_file &f, const cvec &v) { if (f.get_low_precision()) f.write_data_header("fcvec", sizeof(int) + v.size() * 2 * sizeof(float)); else f.write_data_header("dcvec", sizeof(int) + v.size() * 2 * sizeof(double)); f.low_level_write(v); return f; } it_file &operator<<(it_file &f, const std::string &str) { f.write_data_header("string", sizeof(int) + str.size() * sizeof(char) ); f.low_level_write(str); return f; } it_file &operator<<(it_file &f, const mat &m) { if (f.get_low_precision()) f.write_data_header("fmat", 2*sizeof(int) + m.rows()*m.cols()*sizeof(float)); else f.write_data_header("dmat", 2*sizeof(int) + m.rows()*m.cols()*sizeof(double)); f.low_level_write(m); return f; } it_file &operator<<(it_file &f, const imat &m) { f.write_data_header("imat", (2 + m.rows()*m.cols()) * sizeof(int)); f.low_level_write(m); return f; } it_file &operator<<(it_file &f, const bmat &m) { f.write_data_header("bmat", 2*sizeof(int) + m.rows()*m.cols()*sizeof(bin) ); f.low_level_write(m); return f; } it_file &operator<<(it_file &f, const cmat &m) { if (f.get_low_precision()) f.write_data_header("fcmat", 2*sizeof(int) + 2*m.rows()*m.cols()*sizeof(float)); else f.write_data_header("dcmat", 2*sizeof(int) + 2*m.rows()*m.cols()*sizeof(double)); f.low_level_write(m); return f; } it_file &operator<<(it_file &f, const Array &v) { f.write_data_header("fArray", sizeof(int) + v.size() * sizeof(float)); f.low_level_write(v); return f; } it_file &operator<<(it_file &f, const Array &v) { if (f.get_low_precision()) f.write_data_header("fArray", sizeof(int) + v.size() * sizeof(float)); else f.write_data_header("dArray", sizeof(int) + v.size() * sizeof(double)); f.low_level_write(v); return f; } it_file &operator<<(it_file &f, const Array &v) { f.write_data_header("iArray", (1 + v.size()) * sizeof(int)); f.low_level_write(v); return f; } it_file &operator<<(it_file &f, const Array &v) { f.write_data_header("bArray", sizeof(int) + v.size() * sizeof(bin) ); f.low_level_write(v); return f; } it_file &operator<<(it_file &f, const Array > &v) { f.write_data_header("fcArray", sizeof(int) + v.size() * 2 * sizeof(float)); f.low_level_write(v); return f; } it_file &operator<<(it_file &f, const Array > &v) { if (f.get_low_precision()) f.write_data_header("fcArray", sizeof(int) + v.size() * 2 * sizeof(float)); else f.write_data_header("dcArray", sizeof(int) + v.size() * 2 * sizeof(double)); f.low_level_write(v); return f; } it_file &operator<<(it_file &f, const Array &v) { int i, sum_l=0; // calculate total length of Array for (i=0; i &v) { int i, sum_l=0; // calculate total length of Array for (i=0; i &v) { int i, sum_l=0; // calculate total length of Array for (i=0; i &v) { int i, sum_l=0; // calculate total length of Array for (i=0; i)); f.low_level_write(v.size()); // the length of the array // write one vector at a time (i.e. size and elements) for (i=0; i &v) { int i, sum_l=0; // calculate total length of Array for (i=0; i &v) { int i, sum_l=0; // calculate total length of Array for (i=0; i &v) { int i, sum_l=0; // calculate total length of Array for (i=0; i &v) { int i, sum_l=0; // calculate total length of Array for (i=0; i &v) { int i, sum_l=0; // calculate total length of Array for (i=0; i)); f.low_level_write(v.size()); // the length of the array // write one matrix at a time (i.e. size and elements) for (i=0; i