|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// -*- mode: c++; c-basic-offset:4 -*-
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// This file is part of libdap, A C++ implementation of the OPeNDAP Data
|
|
Packit |
a4aae4 |
// Access Protocol.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Copyright (c) 2002,2003 OPeNDAP, Inc.
|
|
Packit |
a4aae4 |
// Author: James Gallagher <jgallagher@opendap.org>
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// This library is free software; you can redistribute it and/or
|
|
Packit |
a4aae4 |
// modify it under the terms of the GNU Lesser General Public
|
|
Packit |
a4aae4 |
// License as published by the Free Software Foundation; either
|
|
Packit |
a4aae4 |
// version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// This library is distributed in the hope that it will be useful,
|
|
Packit |
a4aae4 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
a4aae4 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
a4aae4 |
// Lesser General Public License for more details.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// You should have received a copy of the GNU Lesser General Public
|
|
Packit |
a4aae4 |
// License along with this library; if not, write to the Free Software
|
|
Packit |
a4aae4 |
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// (c) COPYRIGHT URI/MIT 1994-1999
|
|
Packit |
a4aae4 |
// Please read the full copyright statement in the file COPYRIGHT_URI.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// Authors:
|
|
Packit |
a4aae4 |
// jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// An AttrTable is a table of attributes (type-name-value tuples).
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#ifndef _attrtable_h
|
|
Packit |
a4aae4 |
#define _attrtable_h 1
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include <string>
|
|
Packit |
a4aae4 |
#include <vector>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#ifndef _error_h
|
|
Packit |
a4aae4 |
#include "Error.h"
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
using std::vector;
|
|
Packit |
a4aae4 |
using std::string;
|
|
Packit |
a4aae4 |
using std::vector;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#ifndef A_DapObj_h
|
|
Packit |
a4aae4 |
#include "DapObj.h"
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#ifndef XMLWRITER_H_
|
|
Packit |
a4aae4 |
#include "XMLWriter.h"
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
namespace libdap
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** AttrType identifies the data types which may appear in an
|
|
Packit |
a4aae4 |
attribute table object.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
\code
|
|
Packit |
a4aae4 |
enum AttrType {
|
|
Packit |
a4aae4 |
Attr_unknown,
|
|
Packit |
a4aae4 |
Attr_container,
|
|
Packit |
a4aae4 |
Attr_byte,
|
|
Packit |
a4aae4 |
Attr_int16,
|
|
Packit |
a4aae4 |
Attr_uint16,
|
|
Packit |
a4aae4 |
Attr_int32,
|
|
Packit |
a4aae4 |
Attr_uint32,
|
|
Packit |
a4aae4 |
Attr_float32,
|
|
Packit |
a4aae4 |
Attr_float64,
|
|
Packit |
a4aae4 |
Attr_string,
|
|
Packit |
a4aae4 |
Attr_url,
|
|
Packit |
a4aae4 |
Attr_other_xml
|
|
Packit |
a4aae4 |
};
|
|
Packit |
a4aae4 |
\endcode
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@see AttrTable */
|
|
Packit |
a4aae4 |
enum AttrType {
|
|
Packit |
a4aae4 |
Attr_unknown,
|
|
Packit |
a4aae4 |
Attr_container,
|
|
Packit |
a4aae4 |
Attr_byte,
|
|
Packit |
a4aae4 |
Attr_int16,
|
|
Packit |
a4aae4 |
Attr_uint16,
|
|
Packit |
a4aae4 |
Attr_int32,
|
|
Packit |
a4aae4 |
Attr_uint32,
|
|
Packit |
a4aae4 |
Attr_float32,
|
|
Packit |
a4aae4 |
Attr_float64,
|
|
Packit |
a4aae4 |
Attr_string,
|
|
Packit |
a4aae4 |
Attr_url,
|
|
Packit |
a4aae4 |
Attr_other_xml
|
|
Packit |
a4aae4 |
};
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
string AttrType_to_String(const AttrType at);
|
|
Packit |
a4aae4 |
AttrType String_to_AttrType(const string &s);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** An AttrTable (``Attribute Table'') stores a set of names and, for
|
|
Packit |
a4aae4 |
each name, either a type and a value, or another attribute table.
|
|
Packit |
a4aae4 |
The attribute value can be a vector containing many values of the
|
|
Packit |
a4aae4 |
same type. The attributes can have any of the types listed in the
|
|
Packit |
a4aae4 |
<tt>AttrType</tt> list. However, all attribute types are stored as
|
|
Packit |
a4aae4 |
string data, except for the container type, which is stored as a
|
|
Packit |
a4aae4 |
pointer to another attribute table.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Each element in the attribute table can itself be an attribute
|
|
Packit |
a4aae4 |
table. The table can also contain ``alias'' attributes whose
|
|
Packit |
a4aae4 |
value is given by the value of another attribute to which it is
|
|
Packit |
a4aae4 |
linked.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
The attribute tables have a standard printed representation.
|
|
Packit |
a4aae4 |
There is a member function <tt>print()</tt> for writing this form. Use
|
|
Packit |
a4aae4 |
the <tt>DAS::parse()</tt> function to read the printed form.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
An attribute table might look something like this:
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
\verbatim
|
|
Packit |
a4aae4 |
string long_name "Weekly Means of Sea Surface Temperature";
|
|
Packit |
a4aae4 |
actual_range {
|
|
Packit |
a4aae4 |
Float64 min -1.8;
|
|
Packit |
a4aae4 |
Float64 max 35.09;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
string units "degC";
|
|
Packit |
a4aae4 |
conversion_data {
|
|
Packit |
a4aae4 |
Float64 add_offset 0.;
|
|
Packit |
a4aae4 |
Float64 scale_factor 0.0099999998;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
Int32 missing_value 32767;
|
|
Packit |
a4aae4 |
\endverbatim
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Here, <tt>long_name</tt>, <tt>units</tt>, and
|
|
Packit |
a4aae4 |
<tt>missing_value</tt> are simple
|
|
Packit |
a4aae4 |
attributes, and <tt>actual_range</tt> and <tt>conversion_data</tt>
|
|
Packit |
a4aae4 |
are container attributes containing other attribute tables.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@note This class is used only for DAP2.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@brief Contains the attributes for a dataset.
|
|
Packit |
a4aae4 |
@see DAS
|
|
Packit |
a4aae4 |
@see AttrType */
|
|
Packit |
a4aae4 |
class AttrTable : public DapObj
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
// entry needs to be made public to make up for issues with this class'
|
|
Packit |
a4aae4 |
// design. It should probably be moved to it's own class. 05/22/03 jhrg
|
|
Packit |
a4aae4 |
public:
|
|
Packit |
a4aae4 |
/** Each AttrTable has zero or more entries. Instead of accessing this
|
|
Packit |
a4aae4 |
struct's members directly, use AttrTable methods.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
This struct is public because its type is used in public typedefs. */
|
|
Packit |
a4aae4 |
struct entry
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
string name;
|
|
Packit |
a4aae4 |
AttrType type;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
bool is_alias;
|
|
Packit |
a4aae4 |
string aliased_to;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
bool is_global; // use this to mark non-container attributes. see below.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// If type == Attr_container, use attributes to read the contained
|
|
Packit |
a4aae4 |
// table, otherwise use attr to read the vector of values.
|
|
Packit |
a4aae4 |
AttrTable *attributes;
|
|
Packit |
a4aae4 |
std::vector<string> *attr; // a vector of values. jhrg 12/5/94
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
entry(): name(""), type(Attr_unknown), is_alias(false),
|
|
Packit |
a4aae4 |
aliased_to(""), is_global(true), attributes(0), attr(0) {}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
entry(const entry &rhs): name(rhs.name), type(rhs.type), is_alias(rhs.is_alias),
|
|
Packit |
a4aae4 |
aliased_to(rhs.aliased_to), is_global(rhs.is_global),attributes(0), attr(0)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
clone(rhs);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void delete_entry()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (is_alias) // alias copies the pointers.
|
|
Packit |
a4aae4 |
return;
|
|
Packit |
a4aae4 |
if (type == Attr_container) {
|
|
Packit |
a4aae4 |
delete attributes; attributes = 0;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
else {
|
|
Packit |
a4aae4 |
delete attr; attr = 0;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual ~entry()
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
delete_entry();
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void clone(const entry &rhs)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
#if 0
|
|
Packit |
a4aae4 |
name = rhs.name;
|
|
Packit |
a4aae4 |
type = rhs.type;
|
|
Packit |
a4aae4 |
is_alias = rhs.is_alias;
|
|
Packit |
a4aae4 |
aliased_to = rhs.aliased_to;
|
|
Packit |
a4aae4 |
is_global = rhs.is_global;
|
|
Packit |
a4aae4 |
#endif
|
|
Packit |
a4aae4 |
switch (rhs.type) {
|
|
Packit |
a4aae4 |
case Attr_unknown:
|
|
Packit |
a4aae4 |
break;
|
|
Packit |
a4aae4 |
case Attr_container: {
|
|
Packit |
a4aae4 |
if (rhs.is_alias)
|
|
Packit |
a4aae4 |
attributes = rhs.attributes;
|
|
Packit |
a4aae4 |
else
|
|
Packit |
a4aae4 |
attributes = new AttrTable(*rhs.attributes);
|
|
Packit |
a4aae4 |
break;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
default: {
|
|
Packit |
a4aae4 |
if (rhs.is_alias)
|
|
Packit |
a4aae4 |
attr = rhs.attr;
|
|
Packit |
a4aae4 |
else
|
|
Packit |
a4aae4 |
attr = new std::vector<string>(*rhs.attr);
|
|
Packit |
a4aae4 |
break;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
entry &operator=(const entry &rhs)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
if (this != &rhs) {
|
|
Packit |
a4aae4 |
delete_entry();
|
|
Packit |
a4aae4 |
clone(rhs);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
return *this;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
};
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
typedef std::vector<entry *>::const_iterator Attr_citer ;
|
|
Packit |
a4aae4 |
typedef std::vector<entry *>::iterator Attr_iter ;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
private:
|
|
Packit |
a4aae4 |
string d_name;
|
|
Packit |
a4aae4 |
AttrTable *d_parent;
|
|
Packit |
a4aae4 |
std::vector<entry *> attr_map;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Use this to mark container attributes. Look at the methods
|
|
Packit |
a4aae4 |
// is_global_attribute() and set_is_...., esp. at the versions that take
|
|
Packit |
a4aae4 |
// an iterator. This code is tricky because it has to track both whole
|
|
Packit |
a4aae4 |
// containers that are global and individual attributes that are 'global'
|
|
Packit |
a4aae4 |
// relative to a constructor. That is, there are some attributes that are
|
|
Packit |
a4aae4 |
// bound to a container and not any of the container's children.
|
|
Packit |
a4aae4 |
bool d_is_global_attribute;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void delete_attr_table();
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
friend class AttrTableTest;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
protected:
|
|
Packit |
a4aae4 |
void clone(const AttrTable &at);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void simple_print(FILE *out, string pad, Attr_iter i,
|
|
Packit |
a4aae4 |
bool dereference);
|
|
Packit |
a4aae4 |
void simple_print(ostream &out, string pad, Attr_iter i,
|
|
Packit |
a4aae4 |
bool dereference);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
public:
|
|
Packit |
a4aae4 |
AttrTable();
|
|
Packit |
a4aae4 |
AttrTable(const AttrTable &rhs;;
|
|
Packit |
a4aae4 |
virtual ~AttrTable();
|
|
Packit |
a4aae4 |
AttrTable & operator=(const AttrTable &rhs;;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void erase();
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual unsigned int get_size() const;
|
|
Packit |
a4aae4 |
virtual string get_name() const;
|
|
Packit |
a4aae4 |
virtual void set_name(const string &n);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Return a pointer to the AttrTable which holds this table (aka, its
|
|
Packit |
a4aae4 |
parent. If this AttrTable has no parent, this returns null.
|
|
Packit |
a4aae4 |
@return A pointer to the parent AttrTable. */
|
|
Packit |
a4aae4 |
virtual AttrTable *get_parent() const
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
return d_parent;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual bool is_global_attribute() const { return d_is_global_attribute; }
|
|
Packit |
a4aae4 |
virtual void set_is_global_attribute(bool ga) { d_is_global_attribute = ga; }
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual unsigned int append_attr(const string &name, const string &type,
|
|
Packit |
a4aae4 |
const string &value);
|
|
Packit |
a4aae4 |
virtual unsigned int append_attr(const string &name, const string &type,
|
|
Packit |
a4aae4 |
vector<string> *values);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual AttrTable *append_container(const string &name);
|
|
Packit |
a4aae4 |
virtual AttrTable *append_container(AttrTable *at, const string &name);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void find(const string &target, AttrTable **at, Attr_iter *iter);
|
|
Packit |
a4aae4 |
virtual AttrTable *find_container(const string &target);
|
|
Packit |
a4aae4 |
virtual AttrTable *recurrsive_find(const string &target,
|
|
Packit |
a4aae4 |
Attr_iter *location);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
Attr_iter simple_find(const string &target);
|
|
Packit |
a4aae4 |
AttrTable *simple_find_container(const string &target);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual AttrTable *get_attr_table(const string &name);
|
|
Packit |
a4aae4 |
virtual string get_type(const string &name);
|
|
Packit |
a4aae4 |
virtual AttrType get_attr_type(const string &name);
|
|
Packit |
a4aae4 |
virtual unsigned int get_attr_num(const string &name);
|
|
Packit |
a4aae4 |
virtual string get_attr(const string &name, unsigned int i = 0);
|
|
Packit |
a4aae4 |
virtual vector<string> *get_attr_vector(const string &name);
|
|
Packit |
a4aae4 |
virtual void del_attr(const string &name, int i = -1);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual Attr_iter attr_begin();
|
|
Packit |
a4aae4 |
virtual Attr_iter attr_end();
|
|
Packit |
a4aae4 |
virtual Attr_iter get_attr_iter(int i);
|
|
Packit |
a4aae4 |
virtual string get_name(Attr_iter iter);
|
|
Packit |
a4aae4 |
virtual bool is_container(Attr_iter iter);
|
|
Packit |
a4aae4 |
virtual AttrTable *get_attr_table(Attr_iter iter);
|
|
Packit |
a4aae4 |
virtual Attr_iter del_attr_table(Attr_iter iter);
|
|
Packit |
a4aae4 |
virtual string get_type(Attr_iter iter);
|
|
Packit |
a4aae4 |
virtual AttrType get_attr_type(Attr_iter iter);
|
|
Packit |
a4aae4 |
virtual unsigned int get_attr_num(Attr_iter iter);
|
|
Packit |
a4aae4 |
virtual string get_attr(Attr_iter iter, unsigned int i = 0);
|
|
Packit |
a4aae4 |
virtual std::vector<string> *get_attr_vector(Attr_iter iter);
|
|
Packit |
a4aae4 |
virtual bool is_global_attribute(Attr_iter iter);
|
|
Packit |
a4aae4 |
virtual void set_is_global_attribute(Attr_iter iter, bool ga);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void add_container_alias(const string &name, AttrTable *src);
|
|
Packit |
a4aae4 |
virtual void add_value_alias(AttrTable *at, const string &name,
|
|
Packit |
a4aae4 |
const string &source);
|
|
Packit |
a4aae4 |
virtual bool attr_alias(const string &alias,
|
|
Packit |
a4aae4 |
AttrTable *at,
|
|
Packit |
a4aae4 |
const string &name);
|
|
Packit |
a4aae4 |
virtual bool attr_alias(const string &alias, const string &name);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void print(FILE *out, string pad = " ",
|
|
Packit |
a4aae4 |
bool dereference = false);
|
|
Packit |
a4aae4 |
virtual void print(ostream &out, string pad = " ",
|
|
Packit |
a4aae4 |
bool dereference = false);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void print_xml(FILE *out, string pad = " ",
|
|
Packit |
a4aae4 |
bool constrained = false);
|
|
Packit |
a4aae4 |
virtual void print_xml(ostream &out, string pad = " ",
|
|
Packit |
a4aae4 |
bool constrained = false);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void print_xml_writer(XMLWriter &xml;;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
void print_dap4(XMLWriter &xml;;
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
virtual void dump(ostream &strm) const ;
|
|
Packit |
a4aae4 |
};
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
string remove_space_encoding(const string &s);
|
|
Packit |
a4aae4 |
string add_space_encoding(const string &s);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
} // namespace libdap
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#endif // _attrtable_h
|