tensor-0.1.0
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Enumerator Groups Pages
idata_file.cc
1 // -*- mode: c++; fill-column: 80; c-basic-offset: 2; indent-tabs-mode: nil -*-
2 /*
3  Copyright (c) 2013 Juan Jose Garcia Ripoll
4 
5  Tensor is free software; you can redistribute it and/or modify it
6  under the terms of the GNU Library General Public License as published
7  by the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Library General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License along
16  with this program; if not, write to the Free Software Foundation, Inc.,
17  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 
20 #include <tensor/sdf.h>
21 
22 using namespace sdf;
23 
24 #if !defined(aix)
25 template <class number>
26 void read_raw_with_endian(std::ifstream &s, number *data, size_t n)
27 {
28  s.read((char *)data, n * sizeof(number));
29  if (s.bad()) {
30  std::cerr << "I/O error when reading from stream " << s;
31  abort();
32  }
33 }
34 #else
35 template <class number>
36 void read_raw_with_endian(std::ifstream &s, number *data, size_t n)
37 {
38  const int size = sizeof(number);
39  if (size == 1) {
40  s.read((char *)data, n * sizeof(number));
41  if (s.bad()) {
42  std::cerr << "I/O error when reading from stream " << s;
43  abort();
44  }
45  return;
46  }
47 
48  const int buffer_size = 1024;
49  char *alias = (char *)data;
50  char buffer[buffer_size];
51 
52  do {
53  size_t now = min<size_t>(n*size, buffer_size);
54  s.read(buffer, now);
55  if (s.bad()) {
56  std::cerr << "I/O error when reading from stream " << s;
57  abort();
58  }
59  for (size_t i = 0; i < now; i+=size) {
60  if (size == 4) {
61  *(alias++) = buffer[i+3];
62  *(alias++) = buffer[i+2];
63  *(alias++) = buffer[i+1];
64  *(alias++) = buffer[i];
65  } else if (size == 8) {
66  *(alias++) = buffer[i+7];
67  *(alias++) = buffer[i+6];
68  *(alias++) = buffer[i+5];
69  *(alias++) = buffer[i+4];
70  *(alias++) = buffer[i+3];
71  *(alias++) = buffer[i+2];
72  *(alias++) = buffer[i+1];
73  *(alias++) = buffer[i];
74  } else {
75  for (size_t j = size; j--; ) {
76  *(alias++) = buffer[i+j];
77  }
78  }
79  n--;
80  }
81  } while (n);
82 }
83 #endif
84 
85 InDataFile::InDataFile(const std::string &a_filename, int flags) :
86  DataFile(a_filename, flags), _stream(actual_filename().c_str())
87 {
88  read_header();
89 }
90 
91 void
92 InDataFile::read_raw(char *data, size_t n)
93 {
94  assert(is_open());
95  read_raw_with_endian(_stream, data, n);
96 }
97 
98 void
99 InDataFile::read_raw(int *data, size_t n)
100 {
101  assert(is_open());
102  read_raw_with_endian(_stream, data, n);
103 }
104 
105 void
106 InDataFile::read_raw(long *data, size_t n)
107 {
108  assert(is_open());
109  read_raw_with_endian(_stream, data, n);
110 }
111 
112 void
113 InDataFile::read_raw(size_t *data, size_t n)
114 {
115  assert(is_open());
116  read_raw_with_endian(_stream, data, n);
117 }
118 
119 void
120 InDataFile::read_raw(double *data, size_t n)
121 {
122  assert(is_open());
123  read_raw_with_endian(_stream, data, n);
124 }
125 
126 void
127 InDataFile::read_raw(cdouble *data, size_t n)
128 {
129  assert(is_open());
130  read_raw_with_endian(_stream, (double*)data, 2*n);
131 }
132 
133 size_t
134 InDataFile::read_tag_code()
135 {
136  size_t output;
137  read_raw(output);
138  return output;
139 }
140 
141 std::string
142 InDataFile::read_variable_name()
143 {
144  char buffer[var_name_size];
145  read_raw(buffer, var_name_size);
146  return std::string(buffer);
147 }
148 
149 void
150 InDataFile::read_tag(const std::string &name, size_t type)
151 {
152  std::string other_name = read_variable_name();
153  if (name.size() && (name != other_name)) {
154  std::cerr << "While reading file " << _filename << ", variable "
155  << name << " was expected but found "
156  << other_name << '\n';
157  abort();
158  }
159  size_t other_type = read_tag_code();
160  if (type != other_type) {
161  std::cerr << "While reading file " << _filename << ", an object of type "
162  << tag_to_name(type) << " was expected but found a "
163  << tag_to_name(other_type) << '\n';
164  abort();
165  }
166 }
167 
168 template<class Vector>
169 const Vector InDataFile::load_vector()
170 {
171  size_t length;
172  read_raw(length);
173  Vector v(length);
174  read_raw(v.begin(), length);
175  return v;
176 }
177 
178 void
179 InDataFile::load(RTensor *t, const std::string &name) {
180  read_tag(name, TAG_RTENSOR);
181  Indices dims = load_vector<Indices>();
182  *t = RTensor(dims, load_vector<RTensor>());
183 }
184 
185 void
186 InDataFile::load(CTensor *t, const std::string &name) {
187  read_tag(name, TAG_CTENSOR);
188  Indices dims = load_vector<Indices>();
189  *t = CTensor(dims, load_vector<CTensor>());
190 }
191 
192 void
193 InDataFile::load(std::vector<RTensor> *m, const std::string &name)
194 {
195  read_tag(name, TAG_RTENSOR_VECTOR);
196  size_t l;
197  read_raw(l);
198  m->resize(l);
199  for (size_t k = 0; k < l; k++) {
200  load(&m->at(k));
201  }
202 }
203 
204 void
205 InDataFile::load(std::vector<CTensor> *m, const std::string &name)
206 {
207  read_tag(name, TAG_CTENSOR_VECTOR);
208  size_t l;
209  read_raw(l);
210  m->resize(l);
211  for (size_t k = 0; k < l; k++) {
212  load(&m->at(k));
213  }
214 }
215 
216 void
217 InDataFile::load(double *value, const std::string &name)
218 {
219  RTensor t;
220  load(&t, name);
221  if (t.size() > 1) {
222  std::cerr << "While reading file " << _filename << " found a tensor of size "
223  << t.size() << " while a single value was expected.";
224  abort();
225  }
226  *value = t[0];
227 }
228 
229 void
230 InDataFile::load(cdouble *value, const std::string &name)
231 {
232  CTensor t;
233  load(&t, name);
234  if (t.size() > 1) {
235  std::cerr << "While reading file " << _filename << " found a tensor of size "
236  << t.size() << " while a single value was expected.";
237  abort();
238  }
239  *value = t[0];
240 }
241 
242 void
243 InDataFile::load(size_t *v, const std::string &name)
244 {
245  double aux;
246  load(&aux, name);
247  *v = (size_t)aux;
248 }
249 
250 void
251 InDataFile::load(int *v, const std::string &name)
252 {
253  double aux;
254  load(&aux, name);
255  *v = (int)aux;
256 }
257 
258 void
259 InDataFile::read_header()
260 {
261  std::string var_name = read_variable_name();
262 
263  if (var_name[0] != 's' || var_name[1] != 'd' || var_name[2] != 'f') {
264  std::cerr << "Bogus SDF file";
265  abort();
266  }
267  int file_int_size = var_name[3] - '0';
268  int file_long_size = var_name[4] - '0';
269  int file_endianness = var_name[5] - '0';
270  if (file_int_size != sizeof(int) ||
271  file_long_size != sizeof(long) ||
272  file_endianness != endian)
273  {
274  std::cerr << "File " << _filename << " has word sizes (" << file_int_size
275  << ',' << file_long_size << ") and cannot be read by this computer";
276  abort();
277  }
278 }
Real Tensor with elements of type "double".
Definition: tensor.h:349
Complex Tensor with elements of type "cdouble".
Definition: tensor.h:435
index size() const
Returns total number of elements in Tensor.
Definition: tensor.h:114
Vector of 'index' type, where 'index' fits the indices of a tensor.
Definition: indices.h:35