tensor-0.1.0
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Enumerator Groups Pages
odata_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 
26 template <class number>
27 void write_raw_with_endian(std::ofstream &s, const number *data, size_t n)
28 {
29  s.write((char *)data, n * sizeof(number));
30  if (s.bad()) {
31  std::cerr << "I/O error when reading from stream " << s;
32  abort();
33  }
34 }
35 
36 #else
37 
38 template <class number>
39 void write_raw_with_endian(std::ofstream &s, const number *data, size_t n)
40 {
41  const int size = sizeof(number);
42  if (size == 1) {
43  s.write((char *)data, n * sizeof(number));
44  if (s.bad()) {
45  std::cerr << "I/O error when writing to stream " << s;
46  abort();
47  }
48  s.flush();
49  return;
50  }
51 
52  const int buffer_size = 1024;
53  const char *alias = (char *)data;
54  char buffer[buffer_size];
55 
56  do {
57  size_t now = std::min<size_t>(n, buffer_size/size)*size;
58  for (size_t i = 0; i < now; i+=size) {
59  if (size == 4) {
60  buffer[i+3] = *(alias++);
61  buffer[i+2] = *(alias++);
62  buffer[i+1] = *(alias++);
63  buffer[i] = *(alias++);
64  } else if (size == 8) {
65  buffer[i+7] = *(alias++);
66  buffer[i+6] = *(alias++);
67  buffer[i+5] = *(alias++);
68  buffer[i+4] = *(alias++);
69  buffer[i+3] = *(alias++);
70  buffer[i+2] = *(alias++);
71  buffer[i+1] = *(alias++);
72  buffer[i] = *(alias++);
73  } else {
74  for (size_t j = size; j--; ) {
75  buffer[i+j] = *(alias++);
76  }
77  }
78  n--;
79  }
80  s.write(buffer, now);
81  if (s.bad()) {
82  std::cerr << "I/O error when reading from stream " << s;
83  abort();
84  }
85  s.flush();
86  } while (n);
87 }
88 
89 #endif
90 
91 //----------------------------------------------------------------------
92 // COMMON I/O ROUTINES
93 //
94 
95 OutDataFile::OutDataFile(const std::string &a_filename, int flags) :
96  DataFile(a_filename, flags)
97 {
98  bool existed = file_exists(actual_filename());
99  _stream.open(actual_filename().c_str(), std::ofstream::app | std::ofstream::binary);
100  if (!existed) {
101  write_header();
102  }
103 }
104 
105 OutDataFile::~OutDataFile()
106 {
107  close();
108 }
109 
110 void
111 OutDataFile::close()
112 {
113  if (is_open()) {
114  _stream.close();
115  DataFile::close();
116  }
117 }
118 
119 void
120 OutDataFile::write_raw(const char *data, size_t n)
121 {
122  assert(is_open());
123  write_raw_with_endian(_stream, data, n);
124 }
125 
126 void
127 OutDataFile::write_raw(const int *data, size_t n)
128 {
129  assert(is_open());
130  write_raw_with_endian(_stream, data, n);
131 }
132 
133 void
134 OutDataFile::write_raw(const long *data, size_t n)
135 {
136  assert(is_open());
137  write_raw_with_endian(_stream, data, n);
138 }
139 
140 void
141 OutDataFile::write_raw(const size_t *data, size_t n)
142 {
143  assert(is_open());
144  write_raw_with_endian(_stream, data, n);
145 }
146 
147 void
148 OutDataFile::write_raw(const double *data, size_t n)
149 {
150  assert(is_open());
151  write_raw_with_endian(_stream, data, n);
152 }
153 
154 void
155 OutDataFile::write_raw(const cdouble *data, size_t n)
156 {
157  assert(is_open());
158  write_raw_with_endian(_stream, (double*)data, 2*n);
159 }
160 
161 void
162 OutDataFile::write_variable_name(const std::string &name)
163 {
164  char buffer[var_name_size];
165  memset(buffer, 0, var_name_size);
166  strncpy(buffer, name.c_str(), std::min<size_t>(var_name_size - 1, name.size()));
167  write_raw(buffer, var_name_size);
168 }
169 
170 void
171 OutDataFile::write_tag(const std::string &name, size_t type)
172 {
173  write_variable_name(name);
174  write_raw(type);
175 }
176 
177 template<class Vector>
178 void OutDataFile::dump_vector(const Vector &v)
179 {
180  write_raw(v.size());
181  write_raw(v.begin(), v.size());
182 }
183 
184 void
185 OutDataFile::dump(const RTensor &t, const std::string &name)
186 {
187  write_tag(name, TAG_RTENSOR);
188  dump_vector(t.dimensions());
189  dump_vector(t);
190 }
191 
192 void
193 OutDataFile::dump(const CTensor &t, const std::string &name)
194 {
195  write_tag(name, TAG_CTENSOR);
196  dump_vector(t.dimensions());
197  dump_vector(t);
198 }
199 
200 void
201 OutDataFile::dump(const std::vector<RTensor> &m, const std::string &name)
202 {
203  size_t l = m.size();
204  write_tag(name, TAG_RTENSOR_VECTOR);
205  write_raw(l);
206  for (size_t k = 0; k < l; k++) {
207  dump(m[k]);
208  }
209 }
210 
211 void
212 OutDataFile::dump(const std::vector<CTensor> &m, const std::string &name)
213 {
214  size_t l = m.size();
215  write_tag(name, TAG_CTENSOR_VECTOR);
216  write_raw(l);
217  for (size_t k = 0; k < l; k++) {
218  dump(m[k]);
219  }
220 }
221 
222 void
223 OutDataFile::dump(const double v, const std::string &name)
224 {
225  RTensor t(1);
226  t.at(0) = v;
227  dump(t, name);
228 }
229 
230 void
231 OutDataFile::dump(const cdouble v, const std::string &name)
232 {
233  CTensor t(1);
234  t.at(0) = v;
235  dump(t, name);
236 }
237 
238 void
239 OutDataFile::dump(size_t v, const std::string &name)
240 {
241  dump((double)v, name);
242 }
243 
244 void
245 OutDataFile::dump(int v, const std::string &name)
246 {
247  dump((double)v, name);
248 }
249 
250 void
251 OutDataFile::write_header()
252 {
253  char tag[7] = "sdf ";
254  tag[3] = sizeof(int) + '0';
255  tag[4] = sizeof(long) + '0';
256  tag[5] = endian + '0';
257 
258  write_variable_name(tag);
259 }
Real Tensor with elements of type "double".
Definition: tensor.h:349
Complex Tensor with elements of type "cdouble".
Definition: tensor.h:435
const Indices & dimensions() const
Return Tensor dimensions.
Definition: tensor.h:121
elt_t & at(index i)
Return a mutable reference to an element of a 1D Tensor.