bes  Updated for version 3.20.6
h5cfdaputil.cc
Go to the documentation of this file.
1 // This file is part of hdf5_handler: an HDF5 file handler for the OPeNDAP
2 // data server.
3 
4 // Copyright (c) 2011-2016 The HDF Group, Inc. and OPeNDAP, Inc.
5 //
6 // This is free software; you can redistribute it and/or modify it under the
7 // terms of the GNU Lesser General Public License as published by the Free
8 // Software Foundation; either version 2.1 of the License, or (at your
9 // option) any later version.
10 //
11 // This software is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 // License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 //
20 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
21 // You can contact The HDF Group, Inc. at 1800 South Oak Street,
22 // Suite 203, Champaign, IL 61820
23 
35 
36 
37 #include "h5cfdaputil.h"
38 #include <math.h>
39 
40 using namespace std;
41 using namespace libdap;
42 
43 string HDF5CFDAPUtil::escattr(string s)
44 {
45  const string printable = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~`!@#$%^&*()_-+={[}]|\\:;<,>.?/'\"\n\t\r";
46  const string ESC = "\\";
47  const string DOUBLE_ESC = ESC + ESC;
48  const string QUOTE = "\"";
49  const string ESCQUOTE = ESC + QUOTE;
50 
51  // escape \ with a second backslash
52  size_t ind = 0;
53  while ((ind = s.find(ESC, ind)) != string::npos) {
54  s.replace(ind, 1, DOUBLE_ESC);
55  ind += DOUBLE_ESC.length();
56  }
57 
58  // escape non-printing characters with octal escape
59  ind = 0;
60  while ((ind = s.find_first_not_of(printable, ind)) != string::npos)
61  s.replace(ind, 1, ESC + octstring(s[ind]));
62 
63 
64  // escape " with backslash
65  ind = 0;
66  while ((ind = s.find(QUOTE, ind)) != string::npos) {
67  s.replace(ind, 1, ESCQUOTE);
68  ind += ESCQUOTE.length();
69  }
70 
71  return s;
72 }
73 
74 // present the string in octal base.
75 string
76 HDF5CFDAPUtil::octstring(unsigned char val)
77 {
78  ostringstream buf;
79  buf << oct << setw(3) << setfill('0')
80  << static_cast<unsigned int>(val);
81 
82  return buf.str();
83 }
84 
85 
86 void HDF5CFDAPUtil::replace_double_quote(string & str) {
87 
88  const string offend_char = "\"";
89  const string replace_str = "&quote";
90  size_t found_quote = 0;
91  size_t start_pos = 0;
92  while (found_quote != string::npos) {
93  found_quote = str.find(offend_char,start_pos);
94  if (found_quote!= string::npos){
95  str.replace(found_quote,offend_char.size(),replace_str);
96  start_pos = found_quote+1;
97  }
98  }
99 }
100 
101 
102 string HDF5CFDAPUtil::print_type(H5DataType type) {
103 
104  // The list is based on libdap/AttrTable.h.
105  // We added DAP4 INT64 and UINT64 support.
106  string DAPUNSUPPORTED ="Unsupported";
107  string DAPBYTE ="Byte";
108  string DAPINT16 ="Int16";
109  string DAPUINT16 ="Uint16";
110  string DAPINT32 ="Int32";
111  string DAPUINT32 ="Uint32";
112  string DAPFLOAT32 ="Float32";
113  string DAPFLOAT64 ="Float64";
114  string DAP4INT64 ="Int64";
115  string DAP4UINT64 ="UInt64";
116  string DAPSTRING = "String";
117 
118  switch (type) {
119 
120  case H5UCHAR:
121  return DAPBYTE;
122 
123  case H5CHAR:
124  return DAPINT16;
125 
126  case H5INT16:
127  return DAPINT16;
128 
129  case H5UINT16:
130  return DAPUINT16;
131 
132  case H5INT32:
133  return DAPINT32;
134 
135  case H5UINT32:
136  return DAPUINT32;
137 
138  case H5FLOAT32:
139  return DAPFLOAT32;
140 
141  case H5FLOAT64:
142  return DAPFLOAT64;
143 
144  case H5FSTRING:
145  case H5VSTRING:
146  return DAPSTRING;
147  case H5INT64:
148  return DAP4INT64;
149  case H5UINT64:
150  return DAP4UINT64;
151  case H5REFERENCE:
152  case H5COMPOUND:
153  case H5ARRAY:
154  return DAPUNSUPPORTED;
155 
156  default:
157  return DAPUNSUPPORTED;
158  }
159 
160 }
161 
162 H5DataType
163 HDF5CFDAPUtil::get_mem_dtype(H5DataType dtype,size_t mem_dtype_size ) {
164 
165  // Currently in addition to "char" to "int16", all other memory datatype will be the same as the datatype.
166  // So we have a short cut for this function
167  return ((H5INT16 == dtype) && (1 == mem_dtype_size))?H5CHAR:dtype;
168 }
169 
170 string
171 HDF5CFDAPUtil:: print_attr(H5DataType type, int loc, void *vals)
172 {
173  ostringstream rep;
174 
175  union {
176  unsigned char* ucp;
177  char *cp;
178  short *sp;
179  unsigned short *usp;
180  int *ip;
181  unsigned int *uip;
182  long long *llp;
183  unsigned long long *ullp;
184  float *fp;
185  double *dp;
186  } gp;
187 
188  switch (type) {
189 
190  case H5UCHAR:
191  {
192  unsigned char uc;
193  gp.ucp = (unsigned char *) vals;
194 
195  uc = *(gp.ucp+loc);
196  rep << (int)uc;
197 
198  return rep.str();
199  }
200 
201  case H5CHAR:
202  {
203  gp.cp = (char *) vals;
204  char c;
205  c = *(gp.cp+loc);
206  // Since the character may be a special character and DAP may not be able to represent so supposedly we should escape the character
207  // by calling the escattr function. However, HDF5 native char maps to DAP Int16. So the mapping assumes that users will never
208  // use HDF5 native char or HDF5 unsigned native char to represent characters. Instead HDF5 string should be used to represent characters.
209  // So don't do any escaping of H5CHAR for now. KY 2016-10-14
210  rep <<(int)c;
211  return rep.str();
212  }
213 
214 
215  case H5INT16:
216  {
217  gp.sp = (short *) vals;
218  rep<< *(gp.sp+loc);
219  return rep.str();
220  }
221 
222  case H5UINT16:
223 
224  {
225  gp.usp = (unsigned short *) vals;
226  rep << *(gp.usp+loc);
227  return rep.str();
228  }
229 
230 
231  case H5INT32:
232  {
233  gp.ip = (int *) vals;
234  rep << *(gp.ip+loc);
235  return rep.str();
236  }
237 
238  case H5UINT32:
239  {
240  gp.uip = (unsigned int *) vals;
241  rep << *(gp.uip+loc);
242  return rep.str();
243  }
244  case H5INT64: // For DAP4 CF support only
245  {
246  gp.llp = (long long *) vals;
247  rep << *(gp.llp+loc);
248  return rep.str();
249  }
250 
251  case H5UINT64: // For DAP4 CF support only
252  {
253  gp.ullp = (unsigned long long *) vals;
254  rep << *(gp.ullp+loc);
255  return rep.str();
256  }
257 
258 
259 
260  case H5FLOAT32:
261  {
262  float attr_val = *(float*)vals;
263  bool is_a_fin = isfinite(attr_val);
264  gp.fp = (float *) vals;
265  rep << showpoint;
266  rep << setprecision(10);
267  rep << *(gp.fp+loc);
268  string tmp_rep_str = rep.str();
269  if (tmp_rep_str.find('.') == string::npos
270  && tmp_rep_str.find('e') == string::npos
271  && tmp_rep_str.find('E') == string::npos
272  && (true == is_a_fin)){
273  rep<<".";
274  }
275  return rep.str();
276  }
277 
278  case H5FLOAT64:
279  {
280  double attr_val = *(double*)vals;
281  bool is_a_fin = isfinite(attr_val);
282  gp.dp = (double *) vals;
283  rep << std::showpoint;
284  rep << std::setprecision(17);
285  rep << *(gp.dp+loc);
286  string tmp_rep_str = rep.str();
287  if (tmp_rep_str.find('.') == string::npos
288  && tmp_rep_str.find('e') == string::npos
289  && tmp_rep_str.find('E') == string::npos
290  && (true == is_a_fin)) {
291  rep << ".";
292  }
293  return rep.str();
294  }
295  default:
296  return string("UNKNOWN");
297  }
298 
299 }
300 
301 // This helper function is used for 64-bit integer DAP4 support.
302 // We need to support the attributes of all types for 64-bit integer variables.
303 D4AttributeType HDF5CFDAPUtil::daptype_strrep_to_dap4_attrtype(std::string s){
304 
305  if (s == "Byte")
306  return attr_byte_c;
307  else if (s == "Int8")
308  return attr_int8_c;
309  else if (s == "UInt8") // This may never be used.
310  return attr_uint8_c;
311  else if (s == "Int16")
312  return attr_int16_c;
313  else if (s == "UInt16")
314  return attr_uint16_c;
315  else if (s == "Int32")
316  return attr_int32_c;
317  else if (s == "UInt32")
318  return attr_uint32_c;
319  else if (s == "Int64")
320  return attr_int64_c;
321  else if (s == "UInt64")
322  return attr_uint64_c;
323  else if (s == "Float32")
324  return attr_float32_c;
325  else if (s == "Float64")
326  return attr_float64_c;
327  else if (s == "String")
328  return attr_str_c;
329  else if (s == "Url")
330  return attr_url_c;
331  else
332  return attr_null_c;
333 
334 
335 }
336 
337 
HDF5CFDAPUtil::octstring
static string octstring(unsigned char val)
Helper function for escattr.
Definition: h5cfdaputil.cc:76
HDF5CFDAPUtil::daptype_strrep_to_dap4_attrtype
static D4AttributeType daptype_strrep_to_dap4_attrtype(std::string s)
Definition: h5cfdaputil.cc:303
HDF5CFDAPUtil::escattr
static string escattr(string s)
Definition: h5cfdaputil.cc:43
libdap
Definition: BESDapFunctionResponseCache.h:35
h5cfdaputil.h
Helper functions for generating DAS attributes and a function to check BES Key.