MsPASS C++ API  2.4.1.dev4+g92330b7a
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 <string>
14#include <typeinfo>
15
16namespace mspass {
17namespace utility {
23public:
25 std::stringstream ss;
28 : MsPASSError() {}; // seems necessary to not default this with gcc
33 MetadataGetError(const std::string key, const char *Texpected) {
34
35 std::string pretty_name(boost::core::demangle(Texpected));
36 ss << "Error trying to extract Metadata with key=" << key << std::endl
37 << "No value associated with this key is set in Metadata object"
38 << std::endl
39 << "Expected an entry of type=" << pretty_name << std::endl;
40 message = ss.str();
41 badness = ErrorSeverity::Suspect;
42 };
49 MetadataGetError(const char *boostmessage, const std::string key,
50 const char *Texpected, const char *Tactual) {
51 ss << "Error in Metadata get method. Type mismatch in attempt to get "
52 << "data with key=" << key << std::endl
53 << "boost::any bad_any_cast wrote this message: " << std::endl
54 << boostmessage << std::endl;
55 std::string name_e(boost::core::demangle(Texpected));
56 ss << "Trying to convert to data of type=" << name_e << std::endl;
57 std::string name_a(boost::core::demangle(Tactual));
58 ss << "Actual entry has type=" << name_a << std::endl;
59 message = ss.str();
60 badness = ErrorSeverity::Suspect;
61 };
68 MetadataGetError(const std::string key, const char *Texpected,
69 const char *Tactual, const std::string detail) {
70 ss << "Error in Metadata get method. Type mismatch in attempt to get "
71 << "data with key=" << key << std::endl;
72 std::string name_e(boost::core::demangle(Texpected));
73 ss << "Trying to convert to data of type=" << name_e << std::endl;
74 std::string name_a(boost::core::demangle(Tactual));
75 ss << "Actual entry has type=" << name_a << std::endl;
76 ss << detail << std::endl;
77 message = ss.str();
78 badness = ErrorSeverity::Suspect;
79 };
82 message = parent.message;
83 badness = parent.badness;
84 };
87 if (this != &parent) {
88 message = parent.message;
89 badness = parent.badness;
90 }
91 return *this;
92 };
93};
94
101class Metadata : public BasicMetadata {
102public:
119 Metadata(std::ifstream &ifs, const std::string form = std::string("pf"));
125 Metadata(const Metadata &mdold);
129 virtual ~Metadata() {};
133 Metadata &operator=(const Metadata &mdold);
149 Metadata &operator+=(const Metadata &rhs) noexcept;
151 const Metadata operator+(const Metadata &other) const;
152 /* All the getters - all but the template are wrappers with the type
153 fixed */
161 double get_double(const std::string key) const override;
169 int get_int(const std::string key) const override;
177 long get_long(const std::string key) const;
189 std::string get_string(const std::string key) const override {
190 try {
191 std::string val;
192 val = get<std::string>(key);
193 return val;
194 } catch (...) {
195 throw;
196 };
197 };
206 bool get_bool(const std::string key) const override;
222 template <typename T> T get(const std::string key) const;
237 template <typename T> T get(const char *key) const {
238 try {
239 T val;
240 val = get<T>(std::string(key));
241 return val;
242 } catch (...) {
243 throw;
244 };
245 }
256 boost::any get_any(const std::string key) const {
257 std::map<std::string, boost::any>::const_iterator iptr;
258 iptr = md.find(key);
259 if (iptr == md.end()) {
260 throw MetadataGetError(key, typeid(boost::any).name());
261 }
262 return iptr->second;
263 };
270 std::string type(const std::string key) const;
277 template <typename T> void put(const std::string key, T val) noexcept {
278 boost::any aval = val;
279 md[key] = aval;
280 changed_or_set.insert(key);
281 }
287 template <typename T> void put(const char *key, T val) noexcept {
288 /* could do this as put(string(key),val) but this is so trivial duplicating
289 the code for the string method is more efficient than an added function
290 call.*/
291 boost::any aval = val;
292 md[std::string(key)] = aval;
293 changed_or_set.insert(std::string(key));
294 }
300 void put(const std::string key, const double val) override {
301 this->put<double>(key, val);
302 };
308 void put(const std::string key, const int val) override {
309 this->put<int>(key, val);
310 };
316 void put(const std::string key, const bool val) override {
317 this->put<bool>(key, val);
318 };
324 void put(const std::string key, const std::string val) override {
325 this->put<std::string>(key, val);
326 };
331 void put(const char *key, const char *val) {
332 std::string sval(val);
333 this->put<std::string>(key, val);
334 }
340 void put(std::string key, const char *val) { this->put(key.c_str(), val); }
346 void put_object(const std::string key, const pybind11::object val) {
347 this->put<pybind11::object>(key, val);
348 }
350 void put_int(const std::string key, const int val) {
351 this->put<int>(key, val);
352 };
354 void put_string(const std::string key, const std::string val) {
355 this->put<std::string>(key, val);
356 };
358 void put_bool(const std::string key, const bool val) {
359 this->put<bool>(key, val);
360 };
362 void put_double(const std::string key, const double val) {
363 this->put<double>(key, val);
364 };
366 void put_long(const std::string key, const long val) {
367 this->put<long>(key, val);
368 };
392 void append_chain(const std::string key, const std::string val,
393 const std::string separator = std::string(":"));
394
396 std::set<std::string> modified() const { return changed_or_set; };
407 void clear_modified() { changed_or_set.clear(); };
409 std::set<std::string> keys() const noexcept;
412 bool is_defined(const std::string key) const noexcept;
414 /*
415 bool is_defined(const char* key) const noexcept
416 {
417 return this->is_defined(string(key));
418 };
419 */
421 void erase(const std::string key);
423 /*
424 void erase(const char* key)
425 {
426 return this->erase(string(key));
427 };
428 */
430 std::size_t size() const noexcept;
432 std::map<std::string, boost::any>::const_iterator begin() const noexcept;
434 std::map<std::string, boost::any>::const_iterator end() const noexcept;
449 void change_key(const std::string oldkey, const std::string newkey);
469 const mspass::utility::Metadata &);
470
473 std::map<std::string, boost::any> md;
475 std::set<std::string> changed_or_set;
476};
477template <typename T> T Metadata::get(const std::string key) const {
478 T result;
479 std::map<std::string, boost::any>::const_iterator iptr;
480 iptr = md.find(key);
481 if (iptr == md.end()) {
482 throw MetadataGetError(key, typeid(T).name());
483 }
484 boost::any aval = iptr->second;
485 try {
486 result = boost::any_cast<T>(aval);
487 } catch (boost::bad_any_cast &err) {
488 const std::type_info &ti = aval.type();
489 throw MetadataGetError(err.what(), key, typeid(T).name(), ti.name());
490 };
491 return result;
492}
494template <> double Metadata::get<double>(const std::string key) const;
496template <> int Metadata::get<int>(const std::string key) const;
498template <> long Metadata::get<long>(const std::string key) const;
500template <> bool Metadata::get<bool>(const std::string key) const;
502template <> float Metadata::get<float>(const std::string key) const;
512std::string demangled_name(const boost::any val);
513/* Start of helper procedures for Metadata. */
521enum class MDtype {
522 Real,
523 Real32,
524 Double,
525 Real64,
526 Integer,
527 Int32,
528 Long,
529 Int64,
530 String,
531 Boolean,
532 Double_Array,
533 Invalid
534};
538typedef struct Metadata_typedef {
539 std::string tag;
540 MDtype mdt;
542
548typedef std::list<Metadata_typedef> MetadataList;
549
574int copy_selected_metadata(const Metadata &mdin, Metadata &mdout,
575 const MetadataList &mdlist);
576
597std::string serialize_metadata(const Metadata &md);
609Metadata restore_serialized_metadata(const std::string sd);
610
611Metadata restore_serialized_metadata_py(const pybind11::object &sd);
612} // namespace utility
613} // namespace mspass
614#endif
Abstract base class for Metadata concept.
Definition BasicMetadata.h:13
Error thrown when get operators fail.
Definition Metadata.h:22
std::stringstream ss
Definition Metadata.h:25
MetadataGetError(const MetadataGetError &parent)
Definition Metadata.h:81
MetadataGetError(const std::string key, const char *Texpected, const char *Tactual, const std::string detail)
Constructor called when compatible scalar conversion fails.
Definition Metadata.h:68
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:49
MetadataGetError(const std::string key, const char *Texpected)
Definition Metadata.h:33
MetadataGetError operator=(const MetadataGetError &parent)
Definition Metadata.h:86
MetadataGetError()
Definition Metadata.h:27
Type-safe metadata container used throughout MsPASS.
Definition Metadata.h:101
void erase(const std::string key)
Definition Metadata.cc:495
void put(const std::string key, const int val) override
Definition Metadata.h:308
std::size_t size() const noexcept
Definition Metadata.cc:506
bool is_defined(const std::string key) const noexcept
Definition Metadata.cc:342
void change_key(const std::string oldkey, const std::string newkey)
Change the keyword to access an attribute.
Definition Metadata.cc:651
bool get_bool(const std::string key) const override
Definition Metadata.cc:392
void put(std::string key, const char *val)
Definition Metadata.h:340
friend pybind11::object serialize_metadata_py(const Metadata &md)
Definition Metadata.cc:614
Metadata()
Definition Metadata.h:105
std::set< std::string > keys() const noexcept
Definition Metadata.cc:486
friend Metadata restore_serialized_metadata_py(const pybind11::object &sd)
Definition Metadata.cc:631
T get(const char *key) const
Generic get interface for C char array.
Definition Metadata.h:237
void put_string(const std::string key, const std::string val)
Definition Metadata.h:354
void put_int(const std::string key, const int val)
Definition Metadata.h:350
void clear_modified()
Mark all data as unmodified.
Definition Metadata.h:407
virtual ~Metadata()
Definition Metadata.h:129
int get_int(const std::string key) const override
Definition Metadata.cc:364
long get_long(const std::string key) const
Definition Metadata.cc:379
std::map< std::string, boost::any >::const_iterator end() const noexcept
Definition Metadata.cc:510
std::map< std::string, boost::any > md
Definition Metadata.h:473
boost::any get_any(const std::string key) const
Definition Metadata.h:256
void append_chain(const std::string key, const std::string val, const std::string separator=std::string(":"))
Definition Metadata.cc:442
std::string get_string(const std::string key) const override
Definition Metadata.h:189
void put(const char *key, const char *val)
Definition Metadata.h:331
void put_object(const std::string key, const pybind11::object val)
Definition Metadata.h:346
Metadata & operator=(const Metadata &mdold)
Definition Metadata.cc:460
void put_double(const std::string key, const double val)
Definition Metadata.h:362
void put_long(const std::string key, const long val)
Definition Metadata.h:366
void put(const std::string key, T val) noexcept
Definition Metadata.h:277
void put(const std::string key, const bool val) override
Definition Metadata.h:316
std::set< std::string > changed_or_set
Definition Metadata.h:475
std::set< std::string > modified() const
Definition Metadata.h:396
std::string type(const std::string key) const
Definition Metadata.cc:525
double get_double(const std::string key) const override
Definition Metadata.cc:352
void put(const std::string key, const std::string val) override
Definition Metadata.h:324
void put_bool(const std::string key, const bool val)
Definition Metadata.h:358
void put(const char *key, T val) noexcept
Definition Metadata.h:287
void put(const std::string key, const double val) override
Definition Metadata.h:300
T get(const std::string key) const
Definition Metadata.h:477
std::map< std::string, boost::any >::const_iterator begin() const noexcept
Definition Metadata.cc:507
Metadata & operator+=(const Metadata &rhs) noexcept
Definition Metadata.cc:468
const Metadata operator+(const Metadata &other) const
Definition Metadata.cc:481
Base class for error object thrown by MsPASS library routines.
Definition MsPASSError.h:38
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:538
std::string tag
Definition Metadata.h:539
MDtype mdt
Definition Metadata.h:540