libdap  Updated for version 3.17.0
Str.cc
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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 Str.
00033 //
00034 // jhrg 9/7/94
00035 
00036 
00037 #include "config.h"
00038 
00039 #include <sstream>
00040 
00041 #include "Byte.h"
00042 #include "Int16.h"
00043 #include "UInt16.h"
00044 #include "Int32.h"
00045 #include "UInt32.h"
00046 #include "Float32.h"
00047 #include "Float64.h"
00048 #include "Str.h"
00049 #include "Url.h"
00050 #include "Array.h"
00051 #include "Structure.h"
00052 #include "Sequence.h"
00053 #include "Grid.h"
00054 
00055 #include "DDS.h"
00056 #include "Marshaller.h"
00057 #include "UnMarshaller.h"
00058 
00059 #include "DMR.h"
00060 #include "D4StreamMarshaller.h"
00061 #include "D4StreamUnMarshaller.h"
00062 
00063 #include "util.h"
00064 #include "parser.h"
00065 #include "Operators.h"
00066 #include "InternalErr.h"
00067 #include "escaping.h"
00068 #include "debug.h"
00069 
00070 
00071 using std::cerr;
00072 using std::endl;
00073 
00074 namespace libdap {
00075 
00084 Str::Str(const string &n) : BaseType(n, dods_str_c), d_buf("")
00085 {}
00086 
00094 Str::Str(const string &n, const string &d) : BaseType(n, d, dods_str_c), d_buf("")
00095 {}
00096 
00097 Str::Str(const Str &copy_from) : BaseType(copy_from)
00098 {
00099     d_buf = copy_from.d_buf;
00100 }
00101 
00102 BaseType *
00103 Str::ptr_duplicate()
00104 {
00105     return new Str(*this);
00106 }
00107 
00108 Str &
00109 Str::operator=(const Str &rhs)
00110 {
00111     if (this == &rhs)
00112         return *this;
00113 
00114     // Call BaseType::operator=.
00115     dynamic_cast<BaseType &>(*this) = rhs;
00116 
00117     d_buf = rhs.d_buf;
00118 
00119     return *this;
00120 }
00121 
00122 int
00123 Str::length() const
00124 {
00125     return d_buf.length();
00126 }
00127 
00128 unsigned int
00129 Str::width(bool) const
00130 {
00131     return sizeof(string);
00132 }
00133 
00134 bool
00135 Str::serialize(ConstraintEvaluator &eval, DDS &dds, Marshaller &m, bool ce_eval)
00136 {
00137 
00138     DBG(cerr << "Entering (" << this->name() << " [" << this << "])" << endl);
00139 #if USE_LOCAL_TIMEOUT_SCHEME
00140     dds.timeout_on();
00141 #endif
00142     if (!read_p())
00143         read();
00144 
00145     if (ce_eval && !eval.eval_selection(dds, dataset()))
00146         return true;
00147 #if USE_LOCAL_TIMEOUT_SCHEME
00148     dds.timeout_off();
00149 #endif
00150     m.put_str( d_buf ) ;
00151 
00152     DBG(cerr << "Exiting: buf = " << d_buf << endl);
00153 
00154     return true;
00155 }
00156 
00157 // deserialize the string on stdin and put the result in BUF.
00158 
00159 bool
00160 Str::deserialize(UnMarshaller &um, DDS *, bool)
00161 {
00162     um.get_str( d_buf ) ;
00163 
00164     return false;
00165 }
00166 
00167 void
00168 Str::compute_checksum(Crc32 &checksum)
00169 {
00170         checksum.AddData(reinterpret_cast<const uint8_t*>(d_buf.data()), d_buf.length());
00171 }
00172 
00181 void
00182 Str::serialize(D4StreamMarshaller &m, DMR &, /*ConstraintEvaluator &,*/ bool)
00183 {
00184     if (!read_p())
00185         read();          // read() throws Error
00186 
00187     m.put_str( d_buf ) ;
00188 }
00189 
00190 void
00191 Str::deserialize(D4StreamUnMarshaller &um, DMR &)
00192 {
00193     um.get_str( d_buf ) ;
00194 }
00195 
00205 unsigned int
00206 Str::buf2val(void **val)
00207 {
00208     // Jose Garcia
00209     // The same comment justifying throwing an Error in val2buf applies here.
00210     if (!val)
00211         throw InternalErr(__FILE__, __LINE__,
00212                           "No place to store a reference to the data.");
00213     // If *val is null, then the caller has not allocated storage for the
00214     // value; we must. If there is storage there, assume it is a string and
00215     // assign d_buf's value to that storage.
00216     if (!*val)
00217         *val = new string(d_buf);
00218     else
00219         *static_cast<string*>(*val) = d_buf;
00220 
00221     return sizeof(string*);
00222 }
00223 
00233 unsigned int
00234 Str::val2buf(void *val, bool)
00235 {
00236     // Jose Garcia
00237     // This method is public therefore and I believe it has being designed
00238     // to be use by read which must be implemented on the surrogated library,
00239     // thus if the pointer val is NULL, is an Internal Error.
00240     if (!val)
00241         throw InternalErr(__FILE__, __LINE__, "NULL pointer.");
00242 
00243     d_buf = *static_cast<string*>(val);
00244 
00245     return sizeof(string*);
00246 }
00247 
00252 bool
00253 Str::set_value(const string &value)
00254 {
00255     d_buf = value;
00256     set_read_p(true);
00257 
00258     return true;
00259 }
00260 
00263 string
00264 Str::value() const
00265 {
00266     return d_buf;
00267 }
00268 
00269 void
00270 Str::print_val(FILE *out, string space, bool print_decl_p)
00271 {
00272     ostringstream oss;
00273     print_val(oss, space, print_decl_p);
00274     fwrite(oss.str().data(), sizeof(char), oss.str().length(), out);
00275 }
00276 
00277 void
00278 Str::print_val(ostream &out, string space, bool print_decl_p)
00279 {
00280     if (print_decl_p) {
00281         print_decl(out, space, false);
00282         out << " = \"" << escattr(d_buf) << "\";\n" ;
00283     }
00284     else
00285         out << "\"" << escattr(d_buf) << "\"" ;
00286 }
00287 
00288 bool
00289 Str::ops(BaseType *b, int op)
00290 {
00291     // Extract the Byte arg's value.
00292     if (!read_p() && !read()) {
00293         // Jose Garcia
00294         // Since the read method is virtual and implemented outside
00295         // libdap++ if we cannot read the data that is the problem
00296         // of the user or of whoever wrote the surrogate library
00297         // implemeting read therefore it is an internal error.
00298         throw InternalErr(__FILE__, __LINE__, "This value was not read!");
00299     }
00300 
00301     // Extract the second arg's value.
00302     if (!b || !(b->read_p() || b->read())) {
00303         // Jose Garcia
00304         // Since the read method is virtual and implemented outside
00305         // libdap++ if we cannot read the data that is the problem
00306         // of the user or of whoever wrote the surrogate library
00307         // implemeting read therefore it is an internal error.
00308         throw InternalErr(__FILE__, __LINE__, "Argument value was not read!");
00309     }
00310 
00311     switch (b->type()) {
00312     case dods_str_c:
00313         return StrCmp<string, string>(op, d_buf, static_cast<Str*>(b)->value());
00314     case dods_url_c:
00315         return StrCmp<string, string>(op, d_buf, static_cast<Url*>(b)->value());
00316     default:
00317         return false;
00318     }
00319 }
00320 
00329 void
00330 Str::dump(ostream &strm) const
00331 {
00332     strm << DapIndent::LMarg << "Str::dump - ("
00333     << (void *)this << ")" << endl ;
00334     DapIndent::Indent() ;
00335     BaseType::dump(strm) ;
00336     strm << DapIndent::LMarg << "value: " << d_buf << endl ;
00337     DapIndent::UnIndent() ;
00338 }
00339 
00340 } // namespace libdap
00341