libdap++
Updated for version 3.8.2
|
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 ©_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