bes  Updated for version 3.20.6
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 
40 static char rcsid[] not_used = { "$Id$" };
41 
42 // #define DODS_DEBUG 1
43 #include <netcdf.h>
44 
45 #include <InternalErr.h>
46 #include "NCStr.h"
47 
48 #include <debug.h>
49 
50 NCStr::NCStr(const string &n, const string &d) :
51  Str(n, d)
52 {
53 }
54 
55 NCStr::NCStr(const NCStr &rhs) :
56  Str(rhs)
57 {
58 }
59 
60 NCStr::~NCStr()
61 {
62 }
63 
64 NCStr &
65 NCStr::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 
75 BaseType *
76 NCStr::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.
84 bool 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[0]);
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[0]));' with ...
182  set_value(string(strpp[0]));
183 
184  nc_free_string(1, &strpp[0]);
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 }
Error
NCStr
Definition: NCStr.h:46