bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
NCStr.cc
1// -*- mode: c++; c-basic-offset:4 -*-
2
3// This file is part of nc_handler, a data handler for the OPeNDAP data
4// server.
5
6// Copyright (c) 2002,2003 OPeNDAP, Inc.
7// Author: James Gallagher <jgallagher@opendap.org>
8//
9// This is free software; you can redistribute it and/or modify it under the
10// terms of the GNU Lesser General Public License as published by the Free
11// Software Foundation; either version 2.1 of the License, or (at your
12// option) any later version.
13//
14// This software is distributed in the hope that it will be useful, but
15// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17// License for more details.
18//
19// You should have received a copy of the GNU Lesser General Public
20// License along with this library; if not, write to the Free Software
21// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22//
23// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24
25
26// (c) COPYRIGHT URI/MIT 1994-1996
27// Please read the full copyright statement in the file COPYRIGHT.
28//
29// Authors:
30// reza Reza Nekovei (reza@intcomm.net)
31
32// netCDF sub-class implementation for NCByte,...NCGrid.
33// The files are patterned after the subcalssing examples
34// Test<type>.c,h files.
35//
36// ReZa 1/12/95
37
38#include "config_nc.h"
39
40static char rcsid[] not_used = { "$Id$" };
41
42// #define DODS_DEBUG 1
43#include <netcdf.h>
44
45#include <libdap/InternalErr.h>
46#include "NCStr.h"
47
48#include <libdap/debug.h>
49
50NCStr::NCStr(const string &n, const string &d) :
51 Str(n, d)
52{
53}
54
55NCStr::NCStr(const NCStr &rhs) :
56 Str(rhs)
57{
58}
59
60NCStr::~NCStr()
61{
62}
63
64NCStr &
65NCStr::operator=(const NCStr &rhs)
66{
67 if (this == &rhs)
68 return *this;
69
70 dynamic_cast<NCStr&> (*this) = rhs;
71
72 return *this;
73}
74
75BaseType *
76NCStr::ptr_duplicate()
77{
78 return new NCStr(*this);
79}
80
81// This method assumes that NC_CHAR variables with zero or one dimension will
82// be represented as a DAP String. If there are two or more dimensions, then
83// the variable is represented in an array of DAP Strings.
84bool NCStr::read()
85{
86 if (read_p()) //has been done
87 return true;
88
89 int ncid, errstat;
90 errstat = nc_open(dataset().c_str(), NC_NOWRITE, &ncid); /* netCDF id */
91
92 if (errstat != NC_NOERR) {
93 string err = "Could not open the dataset's file (" + dataset() + ")";
94 throw Error(errstat, err);
95 }
96
97 int varid; /* variable Id */
98 errstat = nc_inq_varid(ncid, name().c_str(), &varid);
99 if (errstat != NC_NOERR)
100 throw Error(errstat, "Could not get variable ID.");
101
102 nc_type datatype; /* variable data type */
103 int num_dim; /* number of dim. in variable */
104 errstat = nc_inq_var(ncid, varid, (char *) 0, &datatype, &num_dim, (int *) 0, (int *) 0);
105 if (errstat != NC_NOERR)
106 throw Error(errstat, string("Could not read information about the variable `") + name() + string("'."));
107
108#if NETCDF_VERSION == 3
109 // This stuff is only relevant when the handler is linked to a netcdf3
110 // library.
111 if (datatype != NC_CHAR)
112 throw InternalErr(__FILE__, __LINE__, "Entered String read method with non-string/char variable!");
113#endif
114
115 switch (datatype) {
116 case NC_CHAR:
117 if (num_dim == 1) {
118 int dim_id;
119 errstat = nc_inq_vardimid(ncid, varid, &dim_id);
120 if (errstat != NC_NOERR)
121 throw Error(errstat, string("Could not read the dimension id of `") + name() + string("'."));
122 size_t dim_size;
123 errstat = nc_inq_dimlen(ncid, dim_id, &dim_size);
124 if (errstat != NC_NOERR)
125 throw Error(errstat, string("Could not read the dimension size of `") + name() + string("'."));
126
127 char *charbuf = new char[dim_size + 1];
128 // get the data
129 size_t cor[1] = { 0 };
130 size_t edg[1];
131 edg[0] = dim_size;
132
133 errstat = nc_get_vara_text(ncid, varid, cor, edg, charbuf);
134 if (errstat != NC_NOERR) {
135 delete[] charbuf;
136 throw Error(errstat, string("Could not read data from the variable `") + name() + string("'."));
137 }
138
139 charbuf[dim_size] = '\0';
140 // poke the data into the DAP string
141 set_value(string(charbuf));
142
143 delete[] charbuf;
144 }
145 else if (num_dim == 0) { // the variable is a scalar, so it's just one character.
146 char *charbuf = new char[2];
147 // get the data
148 errstat = nc_get_var_text(ncid, varid, charbuf);
149 if (errstat != NC_NOERR) {
150 delete[] charbuf;
151 throw Error(errstat, string("Could not read data from the variable `") + name() + string("'."));
152 }
153
154 charbuf[1] = '\0';
155 // poke the data into the DAP string
156 set_value(string(charbuf));
157
158 delete[] charbuf;
159 }
160 else
161 throw Error(string("Multidimensional character array found in string class while reading '") + name() + string("'."));
162
163 break;
164#if NETCDF_VERSION >= 4
165 case NC_STRING: {
166 size_t cor[MAX_NC_DIMS]; /* corner coordinates */
167 for (int id = 0; id <= num_dim && id < MAX_NC_DIMS; id++)
168 cor[id] = 0;
169
170 // before using vector<>, this code used 'char **strpp = new char*[2];'
171 // replaced this 'vector<char> strpp(sizeof(char*));' with...
172 vector<char*> strpp(1);
173
174 // get the data
175 errstat = nc_get_var1_string(ncid, varid, cor, strpp.data());
176 if (errstat != NC_NOERR) {
177 throw Error(errstat, string("Could not read data from the variable `") + name() + string("'."));
178 }
179
180 // poke the data into the DAP string
181 // replaced this 'set_value(string(*(char**)strpp.data()));' with ...
182 set_value(string(strpp[0]));
183
184 nc_free_string(1, strpp.data());
185
186 break;
187 }
188#endif
189 default:
190 throw InternalErr(__FILE__, __LINE__, "Entered String read method with an unrecognized datatype!");
191
192 }
193
194 return true;
195}
Definition NCStr.h:46