version  0.0.1
Defines the C++ API for MsPASS
Metadata.h
1 #ifndef _METADATA_H_
2 #define _METADATA_H_
3 #include <typeinfo>
4 #include <map>
5 #include <set>
6 #include <list>
7 #include <iostream>
8 #include <fstream>
9 #include <sstream>
10 #include <boost/any.hpp>
11 #include <pybind11/pybind11.h>
12 #include "mspass/utility/MsPASSError.h"
13 #include "mspass/utility/BasicMetadata.h"
14 
15 namespace mspass
16 {
17 namespace utility{
23 {
24 public:
25  std::stringstream ss;
26  MetadataGetError():MsPASSError(){}; // seems necessary to not default this with gcc
29  MetadataGetError(const std::string key,const char *Texpected)
30  {
31 
32  std::string pretty_name(boost::core::demangle(Texpected));
33  ss<<"Error trying to extract Metadata with key="<<key<<std::endl
34  << "No value associated with this key is set in Metadata object"<<std::endl
35  << "Expected an entry of type="<<pretty_name<<std::endl;
36  message=ss.str();
37  badness=ErrorSeverity::Suspect;
38  };
45  MetadataGetError(const char *boostmessage,const std::string key,
46  const char *Texpected, const char *Tactual)
47  {
48  ss << "Error in Metadata get method. Type mismatch in attem to get "
49  << "data with key="<<key<<std::endl
50  << "boost::any bad_any_cast wrote this message: "<<std::endl
51  << boostmessage<<std::endl;
52  std::string name_e(boost::core::demangle(Texpected));
53  ss << "Trying to convert to data of type="<<name_e<<std::endl;
54  std::string name_a(boost::core::demangle(Tactual));
55  ss << "Actual entry has type="<<name_a<<std::endl;
56  message=ss.str();
57  badness=ErrorSeverity::Suspect;
58  };
59  MetadataGetError(const MetadataGetError& parent)
60  {
61  message=parent.message;
62  badness=parent.badness;
63  };
64  MetadataGetError operator=(const MetadataGetError& parent)
65  {
66  if(this!=&parent)
67  {
68  message=parent.message;
69  badness=parent.badness;
70  }
71  return *this;
72  };
73 };
74 
75 class Metadata : public BasicMetadata
76 {
77 public:
80  Metadata(){};
94  Metadata(std::ifstream& ifs, const std::string form=std::string("pf"));
100  Metadata(const Metadata& mdold);
104  virtual ~Metadata(){};
108  Metadata& operator=(const Metadata& mdold);
124  Metadata& operator+=(const Metadata& rhs) noexcept;
126  const Metadata operator+(const Metadata& other) const;
127  /* All the getters - all but the template are wrappers with the type
128  fixed */
135  double get_double(const std::string key) const override{
136  try{
137  double val;
138  val=get<double>(key);
139  return val;
140  }catch(MetadataGetError& merr)
141  {
142  /* Try a float if that failed */
143  try{
144  float fval;
145  fval=get<float>(key);
146  return fval;
147  }catch(MetadataGetError& merr)
148  {
149  throw merr;
150  }
151  }
152  };
159  int get_int(const std::string key) const override
160  {
161  try{
162  int val;
163  val=get<int>(key);
164  return val;
165  }
166  catch(MetadataGetError& merr)
167  {
168  try{
169  long lval;
170  lval=get<long>(key);
171  return static_cast<int>(lval);
172  }catch(MetadataGetError& merr)
173  {
174  throw merr;
175  }
176  }
177  };
184  long get_long(const std::string key) const
185  {
186  try{
187  long val;
188  val=get<long>(key);
189  return val;
190  }
191  catch(MetadataGetError& merr)
192  {
193  try{
194  int ival;
195  ival=get<int>(key);
196  return static_cast<long>(ival);
197  }catch(MetadataGetError& merr)
198  {
199  throw merr;
200  }
201  }
202  };
213  std::string get_string(const std::string key) const override{
214  try{
215  std::string val;
216  val=get<std::string>(key);
217  return val;
218  }catch(...){throw;};
219  };
228  bool get_bool(const std::string key) const override{
229  try{
230  bool val;
231  val=get<bool>(key);
232  return val;
233  }catch(...){throw;};
234  };
250  template <typename T> T get(const std::string key) const;
265  template <typename T> T get(const char *key) const
266  {
267  try{
268  T val;
269  val=get<T>(std::string(key));
270  return val;
271  }catch(...){throw;};
272  }
283  boost::any get_any(const std::string key) const {
284  std::map<std::string,boost::any>::const_iterator iptr;
285  iptr=md.find(key);
286  if(iptr==md.end())
287  {
288  throw MetadataGetError(key,typeid(boost::any).name());
289  }
290  return iptr->second;
291  };
292  std::string type(const std::string key) const;
293  template <typename T> void put(const std::string key, T val) noexcept
294  {
295  boost::any aval=val;
296  md[key]=aval;
297  changed_or_set.insert(key);
298  }
299  template <typename T> void put (const char *key, T val) noexcept
300  {
301  /* could do this as put(string(key),val) but this is so trivial duplicating
302  the code for the string method is more efficient than an added function call.*/
303  boost::any aval=val;
304  md[std::string(key)]=aval;
305  changed_or_set.insert(std::string(key));
306  }
307  void put(const std::string key, const double val) override
308  {
309  this->put<double>(key,val);
310  };
311  void put(const std::string key, const int val) override
312  {
313  this->put<int>(key,val);
314  };
315  void put(const std::string key, const bool val) override
316  {
317  this->put<bool>(key,val);
318  };
319  void put(const std::string key, const std::string val) override
320  {
321  this->put<std::string>(key,val);
322  };
327  void put(const char *key,const char *val)
328  {
329  std::string sval(val);
330  this->put<std::string>(key,val);
331  }
332  void put(std::string key,const char *val)
333  {
334  this->put(key.c_str(),val);
335  }
336  void put_object(const std::string key, const pybind11::object val)
337  {
338  this->put<pybind11::object>(key,val);
339  }
340  void put_int(const std::string key,const int val)
341  {
342  this->put<int>(key,val);
343  };
344  void put_string(const std::string key,const std::string val)
345  {
346  this->put<std::string>(key,val);
347  };
348  void put_bool(const std::string key,const bool val)
349  {
350  this->put<bool>(key,val);
351  };
352  void put_double(const std::string key,const double val)
353  {
354  this->put<double>(key,val);
355  };
356  void put_long(const std::string key,const long val)
357  {
358  this->put<long>(key,val);
359  };
383  void append_chain(const std::string key, const std::string val,
384  const std::string separator=std::string(":"));
385 
387  std::set<std::string> modified() const
388  {
389  return changed_or_set;
390  };
402  {
403  changed_or_set.clear();
404  };
406  std::set<std::string> keys() const noexcept;
409  bool is_defined(const std::string key) const noexcept;
411  /*
412  bool is_defined(const char* key) const noexcept
413  {
414  return this->is_defined(string(key));
415  };
416  */
418  void erase(const std::string key);
420  /*
421  void erase(const char* key)
422  {
423  return this->erase(string(key));
424  };
425  */
427  std::size_t size() const noexcept;
429  std::map<std::string,boost::any>::const_iterator begin() const noexcept;
431  std::map<std::string,boost::any>::const_iterator end() const noexcept;
446  void change_key(const std::string oldkey, const std::string newkey);
455  friend pybind11::object serialize_metadata_py(const Metadata &md);
463  friend Metadata restore_serialized_metadata_py(const pybind11::object &sd);
465  friend std::ostringstream& operator<<(std::ostringstream&,
466  const mspass::utility::Metadata&);
467 protected:
468  std::map<std::string,boost::any> md;
469  /* The keys of any entry changed will be contained here. */
470  std::set<std::string> changed_or_set;
471 };
472 template <typename T> T Metadata::get(const std::string key) const
473 {
474  T result;
475  std::map<std::string,boost::any>::const_iterator iptr;
476  iptr=md.find(key);
477  if(iptr==md.end())
478  {
479  throw MetadataGetError(key,typeid(T).name());
480  }
481  boost::any aval=iptr->second;
482  try{
483  result=boost::any_cast<T>(aval);
484  }catch(boost::bad_any_cast& err)
485  {
486  const std::type_info &ti = aval.type();
487  throw MetadataGetError(err.what(),key,typeid(T).name(),ti.name());
488  };
489  return result;
490 }
500 std::string demangled_name(const boost::any val);
501 /* Start of helper procedures for Metadata. */
509 enum class MDtype{
510  Real,
511  Real32,
512  Double,
513  Real64,
514  Integer,
515  Int32,
516  Long,
517  Int64,
518  String,
519  Boolean,
520  Double_Array,
521  Invalid
522 };
526 typedef struct Metadata_typedef {
527  std::string tag;
528  MDtype mdt;
530 
536 typedef std::list<Metadata_typedef> MetadataList;
537 
561 int copy_selected_metadata(const Metadata& mdin, Metadata& mdout,
562  const MetadataList& mdlist);
563 
584 std::string serialize_metadata(const Metadata &md);
596 Metadata restore_serialized_metadata(const std::string);
597 
598 Metadata restore_serialized_metadata_py(const pybind11::object &sd);
599 } // end utility namespace
600 } //End of namespace MsPASS
601 #endif
Abstract base class for Metadata concept.
Definition: BasicMetadata.h:15
Error thrown when get operators fail.
Definition: Metadata.h:23
MetadataGetError(const char *boostmessage, const std::string key, const char *Texpected, const char *Tactual)
Constructor called when type requested does not match contents.
Definition: Metadata.h:45
MetadataGetError(const std::string key, const char *Texpected)
Definition: Metadata.h:29
Definition: Metadata.h:76
void erase(const std::string key)
Definition: Metadata.cc:151
std::set< std::string > modified() const
Definition: Metadata.h:387
std::size_t size() const noexcept
Definition: Metadata.cc:163
bool is_defined(const std::string key) const noexcept
Definition: Metadata.cc:73
void change_key(const std::string oldkey, const std::string newkey)
Change the keyword to access an attribute.
Definition: Metadata.cc:324
bool get_bool(const std::string key) const override
Definition: Metadata.h:228
friend pybind11::object serialize_metadata_py(const Metadata &md)
Definition: Metadata.cc:288
Metadata()
Definition: Metadata.h:80
Metadata(std::ifstream &ifs, const std::string form=std::string("pf"))
std::set< std::string > keys() const noexcept
Definition: Metadata.cc:140
friend Metadata restore_serialized_metadata_py(const pybind11::object &sd)
Definition: Metadata.cc:302
T get(const char *key) const
Generic get interface for C char array.
Definition: Metadata.h:265
void clear_modified()
Mark all data as unmodified.
Definition: Metadata.h:401
virtual ~Metadata()
Definition: Metadata.h:104
int get_int(const std::string key) const override
Definition: Metadata.h:159
long get_long(const std::string key) const
Definition: Metadata.h:184
std::map< std::string, boost::any >::const_iterator end() const noexcept
Definition: Metadata.cc:171
boost::any get_any(const std::string key) const
Definition: Metadata.h:283
void append_chain(const std::string key, const std::string val, const std::string separator=std::string(":"))
Definition: Metadata.cc:86
std::string get_string(const std::string key) const override
Definition: Metadata.h:213
void put(const char *key, const char *val)
Definition: Metadata.h:327
Metadata & operator=(const Metadata &mdold)
Definition: Metadata.cc:108
double get_double(const std::string key) const override
Definition: Metadata.h:135
T get(const std::string key) const
Definition: Metadata.h:472
std::map< std::string, boost::any >::const_iterator begin() const noexcept
Definition: Metadata.cc:167
Metadata & operator+=(const Metadata &rhs) noexcept
Definition: Metadata.cc:118
const Metadata operator+(const Metadata &other) const
Definition: Metadata.cc:134
Base class for error object thrown by MsPASS library routines.
Definition: MsPASSError.h:40
MsPASSError()
Definition: MsPASSError.h:46
std::string message
Definition: MsPASSError.h:109
ErrorSeverity badness
Definition: MsPASSError.h:116
Used in Metadata to defined type of Metadata associated with a given tag.
Definition: Metadata.h:526
std::string tag
Definition: Metadata.h:527
MDtype mdt
Definition: Metadata.h:528