Advertisement
Guest User

Untitled

a guest
Jan 7th, 2020
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.26 KB | None | 0 0
  1.  
  2. #pragma once
  3.  
  4. #include <fir/str/str.h>
  5. #include <map>
  6. #include <vector>
  7. #include <string>
  8. #include <string.h>
  9. #include <stdexcept>
  10.  
  11.  
  12. namespace fir {
  13. namespace ds {
  14.  
  15. class Dmap {
  16.     enum Type {
  17.         TYPE_NULL,
  18.         TYPE_LONG,
  19.         TYPE_ULONG,
  20.         TYPE_STRING_POINTER,
  21.         TYPE_STRING,
  22.         TYPE_MAP,
  23.         TYPE_VECTOR
  24.     };
  25.  
  26. public:
  27.     typedef std::map<std::string, Dmap> MapType;
  28.     typedef std::vector<Dmap> VectorType;
  29.  
  30.     Type type_ = TYPE_NULL;
  31.  
  32.     union Value {
  33.         long val_long;
  34.         unsigned long val_ulong;
  35.         str::BuffPtr val_string;
  36.         MapType *val_map;
  37.         VectorType *val_vector;
  38.  
  39.         Value() {
  40.  
  41.         }
  42.     };
  43.  
  44.     Value m_value;
  45.  
  46.     Dmap() = default;
  47.  
  48.     Dmap(const Dmap& _rhs)
  49.     : type_( TYPE_NULL )
  50.     //, m_value{0L}
  51.     {
  52.         this->operator=( _rhs );
  53.     }
  54.  
  55.     explicit Dmap(const std::string &_str)
  56.     : type_( TYPE_NULL )
  57.     {
  58.         this->operator=(_str);
  59.     }
  60.  
  61.     virtual ~Dmap()
  62.     {
  63.         forget();
  64.     }
  65.  
  66.     operator bool() const { return TYPE_NULL != type_; }
  67.     bool isLong() { return TYPE_LONG == type_; }
  68.     bool isULong() { return TYPE_ULONG == type_; }
  69.     bool isNumeric() { return (TYPE_LONG == type_) || (TYPE_ULONG == type_); }
  70.     bool isString() { return ((TYPE_STRING_POINTER == type_) || (TYPE_STRING == type_)); }
  71.     bool isVector() { return TYPE_VECTOR == type_; }
  72.     bool isMap() { return TYPE_MAP == type_; }
  73.  
  74.  
  75.     long getLong() {
  76.         if ( TYPE_LONG == type_ ) {
  77.             return m_value.val_long;
  78.         }
  79.  
  80.         if ( TYPE_ULONG == type_ ) {
  81.             return m_value.val_ulong;
  82.         }
  83.  
  84.         return 0;
  85.     }
  86.  
  87.  
  88.     unsigned long getULong() {
  89.         if ( TYPE_LONG == type_ ) {
  90.             return m_value.val_long;
  91.         }
  92.  
  93.         if ( TYPE_ULONG == type_ ) {
  94.             return m_value.val_ulong;
  95.         }
  96.  
  97.         return 0;
  98.     }
  99.  
  100.     str::BuffPtr getString() {
  101.         if ( ! ((TYPE_STRING_POINTER == type_) || (TYPE_STRING == type_)) ) {
  102.             return str::BuffPtr();
  103.         }
  104.  
  105.         return m_value.val_string;
  106.     }
  107.  
  108.     VectorType& get_vector()
  109.     {
  110.         if ( TYPE_VECTOR != type_ )
  111.             throw std::runtime_error("not a vector");
  112.  
  113.         return *(m_value.val_vector);
  114.     }
  115.  
  116.  
  117.     Dmap& operator=(const Dmap& _rhs) {
  118.         forget();
  119.         type_ = _rhs.type_;
  120.  
  121.         switch (type_) {
  122.         default: {
  123.           m_value.val_long = _rhs.m_value.val_long;
  124.           m_value.val_ulong = _rhs.m_value.val_ulong;
  125.           break;
  126.         }
  127.  
  128.         case TYPE_STRING: {
  129.           m_value.val_string.ptr = new char[_rhs.m_value.val_string.size];
  130.           m_value.val_string.size = _rhs.m_value.val_string.size;
  131.           m_value.val_string.clone(_rhs.m_value.val_string);
  132.           break;
  133.         }
  134.  
  135.         case TYPE_STRING_POINTER: {
  136.           m_value.val_string = _rhs.m_value.val_string;
  137.           break;
  138.         }
  139.  
  140.         case TYPE_VECTOR: {
  141.           m_value.val_vector = new VectorType;
  142.           *(m_value.val_vector) = *(_rhs.m_value.val_vector);
  143.           break;
  144.         }
  145.  
  146.         case TYPE_MAP: {
  147.           m_value.val_map = new MapType;
  148.           *(m_value.val_map) = *(_rhs.m_value.val_map);
  149.           break;
  150.         }
  151.       }
  152.  
  153.         return *this;
  154.     }
  155.  
  156.  
  157.     Dmap& operator=(int _val) {
  158.         forget();
  159.  
  160.         type_ = TYPE_LONG;
  161.         m_value.val_long = _val;
  162.         return *this;
  163.     }
  164.  
  165.     Dmap& operator=(unsigned int _val) {
  166.         forget();
  167.  
  168.         type_ = TYPE_ULONG;
  169.         m_value.val_long = _val;
  170.         return *this;
  171.     }
  172.  
  173.     Dmap& operator=(long _val) {
  174.         forget();
  175.  
  176.         type_ = TYPE_LONG;
  177.         m_value.val_long = _val;
  178.         return *this;
  179.     }
  180.  
  181.     Dmap& operator=(unsigned long _val) {
  182.         forget();
  183.  
  184.         type_ = TYPE_ULONG;
  185.         m_value.val_ulong = _val;
  186.         return *this;
  187.     }
  188.  
  189.     Dmap& operator=(const str::BuffPtr& _buffptr) {
  190.         forget();
  191.  
  192.         type_ = TYPE_STRING;
  193.         char *s = new char[_buffptr.size];
  194.         memcpy(s, _buffptr.ptr, _buffptr.size);
  195.         m_value.val_string.ptr = s;
  196.         m_value.val_string.size = _buffptr.size;
  197.         return *this;
  198.     }
  199.  
  200.     Dmap& operator=(const std::string &_str) {
  201.         return this->operator=(str::BuffPtr(_str));
  202.     }
  203.  
  204.     Dmap& operator=(const char *_str) {
  205.         if ( ! _str ) {
  206.             this->operator=( (int) 0);
  207.             return *this;
  208.         }
  209.  
  210.         return this->operator=(str::BuffPtr(_str));
  211.     }
  212.  
  213.     Dmap& set_ref(const char *_str) {
  214.         return set_ref( str::BuffPtr(_str) );
  215.     }
  216.  
  217.     Dmap& set_ref(const std::string &_str) {
  218.         return set_ref(str::BuffPtr(_str));
  219.     }
  220.  
  221.     Dmap& set_ref(const str::BuffPtr& _buffptr) {
  222.         forget();
  223.         type_ = TYPE_STRING_POINTER;
  224.         m_value.val_string = _buffptr;
  225.         return *this;
  226.     }
  227.  
  228.     Dmap& make_vector() {
  229.         forget();
  230.         m_value.val_vector = new VectorType;
  231.         type_ = TYPE_VECTOR;
  232.         return *this;
  233.     }
  234.  
  235.     void push_back( const Dmap &_rhs) {
  236.         if ( TYPE_VECTOR != type_ ) {
  237.         return;
  238.       }
  239.  
  240.         m_value.val_vector->push_back(_rhs);
  241.     }
  242.  
  243.     Dmap& operator[](const char *_key) {
  244.         if ( TYPE_MAP != type_ ) {
  245.             forget();
  246.             type_ = TYPE_MAP;
  247.             m_value.val_map = new MapType;
  248.         }
  249.  
  250.         return (*(m_value.val_map))[ _key ];
  251.     }
  252.  
  253.     Dmap& operator[](const std::string &_key) {
  254.         return operator[]( _key.c_str() );
  255.     }
  256.  
  257.     Dmap& operator[](int _index) {
  258.         return operator[]((size_t)_index);
  259.     }
  260.  
  261.     Dmap& operator[](size_t _index) {
  262.         if ( TYPE_VECTOR != type_ ) {
  263.             make_vector();
  264.         }
  265.  
  266.         if ( _index >= m_value.val_vector->size() ) {
  267.             m_value.val_vector->resize( _index + 1 );
  268.         }
  269.  
  270.         return (*(m_value.val_vector))[ _index ];
  271.     }
  272.  
  273.     size_t size() {
  274.         if ( TYPE_VECTOR == type_ ) {
  275.             return m_value.val_vector->size();
  276.         }
  277.         return 0;
  278.     }
  279.  
  280.  
  281.  
  282. protected:
  283.     void forget() {
  284.         switch(type_) {
  285.         case TYPE_STRING:
  286.             if (m_value.val_string.size) {
  287.                 delete[] m_value.val_string.ptr;
  288.                 m_value.val_string.size = 0;
  289.                 m_value.val_string.ptr = nullptr;
  290.             }
  291.             break;
  292.  
  293.         case TYPE_MAP:
  294.             delete m_value.val_map;
  295.             break;
  296.  
  297.         case TYPE_VECTOR:
  298.             delete m_value.val_vector;
  299.             break;
  300.  
  301.         default:
  302.             break;
  303.         }
  304.  
  305.         type_ = TYPE_NULL;
  306.     }
  307. };
  308.  
  309. }
  310. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement