libdap  Updated for version 3.17.0
D4EnumDefs.cc
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 */