OPeNDAP Hyrax Back End Server (BES)  Updated for version 3.8.3
FONcAttributes.cc
Go to the documentation of this file.
1 // FONcAttributes.cc
2 
3 // This file is part of BES Netcdf File Out Module
4 
5 // Copyright (c) 2004,2005 University Corporation for Atmospheric Research
6 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 //
22 // You can contact University Corporation for Atmospheric Research at
23 // 3080 Center Green Drive, Boulder, CO 80301
24 
25 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
26 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
27 //
28 // Authors:
29 // pwest Patrick West <pwest@ucar.edu>
30 // jgarcia Jose Garcia <jgarcia@ucar.edu>
31 
32 #include <sstream>
33 
34 using std::istringstream ;
35 
36 #include <netcdf.h>
37 
38 #include <BESDebug.h>
39 #include <BESInternalError.h>
40 
41 #include "FONcAttributes.h"
42 #include "FONcUtils.h"
43 
74 void
75 FONcAttributes::add_attributes( int ncid, int varid, BaseType *b )
76 {
77  string emb_name ;
78  BaseType *parent = b->get_parent() ;
79  if( parent )
80  {
81  FONcAttributes::add_attributes( ncid, varid, parent, emb_name ) ;
82  }
83  addattrs( ncid, varid, b, "" ) ;
84 }
85 
99 void
100 FONcAttributes::add_attributes( int ncid, int varid, BaseType *b,
101  string &emb_name )
102 {
103  BaseType *parent = b->get_parent() ;
104  if( parent )
105  {
106  FONcAttributes::add_attributes( ncid, varid, parent, emb_name ) ;
107  }
108  if( !emb_name.empty() )
109  {
110  emb_name += FONC_EMBEDDED_SEPARATOR ;
111  }
112  emb_name += b->name() ;
113  addattrs( ncid, varid, b, emb_name ) ;
114 }
115 
125 void
126 FONcAttributes::addattrs( int ncid, int varid, BaseType *b,
127  const string &var_name )
128 {
129  AttrTable &attrs = b->get_attr_table() ;
130  addattrs( ncid, varid, attrs, var_name, "" ) ;
131 }
132 
146 void
147 FONcAttributes::addattrs( int ncid, int varid, AttrTable &attrs,
148  const string &var_name, const string &prepend_attr )
149 {
150  unsigned int num_attrs = attrs.get_size() ;
151  if( num_attrs )
152  {
153  AttrTable::Attr_iter i = attrs.attr_begin() ;
154  AttrTable::Attr_iter e = attrs.attr_end() ;
155  for( ; i != e; i++ )
156  {
157  unsigned int num_vals = attrs.get_attr_num( i ) ;
158  if( num_vals )
159  {
160  addattrs( ncid, varid, var_name, attrs, i, prepend_attr ) ;
161  }
162  }
163  }
164 }
165 
178 void
179 FONcAttributes::addattrs( int ncid, int varid, const string &var_name,
180  AttrTable &attrs,
181  AttrTable::Attr_iter &attr,
182  const string &prepend_attr )
183 {
184  string attr_name = attrs.get_name( attr ) ;
185  string new_attr_name ;
186  if( !prepend_attr.empty() )
187  {
188  new_attr_name = prepend_attr + FONC_EMBEDDED_SEPARATOR + attr_name ;
189  }
190  else
191  {
192  new_attr_name = attr_name ;
193  }
194 
195  string new_name ;
196  if( !var_name.empty() )
197  {
198  new_name = var_name + FONC_ATTRIBUTE_SEPARATOR + new_attr_name ;
199  }
200  else
201  {
202  new_name = new_attr_name ;
203  }
204  new_name = FONcUtils::id2netcdf( new_name ) ;
205  if( varid == NC_GLOBAL )
206  BESDEBUG( "fonc", "Adding global attributes " << new_name << endl ) ;
207  else
208  BESDEBUG( "fonc", "Adding attributes " << new_name << endl ) ;
209 
210  int stax = NC_NOERR ;
211  unsigned int attri = 0 ;
212  AttrType type = attrs.get_attr_type( attr ) ;
213  unsigned int num_vals = attrs.get_attr_num( attr ) ;
214  switch( type )
215  {
216  case Attr_container:
217  {
218  // flatten
219  BESDEBUG( "fonc", "Attribute " << new_name
220  << " is an attribute container" << endl ) ;
221  AttrTable *container = attrs.get_attr_table( attr ) ;
222  if( container )
223  {
224  addattrs( ncid, varid, *container, var_name, new_attr_name ) ;
225  }
226  }
227  break ;
228  case Attr_byte:
229  {
230  // unsigned char
231  unsigned char vals[num_vals] ;
232  for( attri = 0; attri < num_vals; attri++ )
233  {
234  string val = attrs.get_attr( attr, attri ) ;
235  istringstream is( val ) ;
236  unsigned int uival = 0 ;
237  is >> uival ;
238  vals[attri] = (unsigned char)uival ;
239  }
240  stax = nc_put_att_uchar( ncid, varid, new_name.c_str(),
241  NC_BYTE, num_vals, vals ) ;
242  if( stax != NC_NOERR )
243  {
244  string err = (string)"File out netcdf, "
245  + "failed to write byte attribute "
246  + new_name ;
247  FONcUtils::handle_error( stax, err, __FILE__, __LINE__ ) ;
248  }
249  }
250  break ;
251  case Attr_int16:
252  {
253  // short
254  short vals[num_vals] ;
255  for( attri = 0; attri < num_vals; attri++ )
256  {
257  string val = attrs.get_attr( attr, attri ) ;
258  istringstream is( val ) ;
259  short sval = 0 ;
260  is >> sval ;
261  vals[attri] = sval ;
262  }
263  stax = nc_put_att_short( ncid, varid, new_name.c_str(),
264  NC_SHORT, num_vals, vals ) ;
265  if( stax != NC_NOERR )
266  {
267  string err = (string)"File out netcdf, "
268  + "failed to write short attribute "
269  + new_name ;
270  FONcUtils::handle_error( stax, err, __FILE__, __LINE__ ) ;
271  }
272  }
273  break ;
274  case Attr_uint16:
275  {
276  // unsigned short
277  // (needs to be big enough to store an unsigned short
278  int vals[num_vals] ;
279  for( attri = 0; attri < num_vals; attri++ )
280  {
281  string val = attrs.get_attr( attr, attri ) ;
282  istringstream is( val ) ;
283  int ival = 0 ;
284  is >> ival ;
285  vals[attri] = ival ;
286  }
287  stax = nc_put_att_int( ncid, varid, new_name.c_str(),
288  NC_INT, num_vals, vals ) ;
289  if( stax != NC_NOERR )
290  {
291  string err = (string)"File out netcdf, "
292  + "failed to write unsinged short attribute "
293  + new_name ;
294  FONcUtils::handle_error( stax, err, __FILE__, __LINE__ ) ;
295  }
296  }
297  break ;
298  case Attr_int32:
299  {
300  // int
301  int vals[num_vals] ;
302  for( attri = 0; attri < num_vals; attri++ )
303  {
304  string val = attrs.get_attr( attr, attri ) ;
305  istringstream is( val ) ;
306  int ival = 0 ;
307  is >> ival ;
308  vals[attri] = ival ;
309  }
310  stax = nc_put_att_int( ncid, varid, new_name.c_str(),
311  NC_INT, num_vals, vals ) ;
312  if( stax != NC_NOERR )
313  {
314  string err = (string)"File out netcdf, "
315  + "failed to write int attribute "
316  + new_name ;
317  FONcUtils::handle_error( stax, err, __FILE__, __LINE__ ) ;
318  }
319  }
320  break ;
321  case Attr_uint32:
322  {
323  // uint
324  // needs to be big enough to store an unsigned int
325  int vals[num_vals] ;
326  for( attri = 0; attri < num_vals; attri++ )
327  {
328  string val = attrs.get_attr( attr, attri ) ;
329  istringstream is( val ) ;
330  int lval = 0 ;
331  is >> lval ;
332  vals[attri] = lval ;
333  }
334  stax = nc_put_att_int( ncid, varid, new_name.c_str(),
335  NC_INT, num_vals, vals ) ;
336  if( stax != NC_NOERR )
337  {
338  string err = (string)"File out netcdf, "
339  + "failed to write byte attribute "
340  + new_name ;
341  FONcUtils::handle_error( stax, err, __FILE__, __LINE__ ) ;
342  }
343  }
344  break ;
345  case Attr_float32:
346  {
347  // float
348  float vals[num_vals] ;
349  for( attri = 0; attri < num_vals; attri++ )
350  {
351  string val = attrs.get_attr( attr, attri ) ;
352  istringstream is( val ) ;
353  float fval = 0 ;
354  is >> fval ;
355  vals[attri] = fval ;
356  }
357  stax = nc_put_att_float( ncid, varid, new_name.c_str(),
358  NC_FLOAT, num_vals, vals ) ;
359  if( stax != NC_NOERR )
360  {
361  string err = (string)"File out netcdf, "
362  + "failed to write float attribute "
363  + new_name ;
364  FONcUtils::handle_error( stax, err, __FILE__, __LINE__ ) ;
365  }
366  }
367  break ;
368  case Attr_float64:
369  {
370  // double
371  double vals[num_vals] ;
372  for( attri = 0; attri < num_vals; attri++ )
373  {
374  string val = attrs.get_attr( attr, attri ) ;
375  istringstream is( val ) ;
376  double dval = 0 ;
377  is >> dval ;
378  vals[attri] = dval ;
379  }
380  stax = nc_put_att_double( ncid, varid, new_name.c_str(),
381  NC_DOUBLE, num_vals, vals ) ;
382  if( stax != NC_NOERR )
383  {
384  string err = (string)"File out netcdf, "
385  + "failed to write double attribute "
386  + new_name ;
387  FONcUtils::handle_error( stax, err, __FILE__, __LINE__ ) ;
388  }
389  }
390  break ;
391  case Attr_string:
392  case Attr_url:
393  case Attr_other_xml: // Added. jhrg 12.27.2011
394  {
395  // string
396  string val = attrs.get_attr( attr, 0 ) ;
397  for( attri = 1; attri < num_vals; attri++ )
398  {
399  val += "\n" + attrs.get_attr( attr, attri ) ;
400  }
401  stax = nc_put_att_text( ncid, varid, new_name.c_str(),
402  val.length(), val.c_str());
403  if( stax != NC_NOERR )
404  {
405  string err = (string)"File out netcdf, "
406  + "failed to write string attribute "
407  + new_name ;
408  FONcUtils::handle_error( stax, err, __FILE__, __LINE__ ) ;
409  }
410  }
411  break ;
412  case Attr_unknown:
413  {
414  string err = (string)"File out netcdf, "
415  + "failed to write unknown type of attribute "
416  + new_name ;
417  FONcUtils::handle_error( stax, err, __FILE__, __LINE__ ) ;
418  }
419  break ;
420  }
421 }
422 
436 void
438  const string &var_name,
439  const string &orig )
440 {
441  if( var_name != orig )
442  {
443  string attr_name = FONC_ORIGINAL_NAME ;
444  int stax = nc_put_att_text( ncid, varid, attr_name.c_str(),
445  orig.length(), orig.c_str());
446  if( stax != NC_NOERR )
447  {
448  string err = (string)"File out netcdf, "
449  + "failed to write change of name attribute for "
450  + var_name ;
451  FONcUtils::handle_error( stax, err, __FILE__, __LINE__ ) ;
452  }
453  }
454 }
455 
#define FONC_EMBEDDED_SEPARATOR
Definition: FONcUtils.h:45
static void add_original_name(int ncid, int varid, const string &var_name, const string &orig)
Adds an attribute for the variable if the variable name had to be modified in any way...
#define FONC_ORIGINAL_NAME
static void handle_error(int stax, string &err, const string &file, int line)
handle any netcdf errors
Definition: FONcUtils.cc:238
#define FONC_ATTRIBUTE_SEPARATOR
Definition: FONcUtils.h:46
#define BESDEBUG(x, y)
macro used to send debug information to the debug stream
Definition: BESDebug.h:64
static string id2netcdf(string in)
convert the provided string to a netcdf allowed identifier.
Definition: FONcUtils.cc:73