libdap++  Updated for version 3.8.2
BaseType.cc
Go to the documentation of this file.
00001 
00002 // -*- mode: c++; c-basic-offset:4 -*-
00003 
00004 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
00005 // Access Protocol.
00006 
00007 // Copyright (c) 2002,2003 OPeNDAP, Inc.
00008 // Author: James Gallagher <jgallagher@opendap.org>
00009 //
00010 // This library is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU Lesser General Public
00012 // License as published by the Free Software Foundation; either
00013 // version 2.1 of the License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023 //
00024 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
00025 
00026 // (c) COPYRIGHT URI/MIT 1994-1999
00027 // Please read the full copyright statement in the file COPYRIGHT_URI.
00028 //
00029 // Authors:
00030 //      jhrg,jimg       James Gallagher <jgallagher@gso.uri.edu>
00031 
00032 // Implementation for BaseType.
00033 //
00034 // jhrg 9/6/94
00035 
00036 #include "config.h"
00037 
00038 #include <cstdio>  // for stdin and stdout
00039 
00040 #include <sstream>
00041 #include <string>
00042 
00043 //#define DODS_DEBUG
00044 
00045 #include "BaseType.h"
00046 #include "Byte.h"
00047 #include "Int16.h"
00048 #include "UInt16.h"
00049 #include "Int32.h"
00050 #include "UInt32.h"
00051 #include "Float32.h"
00052 #include "Float64.h"
00053 #include "Str.h"
00054 #include "Url.h"
00055 #include "Array.h"
00056 #include "Structure.h"
00057 #include "Sequence.h"
00058 #include "Grid.h"
00059 
00060 #include "InternalErr.h"
00061 
00062 #include "util.h"
00063 #include "escaping.h"
00064 
00065 #include "debug.h"
00066 
00067 using namespace std;
00068 
00069 namespace libdap {
00070 
00071 // Protected copy mfunc
00072 
00079 void
00080 BaseType::_duplicate(const BaseType &bt)
00081 {
00082     DBG2(cerr << "BaseType::_duplicate: " << bt._name << " send_p: "
00083             << bt._send_p << endl);
00084     _name = bt._name;
00085     _type = bt._type;
00086     _dataset = bt._dataset;
00087     _read_p = bt._read_p; // added, reza
00088     _send_p = bt._send_p; // added, reza
00089     d_in_selection = bt.d_in_selection;
00090     _synthesized_p = bt._synthesized_p; // 5/11/2001 jhrg
00091 
00092     d_parent = bt.d_parent; // copy pointers 6/4/2001 jhrg
00093 
00094     d_attr = bt.d_attr;  // Deep copy.
00095 }
00096 
00097 // Public mfuncs
00098 
00110 BaseType::BaseType(const string &n, const Type &t)
00111         : _name(n), _type(t), _dataset(""), _read_p(false), _send_p(false),
00112         d_in_selection(false), _synthesized_p(false), d_parent(0)
00113 {}
00114 
00128 BaseType::BaseType(const string &n, const string &d, const Type &t)
00129         : _name(n), _type(t), _dataset(d), _read_p(false), _send_p(false),
00130         d_in_selection(false), _synthesized_p(false), d_parent(0)
00131 {}
00132 
00134 BaseType::BaseType(const BaseType &copy_from) : DapObj()
00135 {
00136     _duplicate(copy_from);
00137 }
00138 
00139 BaseType::~BaseType()
00140 {
00141     DBG2(cerr << "Entering ~BaseType (" << this << ")" << endl);
00142     DBG2(cerr << "Exiting ~BaseType" << endl);
00143 }
00144 
00145 BaseType &
00146 BaseType::operator=(const BaseType &rhs)
00147 {
00148     if (this == &rhs)
00149         return *this;
00150 
00151     _duplicate(rhs);
00152 
00153     return *this;
00154 }
00155 
00160 string
00161 BaseType::toString()
00162 {
00163     ostringstream oss;
00164     oss << "BaseType (" << this << "):" << endl
00165     << "          _name: " << _name << endl
00166     << "          _type: " << type_name() << endl
00167     << "          _dataset: " << _dataset << endl
00168     << "          _read_p: " << _read_p << endl
00169     << "          _send_p: " << _send_p << endl
00170     << "          _synthesized_p: " << _synthesized_p << endl
00171     << "          d_parent: " << d_parent << endl
00172     << "          d_attr: " << hex << &d_attr << dec << endl;
00173 
00174     return oss.str();
00175 }
00176 
00185 void
00186 BaseType::dump(ostream &strm) const
00187 {
00188     strm << DapIndent::LMarg << "BaseType::dump - ("
00189     << (void *)this << ")" << endl ;
00190     DapIndent::Indent() ;
00191 
00192     strm << DapIndent::LMarg << "name: " << _name << endl ;
00193     strm << DapIndent::LMarg << "type: " << type_name() << endl ;
00194     strm << DapIndent::LMarg << "dataset: " << _dataset << endl ;
00195     strm << DapIndent::LMarg << "read_p: " << _read_p << endl ;
00196     strm << DapIndent::LMarg << "send_p: " << _send_p << endl ;
00197     strm << DapIndent::LMarg << "synthesized_p: " << _synthesized_p << endl ;
00198     strm << DapIndent::LMarg << "parent: " << (void *)d_parent << endl ;
00199     strm << DapIndent::LMarg << "attributes: " << endl ;
00200     DapIndent::Indent() ;
00201     d_attr.dump(strm) ;
00202     DapIndent::UnIndent() ;
00203 
00204     DapIndent::UnIndent() ;
00205 }
00206 
00209 string
00210 BaseType::name() const
00211 {
00212     return _name;
00213 }
00214 
00216 void
00217 BaseType::set_name(const string &n)
00218 {
00219     string name = n;
00220     _name = www2id(name); // www2id writes into its param.
00221 }
00222 
00230 string
00231 BaseType::dataset() const
00232 {
00233     return _dataset;
00234 }
00235 
00237 Type
00238 BaseType::type() const
00239 {
00240     return _type;
00241 }
00242 
00244 void
00245 BaseType::set_type(const Type &t)
00246 {
00247     _type = t;
00248 }
00249 
00251 string
00252 BaseType::type_name() const
00253 {
00254     switch (_type) {
00255     case dods_null_c:
00256         return string("Null");
00257     case dods_byte_c:
00258         return string("Byte");
00259     case dods_int16_c:
00260         return string("Int16");
00261     case dods_uint16_c:
00262         return string("UInt16");
00263     case dods_int32_c:
00264         return string("Int32");
00265     case dods_uint32_c:
00266         return string("UInt32");
00267     case dods_float32_c:
00268         return string("Float32");
00269     case dods_float64_c:
00270         return string("Float64");
00271     case dods_str_c:
00272         return string("String");
00273     case dods_url_c:
00274         return string("Url");
00275     case dods_array_c:
00276         return string("Array");
00277     case dods_structure_c:
00278         return string("Structure");
00279     case dods_sequence_c:
00280         return string("Sequence");
00281     case dods_grid_c:
00282         return string("Grid");
00283     default:
00284         cerr << "BaseType::type_name: Undefined type" << endl;
00285         return string("");
00286     }
00287 }
00288 
00294 bool
00295 BaseType::is_simple_type()
00296 {
00297     switch (type()) {
00298     case dods_null_c:
00299     case dods_byte_c:
00300     case dods_int16_c:
00301     case dods_uint16_c:
00302     case dods_int32_c:
00303     case dods_uint32_c:
00304     case dods_float32_c:
00305     case dods_float64_c:
00306     case dods_str_c:
00307     case dods_url_c:
00308         return true;
00309 
00310     case dods_array_c:
00311     case dods_structure_c:
00312     case dods_sequence_c:
00313     case dods_grid_c:
00314         return false;
00315     }
00316 
00317     return false;
00318 }
00319 
00323 bool
00324 BaseType::is_vector_type()
00325 {
00326     switch (type()) {
00327     case dods_null_c:
00328     case dods_byte_c:
00329     case dods_int16_c:
00330     case dods_uint16_c:
00331     case dods_int32_c:
00332     case dods_uint32_c:
00333     case dods_float32_c:
00334     case dods_float64_c:
00335     case dods_str_c:
00336     case dods_url_c:
00337         return false;
00338 
00339     case dods_array_c:
00340         return true;
00341 
00342     case dods_structure_c:
00343     case dods_sequence_c:
00344     case dods_grid_c:
00345         return false;
00346     }
00347 
00348     return false;
00349 }
00350 
00355 bool
00356 BaseType::is_constructor_type()
00357 {
00358     switch (type()) {
00359     case dods_null_c:
00360     case dods_byte_c:
00361     case dods_int16_c:
00362     case dods_uint16_c:
00363     case dods_int32_c:
00364     case dods_uint32_c:
00365     case dods_float32_c:
00366     case dods_float64_c:
00367     case dods_str_c:
00368     case dods_url_c:
00369     case dods_array_c:
00370         return false;
00371 
00372     case dods_structure_c:
00373     case dods_sequence_c:
00374     case dods_grid_c:
00375         return true;
00376     }
00377 
00378     return false;
00379 }
00380 
00406 int
00407 BaseType::element_count(bool)
00408 {
00409     return 1;
00410 }
00411 
00415 bool
00416 BaseType::synthesized_p()
00417 {
00418     return _synthesized_p;
00419 }
00420 
00426 void
00427 BaseType::set_synthesized_p(bool state)
00428 {
00429     _synthesized_p = state;
00430 }
00431 
00432 // Return the state of _read_p (true if the value of the variable has been
00433 // read (and is in memory) false otherwise).
00434 
00443 bool
00444 BaseType::read_p()
00445 {
00446     return _read_p;
00447 }
00448 
00482 void
00483 BaseType::set_read_p(bool state)
00484 {
00485     if (! _synthesized_p) {
00486         DBG2(cerr << "Changing read_p state of " << name() << " to "
00487                  << state << endl);
00488         _read_p = state;
00489     }
00490 }
00491 
00502 bool
00503 BaseType::send_p()
00504 {
00505     return _send_p;
00506 }
00507 
00516 void
00517 BaseType::set_send_p(bool state)
00518 {
00519     DBG2(cerr << "Calling BaseType::set_send_p() for: " << this->name()
00520         << endl);
00521     _send_p = state;
00522 }
00523 
00524 
00530 AttrTable &
00531 BaseType::get_attr_table()
00532 {
00533     return d_attr;
00534 }
00535 
00538 void
00539 BaseType::set_attr_table(const AttrTable &at)
00540 {
00541     d_attr = at;
00542 }
00543 
00570 void BaseType::transfer_attributes(AttrTable *at_container) {
00571         AttrTable *at = at_container->get_attr_table(name());
00572 
00573         DBG(cerr << "In BaseType::transfer_attributes; processing " << name() << endl);
00574 
00575         if (at) {
00576                 at->set_is_global_attribute(false);
00577                 DBG(cerr << "Processing AttrTable: " << at->get_name() << endl);
00578 
00579                 AttrTable::Attr_iter at_p = at->attr_begin();
00580                 while (at_p != at->attr_end()) {
00581                         DBG(cerr << "About to append " << "attr name, type:" << at->get_name(at_p) << ", " << at->get_type(at_p) << endl);
00582 
00583                         if (at->get_attr_type(at_p) == Attr_container)
00584                                 get_attr_table().append_container(new AttrTable(*at->get_attr_table(at_p)), at->get_name(at_p));
00585                         else
00586                                 get_attr_table().append_attr(at->get_name(at_p), at->get_type(at_p), at->get_attr_vector(at_p));
00587 
00588                         at_p++;
00589                 }
00590         }
00591 }
00592 
00604 bool
00605 BaseType::is_in_selection()
00606 {
00607     return d_in_selection;
00608 }
00609 
00619 void
00620 BaseType::set_in_selection(bool state)
00621 {
00622     d_in_selection = state;
00623 }
00624 
00625 // Protected method.
00632 void
00633 BaseType::set_parent(BaseType *parent)
00634 {
00635     if (!dynamic_cast<Constructor *>(parent)
00636         && !dynamic_cast<Vector *>(parent))
00637         throw InternalErr("Call to set_parent with incorrect variable type.");
00638 
00639     d_parent = parent;
00640 }
00641 
00642 // Public method.
00643 
00649 BaseType *
00650 BaseType::get_parent()
00651 {
00652     return d_parent;
00653 }
00654 
00655 // Documented in the header file.
00656 BaseType *
00657 BaseType::var(const string &/*name*/, bool /*exact_match*/, btp_stack */*s*/)
00658 {
00659     return static_cast<BaseType *>(0);
00660 }
00661 
00678 BaseType *
00679 BaseType::var(const string &, btp_stack &)
00680 {
00681     return static_cast<BaseType *>(0);
00682 }
00683 
00713 void
00714 BaseType::add_var(BaseType *, Part)
00715 {
00716     throw InternalErr(__FILE__, __LINE__, "BaseType::add_var unimplemented");
00717 }
00718 
00784 bool
00785 BaseType::read()
00786 {
00787     if (_read_p)
00788         return false;
00789 
00790     throw InternalErr("Unimplemented BaseType::read() method called.");
00791 }
00792 
00793 void
00794 BaseType::intern_data(ConstraintEvaluator &, DDS &dds)
00795 {
00796     dds.timeout_on();
00797     DBG2(cerr << "BaseType::intern_data: " << name() << endl);
00798     if (!read_p())
00799         read();          // read() throws Error and InternalErr
00800 
00801     dds.timeout_off();
00802 }
00803 
00804 #if FILE_METHODS
00805 
00847 void
00848 BaseType::print_decl(FILE *out, string space, bool print_semi,
00849                      bool constraint_info, bool constrained)
00850 {
00851     // if printing the constrained declaration, exit if this variable was not
00852     // selected.
00853     if (constrained && !send_p())
00854         return;
00855 
00856     fprintf(out, "%s%s %s", space.c_str(), type_name().c_str(),
00857             id2www(_name).c_str()) ;
00858 
00859     if (constraint_info) {
00860         if (send_p())
00861             fprintf(out, ": Send True") ;
00862         else
00863             fprintf(out, ": Send False") ;
00864     }
00865 
00866     if (print_semi)
00867         fprintf(out, ";\n") ;
00868 }
00869 #endif
00870 
00913 void
00914 BaseType::print_decl(ostream &out, string space, bool print_semi,
00915                      bool constraint_info, bool constrained)
00916 {
00917     // if printing the constrained declaration, exit if this variable was not
00918     // selected.
00919     if (constrained && !send_p())
00920         return;
00921 
00922     out << space << type_name() << " " << id2www(_name) ;
00923 
00924     if (constraint_info) {
00925         if (send_p())
00926             out << ": Send True" ;
00927         else
00928             out << ": Send False" ;
00929     }
00930 
00931     if (print_semi)
00932         out << ";\n" ;
00933 }
00934 
00935 #if FILE_METHODS
00936 
00943 void
00944 BaseType::print_xml(FILE *out, string space, bool constrained)
00945 {
00946     if (constrained && !send_p())
00947         return;
00948 
00949     fprintf(out, "%s<%s", space.c_str(), type_name().c_str());
00950     if (!_name.empty())
00951         fprintf(out, " name=\"%s\"", id2xml(_name).c_str());
00952 
00953     if (get_attr_table().get_size() > 0) {
00954         fprintf(out, ">\n"); // close the variable's tag
00955         get_attr_table().print_xml(out, space + "    ", constrained);
00956         // After attributes, print closing tag
00957         fprintf(out, "%s</%s>\n", space.c_str(), type_name().c_str());
00958     }
00959     else {
00960         fprintf(out, "/>\n"); // no attributes; just close tag.
00961     }
00962 }
00963 #endif
00964 
00972 void
00973 BaseType::print_xml(ostream &out, string space, bool constrained)
00974 {
00975     if (constrained && !send_p())
00976         return;
00977 
00978     out << space << "<" << type_name() ;
00979     if (!_name.empty())
00980     out << " name=\"" << id2xml(_name) << "\"" ;
00981 
00982     if (get_attr_table().get_size() > 0) {
00983     out << ">\n" ;
00984         get_attr_table().print_xml(out, space + "    ", constrained);
00985         // After attributes, print closing tag
00986     out << space << "</" << type_name() << ">\n" ;
00987     }
00988     else {
00989     out << "/>\n" ;
00990     }
00991 }
00992 
00999 void
01000 BaseType::print_xml_writer(XMLWriter &xml, bool constrained)
01001 {
01002     if (constrained && !send_p())
01003         return;
01004 
01005     if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*)type_name().c_str()) < 0)
01006         throw InternalErr(__FILE__, __LINE__, "Could not write " + type_name() + " element");
01007 
01008     if (!_name.empty())
01009     if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "name", (const xmlChar*)_name.c_str()) < 0)
01010         throw InternalErr(__FILE__, __LINE__, "Could not write attribute for name");
01011 
01012     if (get_attr_table().get_size() > 0)
01013         get_attr_table().print_xml_writer(xml);
01014 
01015     if (xmlTextWriterEndElement(xml.get_writer()) < 0)
01016         throw InternalErr(__FILE__, __LINE__, "Could not end " + type_name() + " element");
01017 
01018 }
01019 
01020 // Compares the object's current state with the semantics of a particular
01021 // type. This will typically be defined in ctor classes (which have
01022 // complicated semantics). For BaseType, an object is semantically correct if
01023 // it has both a non-null name and type.
01024 //
01025 // NB: This is not the same as an invariant -- during the parse objects exist
01026 // but have no name. Also, the bool ALL defaults to false for BaseType. It is
01027 // used by children of CtorType.
01028 //
01029 // Returns: true if the object is semantically correct, false otherwise.
01030 
01059 bool
01060 BaseType::check_semantics(string &msg, bool)
01061 {
01062     bool sem = (_type != dods_null_c && _name.length());
01063 
01064     if (!sem)
01065         msg = "Every variable must have both a name and a type\n";
01066 
01067     return sem;
01068 }
01069 
01104 bool
01105 BaseType::ops(BaseType *, int)
01106 {
01107     // Even though ops is a public method, it can never be called because
01108     // they will never have a BaseType object since this class is abstract,
01109     // however any of the child classes could by mistake call BaseType::ops
01110     // so this is an internal error. Jose Garcia
01111     throw InternalErr(__FILE__, __LINE__, "Unimplemented operator.");
01112 }
01113 
01123 unsigned int
01124 BaseType::width(bool /*constrained*/)
01125 {
01126         return width();
01127 }
01128 
01129 } // namespace libdap