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