Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
fld/load_header.hh
1 // Copyright (C) 2008, 2009, 2011 EPITA Research and Development
2 // Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena 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 GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_IO_FLD_LOAD_HEADER_HH
28 # define MLN_IO_FLD_LOAD_HEADER_HH
29 
34 
35 # include <mln/io/fld/header.hh>
36 # include <cstdlib>
37 # include <locale>
38 # include <iostream>
39 # include <sstream>
40 # include <string>
41 
42 namespace mln
43 {
44 
45  namespace io
46  {
47 
48  namespace fld
49  {
50 
57  fld_header read_header(std::istream& ins);
58 
59 # ifndef MLN_INCLUDE_ONLY
60 
61  namespace internal
62  {
63 
64  inline
65  void
66  abort_fld_reader(const char* msg, unsigned line = 0)
67  {
68  std::cerr << "AVS field file reader: " << msg << " on line " << line << std::endl;
69  abort();
70  }
71 
72  }
73 
74  inline
75  fld_header
76  read_header(std::istream& file)
77  {
78  std::stringstream ins;
79  std::string line_str, lhs, rhs;
80  fld_header header;
81  unsigned line;
82 
83  std::getline(file, line_str);
84  line = 1;
85  if (line_str.compare(0, 5, "# AVS"))
86  internal::abort_fld_reader("Invalid format", line);
87 
88  while (file.good() && file.peek() != '\f')
89  {
90  std::getline(file, line_str);
91  ++line;
92 
93  ins.clear();
94  ins.str(line_str);
95  rhs.clear();
96  lhs.clear();
97 
98  { // Parse the line
99  char c = ins.get();
100  while (isspace(c))
101  ins.get(c);
102  if (c == '#') // Comments
103  continue;
104  while (isalnum(c) || c == '_')
105  {
106  lhs.push_back(c);
107  ins.get(c);
108  }
109  while (isspace(c))
110  ins.get(c);
111  if (c != '=')
112  internal::abort_fld_reader("Parse error", line);
113  while (isspace(ins.peek()))
114  ins.ignore();
115  }
116 
117  if (lhs == "ndim")
118  {
119  ins >> header.ndim;
120  if (header.ndim < 1)
121  internal::abort_fld_reader("Invalid dimension", line);
122  header.dim = new int[header.ndim];
123  std::fill(header.dim, header.dim + header.ndim, -1);
124  }
125  else if (lhs.compare(0, 3, "dim") == 0)
126  {
127  std::stringstream ss(lhs.substr(3));
128  int dim;
129  ss >> dim;
130  if (dim < 1 || dim > header.ndim)
131  internal::abort_fld_reader("Invalid dimension", line);
132  if (!ss.eof())
133  internal::abort_fld_reader("Parse error", line);
134  ins >> header.dim[dim - 1];
135  if (header.dim[dim - 1] < 1)
136  internal::abort_fld_reader("Invalid dimension", line);
137  }
138  else if (lhs == "nspace")
139  {
140  ins >> header.nspace;
141  if (header.nspace < 1)
142  internal::abort_fld_reader("Invalid space dimension", line);
143  header.min_ext = new float[header.nspace];
144  header.max_ext = new float[header.nspace];
145  }
146  else if (lhs == "veclen")
147  {
148  ins >> header.veclen;
149  if (header.veclen == -1)
150  internal::abort_fld_reader("Invalid vector length", line);
151  }
152  else if (lhs == "data")
153  {
154  ins >> rhs;
155  if (rhs == "byte")
156  header.data = data_type::BYTE;
157  else if (rhs == "short")
158  header.data = data_type::SHORT;
159  else if (rhs == "integer")
160  header.data = data_type::INTEGER;
161  else if (rhs == "float")
162  header.data = data_type::FLOAT;
163  else if (rhs == "double")
164  header.data = data_type::DOUBLE;
165  else
166  internal::abort_fld_reader("Invalid data type", line);
167  }
168  else if (lhs == "field")
169  {
170  ins >> rhs;
171  if (rhs != "uniform")
172  internal::abort_fld_reader("Unhandled field type", line);
173  header.field = field_type::UNIFORM;
174  }
175  else if (lhs == "min_ext")
176  {
177  for (int i = 0; i < header.ndim; ++i)
178  {
179  ins >> header.min_ext[i];
180  if (ins.peek() == ',')
181  ins.ignore();
182  }
183  }
184  else if (lhs == "max_ext")
185  {
186  for (int i = 0; i < header.ndim; ++i)
187  {
188  ins >> header.max_ext[i];
189  if (ins.peek() == ',')
190  ins.ignore();
191  }
192  }
193  else
194  internal::abort_fld_reader("Parse error", line);
195 
196  rhs.clear();
197  ins >> rhs;
198  if (!rhs.empty() && rhs[0] != '#')
199  internal::abort_fld_reader("Parse error", line);
200  }
201 
202  file.ignore();
203  if (file.get() != '\f')
204  internal::abort_fld_reader("Parse error", line);
205 
206  if (header.ndim == -1 || header.nspace == -1 || header.veclen == -1 ||
207  header.data == data_type::UNKNOWN || header.field == field_type::UNKNOWN)
208  internal::abort_fld_reader("Invalid format", line);
209  for (int i = 0; i < header.ndim; ++i)
210  if (header.dim[i] == -1)
211  internal::abort_fld_reader("Invalid format", line);
212  return header;
213  }
214 
215 # endif // ! MLN_INCLUDE_ONLY
216 
217  } // end of namespace mln::io::fld
218 
219  } // end of namespace mln::io
220 
221 } // end of namespace mln
222 
223 #endif // !MLN_IO_FLD_LOAD_HEADER_HH