version  0.0.1
Defines the C++ API for MsPASS
Loading...
Searching...
No Matches
Metadata.h
1#ifndef _METADATA_H_
2#define _METADATA_H_
3#include "mspass/utility/BasicMetadata.h"
4#include "mspass/utility/MsPASSError.h"
5#include <boost/any.hpp>
6#include <fstream>
7#include <iostream>
8#include <list>
9#include <map>
10#include <pybind11/pybind11.h>
11#include <set>
12#include <sstream>
13#include <typeinfo>
14
15namespace mspass {
16namespace utility {
22public:
23 std::stringstream ss;
25 : MsPASSError() {}; // seems necessary to not default this with gcc
29 MetadataGetError(const std::string key, const char *Texpected) {
30
31 std::string pretty_name(boost::core::demangle(Texpected));
32 ss << "Error trying to extract Metadata with key=" << key << std::endl
33 << "No value associated with this key is set in Metadata object"
34 << 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 ss << "Error in Metadata get method. Type mismatch in attem to get "
48 << "data with key=" << key << std::endl
49 << "boost::any bad_any_cast wrote this message: " << std::endl
50 << boostmessage << std::endl;
51 std::string name_e(boost::core::demangle(Texpected));
52 ss << "Trying to convert to data of type=" << name_e << std::endl;
53 std::string name_a(boost::core::demangle(Tactual));
54 ss << "Actual entry has type=" << name_a << std::endl;
55 message = ss.str();
56 badness = ErrorSeverity::Suspect;
57 };
58 MetadataGetError(const MetadataGetError &parent) {
59 message = parent.message;
60 badness = parent.badness;
61 };
62 MetadataGetError operator=(const MetadataGetError &parent) {
63 if (this != &parent) {
64 message = parent.message;
65 badness = parent.badness;
66 }
67 return *this;
68 };
69};
70
71class Metadata : public BasicMetadata {
72public:
89 Metadata(std::ifstream &ifs, const std::string form = std::string("pf"));
95 Metadata(const Metadata &mdold);
99 virtual ~Metadata() {};
103 Metadata &operator=(const Metadata &mdold);
119 Metadata &operator+=(const Metadata &rhs) noexcept;
121 const Metadata operator+(const Metadata &other) const;
122 /* All the getters - all but the template are wrappers with the type
123 fixed */
131 double get_double(const std::string key) const override {
132 try {
133 double val;
134 val = get<double>(key);
135 return val;
136 } catch (MetadataGetError &merr) {
137 /* Try a float if that failed */
138 try {
139 float fval;
141 return fval;
142 } catch (MetadataGetError &merr) {
143 throw merr;
144 }
145 }
146 };
154 int get_int(const std::string key) const override {
155 try {
156 int val;
157 val = get<int>(key);
158 return val;
159 } catch (MetadataGetError &merr) {
160 try {
161 long lval;
162 lval = get<long>(key);
163 return static_cast<int>(lval);
164 } catch (MetadataGetError &merr) {
165 throw merr;
166 }
167 }
168 };
176 long get_long(const std::string key) const {
177 try {
178 long val;
179 val = get<long>(key);
180 return val;
181 } catch (MetadataGetError &merr) {
182 try {
183 int ival;
184 ival = get<int>(key);
185 return static_cast<long>(ival);
186 } catch (MetadataGetError &merr) {
187 throw merr;
188 }
189 }
190 };
202 std::string get_string(const std::string key) const override {
203 try {
204 std::string val;
206 return val;
207 } catch (...) {
208 throw;
209 };
210 };
219 bool get_bool(const std::string key) const override {
220 try {
221 bool val;
222 val = get<bool>(key);
223 return val;
224 } catch (...) {
225 throw;
226 };
227 };
243 template <typename T> T get(const std::string key) const;
258 template <typename T> T get(const char *key) const {
259 try {
260 T val;
261 val = get<T>(std::string(key));
262 return val;
263 } catch (...) {
264 throw;
265 };
266 }
277 boost::any get_any(const std::string key) const {
278 std::map<std::string, boost::any>::const_iterator iptr;
279 iptr = md.find(key);
280 if (iptr == md.end()) {
281 throw MetadataGetError(key, typeid(boost::any).name());
282 }
283 return iptr->second;
284 };
285 std::string type(const std::string key) const;
286 template <typename T> void put(const std::string key, T val) noexcept {
287 boost::any aval = val;
288 md[key] = aval;
289 changed_or_set.insert(key);
290 }
291 template <typename T> void put(const char *key, T val) noexcept {
292 /* could do this as put(string(key),val) but this is so trivial duplicating
293 the code for the string method is more efficient than an added function
294 call.*/
295 boost::any aval = val;
296 md[std::string(key)] = aval;
297 changed_or_set.insert(std::string(key));
298 }
299 void put(const std::string key, const double val) override {
300 this->put<double>(key, val);
301 };
302 void put(const std::string key, const int val) override {
303 this->put<int>(key, val);
304 };
305 void put(const std::string key, const bool val) override {
306 this->put<bool>(key, val);
307 };
308 void put(const std::string key, const std::string val) override {
309 this->put<std::string>(key, val);
310 };
315 void put(const char *key, const char *val) {
316 std::string sval(val);
317 this->put<std::string>(key, val);
318 }
319 void put(std::string key, const char *val) { this->put(key.c_str(), val); }
320 void put_object(const std::string key, const pybind11::object val) {
321 this->put<pybind11::object>(key, val);
322 }
323 void put_int(const std::string key, const int val) {
324 this->put<int>(key, val);
325 };
326 void put_string(const std::string key, const std::string val) {
327 this->put<std::string>(key, val);
328 };
329 void put_bool(const std::string key, const bool val) {
330 this->put<bool>(key, val);
331 };
332 void put_double(const std::string key, const double val) {
333 this->put<double>(key, val);
334 };
335 void put_long(const std::string key, const long val) {
336 this->put<long>(key, val);
337 };
361 void append_chain(const std::string key, const std::string val,
362 const std::string separator = std::string(":"));
363
365 std::set<std::string> modified() const { return changed_or_set; };
376 void clear_modified() { changed_or_set.clear(); };
378 std::set<std::string> keys() const noexcept;
381 bool is_defined(const std::string key) const noexcept;
383 /*
384 bool is_defined(const char* key) const noexcept
385 {
386 return this->is_defined(string(key));
387 };
388 */
390 void erase(const std::string key);
392 /*
393 void erase(const char* key)
394 {
395 return this->erase(string(key));
396 };
397 */
399 std::size_t size() const noexcept;
401 std::map<std::string, boost::any>::const_iterator begin() const noexcept;
403 std::map<std::string, boost::any>::const_iterator end() const noexcept;
418 void change_key(const std::string oldkey, const std::string newkey);
438 const mspass::utility::Metadata &);
439
441 std::map<std::string, boost::any> md;
442 /* The keys of any entry changed will be contained here. */
443 std::set<std::string> changed_or_set;
444};
445template <typename T> T Metadata::get(const std::string key) const {
446 T result;
447 std::map<std::string, boost::any>::const_iterator iptr;
448 iptr = md.find(key);
449 if (iptr == md.end()) {
450 throw MetadataGetError(key, typeid(T).name());
451 }
452 boost::any aval = iptr->second;
453 try {
454 result = boost::any_cast<T>(aval);
455 } catch (boost::bad_any_cast &err) {
456 const std::type_info &ti = aval.type();
457 throw MetadataGetError(err.what(), key, typeid(T).name(), ti.name());
458 };
459 return result;
460}
470std::string demangled_name(const boost::any val);
471/* Start of helper procedures for Metadata. */
479enum class MDtype {
480 Real,
481 Real32,
482 Double,
483 Real64,
484 Integer,
485 Int32,
486 Long,
487 Int64,
488 String,
489 Boolean,
490 Double_Array,
491 Invalid
492};
496typedef struct Metadata_typedef {
497 std::string tag;
498 MDtype mdt;
500
506typedef std::list<Metadata_typedef> MetadataList;
507
532int copy_selected_metadata(const Metadata &mdin, Metadata &mdout,
533 const MetadataList &mdlist);
534
555std::string serialize_metadata(const Metadata &md);
567Metadata restore_serialized_metadata(const std::string);
568
569Metadata restore_serialized_metadata_py(const pybind11::object &sd);
570} // namespace utility
571} // namespace mspass
572#endif
Abstract base class for Metadata concept.
Definition BasicMetadata.h:13
Error thrown when get operators fail.
Definition Metadata.h:21
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:71
void erase(const std::string key)
Definition Metadata.cc:125
std::size_t size() const noexcept
Definition Metadata.cc:136
bool is_defined(const std::string key) const noexcept
Definition Metadata.cc:63
void change_key(const std::string oldkey, const std::string newkey)
Change the keyword to access an attribute.
Definition Metadata.cc:281
bool get_bool(const std::string key) const override
Definition Metadata.h:219
friend pybind11::object serialize_metadata_py(const Metadata &md)
Definition Metadata.cc:244
Metadata()
Definition Metadata.h:75
Metadata(std::ifstream &ifs, const std::string form=std::string("pf"))
std::set< std::string > keys() const noexcept
Definition Metadata.cc:116
friend Metadata restore_serialized_metadata_py(const pybind11::object &sd)
Definition Metadata.cc:261
T get(const char *key) const
Generic get interface for C char array.
Definition Metadata.h:258
void clear_modified()
Mark all data as unmodified.
Definition Metadata.h:376
virtual ~Metadata()
Definition Metadata.h:99
int get_int(const std::string key) const override
Definition Metadata.h:154
long get_long(const std::string key) const
Definition Metadata.h:176
std::map< std::string, boost::any >::const_iterator end() const noexcept
Definition Metadata.cc:140
boost::any get_any(const std::string key) const
Definition Metadata.h:277
void append_chain(const std::string key, const std::string val, const std::string separator=std::string(":"))
Definition Metadata.cc:72
std::string get_string(const std::string key) const override
Definition Metadata.h:202
void put(const char *key, const char *val)
Definition Metadata.h:315
Metadata & operator=(const Metadata &mdold)
Definition Metadata.cc:90
std::set< std::string > modified() const
Definition Metadata.h:365
double get_double(const std::string key) const override
Definition Metadata.h:131
T get(const std::string key) const
Definition Metadata.h:445
std::map< std::string, boost::any >::const_iterator begin() const noexcept
Definition Metadata.cc:137
Metadata & operator+=(const Metadata &rhs) noexcept
Definition Metadata.cc:98
const Metadata operator+(const Metadata &other) const
Definition Metadata.cc:111
Base class for error object thrown by MsPASS library routines.
Definition MsPASSError.h:38
MsPASSError()
Definition MsPASSError.h:43
std::string message
Definition MsPASSError.h:108
ErrorSeverity badness
Definition MsPASSError.h:110
Used in Metadata to defined type of Metadata associated with a given tag.
Definition Metadata.h:496
std::string tag
Definition Metadata.h:497
MDtype mdt
Definition Metadata.h:498