Milena (Olena)  User documentation 2.0a Id
load_header.hh
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
 All Classes Namespaces Functions Variables Typedefs Enumerator