-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathAttrTable.h
More file actions
407 lines (338 loc) · 13.7 KB
/
AttrTable.h
File metadata and controls
407 lines (338 loc) · 13.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
// -*- mode: c++; c-basic-offset:4 -*-
// This file is part of libdap, A C++ implementation of the OPeNDAP Data
// Access Protocol.
// Copyright (c) 2002,2003 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
// (c) COPYRIGHT URI/MIT 1994-1999
// Please read the full copyright statement in the file COPYRIGHT_URI.
//
// Authors:
// jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
// An AttrTable is a table of attributes (type-name-value tuples).
#ifndef _attrtable_h
#define _attrtable_h 1
#include <string>
#include <vector>
#ifndef _error_h
#include "Error.h"
#endif
using std::string;
using std::vector;
#ifndef A_DapObj_h
#include "DapObj.h"
#endif
#ifndef XMLWRITER_H_
#include "XMLWriter.h"
#endif
namespace libdap {
/** <b>AttrType</b> identifies the data types which may appear in an
attribute table object.
\code
enum AttrType {
Attr_unknown,
Attr_container,
Attr_byte,
Attr_int16,
Attr_uint16,
Attr_int32,
Attr_uint32,
Attr_float32,
Attr_float64,
Attr_string,
Attr_url,
Attr_other_xml
};
\endcode
@see AttrTable */
enum AttrType {
Attr_unknown,
Attr_container,
Attr_byte,
Attr_int16,
Attr_uint16,
Attr_int32,
Attr_uint32,
Attr_float32,
Attr_float64,
Attr_string,
Attr_url,
Attr_other_xml,
// Added for DAP4
Attr_int8,
Attr_uint8,
Attr_int64,
Attr_uint64,
Attr_enum,
Attr_opaque
};
string AttrType_to_String(const AttrType at);
AttrType String_to_AttrType(const string &s);
/** An AttrTable (``Attribute Table'') stores a set of names and, for
each name, either a type and a value, or another attribute table.
The attribute value can be a vector containing many values of the
same type. The attributes can have any of the types listed in the
<tt>AttrType</tt> list. However, all attribute types are stored as
string data, except for the container type, which is stored as a
pointer to another attribute table.
Each element in the attribute table can itself be an attribute
table. The table can also contain ``alias'' attributes whose
value is given by the value of another attribute to which it is
linked.
The attribute tables have a standard printed representation.
There is a member function <tt>print()</tt> for writing this form. Use
the <tt>DAS::parse()</tt> function to read the printed form.
An attribute table might look something like this:
\verbatim
string long_name "Weekly Means of Sea Surface Temperature";
actual_range {
Float64 min -1.8;
Float64 max 35.09;
}
string units "degC";
conversion_data {
Float64 add_offset 0.;
Float64 scale_factor 0.0099999998;
}
Int32 missing_value 32767;
\endverbatim
Here, <tt>long_name</tt>, <tt>units</tt>, and
<tt>missing_value</tt> are simple
attributes, and <tt>actual_range</tt> and <tt>conversion_data</tt>
are container attributes containing other attribute tables.
@note This class is used only for DAP2.
@brief Contains the attributes for a dataset.
@see DAS
@see AttrType */
class AttrTable : public DapObj {
// entry needs to be made public to make up for issues with this class'
// design. It should probably be moved to it's own class. 05/22/03 jhrg
public:
/** Each AttrTable has zero or more entries. Instead of accessing this
struct's members directly, use AttrTable methods.
This struct is public because its type is used in public typedefs. */
struct entry {
string name; ///< Attribute name within the containing table.
AttrType type; ///< Attribute type tag.
bool is_alias; ///< True when this entry aliases another entry's value/container.
string aliased_to; ///< Alias target path or name.
bool is_global; ///< Marks non-container attributes that are global to their constructor context.
bool is_utf8_str = false; ///< True when string values should be emitted as UTF-8 text.
// If type == Attr_container, use attributes to read the contained
// table, otherwise use attr to read the vector of values.
AttrTable *attributes; ///< Nested container table when `type == Attr_container`.
std::vector<string> *attr; ///< Scalar/vector values for non-container attributes.
entry()
: name(""), type(Attr_unknown), is_alias(false), aliased_to(""), is_global(true), attributes(0), attr(0) {}
/**
* @brief Copy-constructs an entry.
* @param rhs Entry to copy.
*/
entry(const entry &rhs)
: name(rhs.name), type(rhs.type), is_alias(rhs.is_alias), aliased_to(rhs.aliased_to),
is_global(rhs.is_global), attributes(0), attr(0) {
clone(rhs);
}
/** @brief Deletes owned value or container storage for this entry. */
void delete_entry() {
if (is_alias) // alias copies the pointers.
return;
if (type == Attr_container) {
delete attributes;
attributes = 0;
} else {
delete attr;
attr = 0;
}
}
virtual ~entry() { delete_entry(); }
/**
* @brief Clones entry payload from another entry.
* @param rhs Entry that provides value/container payload.
*/
void clone(const entry &rhs) {
#if 0
name = rhs.name;
type = rhs.type;
is_alias = rhs.is_alias;
aliased_to = rhs.aliased_to;
is_global = rhs.is_global;
#endif
switch (rhs.type) {
case Attr_unknown:
break;
case Attr_container: {
if (rhs.is_alias)
attributes = rhs.attributes;
else
attributes = new AttrTable(*rhs.attributes);
break;
}
default: {
if (rhs.is_alias)
attr = rhs.attr;
else
attr = new std::vector<string>(*rhs.attr);
break;
}
}
}
/**
* @brief Assigns this entry from another entry.
* @param rhs Entry to copy.
* @return This entry after assignment.
*/
entry &operator=(const entry &rhs) {
if (this != &rhs) {
delete_entry();
clone(rhs);
}
return *this;
}
/**
* Returns true if this Attribute is a dap4 type.
* @param path
* @param inventory
* @return True of the attribute is a dap4 type, false otherwise
*/
bool is_dap4_type(const std::string &path, std::vector<std::string> &inventory) const {
bool ima_d4_attr = false;
switch (type) {
case Attr_int8:
case Attr_int64:
case Attr_uint64:
ima_d4_attr = true;
break;
case Attr_container:
ima_d4_attr = attributes->has_dap4_types(path, inventory);
break;
default:
break;
}
return ima_d4_attr;
}
};
/** @brief Read-only iterator over attribute entries. */
typedef std::vector<entry *>::const_iterator Attr_citer;
/** @brief Mutable iterator over attribute entries. */
typedef std::vector<entry *>::iterator Attr_iter;
private:
string d_name;
AttrTable *d_parent;
std::vector<entry *> attr_map;
// Use this to mark container attributes. Look at the methods
// is_global_attribute() and set_is_...., esp. at the versions that take
// an iterator. This code is tricky because it has to track both whole
// containers that are global and individual attributes that are 'global'
// relative to a constructor. That is, there are some attributes that are
// bound to a container and not any of the container's children.
bool d_is_global_attribute;
void delete_attr_table();
friend class AttrTableTest;
protected:
void clone(const AttrTable &at);
void simple_print(FILE *out, string pad, Attr_iter i, bool dereference);
void simple_print(ostream &out, string pad, Attr_iter i, bool dereference);
public:
AttrTable();
AttrTable(const AttrTable &rhs);
~AttrTable() override;
AttrTable &operator=(const AttrTable &rhs);
virtual void erase();
virtual unsigned int get_size() const;
virtual string get_name() const;
virtual void set_name(const string &n);
/** Return a pointer to the AttrTable which holds this table (aka, its
parent. If this AttrTable has no parent, this returns null.
@return A pointer to the parent AttrTable. */
virtual AttrTable *get_parent() const { return d_parent; }
/**
* @brief Reports whether this table models global attributes.
* @return True when this container is marked as global.
*/
virtual bool is_global_attribute() const { return d_is_global_attribute; }
/**
* @brief Marks whether this table models global attributes.
* @param ga True to mark the table as global.
*/
virtual void set_is_global_attribute(bool ga) { d_is_global_attribute = ga; }
virtual unsigned int append_attr(const string &name, const string &type, const string &value);
virtual unsigned int append_attr(const string &name, const string &type, vector<string> *values);
virtual unsigned int append_attr(const string &name, const string &type, const string &value, bool is_utf8_str);
virtual unsigned int append_attr(const string &name, const string &type, vector<string> *values, bool is_utf8_str);
virtual AttrTable *append_container(const string &name);
virtual AttrTable *append_container(AttrTable *at, const string &name);
virtual void find(const string &target, AttrTable **at, Attr_iter *iter);
virtual AttrTable *find_container(const string &target);
virtual AttrTable *recurrsive_find(const string &target, Attr_iter *location);
Attr_iter simple_find(const string &target);
/**
* @brief Finds a direct child container by name.
* @param target Child container name.
* @return Matching child container or null.
*/
AttrTable *simple_find_container(const string &target);
virtual AttrTable *get_attr_table(const string &name);
virtual string get_type(const string &name);
virtual AttrType get_attr_type(const string &name);
virtual unsigned int get_attr_num(const string &name);
virtual string get_attr(const string &name, unsigned int i = 0);
virtual vector<string> *get_attr_vector(const string &name);
virtual void del_attr(const string &name, int i = -1);
virtual Attr_iter attr_begin();
virtual Attr_iter attr_end();
virtual Attr_iter get_attr_iter(int i);
virtual string get_name(Attr_iter iter);
virtual bool is_container(Attr_iter iter);
virtual AttrTable *get_attr_table(Attr_iter iter);
virtual Attr_iter del_attr_table(Attr_iter iter);
virtual string get_type(Attr_iter iter);
virtual AttrType get_attr_type(Attr_iter iter);
virtual unsigned int get_attr_num(Attr_iter iter);
virtual string get_attr(Attr_iter iter, unsigned int i = 0);
virtual std::vector<string> *get_attr_vector(Attr_iter iter);
virtual bool is_global_attribute(Attr_iter iter);
virtual void set_is_global_attribute(Attr_iter iter, bool ga);
virtual void add_container_alias(const string &name, AttrTable *src);
virtual void add_value_alias(AttrTable *at, const string &name, const string &source);
virtual bool attr_alias(const string &alias, AttrTable *at, const string &name);
virtual bool attr_alias(const string &alias, const string &name);
bool has_dap4_types(const std::string &path, std::vector<std::string> &inventory) const;
/**
* @brief Reports whether this table contains DAP4-only attribute types.
* @param path Path prefix used when recording discovered attributes.
* @param inventory Output list populated with names of DAP4-typed attributes.
* @return True if at least one DAP4-only attribute type is present.
*/
bool is_dap4_type(const std::string &path, std::vector<std::string> &inventory) const;
virtual void print(FILE *out, string pad = " ", bool dereference = false);
virtual void print(ostream &out, string pad = " ", bool dereference = false);
virtual void print_xml(FILE *out, string pad = " ", bool constrained = false);
virtual void print_xml(ostream &out, string pad = " ", bool constrained = false);
/**
* @brief Prints this table using the XML writer API.
* @param xml Destination XML writer.
*/
void print_xml_writer(XMLWriter &xml);
void print_dap4(XMLWriter &xml);
void dump(ostream &strm) const override;
};
string remove_space_encoding(const string &s);
string add_space_encoding(const string &s);
} // namespace libdap
#endif // _attrtable_h