Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009, 2011 EPITA Research and Development 00002 // Laboratory (LRDE) 00003 // 00004 // This file is part of Olena. 00005 // 00006 // Olena is free software: you can redistribute it and/or modify it under 00007 // the terms of the GNU General Public License as published by the Free 00008 // Software Foundation, version 2 of the License. 00009 // 00010 // Olena is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software project without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to produce 00022 // an executable, this file does not by itself cause the resulting 00023 // executable to be covered by the GNU General Public License. This 00024 // exception does not however invalidate any other reasons why the 00025 // executable file might be covered by the GNU General Public License. 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 { // Parse the line 00099 char c = ins.get(); 00100 while (isspace(c)) 00101 ins.get(c); 00102 if (c == '#') // Comments 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 } // end of namespace mln::io::fld 00218 00219 } // end of namespace mln::io 00220 00221 } // end of namespace mln 00222 00223 #endif // !MLN_IO_FLD_LOAD_HEADER_HH