-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathD4EnumDefs.cc
133 lines (110 loc) · 5.07 KB
/
D4EnumDefs.cc
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
// -*- mode: c++; c-basic-offset:4 -*-
// This file is part of libdap, A C++ implementation of the OPeNDAP Data
// Access Protocol.
// Copyright (c) 2013 OPeNDAP, Inc.
// Author: James Gallagher <[email protected]>
//
// 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.
#include "config.h"
#include "D4EnumDefs.h"
#include "D4Group.h"
#include <sstream>
#include "dods-limits.h"
#include "util.h"
namespace libdap {
/** Test if a particular value is legal for a given type. In a D4EnumDef,
* all values are actually stored in a long long, but the different
* enumerations can specify different types like Byte, Int32, ..., and this
* method is used to test that the values match those types.
*/
bool D4EnumDef::is_valid_enum_value(long long value) {
switch (type()) {
case dods_int8_c:
return (value >= DODS_SCHAR_MIN && value <= DODS_SCHAR_MAX);
case dods_byte_c:
case dods_uint8_c:
return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_UCHAR_MAX);
case dods_int16_c:
return (value >= DODS_SHRT_MIN && value <= DODS_SHRT_MAX);
case dods_uint16_c:
return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_USHRT_MAX);
case dods_int32_c:
return (value >= DODS_INT_MIN && value <= DODS_INT_MAX);
case dods_uint32_c:
return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_UINT_MAX);
case dods_int64_c:
return true; // This is always true: (value >= DODS_LLONG_MIN && value <= DODS_LLONG_MAX);
case dods_uint64_c:
return (value >= 0 /*Always true: && static_cast<unsigned long long>(value) <= DODS_ULLONG_MAX*/);
default:
return false;
}
}
#if 0
// Note that in order for this to work the second argument must not be a reference.
// jhrg 8/20/13
static bool
enum_def_name_eq(D4EnumDef *d, const string name)
{
return d->name() == name;
}
#endif
D4EnumDef *D4EnumDefs::find_enum_def(const string &name) {
auto d = find_if(d_enums.begin(), d_enums.end(), [name](const D4EnumDef *def) { return name == def->name(); });
return (d != d_enums.end()) ? *d : nullptr;
}
void D4EnumDef::print_value(XMLWriter &xml, const D4EnumDef::tuple &tuple) const {
if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar *)"EnumConst") < 0)
throw InternalErr(__FILE__, __LINE__, "Could not write EnumConst element");
if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar *)"name", (const xmlChar *)tuple.label.c_str()) <
0)
throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
ostringstream oss;
oss << tuple.value;
if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar *)"value", (const xmlChar *)oss.str().c_str()) < 0)
throw InternalErr(__FILE__, __LINE__, "Could not write attribute for value");
if (xmlTextWriterEndElement(xml.get_writer()) < 0)
throw InternalErr(__FILE__, __LINE__, "Could not end EnumConst element");
}
void D4EnumDef::print_dap4(XMLWriter &xml) const {
vector<D4EnumDef::tuple>::const_iterator i = d_tuples.begin();
while (i != d_tuples.end()) {
print_value(xml, *i++);
}
}
void D4EnumDefs::m_print_enum(XMLWriter &xml, D4EnumDef *e) const {
if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar *)"Enumeration") < 0)
throw InternalErr(__FILE__, __LINE__, "Could not write Enumeration element");
if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar *)"name", (const xmlChar *)e->name().c_str()) < 0)
throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar *)"basetype",
(const xmlChar *)D4type_name(e->type()).c_str()) < 0)
throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
// print each of e.values
e->print_dap4(xml);
if (xmlTextWriterEndElement(xml.get_writer()) < 0)
throw InternalErr(__FILE__, __LINE__, "Could not end Enumeration element");
}
void D4EnumDefs::print_dap4(XMLWriter &xml, bool constrained) const {
D4EnumDefCIter i = d_enums.begin();
while (i != d_enums.end()) {
if (!constrained || parent()->find_first_var_that_uses_enumeration(*i))
m_print_enum(xml, *i);
++i;
}
}
} /* namespace libdap */