bes Updated for version 3.20.13
genvec.cc
1// This file is part of the hdf4 data handler for the OPeNDAP data server.
2
3// Copyright (c) 2005 OPeNDAP, Inc.
4// Author: James Gallagher <jgallagher@opendap.org>
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 License
17// along with this software; if not, write to the Free Software Foundation,
18// 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
23// Copyright 1996, by the California Institute of Technology.
24// ALL RIGHTS RESERVED. United States Government Sponsorship
25// acknowledged. Any commercial use must be negotiated with the
26// Office of Technology Transfer at the California Institute of
27// Technology. This software may be subject to U.S. export control
28// laws and regulations. By accepting this software, the user
29// agrees to comply with all applicable U.S. export laws and
30// regulations. User has the responsibility to obtain export
31// licenses, or other export authority as may be required before
32// exporting such information to foreign countries or providing
33// access to foreign persons.
34
35// U.S. Government Sponsorship under NASA Contract
36// NAS7-1260 is acknowledged.
37//
38// Author: Todd.K.Karakashian@jpl.nasa.gov
39//
40// $RCSfile: genvec.cc,v $ - implementation of HDF generic vector class
41//
43
44#include "config_hdf.h"
45
46#include <mfhdf.h>
47
48#ifdef __POWERPC__
49#undef isascii
50#endif
51#include <sstream>
52#include <string>
53#include <vector>
54
55#include <libdap/InternalErr.h>
56
57#include <hcerr.h>
58#include <hdfclass.h>
59
60using namespace std;
61
62// Convert an array of U with length nelts into an array of T by casting each
63// element of array to a T.
64template < class T, class U >
65 void ConvertArrayByCast(U * array, int nelts, T ** carray)
66{
67 if (nelts == 0) {
68 *carray = 0;
69 return;
70 }
71 *carray = new T[nelts];
72 if (*carray == 0) // Harmless but should never be used.
73 THROW(hcerr_nomemory);
74 for (int i = 0; i < nelts; ++i) {
75 *(*carray + i) = static_cast < T > (*(array + i));
76 }
77}
78
79//
80// protected member functions
81//
82
83// Initialize an hdf_genvec from an input C array. If data, begin, end,
84// stride are zero, a zero-length hdf_genvec of the specified type will be
85// initialized.
86void hdf_genvec::_init(int32 nt, void *data, int begin, int end,
87 int stride)
88{
89
90 // input checking: nt must be a valid HDF number type;
91 // data, nelts can optionally both together be 0.
92 int32 eltsize; // number of bytes per element
93 if ((eltsize = DFKNTsize(nt)) <= 0)
94 THROW(hcerr_dftype); // invalid number type
95 bool zerovec = (data == 0 && begin == 0 && end == 0 && stride == 0);
96 if (zerovec) { // if this is a zero-length vector
97 _nelts = 0;
98 _data = 0;
99 } else {
100 if (begin < 0 || end < 0 || stride <= 0 || end < begin)
101 THROW(hcerr_range); // invalid range given for subset of data
102 if (data == 0)
103 THROW(hcerr_invarr); // if specify a range, need a data array!
104
105 // allocate memory for _data and assign _nt, _nelts
106 int nelts = (int) ((end - begin) / stride + 1);
107 _data = new char[nelts * eltsize]; // allocate memory
108 if (_data == 0)
109 THROW(hcerr_nomemory);
110 if (stride == 1) // copy data directly
111 (void) memcpy(_data, (void *) ((char *) data + begin),
112 eltsize * nelts);
113 else {
114 for (int i = 0, j = begin; i < nelts; ++i, j += stride) // subsample data
115 memcpy((void *) ((char *) _data + i * eltsize),
116 (void *) ((char *) data + j * eltsize), eltsize);
117 }
118 _nelts = nelts; // assign number of elements
119 }
120 _nt = nt; // assign HDF number type
121 return;
122}
123
124// initialize an empty hdf_genvec
125void hdf_genvec::_init(void)
126{
127 _data = 0;
128 _nelts = _nt = 0;
129 return;
130}
131
132// initialize hdf_genvec from another hdf_genvec
133void hdf_genvec::_init(const hdf_genvec & gv)
134{
135 if (gv._nt == 0 && gv._nelts == 0 && gv._data == 0)
136 _init();
137 else if (gv._nelts == 0)
138 _init(gv._nt, 0, 0, 0, 0);
139 else
140 _init(gv._nt, gv._data, 0, gv._nelts - 1, 1);
141 return;
142}
143
144// free up memory of hdf_genvec
145void hdf_genvec::_del(void)
146{
147 delete[]_data;
148 _nelts = _nt = 0;
149 _data = 0;
150 return;
151}
152
153
154
155//
156// public member functions
157//
158
159hdf_genvec::hdf_genvec(void)
160{
161 _init();
162 return;
163}
164
165hdf_genvec::hdf_genvec(int32 nt, void *data, int begin, int end,
166 int stride)
167{
168 _init(nt, data, begin, end, stride);
169 return;
170}
171
172hdf_genvec::hdf_genvec(int32 nt, void *data, int nelts)
173{
174 _init(nt, data, 0, nelts - 1, 1);
175 return;
176}
177
178hdf_genvec::hdf_genvec(const hdf_genvec & gv)
179{
180 _init(gv);
181 return;
182}
183
184hdf_genvec::~hdf_genvec(void)
185{
186 _del();
187 return;
188}
189
190hdf_genvec & hdf_genvec::operator=(const hdf_genvec & gv)
191{
192 if (this == &gv)
193 return *this;
194 _del();
195 _init(gv);
196 return *this;
197}
198
199// An append method...
200void hdf_genvec::append(int32 nt, const char *new_data, int32 nelts)
201{
202 // input checking: nt must be a valid HDF number type;
203 // data, nelts can optionally both together be 0.
204 int32 eltsize; // number of bytes per element
205 if ((eltsize = DFKNTsize(nt)) <= 0)
206 THROW(hcerr_dftype); // invalid number type
207
208 if (new_data == 0 && nelts == 0) { // if this is a zero-length vector
209 _nelts = 0;
210 _data = 0;
211 } else {
212 if (nelts == 0)
213 THROW(hcerr_range); // invalid range given for subset of data
214 if (new_data == 0)
215 THROW(hcerr_invarr); // if specify a range, need a data array!
216
217 // allocate memory for _data and assign _nt, _nelts
218 char *d = new char[(_nelts + nelts) * eltsize]; // allocate memory
219 memcpy(d, _data, _nelts);
220 memcpy(d + _nelts, new_data, nelts);
221
222 delete[]_data;
223
224 _data = d;
225 _nelts += nelts; // assign number of elements
226 }
227
228 _nt = nt; // assign HDF number type
229 return;
230}
231
232// import new data into hdf_genvec (old data is deleted)
233void hdf_genvec::import(int32 nt, void *data, int begin, int end,
234 int stride)
235{
236 _del();
237 if (nt == 0)
238 _init();
239 else
240 _init(nt, data, begin, end, stride);
241 return;
242}
243
244// import new data into hdf_genvec from a vector of strings
245void hdf_genvec::import(int32 nt, const vector < string > &sv)
246{
247 static char strbuf[hdfclass::MAXSTR];
248
249 int eltsize = DFKNTsize(nt);
250 if (eltsize == 0)
251 THROW(hcerr_invnt);
252 if (sv.size() == 0) {
253 this->import(nt);
254 return;
255 }
256
257 char *obuf = new char[DFKNTsize(nt) * sv.size()];
258 switch (nt) {
259 case DFNT_FLOAT32:{
260 float32 val;
261 for (int i = 0; i < (int) sv.size(); ++i) {
262 strncpy(strbuf, sv[i].c_str(), hdfclass::MAXSTR - 1);
263 istringstream(strbuf) >> val;
264 *((float32 *) obuf + i) = val;
265 }
266 break;
267 }
268 case DFNT_FLOAT64:{
269 float64 val;
270 for (int i = 0; i < (int) sv.size(); ++i) {
271 strncpy(strbuf, sv[i].c_str(), hdfclass::MAXSTR - 1);
272 istringstream(strbuf) >> val;
273 *((float64 *) obuf + i) = val;
274 }
275 break;
276 }
277 case DFNT_INT8:{
278 int8 val;
279 for (int i = 0; i < (int) sv.size(); ++i) {
280 strncpy(strbuf, sv[i].c_str(), hdfclass::MAXSTR - 1);
281 istringstream iss(strbuf);
282 iss >> val;
283 *((int8 *) obuf + i) = val;
284 }
285 break;
286 }
287 case DFNT_INT16:{
288 int16 val;
289 for (int i = 0; i < (int) sv.size(); ++i) {
290 istringstream(strbuf) >> val;
291 *((int16 *) obuf + i) = val;
292 }
293 break;
294 }
295 case DFNT_INT32:{
296 int32 val;
297 for (int i = 0; i < (int) sv.size(); ++i) {
298 strncpy(strbuf, sv[i].c_str(), hdfclass::MAXSTR - 1);
299 istringstream(strbuf) >> val;
300 *((int32 *) obuf + i) = val;
301 }
302 break;
303 }
304 case DFNT_UINT8:{
305 uint8 val;
306 for (int i = 0; i < (int) sv.size(); ++i) {
307 strncpy(strbuf, sv[i].c_str(), hdfclass::MAXSTR - 1);
308 istringstream iss(strbuf);
309 iss >> val;
310 *((uint8 *) obuf + i) = val;
311 }
312 break;
313 }
314 case DFNT_UINT16:{
315 uint16 val;
316 for (int i = 0; i < (int) sv.size(); ++i) {
317 strncpy(strbuf, sv[i].c_str(), hdfclass::MAXSTR - 1);
318 istringstream(strbuf) >> val;
319 *((uint16 *) obuf + i) = val;
320 }
321 break;
322 }
323 case DFNT_UINT32:{
324 uint32 val;
325 for (int i = 0; i < (int) sv.size(); ++i) {
326 strncpy(strbuf, sv[i].c_str(), hdfclass::MAXSTR - 1);
327 istringstream(strbuf) >> val;
328 *((uint32 *) obuf + i) = val;
329 }
330 break;
331 }
332 case DFNT_UCHAR8:{
333 uchar8 val;
334 for (int i = 0; i < (int) sv.size(); ++i) {
335 strncpy(strbuf, sv[i].c_str(), hdfclass::MAXSTR - 1);
336 istringstream iss(strbuf);
337 iss >> val;
338 *((uchar8 *) obuf + i) = val;
339 }
340 break;
341 }
342 case DFNT_CHAR8:{
343 char8 val;
344 for (int i = 0; i < (int) sv.size(); ++i) {
345 strncpy(strbuf, sv[i].c_str(), hdfclass::MAXSTR - 1);
346 istringstream iss(strbuf);
347 iss >> val;
348 *((char8 *) obuf + i) = val;
349 }
350 break;
351 }
352 default:
353 delete[] obuf;
354 THROW(hcerr_invnt);
355 }
356
357 this->import(nt, obuf, (int) sv.size());
358 delete[] obuf;
359 return;
360}
361
362// export an hdf_genvec holding uint8 or uchar8 data to a uchar8 array
363// Added export of int8 to uchar8. A bad idea, but needed to fix some
364// clients. The same `fix' has been applied to some other mfuncs that follow.
365// 1/13/98 jhrg.
366//
367// It looks like this code treats all 8-bit datatypes as the same the user
368// has to know if they are signed or not. 4/8/2002 jhrg
369uchar8 *hdf_genvec::export_uchar8(void) const
370{
371 uchar8 *rv = 0;
372 if (_nt == DFNT_UINT8)
373 ConvertArrayByCast((uint8 *) _data, _nelts, &rv);
374 else if (_nt == DFNT_UCHAR8)
375 ConvertArrayByCast((uchar8 *) _data, _nelts, &rv);
376 // Added the following case. jhrg 1/13/98.
377#if 0
378 else if (_nt == DFNT_INT8)
379 ConvertArrayByCast((int8 *) _data, _nelts, &rv);
380#endif
381 else
382 THROW(hcerr_dataexport);
383 return rv;
384}
385
386// return the i'th element of the vector as a uchar8
387uchar8 hdf_genvec::elt_uchar8(int i) const
388{
389 uchar8 rv;
390 if (i < 0 || i > _nelts)
391 THROW(hcerr_range);
392 if (_nt == DFNT_UINT8)
393 rv = (uchar8) * ((uint8 *) _data + i);
394 else if (_nt == DFNT_UCHAR8)
395 rv = *((uchar8 *) _data + i);
396 // Added the following case. 1/13/98 jhrg.
397#if 0
398 else if (_nt == DFNT_INT8)
399 rv = *((int8 *) _data + i);
400#endif
401 else
402 THROW(hcerr_dataexport);
403 return rv;
404}
405
406// export an hdf_genvec holding uint8 or uchar8 data to a uchar8 vector
407vector < uchar8 > hdf_genvec::exportv_uchar8(void) const
408{
409 vector < uchar8 > rv = vector < uchar8 > (0);
410 uchar8 *dtmp = 0;
411 if (_nt == DFNT_UINT8) // cast to uchar8 array and export
412 ConvertArrayByCast((uint8 *) _data, _nelts, &dtmp);
413 else if (_nt == DFNT_UCHAR8)
414 dtmp = (uchar8 *) _data;
415 // Added the following case. 1/13/98 jhrg.
416#if 0
417 else if (_nt == DFNT_INT8)
418 ConvertArrayByCast((int8 *) _data, _nelts, &dtmp);
419#endif
420 else
421 THROW(hcerr_dataexport);
422 rv = vector < uchar8 > (dtmp, dtmp + _nelts);
423 if (dtmp != (uchar8 *) _data)
424 delete[]dtmp;
425 return rv;
426}
427
428// export an hdf_genvec holding int8 or char8 data to a char8 array
429char8 *hdf_genvec::export_char8(void) const
430{
431 char8 *rv = 0;
432 if (_nt == DFNT_INT8)
433 ConvertArrayByCast((int8 *) _data, _nelts, &rv);
434 else if (_nt == DFNT_CHAR8)
435 ConvertArrayByCast((char8 *) _data, _nelts, &rv);
436 else
437 THROW(hcerr_dataexport);
438 return rv;
439}
440
441// return the i'th element of the vector as a char8
442char8 hdf_genvec::elt_char8(int i) const
443{
444 char8 rv;
445 if (i < 0 || i > _nelts)
446 THROW(hcerr_range);
447 if (_nt == DFNT_INT8)
448 rv = (char8) * ((int8 *) _data + i);
449 else if (_nt == DFNT_CHAR8 || _nt == DFNT_UCHAR8)
450 rv = *((char8 *) _data + i);
451 else
452 THROW(hcerr_dataexport);
453 return rv;
454}
455
456// export an hdf_genvec holding int8 or char8 data to a char8 vector
457vector < char8 > hdf_genvec::exportv_char8(void) const
458{
459 vector < char8 > rv = vector < char8 > (0);
460 char8 *dtmp = 0;
461 if (_nt == DFNT_INT8) // cast to char8 array and export
462 ConvertArrayByCast((int8 *) _data, _nelts, &dtmp);
463 else if (_nt == DFNT_CHAR8)
464 ConvertArrayByCast((char8 *) _data, _nelts, &dtmp);
465// dtmp = (char8 *)_data;
466 else
467 THROW(hcerr_dataexport);
468 if (!dtmp)
469 throw InternalErr(__FILE__, __LINE__, "No data returned for the character array.");
470 rv = vector < char8 > (dtmp, dtmp + _nelts);
471 if (dtmp != (char8 *) _data)
472 delete[]dtmp;
473 return rv;
474}
475
476// export an hdf_genvec holding uchar8 or uint8 data to a uint8 array
477uint8 *hdf_genvec::export_uint8(void) const
478{
479 uint8 *rv = 0;
480 if (_nt == DFNT_UCHAR8 || _nt == DFNT_CHAR8)
481 ConvertArrayByCast((uchar8 *) _data, _nelts, &rv);
482 else if (_nt == DFNT_UINT8)
483 ConvertArrayByCast((uint8 *) _data, _nelts, &rv);
484 else
485 THROW(hcerr_dataexport);
486 return rv;
487}
488
489// return the i'th element of the vector as a uint8
490uint8 hdf_genvec::elt_uint8(int i) const
491{
492 uint8 rv;
493 if (i < 0 || i > _nelts)
494 THROW(hcerr_range);
495 if (_nt == DFNT_UCHAR8 || _nt == DFNT_CHAR8)
496 rv = (uint8) * ((uchar8 *) _data + i);
497 else if (_nt == DFNT_UINT8)
498 rv = *((uint8 *) _data + i);
499 else
500 THROW(hcerr_dataexport);
501 return rv;
502}
503
504// export an hdf_genvec holding uchar8 or uint8 data to a uint8 vector
505vector < uint8 > hdf_genvec::exportv_uint8(void) const
506{
507 vector < uint8 > rv = vector < uint8 > (0);
508 uint8 *dtmp = 0;
509 if (_nt == DFNT_UCHAR8 || _nt == DFNT_CHAR8) // cast to uint8 array and export
510 ConvertArrayByCast((uchar8 *) _data, _nelts, &dtmp);
511 else if (_nt == DFNT_UINT8)
512 dtmp = (uint8 *) _data;
513 else
514 THROW(hcerr_dataexport);
515
516 rv = vector < uint8 > (dtmp, dtmp + _nelts);
517 if (dtmp != (uint8 *) _data)
518 delete[]dtmp;
519 return rv;
520}
521
522// export an hdf_genvec holding char8 or int8 data to a int8 array
523int8 *hdf_genvec::export_int8(void) const
524{
525 int8 *rv = 0;
526 if (_nt == DFNT_CHAR8)
527 ConvertArrayByCast((char8 *) _data, _nelts, &rv);
528 else if (_nt == DFNT_INT8)
529 ConvertArrayByCast((int8 *) _data, _nelts, &rv);
530 else
531 THROW(hcerr_dataexport);
532 return rv;
533}
534
535// return the i'th element of the vector as a int8
536int8 hdf_genvec::elt_int8(int i) const
537{
538 int8 rv;
539 if (i < 0 || i > _nelts)
540 THROW(hcerr_range);
541 if (_nt == DFNT_CHAR8)
542 rv = (int8) * ((char8 *) _data + i);
543 else if (_nt == DFNT_INT8)
544 rv = *((int8 *) _data + i);
545 else
546 THROW(hcerr_dataexport);
547 return rv;
548}
549
550// export an hdf_genvec holding int8 data to a int8 vector
551vector < int8 > hdf_genvec::exportv_int8(void) const
552{
553 vector < int8 > rv = vector < int8 > (0);
554 int8 *dtmp = 0;
555 if (_nt == DFNT_CHAR8) // cast to int8 array and export
556 ConvertArrayByCast((char8 *) _data, _nelts, &dtmp);
557 else if (_nt == DFNT_INT8)
558 dtmp = (int8 *) _data;
559 else
560 THROW(hcerr_dataexport);
561 rv = vector < int8 > (dtmp, dtmp + _nelts);
562 if (dtmp != (int8 *) _data)
563 delete[]dtmp;
564 return rv;
565}
566
567// export an hdf_genvec holding uchar8, uint8 or uint16 data to a uint16 array
568uint16 *hdf_genvec::export_uint16(void) const
569{
570 uint16 *rv = 0;
571 if (_nt == DFNT_UCHAR8) // cast to uint16 array and export
572 ConvertArrayByCast((uchar8 *) _data, _nelts, &rv);
573 else if (_nt == DFNT_UINT8) // cast to uint16 array and export
574 ConvertArrayByCast((uint8 *) _data, _nelts, &rv);
575 else if (_nt == DFNT_UINT16)
576 ConvertArrayByCast((uint16 *) _data, _nelts, &rv);
577 else
578 THROW(hcerr_dataexport);
579 return rv;
580}
581
582// return the i'th element of the vector as a uint16
583uint16 hdf_genvec::elt_uint16(int i) const
584{
585 if (i < 0 || i > _nelts)
586 THROW(hcerr_range);
587 if (_nt == DFNT_UCHAR8)
588 return (uint16) * ((uchar8 *) _data + i);
589 else if (_nt == DFNT_UINT8)
590 return (uint16) * ((uint8 *) _data + i);
591 else if (_nt == DFNT_UINT16)
592 return *((uint16 *) _data + i);
593 else
594 THROW(hcerr_dataexport);
595 return 0;
596}
597
598// export an hdf_genvec holding uchar8, uint8 or uint16 data to a uint16 vector
599vector < uint16 > hdf_genvec::exportv_uint16(void) const
600{
601 vector < uint16 > rv = vector < uint16 > (0);
602 uint16 *dtmp = 0;
603 if (_nt == DFNT_UCHAR8) // cast to uint16 array and export
604 ConvertArrayByCast((uchar8 *) _data, _nelts, &dtmp);
605 else if (_nt == DFNT_UINT8) // cast to uint16 array and export
606 ConvertArrayByCast((uint8 *) _data, _nelts, &dtmp);
607 else if (_nt == DFNT_UINT16)
608 dtmp = (uint16 *) _data;
609 else
610 THROW(hcerr_dataexport);
611 rv = vector < uint16 > (dtmp, dtmp + _nelts);
612 if (dtmp != (uint16 *) _data)
613 delete[]dtmp;
614 return rv;
615}
616
617// export an hdf_genvec holding uchar8, char8, uint8, int8 or int16 data to
618// an int16 array
619int16 *hdf_genvec::export_int16(void) const
620{
621 int16 *rv = 0;
622 if (_nt == DFNT_UCHAR8) // cast to int16 array and export
623 ConvertArrayByCast((uchar8 *) _data, _nelts, &rv);
624 else if (_nt == DFNT_CHAR8) // cast to int16 array and export
625 ConvertArrayByCast((char8 *) _data, _nelts, &rv);
626 else if (_nt == DFNT_UINT8) // cast to int16 array and export
627 ConvertArrayByCast((uint8 *) _data, _nelts, &rv);
628 else if (_nt == DFNT_INT8) // cast to int16 array and export
629 ConvertArrayByCast((int8 *) _data, _nelts, &rv);
630 else if (_nt == DFNT_INT16)
631 ConvertArrayByCast((int16 *) _data, _nelts, &rv);
632 else
633 THROW(hcerr_dataexport);
634 return rv;
635}
636
637// return the i'th element of the vector as a int16
638int16 hdf_genvec::elt_int16(int i) const
639{
640 if (i < 0 || i > _nelts)
641 THROW(hcerr_range);
642 if (_nt == DFNT_UCHAR8)
643 return (int16) (*((uchar8 *) _data + i));
644 else if (_nt == DFNT_CHAR8)
645 return (int16) (*((char8 *) _data + i));
646 else if (_nt == DFNT_UINT8)
647 return (int16) (*((uint8 *) _data + i));
648 else if (_nt == DFNT_INT8)
649 return (int16) (*((int8 *) _data + i));
650 else if (_nt == DFNT_INT16)
651 return *((int16 *) _data + i);
652 else
653 THROW(hcerr_dataexport);
654 return 0;
655}
656
657// export an hdf_genvec holding int8 or int16 data to an int16 vector
658vector < int16 > hdf_genvec::exportv_int16(void) const
659{
660 vector < int16 > rv = vector < int16 > (0);
661 int16 *dtmp = 0;
662 if (_nt == DFNT_UCHAR8) // cast to int16 array and export
663 ConvertArrayByCast((uchar8 *) _data, _nelts, &dtmp);
664 else if (_nt == DFNT_CHAR8) // cast to int16 array and export
665 ConvertArrayByCast((char8 *) _data, _nelts, &dtmp);
666 else if (_nt == DFNT_UINT8) // cast to int16 array and export
667 ConvertArrayByCast((uint8 *) _data, _nelts, &dtmp);
668 else if (_nt == DFNT_INT8) // cast to int16 array and export
669 ConvertArrayByCast((int8 *) _data, _nelts, &dtmp);
670 else if (_nt == DFNT_INT16)
671 dtmp = (int16 *) _data;
672 else
673 THROW(hcerr_dataexport);
674 rv = vector < int16 > (dtmp, dtmp + _nelts);
675 if (dtmp != (int16 *) _data)
676 delete[]dtmp;
677 return rv;
678}
679
680// export an hdf_genvec holding uchar8, uint8, uint16 or uint32 data to a
681// uint32 array
682uint32 *hdf_genvec::export_uint32(void) const
683{
684 uint32 *rv = 0;
685 if (_nt == DFNT_UCHAR8) // cast to uint32 array and export
686 ConvertArrayByCast((uchar8 *) _data, _nelts, &rv);
687 else if (_nt == DFNT_UINT8) // cast to uint32 array and export
688 ConvertArrayByCast((uint8 *) _data, _nelts, &rv);
689 else if (_nt == DFNT_UINT16) // cast to uint32 array and export
690 ConvertArrayByCast((uint16 *) _data, _nelts, &rv);
691 else if (_nt == DFNT_UINT32)
692 ConvertArrayByCast((uint32 *) _data, _nelts, &rv);
693 else
694 THROW(hcerr_dataexport);
695 return rv;
696}
697
698// return the i'th element of the vector as a uint32
699uint32 hdf_genvec::elt_uint32(int i) const
700{
701 if (i < 0 || i > _nelts)
702 THROW(hcerr_range);
703 if (_nt == DFNT_UCHAR8)
704 return (uint32) (*((uchar8 *) _data + i));
705 else if (_nt == DFNT_UINT8)
706 return (uint32) (*((uint8 *) _data + i));
707 else if (_nt == DFNT_UINT16)
708 return (uint32) (*((uint16 *) _data + i));
709 else if (_nt == DFNT_UINT32)
710 return *((uint32 *) _data + i);
711 else
712 THROW(hcerr_dataexport);
713 return 0;
714}
715
716// export an hdf_genvec holding uchar8, uint8, uint16 or uint32 data to a
717// uint32 vector
718vector < uint32 > hdf_genvec::exportv_uint32(void) const
719{
720 vector < uint32 > rv = vector < uint32 > (0);
721 uint32 *dtmp = 0;
722 if (_nt == DFNT_UCHAR8) // cast to uint32 array and export
723 ConvertArrayByCast((uchar8 *) _data, _nelts, &dtmp);
724 else if (_nt == DFNT_UINT8) // cast to uint32 array and export
725 ConvertArrayByCast((uint8 *) _data, _nelts, &dtmp);
726 else if (_nt == DFNT_UINT16) // cast to uint32 array and export
727 ConvertArrayByCast((uint16 *) _data, _nelts, &dtmp);
728 else if (_nt == DFNT_UINT32)
729 dtmp = (uint32 *) _data;
730 else
731 THROW(hcerr_dataexport);
732 rv = vector < uint32 > (dtmp, dtmp + _nelts);
733 if (dtmp != (uint32 *) _data)
734 delete[]dtmp;
735 return rv;
736}
737
738// export an hdf_genvec holding uchar8, char8, uint8, int8, uint16, int16 or
739// int32 data to a int32 array
740int32 *hdf_genvec::export_int32(void) const
741{
742 int32 *rv = 0;
743 if (_nt == DFNT_UCHAR8) // cast to int32 array and export
744 ConvertArrayByCast((uchar8 *) _data, _nelts, &rv);
745 else if (_nt == DFNT_CHAR8) // cast to int32 array and export
746 ConvertArrayByCast((char8 *) _data, _nelts, &rv);
747 else if (_nt == DFNT_UINT8) // cast to int32 array and export
748 ConvertArrayByCast((uint8 *) _data, _nelts, &rv);
749 else if (_nt == DFNT_INT8) // cast to int32 array and export
750 ConvertArrayByCast((int8 *) _data, _nelts, &rv);
751 else if (_nt == DFNT_UINT16)
752 ConvertArrayByCast((uint16 *) _data, _nelts, &rv);
753 else if (_nt == DFNT_INT16)
754 ConvertArrayByCast((int16 *) _data, _nelts, &rv);
755 else if (_nt == DFNT_INT32)
756 ConvertArrayByCast((int32 *) _data, _nelts, &rv);
757 else
758 THROW(hcerr_dataexport);
759 return rv;
760}
761
762// return the i'th element of the vector as a int32
763int32 hdf_genvec::elt_int32(int i) const
764{
765 if (i < 0 || i > _nelts)
766 THROW(hcerr_range);
767 if (_nt == DFNT_UCHAR8)
768 return (int32) (*((uchar8 *) _data + i));
769 else if (_nt == DFNT_CHAR8)
770 return (int32) (*((char8 *) _data + i));
771 else if (_nt == DFNT_UINT8)
772 return (int32) (*((uint8 *) _data + i));
773 else if (_nt == DFNT_INT8)
774 return (int32) (*((int8 *) _data + i));
775 else if (_nt == DFNT_UINT16)
776 return (int32) (*((uint16 *) _data + i));
777 else if (_nt == DFNT_INT16)
778 return (int32) (*((int16 *) _data + i));
779 else if (_nt == DFNT_INT32)
780 return *((int32 *) _data + i);
781 else
782 THROW(hcerr_dataexport);
783 return 0;
784}
785
786// export an hdf_genvec holding uchar8, char8, uint8, int8, uint16, int16 or
787// int32 data to a int32 vector
788vector < int32 > hdf_genvec::exportv_int32(void) const
789{
790 vector < int32 > rv = vector < int32 > (0);
791 int32 *dtmp = 0;
792 if (_nt == DFNT_UCHAR8) // cast to int32 array and export
793 ConvertArrayByCast((uchar8 *) _data, _nelts, &dtmp);
794 else if (_nt == DFNT_CHAR8) // cast to int32 array and export
795 ConvertArrayByCast((char8 *) _data, _nelts, &dtmp);
796 else if (_nt == DFNT_UINT8) // cast to int32 array and export
797 ConvertArrayByCast((uint8 *) _data, _nelts, &dtmp);
798 else if (_nt == DFNT_INT8) // cast to int32 array and export
799 ConvertArrayByCast((int8 *) _data, _nelts, &dtmp);
800 else if (_nt == DFNT_UINT16) // cast to int32 array and export
801 ConvertArrayByCast((uint16 *) _data, _nelts, &dtmp);
802 else if (_nt == DFNT_INT16) // cast to int32 array and export
803 ConvertArrayByCast((int16 *) _data, _nelts, &dtmp);
804 else if (_nt == DFNT_INT32)
805 dtmp = (int32 *) _data;
806 else
807 THROW(hcerr_dataexport);
808 rv = vector < int32 > (dtmp, dtmp + _nelts);
809 if (dtmp != (int32 *) _data)
810 delete[]dtmp;
811 return rv;
812}
813
814// export an hdf_genvec holding float32 data to a float32 array
815float32 *hdf_genvec::export_float32(void) const
816{
817 float32 *rv = 0;
818 if (_nt != DFNT_FLOAT32)
819 THROW(hcerr_dataexport);
820 else
821 ConvertArrayByCast((float32 *) _data, _nelts, &rv);
822 return rv;
823}
824
825// return the i'th element of the vector as a float32
826float32 hdf_genvec::elt_float32(int i) const
827{
828 if (i < 0 || i > _nelts)
829 THROW(hcerr_range);
830 if (_nt != DFNT_FLOAT32)
831 THROW(hcerr_dataexport);
832 return *((float32 *) _data + i);
833}
834
835// export an hdf_genvec holding float32 data to a float32 vector
836vector < float32 > hdf_genvec::exportv_float32(void) const
837{
838 if (_nt != DFNT_FLOAT32) {
839 THROW(hcerr_dataexport);
840 // Comment out this line since the following line will never be reached. KY 2015-10-23
841 //return vector < float32 > (0);
842 } else
843 return vector < float32 > ((float32 *) _data,
844 (float32 *) _data + _nelts);
845}
846
847// export an hdf_genvec holding float32 or float64 data to a float64 array
848float64 *hdf_genvec::export_float64(void) const
849{
850 float64 *rv = 0;
851 if (_nt == DFNT_FLOAT64)
852 ConvertArrayByCast((float64 *) _data, _nelts, &rv);
853 else if (_nt == DFNT_FLOAT32) // cast to float64 array and export
854 ConvertArrayByCast((float32 *) _data, _nelts, &rv);
855 else
856 THROW(hcerr_dataexport);
857 return rv;
858}
859
860// return the i'th element of the vector as a float64
861float64 hdf_genvec::elt_float64(int i) const
862{
863 if (i < 0 || i > _nelts)
864 THROW(hcerr_range);
865 if (_nt == DFNT_FLOAT64)
866 return *((float64 *) _data + i);
867 else if (_nt == DFNT_FLOAT32)
868 return (float64) (*((float32 *) _data + i));
869 else
870 THROW(hcerr_dataexport);
871 //return 0;
872}
873
874// export an hdf_genvec holding float32 or float64 data to a float64 vector
875vector < float64 > hdf_genvec::exportv_float64(void) const
876{
877 vector < float64 > rv = vector < float64 > (0);
878 float64 *dtmp = 0;
879 if (_nt == DFNT_FLOAT32) // cast to float64 array and export
880 ConvertArrayByCast((float32 *) _data, _nelts, &dtmp);
881 else if (_nt == DFNT_FLOAT64)
882 dtmp = (float64 *) _data;
883 else
884 THROW(hcerr_dataexport);
885 rv = vector < float64 > (dtmp, dtmp + _nelts);
886 if (dtmp != (float64 *) _data)
887 delete[]dtmp;
888 return rv;
889}
890
891// export an hdf_genvec holding char data to a string
892string hdf_genvec::export_string(void) const
893{
894 if (_nt != DFNT_CHAR8 && _nt != DFNT_UCHAR8) {
895 THROW(hcerr_dataexport);
896 }
897 else {
898 if (_data == 0)
899 return string();
900 else
901 return string((char *) _data, _nelts);
902 }
903}
904
905// print all of the elements of hdf_genvec to a vector of string
906void hdf_genvec::print(vector < string > &sv) const
907{
908 if (_nelts > 0)
909 print(sv, 0, _nelts - 1, 1);
910 return;
911}
912
913// print the elements of hdf_genvec to a vector of string; start with initial
914// element "begin", end with "end" and increment by "stride" elements.
915void hdf_genvec::print(vector < string > &sv, int begin, int end,
916 int stride) const
917{
918 if (begin < 0 || begin > _nelts || stride < 1 || end < 0 || end < begin
919 || stride <= 0 || end > _nelts - 1)
920 THROW(hcerr_range);
921 if (_nt == DFNT_CHAR8 || _nt == DFNT_UCHAR8) {
922 string sub;
923 sub = string((char *) _data + begin, (end - begin + 1));
924 if (stride > 1) {
925 string x;
926 for (int i = 0; i < (end - begin + 1); i += stride)
927 x += sub[i];
928 sub = x;
929 }
930 sv.push_back(sub);
931 } else {
932#if 0
933 char buf[hdfclass::MAXSTR];
934#endif
935 int i;
936 switch (_nt) {
937#if 0
938 case DFNT_UCHAR8:
939 for (i = begin; i <= end; i += stride) {
940 ostrstream(buf, hdfclass::MAXSTR) <<
941 (int) *((uchar8 *) _data + i) << ends;
942 sv.push_back(string(buf));
943 }
944 break;
945#endif
946 case DFNT_UINT8:
947 for (i = begin; i <= end; i += stride) {
948 ostringstream buf;
949 buf << (unsigned int) *((uint8 *) _data + i);
950 sv.push_back(buf.str());
951 }
952 break;
953 case DFNT_INT8:
954 for (i = begin; i <= end; i += stride) {
955 ostringstream buf;
956 buf << (int) *((int8 *) _data + i);
957 sv.push_back(buf.str());
958 }
959 break;
960 case DFNT_UINT16:
961 for (i = begin; i <= end; i += stride) {
962 ostringstream buf;
963 buf << *((uint16 *) _data + i);
964 sv.push_back(buf.str());
965 }
966 break;
967 case DFNT_INT16:
968 for (i = begin; i <= end; i += stride) {
969 ostringstream buf;
970 buf << *((int16 *) _data + i);
971 sv.push_back(buf.str());
972 }
973 break;
974 case DFNT_UINT32:
975 for (i = begin; i <= end; i += stride) {
976 ostringstream buf;
977 buf << *((uint32 *) _data + i);
978 sv.push_back(buf.str());
979 }
980 break;
981 case DFNT_INT32:
982 for (i = begin; i <= end; i += stride) {
983 ostringstream buf;
984 buf << *((int32 *) _data + i);
985 sv.push_back(buf.str());
986 }
987 break;
988 case DFNT_FLOAT32:
989 for (i = begin; i <= end; i += stride) {
990 ostringstream buf;
991 buf << *((float32 *) _data + i);
992 sv.push_back(buf.str());
993 }
994 break;
995 case DFNT_FLOAT64:
996 for (i = begin; i <= end; i += stride) {
997 ostringstream buf;
998 buf << *((float64 *) _data + i);
999 sv.push_back(buf.str());
1000 }
1001 break;
1002 }
1003 }
1004 return;
1005}
1006
1007// $Log: genvec.cc,v $
1008// Revision 1.7.4.1.2.1 2004/02/23 02:08:03 rmorris
1009// There is some incompatibility between the use of isascii() in the hdf library
1010// and its use on OS X. Here we force in the #undef of isascii in the osx case.
1011//
1012// Revision 1.7.4.1 2003/05/21 16:26:58 edavis
1013// Updated/corrected copyright statements.
1014//
1015// Revision 1.7 2003/01/31 02:08:37 jimg
1016// Merged with release-3-2-7.
1017//
1018// Revision 1.6.4.3 2002/12/18 23:32:50 pwest
1019// gcc3.2 compile corrections, mainly regarding the using statement. Also,
1020// missing semicolon in .y file
1021//
1022// Revision 1.6.4.2 2002/04/11 03:15:43 jimg
1023// Minor change to the ConvertArrayByCast template function. Still, avoid using
1024// this if possible.
1025//
1026// Revision 1.6.4.1 2001/10/30 06:36:35 jimg
1027// Added genvec::append(...) method.
1028// Fixed up some comments in genvec.
1029// Changed genvec's data member from void * to char * to quell warnings
1030// about void * being passed to delete.
1031//
1032// Revision 1.6 2000/10/09 19:46:19 jimg
1033// Moved the CVS Log entries to the end of each file.
1034// Added code to catch Error objects thrown by the dap library.
1035// Changed the read() method's definition to match the dap library.
1036//
1037// Revision 1.5 1999/05/06 03:23:33 jimg
1038// Merged changes from no-gnu branch
1039//
1040// Revision 1.4 1999/05/05 23:33:43 jimg
1041// String --> string conversion
1042//
1043// Revision 1.3.6.1 1999/05/06 00:35:45 jimg
1044// Jakes String --> string changes
1045//
1046// Revision 1.3 1998/09/10 21:33:24 jehamby
1047// Map DFNT_CHAR8 and DFNT_UCHAR8 to Byte instead of string in SDS.
1048//
1049// Revision 1.2 1998/02/05 20:14:29 jimg
1050// DODS now compiles with gcc 2.8.x
1051//
1052// Revision 1.1 1996/10/31 18:42:56 jimg
1053// Added.
1054//
1055// Revision 1.12 1996/10/14 23:07:53 todd
1056// Added a new import function to hdf_genvec to allow import from a vector
1057// of string.
1058//
1059// Revision 1.11 1996/08/22 20:54:14 todd
1060// Rewrite of export function suite to correctly support casts. Now all casts towards
1061// integers of greater size are supported. (E.g., char8 -> int8 ->int16 -> int32, but
1062// disallow int16 -> uint32 or uint32 -> int32).
1063//
1064// Revision 1.10 1996/08/21 23:18:59 todd
1065// Added mfuncs to return the i'th element of a genvec.
1066//
1067// Revision 1.9 1996/07/22 17:12:20 todd
1068// Changed export_*() mfuncs so they return a C++ array. Added exportv_*() mfuncs
1069// to return STL vectors.
1070//
1071// Revision 1.8 1996/06/18 21:49:21 todd
1072// Fixed pointer expressions so they would be in conformance with proper usage of void *
1073//
1074// Revision 1.7 1996/06/18 18:37:42 todd
1075// Added support for initialization from a subsampled array to the _init() and
1076// constructor mfuncs; also added support for print() to output a subsample of
1077// the hdf_genvec.
1078// Added copyright notice.
1079//
1080// Revision 1.6 1996/05/02 18:10:51 todd
1081// Fixed a bug in print() and in export_string().
1082//
1083// Revision 1.5 1996/04/23 21:11:50 todd
1084// Fixed declaration of print mfunc so it was const correct.
1085//
1086// Revision 1.4 1996/04/18 19:06:37 todd
1087// Added print() mfunc
1088//
1089// Revision 1.3 1996/04/04 01:11:30 todd
1090// Added support for empty vectors that have a number type.
1091// Added import() public member function.
1092//
1093// Revision 1.2 1996/04/03 00:18:18 todd
1094// Fixed a bug in _init(int32, void *, int)
1095//
1096// Revision 1.1 1996/04/02 20:36:43 todd
1097// Initial revision
1098//