SCIRun  5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GenericReader.h
Go to the documentation of this file.
1 /*
2  For more information, please see: http://software.sci.utah.edu
3 
4  The MIT License
5 
6  Copyright (c) 2009 Scientific Computing and Imaging Institute,
7  University of Utah.
8 
9 
10  Permission is hereby granted, free of charge, to any person obtaining a
11  copy of this software and associated documentation files (the "Software"),
12  to deal in the Software without restriction, including without limitation
13  the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  and/or sell copies of the Software, and to permit persons to whom the
15  Software is furnished to do so, subject to the following conditions:
16 
17  The above copyright notice and this permission notice shall be included
18  in all copies or substantial portions of the Software.
19 
20  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  DEALINGS IN THE SOFTWARE.
27 */
28 
29 
30 ///
31 ///@author
32 /// Steven G. Parker
33 /// Department of Computer Science
34 /// University of Utah
35 ///@date July 1994
36 ///
37 
38 #ifndef MODULES_DATAIO_GENERIC_READER_H
39 #define MODULES_DATAIO_GENERIC_READER_H
40 
41 #include <boost/filesystem.hpp>
42 #include <Core/Datatypes/String.h>
44 #include <Core/Thread/Mutex.h>
46 
47 namespace SCIRun {
48  namespace Modules {
49  namespace DataIO {
50 
51 template <class HType, class PortTag>
53  public Has1InputPort<StringPortTag>,
54  public Has2OutputPorts<PortTag, StringPortTag>
55 {
56 public:
57  GenericReader(const std::string &name, const std::string &category, const std::string &package, const std::string& stateFilename);
58 
59  virtual void execute();
60  INPUT_PORT(0, Filename, String);
61  //OUTPUT_PORT(0, Object, PortType);
62  OUTPUT_PORT(1, FileLoaded, String);
63 
64 protected:
65  std::string filename_;
67  //GuiFilename gui_filename_;
68  //GuiString gui_from_env_;
69 
71 
72  virtual bool useCustomImporter(const std::string& filename) const = 0;
73  virtual bool call_importer(const std::string &filename, HType & handle) { return false; }
74 
76  static bool file_exists(const std::string & filename);
77 };
78 
79 
80 template <class HType, class PortTag>
82  const std::string &cat, const std::string &pack, const std::string& objectPortName)
83  : SCIRun::Dataflow::Networks::Module(SCIRun::Dataflow::Networks::ModuleLookupInfo(name, cat, pack)),
84  //gui_filename_(get_ctx()->subVar("filename"), ""),
85  //gui_from_env_(get_ctx()->subVar("from-env"),""),
86  objectPortName_(SCIRun::Dataflow::Networks::PortId(0, objectPortName)),
87  old_filemodification_(0)
88 {
89  INITIALIZE_PORT(Filename);
90  INITIALIZE_PORT(FileLoaded);
91 }
92 
93 template <class HType, class PortTag>
95 
96 template <class HType, class PortTag>
97 bool
98  GenericReader<HType, PortTag>::file_exists(const std::string & filename)
99 {
100  //BOOST FILESYSTEM BUG: it is not thread-safe. TODO: need to meld this locking code into the ENSURE_FILE_EXISTS macro.
102  return boost::filesystem::exists(filename);
103 }
104 
105 template <class HType, class PortTag>
106 void
108 {
109 #ifdef SCIRUN4_CODE_TO_BE_ENABLED_LATER
110  bool filename_changed = gui_filename_.changed();
111 
112  if (gui_from_env_.get() != "")
113  {
114  std::string filename_from_env = gui_from_env_.get();
115  if (sci_getenv(filename_from_env))
116  {
117  std::string envfilename = sci_getenv(filename_from_env);
118  gui_filename_.set(envfilename);
119  get_ctx()->reset();
120  filename_changed = true;
121  }
122  }
123 #endif
124 
125  // If there is an optional input string set the filename to it in the GUI.
126  /// @todo: this will be a common pattern for file loading. Perhaps it will be a base class method someday...
127  auto fileOption = getOptionalInput(Filename);
128  if (!fileOption)
129  filename_ = get_state()->getValue(SCIRun::Core::Algorithms::Variables::Filename).getString();
130  else
131  filename_ = (*fileOption)->value();
132 
133  // Read the status of this file so we can compare modification timestamps
134 
135  if (filename_.empty())
136  {
137  error("No file has been selected. Please choose a file.");
138  return;
139  }
140  else if (!file_exists(filename_))
141  {
142  if (!useCustomImporter(filename_))
143  {
144  error("File '" + filename_ + "' not found.");
145  return;
146  }
147  else
148  {
149  warning("File '" + filename_ + "' not found. Maybe the plugin can find it?");
150  }
151  }
152 
153  // If we haven't read yet, or if it's a new filename,
154  // or if the datestamp has changed -- then read...
155 
156  time_t new_filemodification = boost::filesystem::last_write_time(filename_);
157 
158  if(
160  inputs_changed_ || filename_changed ||
161  new_filemodification != old_filemodification_ ||
162  !oport_cached(0) ||
163  !oport_cached("Filename")
164 #else
165  true
166 #endif
167  )
168  {
169  update_state(Executing);
170  old_filemodification_ = new_filemodification;
171 
172  HType handle;
173 
174  remark("loading file " +filename_);
175 
176  if (useCustomImporter(filename_))
177  {
178  if (!call_importer(filename_, handle))
179  {
180  error("Import failed.");
181  return;
182  }
183  }
184  else
185  {
186  PiostreamPtr stream = auto_istream(filename_, getLogger());
187  if (!stream)
188  {
189  error("Error reading file '" + filename_ + "'.");
190  return;
191  }
192 
193  // Read the file
194  Pio(*stream, handle);
195 
196  if (!handle || stream->error())
197  {
198  error("Error reading data from file '" + filename_ +"'.");
199  return;
200  }
201  }
202 
204  sendOutput(FileLoaded, shandle);
205  sendOutput(objectPortName_, handle);
206  }
207 
208 }
209 
210 } }}
211 
212 #endif
#define SCIRUN4_CODE_TO_BE_ENABLED_LATER
Definition: Macros.h:32
OUTPUT_PORT(1, FileLoaded, String)
Definition: String.h:40
std::string filename_
Definition: GenericReader.h:65
GenericReader(const std::string &name, const std::string &category, const std::string &package, const std::string &stateFilename)
Definition: GenericReader.h:81
Definition: Mutex.h:43
Definition: Module.h:512
virtual void execute()
Definition: GenericReader.h:107
SCISHARE const char * sci_getenv(const std::string &key)
PiostreamPtr auto_istream(const std::string &filename, LoggerHandle pr)
Definition: Persistent.cc:394
boost::shared_ptr< Piostream > PiostreamPtr
Definition: Persistent.h:80
const char * name[]
Definition: BoostGraphExampleTests.cc:87
boost::shared_ptr< String > StringHandle
Definition: DatatypeFwd.h:58
static const AlgorithmParameterName Filename
Definition: AlgorithmVariableNames.h:49
static Core::Thread::Mutex fileCheckMutex_
Definition: GenericReader.h:75
#define INITIALIZE_PORT(nameObj)
Definition: Module.h:674
Definition: GenericReader.h:52
void Pio(Piostream &stream, Array1< T > &array)
Definition: Array1.h:65
StaticPortName< typename HType::element_type, 0 > objectPortName_
Definition: GenericReader.h:66
virtual bool useCustomImporter(const std::string &filename) const =0
Definition: Module.h:53
static bool file_exists(const std::string &filename)
Definition: GenericReader.h:98
boost::lock_guard< boost::mutex > Guard
Definition: Mutex.h:55
Definition: Module.h:425
Definition: String.h:60
virtual bool call_importer(const std::string &filename, HType &handle)
Definition: GenericReader.h:73
time_t old_filemodification_
Definition: GenericReader.h:70