00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_IO_FLD_LOAD_HEADER_HH
00027 # define MLN_IO_FLD_LOAD_HEADER_HH
00028
00033
00034 # include <mln/io/fld/header.hh>
00035 # include <cstdlib>
00036 # include <locale>
00037 # include <iostream>
00038 # include <sstream>
00039 # include <string>
00040
00041 namespace mln
00042 {
00043
00044 namespace io
00045 {
00046
00047 namespace fld
00048 {
00049
00056 fld_header read_header(std::istream& ins);
00057
00058 # ifndef MLN_INCLUDE_ONLY
00059
00060 namespace internal
00061 {
00062 void
00063 abort_fld_reader(const char* msg, unsigned line = 0)
00064 {
00065 std::cerr << "AVS field file reader: " << msg << " on line " << line << std::endl;
00066 abort();
00067 }
00068
00069 }
00070
00071 inline
00072 fld_header
00073 read_header(std::istream& file)
00074 {
00075 std::stringstream ins;
00076 std::string line_str, lhs, rhs;
00077 fld_header header;
00078 unsigned line;
00079
00080 std::getline(file, line_str);
00081 line = 1;
00082 if (line_str.compare(0, 5, "# AVS"))
00083 internal::abort_fld_reader("Invalid format", line);
00084
00085 while (file.good() && file.peek() != '\f')
00086 {
00087 std::getline(file, line_str);
00088 ++line;
00089
00090 ins.clear();
00091 ins.str(line_str);
00092 rhs.clear();
00093 lhs.clear();
00094
00095 {
00096 char c = ins.get();
00097 while (isspace(c))
00098 ins.get(c);
00099 if (c == '#')
00100 continue;
00101 while (isalnum(c) || c == '_')
00102 {
00103 lhs.push_back(c);
00104 ins.get(c);
00105 }
00106 while (isspace(c))
00107 ins.get(c);
00108 if (c != '=')
00109 internal::abort_fld_reader("Parse error", line);
00110 while (isspace(ins.peek()))
00111 ins.ignore();
00112 }
00113
00114 if (lhs == "ndim")
00115 {
00116 ins >> header.ndim;
00117 if (header.ndim < 1)
00118 internal::abort_fld_reader("Invalid dimension", line);
00119 header.dim = new int[header.ndim];
00120 std::fill(header.dim, header.dim + header.ndim, -1);
00121 }
00122 else if (lhs.compare(0, 3, "dim") == 0)
00123 {
00124 std::stringstream ss(lhs.substr(3));
00125 int dim;
00126 ss >> dim;
00127 if (dim < 1 || dim > header.ndim)
00128 internal::abort_fld_reader("Invalid dimension", line);
00129 if (!ss.eof())
00130 internal::abort_fld_reader("Parse error", line);
00131 ins >> header.dim[dim - 1];
00132 if (header.dim[dim - 1] < 1)
00133 internal::abort_fld_reader("Invalid dimension", line);
00134 }
00135 else if (lhs == "nspace")
00136 {
00137 ins >> header.nspace;
00138 if (header.nspace < 1)
00139 internal::abort_fld_reader("Invalid space dimension", line);
00140 header.min_ext = new float[header.nspace];
00141 header.max_ext = new float[header.nspace];
00142 }
00143 else if (lhs == "veclen")
00144 {
00145 ins >> header.veclen;
00146 if (header.veclen == -1)
00147 internal::abort_fld_reader("Invalid vector length", line);
00148 }
00149 else if (lhs == "data")
00150 {
00151 ins >> rhs;
00152 if (rhs == "byte")
00153 header.data = data_type::BYTE;
00154 else if (rhs == "short")
00155 header.data = data_type::SHORT;
00156 else if (rhs == "integer")
00157 header.data = data_type::INTEGER;
00158 else if (rhs == "float")
00159 header.data = data_type::FLOAT;
00160 else if (rhs == "double")
00161 header.data = data_type::DOUBLE;
00162 else
00163 internal::abort_fld_reader("Invalid data type", line);
00164 }
00165 else if (lhs == "field")
00166 {
00167 ins >> rhs;
00168 if (rhs != "uniform")
00169 internal::abort_fld_reader("Unhandled field type", line);
00170 header.field = field_type::UNIFORM;
00171 }
00172 else if (lhs == "min_ext")
00173 {
00174 for (int i = 0; i < header.ndim; ++i)
00175 {
00176 ins >> header.min_ext[i];
00177 if (ins.peek() == ',')
00178 ins.ignore();
00179 }
00180 }
00181 else if (lhs == "max_ext")
00182 {
00183 for (int i = 0; i < header.ndim; ++i)
00184 {
00185 ins >> header.max_ext[i];
00186 if (ins.peek() == ',')
00187 ins.ignore();
00188 }
00189 }
00190 else
00191 internal::abort_fld_reader("Parse error", line);
00192
00193 rhs.clear();
00194 ins >> rhs;
00195 if (!rhs.empty() && rhs[0] != '#')
00196 internal::abort_fld_reader("Parse error", line);
00197 }
00198
00199 file.ignore();
00200 if (file.get() != '\f')
00201 internal::abort_fld_reader("Parse error", line);
00202
00203 if (header.ndim == -1 || header.nspace == -1 || header.veclen == -1 ||
00204 header.data == data_type::UNKNOWN || header.field == field_type::UNKNOWN)
00205 internal::abort_fld_reader("Invalid format", line);
00206 for (int i = 0; i < header.ndim; ++i)
00207 if (header.dim[i] == -1)
00208 internal::abort_fld_reader("Invalid format", line);
00209 return header;
00210 }
00211
00212 # endif // ! MLN_INCLUDE_ONLY
00213
00214 }
00215
00216 }
00217
00218 }
00219
00220 #endif // !MLN_IO_FLD_LOAD_HEADER_HH