libdap  Updated for version 3.17.0
AttrTable.h
00001 
00002 // -*- mode: c++; c-basic-offset:4 -*-
00003 
00004 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
00005 // Access Protocol.
00006 
00007 // Copyright (c) 2002,2003 OPeNDAP, Inc.
00008 // Author: James Gallagher <jgallagher@opendap.org>
00009 //
00010 // This library is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU Lesser General Public
00012 // License as published by the Free Software Foundation; either
00013 // version 2.1 of the License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00023 //
00024 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
00025 
00026 // (c) COPYRIGHT URI/MIT 1994-1999
00027 // Please read the full copyright statement in the file COPYRIGHT_URI.
00028 //
00029 // Authors:
00030 //      jhrg,jimg       James Gallagher <jgallagher@gso.uri.edu>
00031 
00032 // An AttrTable is a table of attributes (type-name-value tuples).
00033 
00034 #ifndef _attrtable_h
00035 #define _attrtable_h 1
00036 
00037 
00038 #include <string>
00039 #include <vector>
00040 
00041 #ifndef _error_h
00042 #include "Error.h"
00043 #endif
00044 
00045 using std::vector;
00046 using std::string;
00047 using std::vector;
00048 
00049 #ifndef A_DapObj_h
00050 #include "DapObj.h"
00051 #endif
00052 
00053 #ifndef XMLWRITER_H_
00054 #include "XMLWriter.h"
00055 #endif
00056 
00057 namespace libdap
00058 {
00059 
00081 enum AttrType {
00082     Attr_unknown,
00083     Attr_container,
00084     Attr_byte,
00085     Attr_int16,
00086     Attr_uint16,
00087     Attr_int32,
00088     Attr_uint32,
00089     Attr_float32,
00090     Attr_float64,
00091     Attr_string,
00092     Attr_url,
00093     Attr_other_xml
00094 };
00095 
00096 string AttrType_to_String(const AttrType at);
00097 AttrType String_to_AttrType(const string &s);
00098 
00142 class AttrTable : public DapObj
00143 {
00144     // entry needs to be made public to make up for issues with this class'
00145     // design. It should probably be moved to it's own class. 05/22/03 jhrg
00146 public:
00151     struct entry
00152     {
00153         string name;
00154         AttrType type;
00155 
00156         bool is_alias;
00157         string aliased_to;
00158 
00159         bool is_global; // use this to mark non-container attributes. see below.
00160 
00161         // If type == Attr_container, use attributes to read the contained
00162         // table, otherwise use attr to read the vector of values.
00163         AttrTable *attributes;
00164         std::vector<string> *attr; // a vector of values. jhrg 12/5/94
00165 
00166         entry(): name(""), type(Attr_unknown), is_alias(false),
00167                 aliased_to(""), is_global(true), attributes(0), attr(0) {}
00168 
00169         entry(const entry &rhs): name(rhs.name), type(rhs.type), is_alias(rhs.is_alias),
00170                 aliased_to(rhs.aliased_to), is_global(rhs.is_global),attributes(0), attr(0)
00171         {
00172             clone(rhs);
00173         }
00174 
00175         void delete_entry()
00176         {
00177             if (is_alias) // alias copies the pointers.
00178                 return;
00179             if (type == Attr_container) {
00180                 delete attributes; attributes = 0;
00181             }
00182             else {
00183                 delete attr; attr = 0;
00184             }
00185         }
00186 
00187         virtual ~entry()
00188         {
00189             delete_entry();
00190         }
00191 
00192         void clone(const entry &rhs)
00193         {
00194 #if 0
00195             name = rhs.name;
00196             type = rhs.type;
00197             is_alias = rhs.is_alias;
00198             aliased_to = rhs.aliased_to;
00199             is_global = rhs.is_global;
00200 #endif
00201             switch (rhs.type) {
00202             case Attr_unknown:
00203                 break;
00204             case Attr_container: {
00205                 if (rhs.is_alias)
00206                     attributes = rhs.attributes;
00207                 else
00208                     attributes = new AttrTable(*rhs.attributes);
00209                 break;
00210             }
00211             default: {
00212                 if (rhs.is_alias)
00213                     attr = rhs.attr;
00214                 else
00215                     attr = new std::vector<string>(*rhs.attr);
00216                 break;
00217             }
00218             }
00219         }
00220 
00221         entry &operator=(const entry &rhs)
00222         {
00223             if (this != &rhs) {
00224                 delete_entry();
00225                 clone(rhs);
00226             }
00227             return *this;
00228         }
00229     };
00230 
00231     typedef std::vector<entry *>::const_iterator Attr_citer ;
00232     typedef std::vector<entry *>::iterator Attr_iter ;
00233 
00234 private:
00235     string d_name;
00236     AttrTable *d_parent;
00237     std::vector<entry *> attr_map;
00238 
00239     // Use this to mark container attributes. Look at the methods
00240     // is_global_attribute() and set_is_...., esp. at the versions that take
00241     // an iterator. This code is tricky because it has to track both whole
00242     // containers that are global and individual attributes that are 'global'
00243     // relative to a constructor. That is, there are some attributes that are
00244     // bound to a container and not any of the container's children.
00245     bool d_is_global_attribute;
00246 
00247     void delete_attr_table();
00248 
00249     friend class AttrTableTest;
00250 
00251 protected:
00252     void clone(const AttrTable &at);
00253 
00254     void simple_print(FILE *out, string pad, Attr_iter i,
00255                       bool dereference);
00256     void simple_print(ostream &out, string pad, Attr_iter i,
00257                       bool dereference);
00258 
00259 public:
00260     AttrTable();
00261     AttrTable(const AttrTable &rhs);
00262     virtual ~AttrTable();
00263     AttrTable & operator=(const AttrTable &rhs);
00264 
00265     virtual void erase();
00266 
00267     virtual unsigned int get_size() const;
00268     virtual string get_name() const;
00269     virtual void set_name(const string &n);
00270 
00274     virtual AttrTable *get_parent() const
00275     {
00276         return d_parent;
00277     }
00278 
00279     virtual bool is_global_attribute() const { return d_is_global_attribute; }
00280     virtual void set_is_global_attribute(bool ga) { d_is_global_attribute = ga; }
00281 
00282     virtual unsigned int append_attr(const string &name, const string &type,
00283                                      const string &value);
00284     virtual unsigned int append_attr(const string &name, const string &type,
00285                                      vector<string> *values);
00286 
00287     virtual AttrTable *append_container(const string &name);
00288     virtual AttrTable *append_container(AttrTable *at, const string &name);
00289 
00290     virtual void find(const string &target, AttrTable **at, Attr_iter *iter);
00291     virtual AttrTable *find_container(const string &target);
00292     virtual AttrTable *recurrsive_find(const string &target,
00293                                        Attr_iter *location);
00294 
00295     Attr_iter simple_find(const string &target);
00296     AttrTable *simple_find_container(const string &target);
00297 
00298 
00299     virtual AttrTable *get_attr_table(const string &name);
00300     virtual string get_type(const string &name);
00301     virtual AttrType get_attr_type(const string &name);
00302     virtual unsigned int get_attr_num(const string &name);
00303     virtual string get_attr(const string &name, unsigned int i = 0);
00304     virtual vector<string> *get_attr_vector(const string &name);
00305     virtual void del_attr(const string &name, int i = -1);
00306 
00307     virtual Attr_iter attr_begin();
00308     virtual Attr_iter attr_end();
00309     virtual Attr_iter get_attr_iter(int i);
00310     virtual string get_name(Attr_iter iter);
00311     virtual bool is_container(Attr_iter iter);
00312     virtual AttrTable *get_attr_table(Attr_iter iter);
00313     virtual Attr_iter del_attr_table(Attr_iter iter);
00314     virtual string get_type(Attr_iter iter);
00315     virtual AttrType get_attr_type(Attr_iter iter);
00316     virtual unsigned int get_attr_num(Attr_iter iter);
00317     virtual string get_attr(Attr_iter iter, unsigned int i = 0);
00318     virtual std::vector<string> *get_attr_vector(Attr_iter iter);
00319     virtual bool is_global_attribute(Attr_iter iter);
00320     virtual void set_is_global_attribute(Attr_iter iter, bool ga);
00321 
00322     virtual void add_container_alias(const string &name, AttrTable *src);
00323     virtual void add_value_alias(AttrTable *at, const string &name,
00324                          const string &source);
00325     virtual bool attr_alias(const string &alias,
00326                             AttrTable *at,
00327                             const string &name);
00328     virtual bool attr_alias(const string &alias, const string &name);
00329 
00330     virtual void print(FILE *out, string pad = "    ",
00331                        bool dereference = false);
00332     virtual void print(ostream &out, string pad = "    ",
00333                        bool dereference = false);
00334 
00335     virtual void print_xml(FILE *out, string pad = "    ",
00336                            bool constrained = false);
00337     virtual void print_xml(ostream &out, string pad = "    ",
00338                            bool constrained = false);
00339 
00340     void print_xml_writer(XMLWriter &xml);
00341 
00342     void print_dap4(XMLWriter &xml);
00343 
00344     virtual void dump(ostream &strm) const ;
00345 };
00346 
00347 } // namespace libdap
00348 
00349 #endif // _attrtable_h