libdap  Updated for version 3.17.0
D4EnumDefs.h
00001 // -*- mode: c++; c-basic-offset:4 -*-
00002 
00003 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
00004 // Access Protocol.
00005 
00006 // Copyright (c) 2013 OPeNDAP, Inc.
00007 // Author: James Gallagher <jgallagher@opendap.org>
00008 //
00009 // This library is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU Lesser General Public
00011 // License as published by the Free Software Foundation; either
00012 // version 2.1 of the License, or (at your option) any later version.
00013 //
00014 // This library is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 // Lesser General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU Lesser General Public
00020 // License along with this library; if not, write to the Free Software
00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022 //
00023 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
00024 
00025 #ifndef D4ENUMDEF_H_
00026 #define D4ENUMDEF_H_
00027 
00028 #include <string>
00029 #include <vector>
00030 #include <algorithm>
00031 #include <functional>
00032 
00033 #include "BaseType.h"
00034 
00035 using namespace std;
00036 
00037 namespace libdap {
00038 
00039 class D4EnumDefs;
00040 class D4Group;
00041 
00042 class D4EnumDef {
00043     string d_name;
00044     Type d_type;
00045     D4EnumDefs *d_parent;
00046 
00047     struct tuple {
00048         string label;
00049         long long value;
00050 
00051         tuple(const string &l, long long v) : label(l), value(v) {}
00052     };
00053 
00054     vector<tuple> d_tuples;
00055 
00056     void m_duplicate(const D4EnumDef &rhs)
00057     {
00058         d_name = rhs.d_name;
00059         d_type = rhs.d_type;
00060         d_parent = rhs.d_parent;
00061         d_tuples = rhs.d_tuples;
00062     }
00063 
00064     void print_value(XMLWriter &xml, const D4EnumDef::tuple &tuple) const;
00065 
00066 public:
00067     typedef vector<tuple>::iterator D4EnumValueIter;
00068 
00069     D4EnumDef() : d_name(""), d_type(dods_null_c), d_parent(0) {}
00070     D4EnumDef(const string &n, const Type &t, D4EnumDefs *e = 0) : d_name(n), d_type(t), d_parent(e) {}
00071     D4EnumDef(const D4EnumDef &rhs) {
00072         m_duplicate(rhs);
00073     }
00074 
00075     string name() const { return d_name; }
00076     void set_name(const string &n) { d_name = n; }
00077 
00078     Type type() const { return d_type; }
00079     void set_type(Type t) { d_type = t; }
00080 
00081     D4EnumDefs *parent() const { return d_parent; }
00082     void set_parent(D4EnumDefs *e) { d_parent = e; }
00083 
00084     bool empty() const { return d_tuples.empty(); }
00085 
00086     void add_value(const string &label, long long value) {
00087         d_tuples.push_back(tuple(label, value));
00088     }
00089 
00090     D4EnumValueIter value_begin() { return d_tuples.begin(); }
00091     D4EnumValueIter value_end() { return d_tuples.end(); }
00092     string &label(D4EnumValueIter i) { return (*i).label; }
00093     long long value(D4EnumValueIter i) { return (*i).value; }
00094 
00095     bool is_valid_enum_value(long long value);
00096     void print_dap4(XMLWriter &xml) const;
00097 };
00098 
00100 class D4EnumDefs {
00101     vector<D4EnumDef*> d_enums;
00102 
00103     D4Group *d_parent;          // the group that holds this set of D4EnumDefs; weak pointer, don't delete
00104 
00105     void m_print_enum(XMLWriter &xml, D4EnumDef *e) const;
00106 
00107     void m_duplicate(const D4EnumDefs &rhs) {
00108         D4EnumDefCIter i = rhs.d_enums.begin();
00109         while (i != rhs.d_enums.end()) {
00110             d_enums.push_back(new D4EnumDef(**i++));    // deep copy
00111         }
00112 
00113         d_parent = rhs.d_parent;
00114     }
00115 
00116 public:
00117     typedef vector<D4EnumDef*>::iterator D4EnumDefIter;
00118     typedef vector<D4EnumDef*>::const_iterator D4EnumDefCIter;
00119 
00120     D4EnumDefs() : d_parent(0) {}
00121     D4EnumDefs(const D4EnumDefs &rhs) {
00122         m_duplicate(rhs);
00123     }
00124 
00125     virtual ~D4EnumDefs() {
00126         D4EnumDefIter i = d_enums.begin();
00127         while(i != d_enums.end()) {
00128             delete *i++;
00129         }
00130     }
00131 
00132     D4EnumDefs &operator=(const D4EnumDefs &rhs) {
00133         if (this == &rhs) return *this;
00134         m_duplicate(rhs);
00135         return *this;
00136     }
00137 
00138     bool empty() const { return d_enums.empty(); }
00139 
00140     D4Group *parent() const { return d_parent; }
00141     void set_parent(D4Group *p) { d_parent = p; }
00142 
00147     void add_enum(D4EnumDef *enum_def) {
00148         add_enum_nocopy(new D4EnumDef(*enum_def));
00149     }
00150     void add_enum_nocopy(D4EnumDef *enum_def) {
00151         enum_def->set_parent(this);
00152         d_enums.push_back(enum_def);
00153     }
00154 
00156     D4EnumDefIter enum_begin() { return d_enums.begin(); }
00157 
00159     D4EnumDefIter enum_end() { return d_enums.end(); }
00160 
00161     D4EnumDef *find_enum_def(const string &name);
00162 
00171     void insert_enum(D4EnumDef *enum_def, D4EnumDefIter i) {
00172         D4EnumDef *enum_def_copy = new D4EnumDef(*enum_def);
00173         enum_def_copy->set_parent(this);
00174         d_enums.insert(i, enum_def_copy);
00175     }
00176 
00177     void print_dap4(XMLWriter &xml, bool constrained = false) const;
00178 };
00179 
00180 } /* namespace libdap */
00181 #endif /* D4ENUMDEF_H_ */