libdap
Updated for version 3.17.0
|
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 #include "config.h" 00026 00027 #include "D4Group.h" 00028 #include "D4EnumDefs.h" 00029 00030 #include <sstream> 00031 00032 #include "dods-limits.h" 00033 #include "util.h" 00034 00035 namespace libdap { 00036 00042 bool 00043 D4EnumDef::is_valid_enum_value(long long value) 00044 { 00045 switch (type()) { 00046 case dods_int8_c: 00047 return (value >= DODS_SCHAR_MIN && value <= DODS_SCHAR_MAX); 00048 case dods_byte_c: 00049 case dods_uint8_c: 00050 return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_UCHAR_MAX); 00051 case dods_int16_c: 00052 return (value >= DODS_SHRT_MIN && value <= DODS_SHRT_MAX); 00053 case dods_uint16_c: 00054 return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_USHRT_MAX); 00055 case dods_int32_c: 00056 return (value >= DODS_INT_MIN && value <= DODS_INT_MAX); 00057 case dods_uint32_c: 00058 return (value >= 0 && static_cast<unsigned long long>(value) <= DODS_UINT_MAX); 00059 case dods_int64_c: 00060 return true; // This is always true: (value >= DODS_LLONG_MIN && value <= DODS_LLONG_MAX); 00061 case dods_uint64_c: 00062 return (value >= 0 /*Always true: && static_cast<unsigned long long>(value) <= DODS_ULLONG_MAX*/); 00063 default: 00064 return false; 00065 } 00066 } 00067 00068 // Note that in order for this to work the second argument must not be a reference. 00069 // jhrg 8/20/13 00070 static bool 00071 enum_def_name_eq(D4EnumDef *d, const string name) 00072 { 00073 return d->name() == name; 00074 } 00075 00076 D4EnumDef * 00077 D4EnumDefs::find_enum_def(const string &name) 00078 { 00079 D4EnumDefIter d = find_if(d_enums.begin(), d_enums.end(), bind2nd(ptr_fun(enum_def_name_eq), name)); 00080 return (d != d_enums.end()) ? *d: 0; 00081 } 00082 00083 void D4EnumDef::print_value(XMLWriter &xml, const D4EnumDef::tuple &tuple) const 00084 { 00085 if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)"EnumConst") < 0) 00086 throw InternalErr(__FILE__, __LINE__, "Could not write EnumConst element"); 00087 00088 if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)tuple.label.c_str()) < 0) 00089 throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name"); 00090 00091 ostringstream oss; 00092 oss << tuple.value; 00093 if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "value", (const xmlChar*)oss.str().c_str()) < 0) 00094 throw InternalErr(__FILE__, __LINE__, "Could not write attribute for value"); 00095 00096 if (xmlTextWriterEndElement(xml.get_writer()) < 0) 00097 throw InternalErr(__FILE__, __LINE__, "Could not end EnumConst element"); 00098 } 00099 00100 void D4EnumDef::print_dap4(XMLWriter &xml) const 00101 { 00102 vector<D4EnumDef::tuple>::const_iterator i = d_tuples.begin(); 00103 while(i != d_tuples.end()) { 00104 print_value(xml, *i++); 00105 } 00106 } 00107 00108 void D4EnumDefs::m_print_enum(XMLWriter &xml, D4EnumDef *e) const 00109 { 00110 if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)"Enumeration") < 0) 00111 throw InternalErr(__FILE__, __LINE__, "Could not write Enumeration element"); 00112 00113 if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)e->name().c_str()) < 0) 00114 throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name"); 00115 00116 if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "basetype", (const xmlChar*)D4type_name(e->type()).c_str()) < 0) 00117 throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name"); 00118 00119 // print each of e.values 00120 e->print_dap4(xml); 00121 00122 if (xmlTextWriterEndElement(xml.get_writer()) < 0) 00123 throw InternalErr(__FILE__, __LINE__, "Could not end Enumeration element"); 00124 } 00125 00126 void D4EnumDefs::print_dap4(XMLWriter &xml, bool constrained) const 00127 { 00128 D4EnumDefCIter i = d_enums.begin(); 00129 while (i != d_enums.end()) { 00130 if (!constrained || parent()->find_first_var_that_uses_enumeration(*i)) 00131 m_print_enum(xml, *i); 00132 ++i; 00133 } 00134 } 00135 00136 } /* namespace libdap */