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