Line data Source code
1 : /*****************************************************************************
2 : *
3 : * This module has a number of additions and improvements over the original
4 : * implementation to be suitable for usage in GDAL HDF driver.
5 : *
6 : * Andrey Kiselev <dron@ak4719.spb.edu> is responsible for all the changes.
7 : ****************************************************************************/
8 :
9 : /*
10 : Copyright (C) 1996 Hughes and Applied Research Corporation
11 :
12 : Permission to use, modify, and distribute this software and its documentation
13 : for any purpose without fee is hereby granted, provided that the above
14 : copyright notice appear in all copies and that both that copyright notice and
15 : this permission notice appear in supporting documentation.
16 : */
17 :
18 : #include "cpl_port.h"
19 : #include <errno.h>
20 : #include <limits.h>
21 : #include "mfhdf.h"
22 : #include "HdfEosDef.h"
23 :
24 : /* Set maximum number of HDF-EOS files to HDF limit (MAX_FILE) */
25 : #define NEOSHDF MAX_FILE
26 : static intn EHXmaxfilecount = 0;
27 : static uint8 *EHXtypeTable = NULL;
28 : static uint8 *EHXacsTable = NULL;
29 : static int32 *EHXfidTable = NULL;
30 : static int32 *EHXsdTable = NULL;
31 :
32 : /* define a macro for the string size of the utility strings and some dimension
33 : list strings. The value in previous versions of this code may not be
34 : enough in some cases. The length now is 512 which seems to be more than
35 : enough to hold larger strings. */
36 :
37 : #define UTLSTR_MAX_SIZE 512
38 : #define UTLSTRSIZE 32000
39 :
40 : #define EHIDOFFSET 524288
41 :
42 : #define HDFEOSVERSION 2.12
43 : #define HDFEOSVERSION1 "2.12"
44 : #include "HDFEOSVersion.h"
45 :
46 : #define MAX_RETRIES 10
47 :
48 : /* Function Prototypes */
49 : static intn EHreset_maxopenfiles(intn);
50 : static intn EHget_maxopenfiles(intn *, intn *);
51 : static intn EHget_numfiles(void);
52 :
53 : /*----------------------------------------------------------------------------|
54 : | BEGIN_PROLOG |
55 : | |
56 : | FUNCTION: EHopen |
57 : | |
58 : | DESCRIPTION: Opens HDF-EOS file and returns file handle |
59 : | |
60 : | |
61 : | Return Value Type Units Description |
62 : | ============ ====== ========= ===================================== |
63 : | fid int32 HDF-EOS file ID |
64 : | |
65 : | INPUTS: |
66 : | filename char Filename |
67 : | access intn HDF access code |
68 : | |
69 : | OUTPUTS: |
70 : | None |
71 : | |
72 : | NOTES: |
73 : | |
74 : | |
75 : | Date Programmer Description |
76 : | ====== ============ ================================================= |
77 : | Jun 96 Joel Gales Original Programmer |
78 : | Jul 96 Joel Gales Add file id offset EHIDOFFSET |
79 : | Aug 96 Joel Gales Add "END" statement to structural metadata |
80 : | Sep 96 Joel Gales Reverse order of Hopen and SDstart statements |
81 : | for RDWR and READ access |
82 : | Oct 96 Joel Gales Trap CREATE & RDWR (no write permission) |
83 : | access errors |
84 : | Apr 97 Joel Gales Fix problem with RDWR open when file previously |
85 : | open for READONLY access |
86 : | |
87 : | END_PROLOG |
88 : -----------------------------------------------------------------------------*/
89 : int32
90 40 : EHopen(const char *filename, intn access)
91 :
92 : {
93 : intn i; /* Loop index */
94 40 : intn status = 0; /* routine return status variable */
95 : intn dum; /* Dummy variable */
96 40 : intn curr_max = 0; /* maximum # of HDF files to open */
97 40 : intn sys_limit = 0; /* OS limit for maximum # of opened files */
98 :
99 40 : int32 HDFfid = 0; /* HDF file ID */
100 40 : int32 fid = -1; /* HDF-EOS file ID */
101 40 : int32 sdInterfaceID = 0; /* HDF SDS interface ID */
102 : int32 attrIndex; /* Structural Metadata attribute index */
103 :
104 40 : uint8 acs = 0; /* Read (0) / Write (1) access code */
105 :
106 : char *testname; /* Test filename */
107 : char errbuf[256];/* Error report buffer */
108 : char *metabuf; /* Pointer to structural metadata buffer */
109 : char hdfeosVersion[32]; /* HDFEOS version string */
110 :
111 : intn retryCount;
112 :
113 : /* Request the system allowed number of opened files */
114 : /* and increase HDFEOS file tables to the same size */
115 : /* ------------------------------------------------- */
116 40 : if (EHget_maxopenfiles(&curr_max, &sys_limit) >= 0
117 40 : && curr_max < sys_limit)
118 : {
119 40 : if (EHreset_maxopenfiles(sys_limit) < 0)
120 : {
121 0 : HEpush(DFE_ALROPEN, "EHopen", __FILE__, __LINE__);
122 0 : HEreport("Can't set maximum opened files number to \"%d\".\n", curr_max);
123 0 : return -1;
124 : }
125 : }
126 :
127 : /* Setup file interface */
128 : /* -------------------- */
129 40 : if (EHget_numfiles() < EHXmaxfilecount)
130 : {
131 :
132 : /*
133 : * Check that file has not been previously opened for write access if
134 : * current open request is not READONLY
135 : */
136 40 : if (access != DFACC_READ)
137 : {
138 : /* Loop through all files */
139 : /* ---------------------- */
140 0 : for (i = 0; i < EHXmaxfilecount; i++)
141 : {
142 : /* if entry is active file opened for write access ... */
143 : /* --------------------------------------------------- */
144 0 : if (EHXtypeTable[i] != 0 && EHXacsTable[i] == 1)
145 : {
146 : /* Get filename (testname) */
147 : /* ----------------------- */
148 0 : Hfidinquire(EHXfidTable[i], &testname, &dum, &dum);
149 :
150 :
151 : /* if same as filename then report error */
152 : /* ------------------------------------- */
153 0 : if (strcmp(testname, filename) == 0)
154 : {
155 0 : status = -1;
156 0 : fid = -1;
157 0 : HEpush(DFE_ALROPEN, "EHopen", __FILE__, __LINE__);
158 0 : HEreport("\"%s\" already open.\n", filename);
159 0 : break;
160 : }
161 : }
162 : }
163 : }
164 40 : if (status == 0)
165 : {
166 : /* Create HDF-EOS file */
167 : /* ------------------- */
168 40 : switch (access)
169 : {
170 0 : case DFACC_CREATE:
171 :
172 : /* Get SDS interface ID */
173 : /* -------------------- */
174 0 : sdInterfaceID = SDstart(filename, DFACC_CREATE);
175 :
176 : /* If SDstart successful ... */
177 : /* ------------------------- */
178 0 : if (sdInterfaceID != -1)
179 : {
180 : /* Set HDFEOS version number in file */
181 : /* --------------------------------- */
182 0 : snprintf(hdfeosVersion, sizeof(hdfeosVersion), "%s%s", "HDFEOS_V",
183 : HDFEOSVERSION1);
184 0 : SDsetattr(sdInterfaceID, "HDFEOSVersion", DFNT_CHAR8,
185 0 : (int)strlen(hdfeosVersion), hdfeosVersion);
186 :
187 :
188 : /* Get HDF file ID */
189 : /* --------------- */
190 0 : HDFfid = Hopen(filename, DFACC_RDWR, 0);
191 :
192 : /* Set open access to write */
193 : /* ------------------------ */
194 0 : acs = 1;
195 :
196 : /* Setup structural metadata */
197 : /* ------------------------- */
198 0 : metabuf = (char *) calloc(UTLSTRSIZE, 1);
199 0 : if(metabuf == NULL)
200 : {
201 0 : HEpush(DFE_NOSPACE,"EHopen", __FILE__, __LINE__);
202 0 : return(-1);
203 : }
204 :
205 0 : strcpy(metabuf, "GROUP=SwathStructure\n");
206 0 : strcat(metabuf, "END_GROUP=SwathStructure\n");
207 0 : strcat(metabuf, "GROUP=GridStructure\n");
208 0 : strcat(metabuf, "END_GROUP=GridStructure\n");
209 0 : strcat(metabuf, "GROUP=PointStructure\n");
210 0 : strcat(metabuf, "END_GROUP=PointStructure\n");
211 0 : strcat(metabuf, "END\n");
212 :
213 : /* Write Structural metadata */
214 : /* ------------------------- */
215 0 : SDsetattr(sdInterfaceID, "StructMetadata.0",
216 : DFNT_CHAR8, UTLSTRSIZE, metabuf);
217 0 : free(metabuf);
218 : } else
219 : {
220 : /* If error in SDstart then report */
221 : /* ------------------------------- */
222 0 : fid = -1;
223 0 : status = -1;
224 0 : HEpush(DFE_FNF, "EHopen", __FILE__, __LINE__);
225 0 : snprintf(errbuf, sizeof(errbuf), "%s%s%s", "\"", filename,
226 : "\" cannot be created.");
227 0 : HEreport("%s\n", errbuf);
228 : }
229 :
230 0 : break;
231 :
232 : /* Open existing HDF-EOS file for read/write access */
233 : /* ------------------------------------------------ */
234 0 : case DFACC_RDWR:
235 :
236 : /* Get HDF file ID */
237 : /* --------------- */
238 : #ifndef _PGS_OLDNFS
239 : /* The following loop around the function Hopen is intended to deal with the NFS cache
240 : problem when opening file fails with errno = 150 or 151. When NFS cache is updated,
241 : this part of change is no longer necessary. 10/18/1999 */
242 0 : retryCount = 0;
243 0 : HDFfid = -1;
244 0 : while ((HDFfid == -1) && (retryCount < MAX_RETRIES))
245 : {
246 0 : HDFfid = Hopen(filename, DFACC_RDWR, 0);
247 0 : if((HDFfid == -1) && (errno == 150 || errno == 151))
248 : {
249 0 : HEpush(DFE_FNF, "EHopen", __FILE__, __LINE__);
250 0 : snprintf(errbuf, sizeof(errbuf), "\"%s\" cannot be opened for READ/WRITE access, will retry %d times.", filename, (MAX_RETRIES - retryCount - 1));
251 0 : HEreport("%s\n", errbuf);
252 : }
253 0 : retryCount++;
254 : }
255 : #else
256 : HDFfid = Hopen(filename, DFACC_RDWR, 0);
257 : #endif
258 :
259 : /* If Hopen successful ... */
260 : /* ----------------------- */
261 0 : if (HDFfid != -1)
262 : {
263 : /* Get SDS interface ID */
264 : /* -------------------- */
265 0 : sdInterfaceID = SDstart(filename, DFACC_RDWR);
266 :
267 : /* If SDstart successful ... */
268 : /* ------------------------- */
269 0 : if (sdInterfaceID != -1)
270 : {
271 : /* Set HDFEOS version number in file */
272 : /* --------------------------------- */
273 :
274 0 : attrIndex = SDfindattr(sdInterfaceID, "HDFEOSVersion");
275 0 : if (attrIndex == -1)
276 : {
277 0 : snprintf(hdfeosVersion, sizeof(hdfeosVersion), "%s%s", "HDFEOS_V",
278 : HDFEOSVERSION1);
279 0 : SDsetattr(sdInterfaceID, "HDFEOSVersion", DFNT_CHAR8,
280 0 : (int)strlen(hdfeosVersion), hdfeosVersion);
281 : }
282 : /* Set open access to write */
283 : /* ------------------------ */
284 0 : acs = 1;
285 :
286 : /* Get structural metadata attribute ID */
287 : /* ------------------------------------ */
288 0 : attrIndex = SDfindattr(sdInterfaceID, "StructMetadata.0");
289 :
290 : /* Write structural metadata if it doesn't exist */
291 : /* --------------------------------------------- */
292 0 : if (attrIndex == -1)
293 : {
294 0 : metabuf = (char *) calloc(UTLSTRSIZE, 1);
295 0 : if(metabuf == NULL)
296 : {
297 0 : HEpush(DFE_NOSPACE,"EHopen", __FILE__, __LINE__);
298 0 : return(-1);
299 : }
300 :
301 0 : strcpy(metabuf, "GROUP=SwathStructure\n");
302 0 : strcat(metabuf, "END_GROUP=SwathStructure\n");
303 0 : strcat(metabuf, "GROUP=GridStructure\n");
304 0 : strcat(metabuf, "END_GROUP=GridStructure\n");
305 0 : strcat(metabuf, "GROUP=PointStructure\n");
306 0 : strcat(metabuf, "END_GROUP=PointStructure\n");
307 0 : strcat(metabuf, "END\n");
308 :
309 0 : SDsetattr(sdInterfaceID, "StructMetadata.0",
310 : DFNT_CHAR8, UTLSTRSIZE, metabuf);
311 0 : free(metabuf);
312 : }
313 : } else
314 : {
315 : /* If error in SDstart then report */
316 : /* ------------------------------- */
317 0 : fid = -1;
318 0 : status = -1;
319 0 : HEpush(DFE_FNF, "EHopen", __FILE__, __LINE__);
320 0 : snprintf(errbuf, sizeof(errbuf), "%s%s%s", "\"", filename,
321 : "\" cannot be opened for read/write access.");
322 0 : HEreport("%s\n", errbuf);
323 : }
324 : } else
325 : {
326 : /* If error in Hopen then report */
327 : /* ----------------------------- */
328 0 : fid = -1;
329 0 : status = -1;
330 0 : HEpush(DFE_FNF, "EHopen", __FILE__, __LINE__);
331 0 : snprintf(errbuf, sizeof(errbuf), "%s%s%s", "\"", filename,
332 : "\" cannot be opened for RDWR access.");
333 0 : HEreport("%s\n", errbuf);
334 : }
335 :
336 0 : break;
337 :
338 :
339 : /* Open existing HDF-EOS file for read-only access */
340 : /* ----------------------------------------------- */
341 40 : case DFACC_READ:
342 :
343 : /* Get HDF file ID */
344 : /* --------------- */
345 : #ifndef _PGS_OLDNFS
346 : /* The following loop around the function Hopen is intended to deal with the NFS cache
347 : problem when opening file fails with errno = 150 or 151. When NFS cache is updated,
348 : this part of change is no longer necessary. 10/18/1999 */
349 40 : retryCount = 0;
350 40 : HDFfid = -1;
351 80 : while ((HDFfid == -1) && (retryCount < MAX_RETRIES))
352 : {
353 40 : HDFfid = Hopen(filename, DFACC_READ, 0);
354 40 : if((HDFfid == -1) && (errno == 150 || errno == 151))
355 : {
356 0 : HEpush(DFE_FNF, "EHopen", __FILE__, __LINE__);
357 0 : snprintf(errbuf, sizeof(errbuf), "\"%s\" cannot be opened for READONLY access, will retry %d times.", filename, (MAX_RETRIES - retryCount - 1));
358 0 : HEreport("%s\n", errbuf);
359 : }
360 40 : retryCount++;
361 : }
362 : #else
363 : HDFfid = Hopen(filename, DFACC_READ, 0);
364 : #endif
365 :
366 : /* If file does not exist report error */
367 : /* ----------------------------------- */
368 40 : if (HDFfid == -1)
369 : {
370 0 : fid = -1;
371 0 : status = -1;
372 0 : HEpush(DFE_FNF, "EHopen", __FILE__, __LINE__);
373 0 : snprintf(errbuf, sizeof(errbuf), "\"%s\" (opened for READONLY access) does not exist.", filename);
374 0 : HEreport("%s\n", errbuf);
375 : } else
376 : {
377 : /* If file exists then get SD interface ID */
378 : /* --------------------------------------- */
379 40 : sdInterfaceID = SDstart(filename, DFACC_RDONLY);
380 :
381 : /* If SDstart successful ... */
382 : /* ------------------------- */
383 40 : if (sdInterfaceID != -1)
384 : {
385 :
386 : /* Set open access to read-only */
387 : /* ---------------------------- */
388 40 : acs = 0;
389 : } else
390 : {
391 : /* If error in SDstart then report */
392 : /* ------------------------------- */
393 0 : fid = -1;
394 0 : status = -1;
395 0 : HEpush(DFE_FNF, "EHopen", __FILE__, __LINE__);
396 0 : snprintf(errbuf, sizeof(errbuf), "%s%s%s", "\"", filename,
397 : "\" cannot be opened for read access.");
398 0 : HEreport("%s\n", errbuf);
399 : }
400 : }
401 :
402 40 : break;
403 :
404 0 : default:
405 : /* Invalid Access Code */
406 : /* ------------------- */
407 0 : fid = -1;
408 0 : status = -1;
409 0 : HEpush(DFE_BADACC, "EHopen", __FILE__, __LINE__);
410 0 : HEreport("Access Code: %d (%s).\n", access, filename);
411 : }
412 :
413 0 : }
414 : } else
415 : {
416 : /* Too many files opened */
417 : /* --------------------- */
418 0 : status = -1;
419 0 : fid = -1;
420 0 : HEpush(DFE_TOOMANY, "EHopen", __FILE__, __LINE__);
421 0 : HEreport("No more than %d files may be open simultaneously (%s).\n",
422 : EHXmaxfilecount, filename);
423 : }
424 :
425 :
426 :
427 :
428 40 : if (status == 0)
429 : {
430 : /* Initialize Vgroup Access */
431 : /* ------------------------ */
432 40 : Vstart(HDFfid);
433 :
434 :
435 : /* Assign HDFEOS fid # & Load HDF fid and sdInterfaceID tables */
436 : /* ----------------------------------------------------------- */
437 40 : for (i = 0; i < EHXmaxfilecount; i++)
438 : {
439 40 : if (EHXtypeTable[i] == 0)
440 : {
441 40 : fid = i + EHIDOFFSET;
442 40 : EHXacsTable[i] = acs;
443 40 : EHXtypeTable[i] = 1;
444 40 : EHXfidTable[i] = HDFfid;
445 40 : EHXsdTable[i] = sdInterfaceID;
446 40 : break;
447 : }
448 : }
449 :
450 : }
451 40 : return (fid);
452 : }
453 :
454 :
455 :
456 :
457 : /*----------------------------------------------------------------------------|
458 : | BEGIN_PROLOG |
459 : | |
460 : | FUNCTION: EHchkfid |
461 : | |
462 : | DESCRIPTION: Checks for valid file id and returns HDF file ID and |
463 : | SD interface ID |
464 : | |
465 : | |
466 : | Return Value Type Units Description |
467 : | ============ ====== ========= ===================================== |
468 : | status intn return status (0) SUCCEED, (-1) FAIL |
469 : | |
470 : | INPUTS: |
471 : | fid int32 HDF-EOS file ID |
472 : | name char Structure name |
473 : | |
474 : | OUTPUTS: |
475 : | HDFfid int32 HDF File ID |
476 : | sdInterfaceID int32 SDS interface ID |
477 : | access uint8 access code |
478 : | |
479 : | NOTES: |
480 : | |
481 : | |
482 : | Date Programmer Description |
483 : | ====== ============ ================================================= |
484 : | Jun 96 Joel Gales Original Programmer |
485 : | Jul 96 Joel Gales set status=-1 if failure |
486 : | Jul 96 Joel Gales Add file id offset EHIDOFFSET |
487 : | |
488 : | END_PROLOG |
489 : -----------------------------------------------------------------------------*/
490 : intn
491 300 : EHchkfid(int32 fid, const char *name, int32 * HDFfid, int32 * sdInterfaceID,
492 : uint8 * access)
493 :
494 : {
495 300 : intn status = 0; /* routine return status variable */
496 : intn fid0; /* HDFEOS file ID - Offset */
497 :
498 :
499 : /* Check for valid HDFEOS file ID range */
500 : /* ------------------------------------ */
501 300 : if (fid < EHIDOFFSET || fid > EHXmaxfilecount + EHIDOFFSET)
502 : {
503 0 : status = -1;
504 0 : HEpush(DFE_RANGE, "EHchkfid", __FILE__, __LINE__);
505 0 : HEreport("Invalid file id: %d. ID must be >= %d and < %d (%s).\n",
506 : fid, EHIDOFFSET, EHXmaxfilecount + EHIDOFFSET, name);
507 : } else
508 : {
509 : /* Compute "reduced" file ID */
510 : /* ------------------------- */
511 300 : fid0 = fid % EHIDOFFSET;
512 :
513 :
514 : /* Check that HDFEOS file ID is active */
515 : /* ----------------------------------- */
516 300 : if (EHXtypeTable[fid0] == 0)
517 : {
518 0 : status = -1;
519 0 : HEpush(DFE_GENAPP, "EHchkfid", __FILE__, __LINE__);
520 0 : HEreport("File id %d not active (%s).\n", fid, name);
521 : } else
522 : {
523 : /*
524 : * Get HDF file ID, SD interface ID and file access from external
525 : * arrays
526 : */
527 300 : *HDFfid = EHXfidTable[fid0];
528 300 : *sdInterfaceID = EHXsdTable[fid0];
529 300 : *access = EHXacsTable[fid0];
530 : }
531 : }
532 :
533 300 : return (status);
534 : }
535 :
536 :
537 :
538 :
539 : /*----------------------------------------------------------------------------|
540 : | BEGIN_PROLOG |
541 : | |
542 : | FUNCTION: EHidinfo |
543 : | |
544 : | DESCRIPTION: Gets Hopen and SD interface IDs from HDF-EOS id |
545 : | |
546 : | |
547 : | Return Value Type Units Description |
548 : | ============ ====== ========= ===================================== |
549 : | status intn return status (0) SUCCEED, (-1) FAIL |
550 : | |
551 : | INPUTS: |
552 : | fid int32 HDF-EOS file ID |
553 : | |
554 : | OUTPUTS: |
555 : | HDFfid int32 HDF File ID |
556 : | sdInterfaceID int32 SDS interface ID |
557 : | |
558 : | NOTES: |
559 : | |
560 : | |
561 : | Date Programmer Description |
562 : | ====== ============ ================================================= |
563 : | Jul 96 Joel Gales Original Programmer |
564 : | |
565 : | END_PROLOG |
566 : -----------------------------------------------------------------------------*/
567 : intn
568 1 : EHidinfo(int32 fid, int32 * HDFfid, int32 * sdInterfaceID)
569 :
570 : {
571 1 : intn status = 0; /* routine return status variable */
572 : uint8 dum; /* Dummy variable */
573 :
574 : /* Call EHchkfid to get HDF and SD interface IDs */
575 : /* --------------------------------------------- */
576 1 : status = EHchkfid(fid, "EHidinfo", HDFfid, sdInterfaceID, &dum);
577 :
578 1 : return (status);
579 : }
580 :
581 :
582 : /*----------------------------------------------------------------------------|
583 : | BEGIN_PROLOG |
584 : | |
585 : | FUNCTION: EHgetversion |
586 : | |
587 : | DESCRIPTION: Returns HDF-EOS version string |
588 : | |
589 : | |
590 : | Return Value Type Units Description |
591 : | ============ ====== ========= ===================================== |
592 : | status intn return status (0) SUCCEED, (-1) FAIL |
593 : | |
594 : | INPUTS: |
595 : | fid int32 HDF-EOS file id |
596 : | |
597 : | OUTPUTS: |
598 : | version char HDF-EOS version string |
599 : | |
600 : | NOTES: |
601 : | |
602 : | |
603 : | Date Programmer Description |
604 : | ====== ============ ================================================= |
605 : | Mar 97 Joel Gales Original Programmer |
606 : | |
607 : | END_PROLOG |
608 : -----------------------------------------------------------------------------*/
609 : intn
610 0 : EHgetversion(int32 fid, char *version)
611 : {
612 0 : intn status = 0; /* routine return status variable */
613 :
614 : uint8 access; /* Access code */
615 : int32 dum; /* Dummy variable */
616 0 : int32 sdInterfaceID = 0; /* HDF SDS interface ID */
617 : int32 attrIndex; /* HDFEOS version attribute index */
618 : int32 count; /* Version string size */
619 :
620 : char attrname[16]; /* Attribute name */
621 :
622 :
623 : /* Get SDS interface ID */
624 : /* -------------------- */
625 0 : status = EHchkfid(fid, "EHgetversion", &dum, &sdInterfaceID, &access);
626 0 : if (status < 0)
627 0 : return -1;
628 :
629 : /* Get attribute index number */
630 : /* -------------------------- */
631 0 : attrIndex = SDfindattr(sdInterfaceID, "HDFEOSVersion");
632 :
633 : /* No such attribute */
634 : /* ----------------- */
635 0 : if (attrIndex < 0)
636 0 : return (-1);
637 :
638 : /* Get attribute size */
639 : /* ------------------ */
640 0 : status = SDattrinfo(sdInterfaceID, attrIndex, attrname, &dum, &count);
641 :
642 : /* Check return status */
643 : /* ------------------- */
644 0 : if (status < 0)
645 0 : return (-1);
646 :
647 : /* Read version attribute */
648 : /* ---------------------- */
649 0 : status = SDreadattr(sdInterfaceID, attrIndex, (VOIDP) version);
650 :
651 :
652 : /* Place string terminator on version string */
653 : /* ----------------------------------------- */
654 0 : version[count] = 0;
655 :
656 :
657 0 : return (status);
658 : }
659 :
660 :
661 :
662 :
663 : /*----------------------------------------------------------------------------|
664 : | BEGIN_PROLOG |
665 : | |
666 : | FUNCTION: EHconvAng |
667 : | |
668 : | DESCRIPTION: Angle conversion Utility |
669 : | |
670 : | |
671 : | Return Value Type Units Description |
672 : | ============ ====== ========= ===================================== |
673 : | outAngle float64 Output Angle value |
674 : | |
675 : | INPUTS: |
676 : | inAngle float64 Input Angle value |
677 : | code intn Conversion code |
678 : ! HDFE_RAD_DEG (0) |
679 : | HDFE_DEG_RAD (1) |
680 : | HDFE_DMS_DEG (2) |
681 : | HDFE_DEG_DMS (3) |
682 : | HDFE_RAD_DMS (4) |
683 : | HDFE_DMS_RAD (5) |
684 : | |
685 : | OUTPUTS: |
686 : | None |
687 : | |
688 : | NOTES: |
689 : | |
690 : | |
691 : | Date Programmer Description |
692 : | ====== ============ ================================================= |
693 : | Jun 96 Joel Gales Original Programmer |
694 : | Feb 97 Joel Gales Correct "60" min & "60" sec in _DMS conversion |
695 : | |
696 : | END_PROLOG |
697 : -----------------------------------------------------------------------------*/
698 : float64
699 0 : EHconvAng(float64 inAngle, intn code)
700 : {
701 : #define RADIANS_TO_DEGREES 180. / 3.14159265358979324
702 : #define DEGREES_TO_RADIANS 3.14159265358979324 / 180.
703 :
704 : int32 min; /* Truncated Minutes */
705 : int32 deg; /* Truncated Degrees */
706 :
707 : float64 sec; /* Seconds */
708 0 : float64 outAngle = 0.0; /* Angle in desired units */
709 :
710 0 : switch (code)
711 : {
712 :
713 : /* Convert radians to degrees */
714 : /* -------------------------- */
715 0 : case HDFE_RAD_DEG:
716 0 : outAngle = inAngle * RADIANS_TO_DEGREES;
717 0 : break;
718 :
719 :
720 : /* Convert degrees to radians */
721 : /* -------------------------- */
722 0 : case HDFE_DEG_RAD:
723 0 : outAngle = inAngle * DEGREES_TO_RADIANS;
724 0 : break;
725 :
726 :
727 : /* Convert packed degrees to degrees */
728 : /* --------------------------------- */
729 0 : case HDFE_DMS_DEG:
730 0 : deg = (int32)(inAngle / 1000000);
731 0 : min = (int32)((inAngle - deg * 1000000) / 1000);
732 0 : sec = (inAngle - deg * 1000000 - min * 1000);
733 0 : outAngle = deg + min / 60.0 + sec / 3600.0;
734 0 : break;
735 :
736 :
737 : /* Convert degrees to packed degrees */
738 : /* --------------------------------- */
739 0 : case HDFE_DEG_DMS:
740 0 : deg = (int32)(inAngle);
741 0 : min = (int32)((inAngle - deg) * 60);
742 0 : sec = (inAngle - deg - min / 60.0) * 3600;
743 :
744 0 : if ((intn) sec == 60)
745 : {
746 0 : sec = sec - 60;
747 0 : min = min + 1;
748 : }
749 0 : if (min == 60)
750 : {
751 0 : min = min - 60;
752 0 : deg = deg + 1;
753 : }
754 0 : outAngle = deg * 1000000 + min * 1000 + sec;
755 0 : break;
756 :
757 :
758 : /* Convert radians to packed degrees */
759 : /* --------------------------------- */
760 0 : case HDFE_RAD_DMS:
761 0 : inAngle = inAngle * RADIANS_TO_DEGREES;
762 0 : deg = (int32)(inAngle);
763 0 : min = (int32)((inAngle - deg) * 60);
764 0 : sec = (inAngle - deg - min / 60.0) * 3600;
765 :
766 0 : if ((intn) sec == 60)
767 : {
768 0 : sec = sec - 60;
769 0 : min = min + 1;
770 : }
771 0 : if (min == 60)
772 : {
773 0 : min = min - 60;
774 0 : deg = deg + 1;
775 : }
776 0 : outAngle = deg * 1000000 + min * 1000 + sec;
777 0 : break;
778 :
779 :
780 : /* Convert packed degrees to radians */
781 : /* --------------------------------- */
782 0 : case HDFE_DMS_RAD:
783 0 : deg = (int32)(inAngle / 1000000);
784 0 : min = (int32)((inAngle - deg * 1000000) / 1000);
785 0 : sec = (inAngle - deg * 1000000 - min * 1000);
786 0 : outAngle = deg + min / 60.0 + sec / 3600.0;
787 0 : outAngle = outAngle * DEGREES_TO_RADIANS;
788 0 : break;
789 : }
790 0 : return (outAngle);
791 : }
792 :
793 : #undef TO_DEGREES
794 : #undef TO_RADIANS
795 :
796 :
797 : /*----------------------------------------------------------------------------|
798 : | BEGIN_PROLOG |
799 : | |
800 : | FUNCTION: EHparsestr |
801 : | |
802 : | DESCRIPTION: String Parser Utility |
803 : | |
804 : | |
805 : | Return Value Type Units Description |
806 : | ============ ====== ========= ===================================== |
807 : | count int32 Number of string entries |
808 : | |
809 : | INPUTS: |
810 : | instring const char Input string |
811 : | delim const char string delimiter |
812 : | |
813 : | OUTPUTS: |
814 : | pntr char * Pointer array to beginning of each |
815 : | string entry |
816 : | len int32 Array of string entry lengths |
817 : | |
818 : | NOTES: |
819 : | |
820 : | |
821 : | Date Programmer Description |
822 : | ====== ============ ================================================= |
823 : | Jun 96 Joel Gales Original Programmer |
824 : | Aug 96 Joel Gales NULL pointer array returns count only |
825 : | |
826 : | END_PROLOG |
827 : -----------------------------------------------------------------------------*/
828 : int32
829 128 : EHparsestr(const char *instring, const char delim,
830 : char *pntr[], size_t pntrsize,
831 : int32 len[], size_t lensize)
832 : {
833 : size_t i; /* Loop index */
834 128 : size_t prevDelimPos = 0; /* Previous delimiter position */
835 : size_t count; /* Number of elements in string list */
836 : size_t slen; /* String length */
837 :
838 : char *delimitor; /* Pointer to delimiter */
839 :
840 :
841 : /* Get length of input string list & Point to first delimiter */
842 : /* ---------------------------------------------------------- */
843 128 : slen = (int)strlen(instring);
844 128 : delimitor = strchr(instring, delim);
845 :
846 : /* If NULL string set count to zero otherwise set to 1 */
847 : /* --------------------------------------------------- */
848 128 : count = (slen == 0) ? 0 : 1;
849 :
850 :
851 : /* if string pointers are requested set first one to beginning of string */
852 : /* --------------------------------------------------------------------- */
853 128 : if (pntr != NULL && pntrsize)
854 : {
855 120 : pntr[0] = (char *)instring;
856 : }
857 : /* If delimiter not found ... */
858 : /* ---------------------------- */
859 128 : if (delimitor == NULL)
860 : {
861 : /* if string length requested then set to input string length */
862 : /* ---------------------------------------------------------- */
863 17 : if (len != NULL && lensize)
864 : {
865 9 : len[0] = (int32)slen;
866 : }
867 : } else
868 : /* Delimiters Found */
869 : /* ---------------- */
870 : {
871 : /* Loop through all characters in string */
872 : /* ------------------------------------- */
873 1673 : for (i = 1; i < slen; i++)
874 : {
875 : /* If character is a delimiter ... */
876 : /* ------------------------------- */
877 1562 : if (instring[i] == delim)
878 : {
879 :
880 : /* If string pointer requested */
881 : /* --------------------------- */
882 111 : if (pntr != NULL)
883 : {
884 : /* if requested then compute string length of entry */
885 : /* ------------------------------------------------ */
886 111 : if (len != NULL)
887 : {
888 111 : if (count - 1 >= lensize)
889 0 : return -1;
890 111 : len[count - 1] = (int32)(i - prevDelimPos);
891 : }
892 : /* Point to beginning of string entry */
893 : /* ---------------------------------- */
894 111 : if (count >= pntrsize)
895 0 : return -1;
896 111 : pntr[count] = (char *)instring + i + 1;
897 : }
898 : /* Reset previous delimiter position and increment counter */
899 : /* ------------------------------------------------------- */
900 111 : prevDelimPos = i + 1;
901 111 : count++;
902 : }
903 : }
904 :
905 : /* Compute string length of last entry */
906 : /* ----------------------------------- */
907 111 : if (pntr != NULL && len != NULL)
908 : {
909 111 : if (count == 0 || (size_t)(count - 1) >= lensize)
910 0 : return -1;
911 111 : len[count - 1] = (int32)(i - prevDelimPos);
912 : }
913 : }
914 :
915 128 : return (int32)(count);
916 : }
917 :
918 :
919 :
920 :
921 : /*----------------------------------------------------------------------------|
922 : | BEGIN_PROLOG |
923 : | |
924 : | FUNCTION: EHstrwithin |
925 : | |
926 : | DESCRIPTION: Searches for string within target string |
927 : | |
928 : | |
929 : | Return Value Type Units Description |
930 : | ============ ====== ========= ===================================== |
931 : | indx int32 Element index (0 - based) |
932 : | |
933 : | INPUTS: |
934 : | target const char Target string |
935 : | search const char Search string |
936 : | delim const char Delimiter |
937 : | |
938 : | OUTPUTS: |
939 : | None |
940 : | |
941 : | NOTES: |
942 : | |
943 : | |
944 : | Date Programmer Description |
945 : | ====== ============ ================================================= |
946 : | Jun 96 Joel Gales Original Programmer |
947 : | Jan 97 Joel Gales Change ptr & slen to dynamic arrays |
948 : | |
949 : | END_PROLOG |
950 : -----------------------------------------------------------------------------*/
951 : int32
952 8 : EHstrwithin(const char *target, const char *search, const char delim)
953 : {
954 8 : intn found = 0; /* Target string found flag */
955 :
956 : int32 indx; /* Loop index */
957 : int32 nentries; /* Number of entries in search string */
958 : int32 *slen; /* Pointer to string length array */
959 :
960 : char **ptr; /* Pointer to string pointer array */
961 : char buffer[128];/* Buffer to hold "test" string entry */
962 :
963 :
964 : /* Count number of entries in search string list */
965 : /* --------------------------------------------- */
966 8 : nentries = EHparsestr(search, delim, NULL, 0, NULL, 0);
967 8 : if (nentries == 0)
968 8 : return -1;
969 :
970 :
971 : /* Allocate string pointer and length arrays */
972 : /* ----------------------------------------- */
973 0 : ptr = (char **) calloc(nentries, sizeof(char *));
974 0 : if(ptr == NULL)
975 : {
976 0 : HEpush(DFE_NOSPACE,"EHstrwithin", __FILE__, __LINE__);
977 0 : return(-1);
978 : }
979 0 : slen = (int32 *) calloc(nentries, sizeof(int32));
980 0 : if(slen == NULL)
981 : {
982 0 : HEpush(DFE_NOSPACE,"EHstrwithin", __FILE__, __LINE__);
983 0 : free(ptr);
984 0 : return(-1);
985 : }
986 :
987 :
988 : /* Parse search string */
989 : /* ------------------- */
990 0 : nentries = EHparsestr(search, delim, ptr, nentries, slen, nentries);
991 0 : if (nentries < 0)
992 : {
993 0 : free(ptr);
994 0 : free(slen);
995 0 : HEpush(DFE_NOSPACE,"EHstrwithin", __FILE__, __LINE__);
996 0 : return(-1);
997 : }
998 :
999 :
1000 : /* Loop through all elements in search string list */
1001 : /* ----------------------------------------------- */
1002 0 : for (indx = 0; indx < nentries; indx++)
1003 : {
1004 : /* Copy string entry into buffer */
1005 : /* ----------------------------- */
1006 0 : memcpy(buffer, ptr[indx], slen[indx]);
1007 0 : buffer[slen[indx]] = 0;
1008 :
1009 :
1010 : /* Compare target string with string entry */
1011 : /* --------------------------------------- */
1012 0 : if (strcmp(target, buffer) == 0)
1013 : {
1014 0 : found = 1;
1015 0 : break;
1016 : }
1017 : }
1018 :
1019 : /* If not found set return to -1 */
1020 : /* ----------------------------- */
1021 0 : if (found == 0)
1022 : {
1023 0 : indx = -1;
1024 : }
1025 0 : free(slen);
1026 0 : free(ptr);
1027 :
1028 0 : return (indx);
1029 : }
1030 :
1031 :
1032 :
1033 :
1034 :
1035 : /*----------------------------------------------------------------------------|
1036 : | BEGIN_PROLOG |
1037 : | |
1038 : | FUNCTION: EHloadliststr |
1039 : | |
1040 : | DESCRIPTION: Builds list string from string array |
1041 : | |
1042 : | |
1043 : | Return Value Type Units Description |
1044 : | ============ ====== ========= ===================================== |
1045 : | status intn return status (0) SUCCEED, (-1) FAIL |
1046 : | |
1047 : | INPUTS: |
1048 : | ptr char String pointer array |
1049 : | nentries int32 Number of string array elements |
1050 : | delim char Delimiter |
1051 : | |
1052 : | OUTPUTS: |
1053 : | liststr char Output list string |
1054 : | |
1055 : | NOTES: |
1056 : | |
1057 : | |
1058 : | Date Programmer Description |
1059 : | ====== ============ ================================================= |
1060 : | Jun 96 Joel Gales Original Programmer |
1061 : | |
1062 : | END_PROLOG |
1063 : -----------------------------------------------------------------------------*/
1064 : intn
1065 0 : EHloadliststr(char *ptr[], int32 nentries, char *liststr, char delim)
1066 : {
1067 0 : intn status = 0; /* routine return status variable */
1068 :
1069 : int32 i; /* Loop index */
1070 : int32 slen; /* String entry length */
1071 0 : int32 off = 0; /* Position of next entry along string list */
1072 : char dstr[2]; /* string version of input variable "delim" */
1073 :
1074 0 : dstr[0] = delim;
1075 0 : dstr[1] = '\0';
1076 :
1077 :
1078 : /* Loop through all entries in string array */
1079 : /* ---------------------------------------- */
1080 0 : for (i = 0; i < nentries; i++)
1081 : {
1082 : /* Get string length of string array entry */
1083 : /* --------------------------------------- */
1084 0 : slen = (int)strlen(ptr[i]);
1085 :
1086 :
1087 : /* Copy string entry to string list */
1088 : /* -------------------------------- */
1089 0 : memcpy(liststr + off, ptr[i], slen + 1);
1090 :
1091 :
1092 : /* Concatenate with delimiter */
1093 : /* -------------------------- */
1094 0 : if (i != nentries - 1)
1095 : {
1096 0 : strcat(liststr, dstr);
1097 : }
1098 : /* Get position of next entry for string list */
1099 : /* ------------------------------------------ */
1100 0 : off += slen + 1;
1101 : }
1102 :
1103 0 : return (status);
1104 : }
1105 :
1106 :
1107 :
1108 :
1109 :
1110 : /*----------------------------------------------------------------------------|
1111 : | BEGIN_PROLOG |
1112 : | |
1113 : | FUNCTION: EHgetid |
1114 : | |
1115 : | DESCRIPTION: Get Vgroup/Vdata ID from name |
1116 : | |
1117 : | |
1118 : | Return Value Type Units Description |
1119 : | ============ ====== ========= ===================================== |
1120 : | outID int32 Output ID |
1121 : | |
1122 : | INPUTS: |
1123 : | fid int32 HDF-EOS file ID |
1124 : | vgid int32 Vgroup ID |
1125 : | objectname const char object name |
1126 : | code intn object code (0 - Vgroup, 1 - Vdata) |
1127 : | access const char access ("w/r") |
1128 : | |
1129 : | |
1130 : | OUTPUTS: |
1131 : | None |
1132 : | |
1133 : | NOTES: |
1134 : | |
1135 : | |
1136 : | Date Programmer Description |
1137 : | ====== ============ ================================================= |
1138 : | Jun 96 Joel Gales Original Programmer |
1139 : | |
1140 : | END_PROLOG |
1141 : -----------------------------------------------------------------------------*/
1142 : int32
1143 1 : EHgetid(int32 fid, int32 vgid, const char *objectname, intn code,
1144 : const char *access)
1145 : {
1146 : intn i; /* Loop index */
1147 :
1148 : int32 nObjects; /* # of objects in Vgroup */
1149 : int32 *tags; /* Pnt to Vgroup object tags array */
1150 : int32 *refs; /* Pnt to Vgroup object refs array */
1151 : int32 id; /* Object ID */
1152 1 : int32 outID = -1; /* Desired object ID */
1153 :
1154 : char name[128]; /* Object name */
1155 :
1156 :
1157 : /* Get Number of objects */
1158 : /* --------------------- */
1159 1 : nObjects = Vntagrefs(vgid);
1160 :
1161 : /* If objects exist ... */
1162 : /* -------------------- */
1163 1 : if (nObjects != 0)
1164 : {
1165 :
1166 : /* Get tags and references of objects */
1167 : /* ---------------------------------- */
1168 0 : tags = (int32 *) malloc(sizeof(int32) * nObjects);
1169 0 : if(tags == NULL)
1170 : {
1171 0 : HEpush(DFE_NOSPACE,"EHgetid", __FILE__, __LINE__);
1172 0 : return(-1);
1173 : }
1174 0 : refs = (int32 *) malloc(sizeof(int32) * nObjects);
1175 0 : if(refs == NULL)
1176 : {
1177 0 : HEpush(DFE_NOSPACE,"EHgetid", __FILE__, __LINE__);
1178 0 : free(tags);
1179 0 : return(-1);
1180 : }
1181 :
1182 0 : Vgettagrefs(vgid, tags, refs, nObjects);
1183 :
1184 :
1185 : /* Vgroup ID Section */
1186 : /* ----------------- */
1187 0 : if (code == 0)
1188 : {
1189 : /* Loop through objects */
1190 : /* -------------------- */
1191 0 : for (i = 0; i < nObjects; i++)
1192 : {
1193 :
1194 : /* If object is Vgroup ... */
1195 : /* ----------------------- */
1196 0 : if (*(tags + i) == DFTAG_VG)
1197 : {
1198 :
1199 : /* Get ID and name */
1200 : /* --------------- */
1201 0 : id = Vattach(fid, *(refs + i), access);
1202 0 : VgetnameSafe(id, name, sizeof(name));
1203 :
1204 : /* If name equals desired object name get ID */
1205 : /* ----------------------------------------- */
1206 0 : if (strcmp(name, objectname) == 0)
1207 : {
1208 0 : outID = id;
1209 0 : break;
1210 : }
1211 : /* If not desired object then detach */
1212 : /* --------------------------------- */
1213 0 : Vdetach(id);
1214 : }
1215 : }
1216 0 : } else if (code == 1)
1217 : {
1218 :
1219 : /* Loop through objects */
1220 : /* -------------------- */
1221 0 : for (i = 0; i < nObjects; i++)
1222 : {
1223 :
1224 : /* If object is Vdata ... */
1225 : /* ---------------------- */
1226 0 : if (*(tags + i) == DFTAG_VH)
1227 : {
1228 :
1229 : /* Get ID and name */
1230 : /* --------------- */
1231 0 : id = VSattach(fid, *(refs + i), access);
1232 0 : VSgetname(id, name);
1233 :
1234 : /* If name equals desired object name get ID */
1235 : /* ----------------------------------------- */
1236 0 : if (EHstrwithin(objectname, name, ',') != -1)
1237 : {
1238 0 : outID = id;
1239 0 : break;
1240 : }
1241 : /* If not desired object then detach */
1242 : /* --------------------------------- */
1243 0 : VSdetach(id);
1244 : }
1245 : }
1246 : }
1247 0 : free(tags);
1248 0 : free(refs);
1249 : }
1250 1 : return (outID);
1251 : }
1252 :
1253 :
1254 :
1255 :
1256 :
1257 : /*----------------------------------------------------------------------------|
1258 : | BEGIN_PROLOG |
1259 : | |
1260 : | FUNCTION: EHrevflds |
1261 : | |
1262 : | DESCRIPTION: Reverses elements in a string list |
1263 : | |
1264 : | |
1265 : | Return Value Type Units Description |
1266 : | ============ ====== ========= ===================================== |
1267 : | status intn return status (0) SUCCEED, (-1) FAIL |
1268 : | |
1269 : | INPUTS: |
1270 : | dimlist char Original dimension list |
1271 : | |
1272 : | OUTPUTS: |
1273 : | revdimlist char Reversed dimension list |
1274 : | |
1275 : | NOTES: |
1276 : | |
1277 : | |
1278 : | Date Programmer Description |
1279 : | ====== ============ ================================================= |
1280 : | Jun 96 Joel Gales Original Programmer |
1281 : | |
1282 : | END_PROLOG |
1283 : -----------------------------------------------------------------------------*/
1284 : intn
1285 0 : EHrevflds(const char *dimlist, char *revdimlist)
1286 : {
1287 0 : intn status = 0; /* routine return status variable */
1288 :
1289 : int32 indx; /* Loop index */
1290 : int32 nentries; /* Number of entries in search string */
1291 : int32 *slen; /* Pointer to string length array */
1292 :
1293 : char **ptr; /* Pointer to string pointer array */
1294 : char *tempPtr; /* Temporary string pointer */
1295 : char *tempdimlist;/* Temporary dimension list */
1296 :
1297 :
1298 : /* Copy dimlist into temp dimlist */
1299 : /* ------------------------------ */
1300 0 : tempdimlist = (char *) malloc(strlen(dimlist) + 1);
1301 0 : if(tempdimlist == NULL)
1302 : {
1303 0 : HEpush(DFE_NOSPACE,"EHrevflds", __FILE__, __LINE__);
1304 0 : return(-1);
1305 : }
1306 0 : strcpy(tempdimlist, dimlist);
1307 :
1308 :
1309 : /* Count number of entries in search string list */
1310 : /* --------------------------------------------- */
1311 0 : nentries = EHparsestr(tempdimlist, ',', NULL, 0, NULL, 0);
1312 :
1313 :
1314 : /* Allocate string pointer and length arrays */
1315 : /* ----------------------------------------- */
1316 0 : ptr = (char **) calloc(nentries, sizeof(char *));
1317 0 : if(ptr == NULL)
1318 : {
1319 0 : HEpush(DFE_NOSPACE,"EHrevflds", __FILE__, __LINE__);
1320 0 : free(tempdimlist);
1321 0 : return(-1);
1322 : }
1323 0 : slen = (int32 *) calloc(nentries, sizeof(int32));
1324 0 : if(slen == NULL)
1325 : {
1326 0 : HEpush(DFE_NOSPACE,"EHrevflds", __FILE__, __LINE__);
1327 0 : free(ptr);
1328 0 : free(tempdimlist);
1329 0 : return(-1);
1330 : }
1331 :
1332 :
1333 : /* Parse search string */
1334 : /* ------------------- */
1335 0 : nentries = EHparsestr(tempdimlist, ',', ptr, nentries, slen, nentries);
1336 0 : if (nentries < 0)
1337 : {
1338 0 : free(ptr);
1339 0 : free(slen);
1340 0 : free(tempdimlist);
1341 0 : HEpush(DFE_NOSPACE, "EHrevflds", __FILE__, __LINE__);
1342 0 : return(-1);
1343 : }
1344 :
1345 : /* Reverse entries in string pointer array */
1346 : /* --------------------------------------- */
1347 0 : for (indx = 0; indx < nentries / 2; indx++)
1348 : {
1349 0 : tempPtr = ptr[indx];
1350 0 : ptr[indx] = ptr[nentries - 1 - indx];
1351 0 : ptr[nentries - 1 - indx] = tempPtr;
1352 : }
1353 :
1354 :
1355 : /* Replace comma delimiters by nulls */
1356 : /* --------------------------------- */
1357 0 : for (indx = 0; indx < nentries - 1; indx++)
1358 : {
1359 0 : *(ptr[indx] - 1) = 0;
1360 : }
1361 :
1362 :
1363 : /* Build new string list */
1364 : /* --------------------- */
1365 0 : status = EHloadliststr(ptr, nentries, revdimlist, ',');
1366 :
1367 :
1368 0 : free(slen);
1369 0 : free(ptr);
1370 0 : free(tempdimlist);
1371 :
1372 0 : return (status);
1373 : }
1374 :
1375 : /*----------------------------------------------------------------------------|
1376 : | BEGIN_PROLOG |
1377 : | |
1378 : | FUNCTION: EHgetmetavalue |
1379 : | |
1380 : | DESCRIPTION: Returns metadata value |
1381 : | |
1382 : | |
1383 : | Return Value Type Units Description |
1384 : | ============ ====== ========= ===================================== |
1385 : | status intn return status (0) SUCCEED, (-1) FAIL |
1386 : | |
1387 : | INPUTS: |
1388 : | metaptrs char Begin and end of metadata section |
1389 : | parameter char parameter to access |
1390 : | |
1391 : | OUTPUTS: |
1392 : | metaptr char Ptr to (updated) beginning of metadata |
1393 : | retstr char return string containing value |
1394 : | |
1395 : | NOTES: |
1396 : | |
1397 : | |
1398 : | Date Programmer Description |
1399 : | ====== ============ ================================================= |
1400 : | Jun 96 Joel Gales Original Programmer |
1401 : | Jan 97 Joel Gales Check string pointer against end of meta section |
1402 : | |
1403 : | END_PROLOG |
1404 : -----------------------------------------------------------------------------*/
1405 : intn
1406 942 : EHgetmetavalue(char *metaptrs[], const char *parameter, char *retstr)
1407 : {
1408 942 : intn status = 0; /* routine return status variable */
1409 :
1410 : int32 slen; /* String length */
1411 : char *newline; /* Position of new line character */
1412 : char *sptr; /* string pointer within metadata */
1413 :
1414 :
1415 : /* Get string length of parameter string + 1 */
1416 : /* ----------------------------------------- */
1417 942 : slen = (int)strlen(parameter) + 1;
1418 :
1419 :
1420 : /* Build search string (parameter string + "=") */
1421 : /* -------------------------------------------- */
1422 942 : strcpy(retstr, parameter);
1423 942 : strcat(retstr, "=");
1424 :
1425 :
1426 : /* Search for string within metadata (beginning at metaptrs[0]) */
1427 : /* ------------------------------------------------------------ */
1428 942 : sptr = strstr(metaptrs[0], retstr);
1429 :
1430 :
1431 : /* If string found within desired section ... */
1432 : /* ------------------------------------------ */
1433 942 : if (sptr != NULL && sptr < metaptrs[1])
1434 : {
1435 : /* Store position of string within metadata */
1436 : /* ---------------------------------------- */
1437 942 : metaptrs[0] = sptr;
1438 :
1439 : /* Find newline "\n" character */
1440 : /* --------------------------- */
1441 942 : newline = strchr(metaptrs[0], '\n');
1442 942 : if (newline == NULL)
1443 : {
1444 0 : retstr[0] = 0;
1445 0 : return -1;
1446 : }
1447 :
1448 : /* Copy from "=" to "\n" (exclusive) into return string */
1449 : /* ---------------------------------------------------- */
1450 942 : memcpy(retstr, metaptrs[0] + slen, newline - metaptrs[0] - slen);
1451 :
1452 : /* Terminate return string with null */
1453 : /* --------------------------------- */
1454 942 : retstr[newline - metaptrs[0] - slen] = 0;
1455 : } else
1456 : {
1457 : /*
1458 : * if parameter string not found within section, null return string
1459 : * and set status to -1.
1460 : */
1461 0 : retstr[0] = 0;
1462 0 : status = -1;
1463 : }
1464 :
1465 942 : return (status);
1466 : }
1467 :
1468 :
1469 :
1470 :
1471 : /*----------------------------------------------------------------------------|
1472 : | BEGIN_PROLOG |
1473 : | |
1474 : | FUNCTION: EHmetagroup |
1475 : | |
1476 : | DESCRIPTION: Returns pointers to beginning and end of metadata group |
1477 : | |
1478 : | |
1479 : | Return Value Type Units Description |
1480 : | ============ ====== ========= ===================================== |
1481 : | metabuf char Pointer to HDF-EOS object in metadata |
1482 : | |
1483 : | INPUTS: |
1484 : | sdInterfaceID int32 SDS interface ID |
1485 : | structname char HDF-EOS structure name |
1486 : | structcode char Structure code ("s/g/p") |
1487 : | groupname char Metadata group name |
1488 : | |
1489 : | OUTPUTS: |
1490 : | metaptrs char pointers to begin and end of metadata |
1491 : | |
1492 : | NOTES: |
1493 : | |
1494 : | |
1495 : | Date Programmer Description |
1496 : | ====== ============ ================================================= |
1497 : | Jun 96 Joel Gales Original Programmer |
1498 : | Aug 96 Joel Gales Make metadata ODL compliant |
1499 : | |
1500 : | END_PROLOG |
1501 : -----------------------------------------------------------------------------*/
1502 : char *
1503 245 : EHmetagroup(int32 sdInterfaceID, const char *structname, const char *structcode,
1504 : const char *groupname, char *metaptrs[])
1505 : {
1506 : intn i; /* Loop index */
1507 :
1508 : int32 attrIndex; /* Structural metadata attribute index */
1509 : int32 nmeta; /* Number of UTLSTRSIZE byte metadata sections */
1510 :
1511 : char *metabuf; /* Pointer (handle) to structural metadata */
1512 245 : char *endptr = NULL; /* Pointer to end of metadata section */
1513 : char *metaptr; /* Metadata pointer */
1514 : char *prevmetaptr;/* Previous position of metadata pointer */
1515 : char *utlstr; /* Utility string */
1516 :
1517 :
1518 :
1519 : /* Allocate memory for utility string */
1520 : /* ---------------------------------- */
1521 245 : utlstr = (char *) calloc(UTLSTR_MAX_SIZE,sizeof(char));
1522 245 : if(utlstr == NULL)
1523 : {
1524 0 : HEpush(DFE_NOSPACE,"EHEHmetagroup", __FILE__, __LINE__);
1525 :
1526 0 : return( NULL);
1527 : }
1528 : /* Determine number of structural metadata "sections" */
1529 : /* -------------------------------------------------- */
1530 245 : nmeta = 0;
1531 : while (1)
1532 : {
1533 : /* Search for "StructMetadata.x" attribute */
1534 : /* --------------------------------------- */
1535 490 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%d", "StructMetadata.", (int)nmeta);
1536 490 : attrIndex = SDfindattr(sdInterfaceID, utlstr);
1537 :
1538 :
1539 : /* If found then increment metadata section counter else exit loop */
1540 : /* --------------------------------------------------------------- */
1541 490 : if (attrIndex != -1)
1542 : {
1543 245 : nmeta++;
1544 : } else
1545 : {
1546 245 : break;
1547 : }
1548 : }
1549 :
1550 245 : if (nmeta > INT_MAX / UTLSTRSIZE )
1551 : {
1552 0 : HEpush(DFE_NOSPACE,"EHEHmetagroup", __FILE__, __LINE__);
1553 :
1554 0 : return( NULL);
1555 : }
1556 :
1557 : /* Allocate space for metadata (in units of UTLSTRSIZE bytes) */
1558 : /* ----------------------------------------------------- */
1559 245 : metabuf = (char *) calloc(UTLSTRSIZE * nmeta, 1);
1560 :
1561 245 : if(metabuf == NULL)
1562 : {
1563 0 : HEpush(DFE_NOSPACE,"EHmetagroup", __FILE__, __LINE__);
1564 0 : free(utlstr);
1565 0 : return(metabuf);
1566 : }
1567 :
1568 :
1569 : /* Read structural metadata */
1570 : /* ------------------------ */
1571 490 : for (i = 0; i < nmeta; i++)
1572 : {
1573 245 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%d", "StructMetadata.", i);
1574 245 : attrIndex = SDfindattr(sdInterfaceID, utlstr);
1575 245 : int metalen = (int)strlen(metabuf);
1576 245 : SDreadattr(sdInterfaceID, attrIndex, metabuf + metalen);
1577 : }
1578 :
1579 : /* Find HDF-EOS structure "root" group in metadata */
1580 : /* ----------------------------------------------- */
1581 :
1582 : /* Setup proper search string */
1583 : /* -------------------------- */
1584 245 : if (strcmp(structcode, "s") == 0)
1585 : {
1586 49 : strcpy(utlstr, "GROUP=SwathStructure");
1587 196 : } else if (strcmp(structcode, "g") == 0)
1588 : {
1589 196 : strcpy(utlstr, "GROUP=GridStructure");
1590 0 : } else if (strcmp(structcode, "p") == 0)
1591 : {
1592 0 : strcpy(utlstr, "GROUP=PointStructure");
1593 : }
1594 : /* Use string search routine (strstr) to move through metadata */
1595 : /* ----------------------------------------------------------- */
1596 245 : metaptr = strstr(metabuf, utlstr);
1597 :
1598 :
1599 :
1600 : /* Save current metadata pointer */
1601 : /* ----------------------------- */
1602 245 : prevmetaptr = metaptr;
1603 :
1604 :
1605 : /* First loop for "old-style" (non-ODL) metadata string */
1606 : /* ---------------------------------------------------- */
1607 245 : if (strcmp(structcode, "s") == 0)
1608 : {
1609 49 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s", "SwathName=\"", structname);
1610 196 : } else if (strcmp(structcode, "g") == 0)
1611 : {
1612 196 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s", "GridName=\"", structname);
1613 0 : } else if (strcmp(structcode, "p") == 0)
1614 : {
1615 0 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s", "PointName=\"", structname);
1616 : }
1617 : /* Do string search */
1618 : /* ---------------- */
1619 245 : if (metaptr)
1620 245 : metaptr = strstr(metaptr, utlstr);
1621 :
1622 :
1623 : /*
1624 : * If not found then return to previous position in metadata and look for
1625 : * "new-style" (ODL) metadata string
1626 : */
1627 245 : if (metaptr == NULL && prevmetaptr)
1628 : {
1629 0 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s", "GROUP=\"", structname);
1630 0 : metaptr = strstr(prevmetaptr, utlstr);
1631 : }
1632 : /* Find group within structure */
1633 : /* --------------------------- */
1634 245 : if (metaptr && groupname != NULL)
1635 : {
1636 229 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s", "GROUP=", groupname);
1637 229 : metaptr = strstr(metaptr, utlstr);
1638 :
1639 229 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s", "\t\tEND_GROUP=", groupname);
1640 229 : if (metaptr)
1641 223 : endptr = strstr(metaptr, utlstr);
1642 : else
1643 6 : endptr = NULL;
1644 16 : } else if (metaptr)
1645 : {
1646 : /* If groupname == NULL then find end of structure in metadata */
1647 : /* ----------------------------------------------------------- */
1648 16 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s", "\n\tEND_GROUP=");
1649 16 : endptr = strstr(metaptr, utlstr);
1650 : }
1651 :
1652 :
1653 : /* Return beginning and ending pointers */
1654 : /* ------------------------------------ */
1655 245 : metaptrs[0] = metaptr;
1656 245 : metaptrs[1] = endptr;
1657 :
1658 245 : free(utlstr);
1659 :
1660 245 : return (metabuf);
1661 : }
1662 :
1663 :
1664 : /*----------------------------------------------------------------------------|
1665 : | BEGIN_PROLOG |
1666 : | |
1667 : | FUNCTION: EHattr |
1668 : | |
1669 : | DESCRIPTION: Reads/Writes attributes for HDF-EOS structures |
1670 : | |
1671 : | |
1672 : | Return Value Type Units Description |
1673 : | ============ ====== ========= ===================================== |
1674 : | status intn return status (0) SUCCEED, (-1) FAIL |
1675 : | |
1676 : | INPUTS: |
1677 : | fid int32 HDF-EOS file ID |
1678 : | attrVgrpID int32 Attribute Vgroup ID |
1679 : | attrname char attribute name |
1680 : | numbertype int32 attribute HDF numbertype |
1681 : | count int32 Number of attribute elements |
1682 : | wrcode char Read/Write Code "w/r" |
1683 : | datbuf void I/O buffer |
1684 : | |
1685 : | |
1686 : | OUTPUTS: |
1687 : | datbuf void I/O buffer |
1688 : | |
1689 : | NOTES: |
1690 : | |
1691 : | |
1692 : | Date Programmer Description |
1693 : | ====== ============ ================================================= |
1694 : | Jun 96 Joel Gales Original Programmer |
1695 : | Oct 96 Joel Gales Pass Vgroup id as routine parameter |
1696 : | Oct 96 Joel Gales Remove Vdetach call |
1697 : | |
1698 : | END_PROLOG |
1699 : -----------------------------------------------------------------------------*/
1700 : intn
1701 1 : EHattr(int32 fid, int32 attrVgrpID, const char *attrname, int32 numbertype,
1702 : int32 count, const char *wrcode, VOIDP datbuf)
1703 :
1704 : {
1705 1 : intn status = 0; /* routine return status variable */
1706 : int32 vdataID; /* Attribute Vdata ID */
1707 :
1708 : /*
1709 : * Attributes are stored as Vdatas with name given by the user, class:
1710 : * "Attr0.0" and fieldname: "AttrValues"
1711 : */
1712 :
1713 :
1714 : /* Get Attribute Vdata ID and "open" with appropriate I/O code */
1715 : /* ----------------------------------------------------------- */
1716 1 : vdataID = EHgetid(fid, attrVgrpID, attrname, 1, wrcode);
1717 :
1718 : /* Write Attribute Section */
1719 : /* ----------------------- */
1720 1 : if (strcmp(wrcode, "w") == 0)
1721 : {
1722 : /* Create Attribute Vdata (if it doesn't exist) */
1723 : /* -------------------------------------------- */
1724 0 : if (vdataID == -1)
1725 : {
1726 0 : vdataID = VSattach(fid, -1, "w");
1727 0 : VSsetname(vdataID, attrname);
1728 0 : VSsetclass(vdataID, "Attr0.0");
1729 :
1730 0 : VSfdefine(vdataID, "AttrValues", numbertype, count);
1731 0 : Vinsert(attrVgrpID, vdataID);
1732 : }
1733 : /* Write Attribute */
1734 : /* --------------- */
1735 0 : VSsetfields(vdataID, "AttrValues");
1736 0 : (void) VSsizeof(vdataID, (char*) "AttrValues");
1737 0 : VSwrite(vdataID, datbuf, 1, FULL_INTERLACE);
1738 :
1739 0 : VSdetach(vdataID);
1740 : }
1741 : /* Read Attribute Section */
1742 : /* ---------------------- */
1743 1 : if (strcmp(wrcode, "r") == 0)
1744 : {
1745 : /* If attribute doesn't exist report error */
1746 : /* --------------------------------------- */
1747 1 : if (vdataID == -1)
1748 : {
1749 1 : status = -1;
1750 1 : HEpush(DFE_GENAPP, "EHattr", __FILE__, __LINE__);
1751 1 : HEreport("Attribute %s not defined.\n", attrname);
1752 : } else
1753 : {
1754 0 : VSsetfields(vdataID, "AttrValues");
1755 0 : (void) VSsizeof(vdataID, (char*) "AttrValues");
1756 0 : VSread(vdataID, datbuf, 1, FULL_INTERLACE);
1757 0 : VSdetach(vdataID);
1758 : }
1759 : }
1760 1 : return (status);
1761 : }
1762 :
1763 :
1764 :
1765 :
1766 : /*----------------------------------------------------------------------------|
1767 : | BEGIN_PROLOG |
1768 : | |
1769 : | FUNCTION: EHattrinfo |
1770 : | |
1771 : | DESCRIPTION: Returns numbertype and count of given HDF-EOS attribute |
1772 : | |
1773 : | |
1774 : | Return Value Type Units Description |
1775 : | ============ ====== ========= ===================================== |
1776 : | status intn return status (0) SUCCEED, (-1) FAIL |
1777 : | |
1778 : | INPUTS: |
1779 : | fid int32 HDF-EOS file ID |
1780 : | attrVgrpID int32 Attribute Vgroup ID |
1781 : | attrname char attribute name |
1782 : | |
1783 : | OUTPUTS: |
1784 : | numbertype int32 attribute HDF numbertype |
1785 : | count int32 Number of attribute elements |
1786 : | |
1787 : | NOTES: |
1788 : | |
1789 : | |
1790 : | Date Programmer Description |
1791 : | ====== ============ ================================================= |
1792 : | Jun 96 Joel Gales Original Programmer |
1793 : | Oct 96 Joel Gales Pass Vgroup id as routine parameter |
1794 : | Oct 96 Joel Gales Remove Vdetach call |
1795 : | |
1796 : | END_PROLOG |
1797 : -----------------------------------------------------------------------------*/
1798 : intn
1799 0 : EHattrinfo(int32 fid, int32 attrVgrpID, const char *attrname, int32 * numbertype,
1800 : int32 * count)
1801 :
1802 : {
1803 0 : intn status = 0; /* routine return status variable */
1804 : int32 vdataID; /* Attribute Vdata ID */
1805 :
1806 : /* Get Attribute Vdata ID */
1807 : /* ---------------------- */
1808 0 : vdataID = EHgetid(fid, attrVgrpID, attrname, 1, "r");
1809 :
1810 : /* If attribute not defined then report error */
1811 : /* ------------------------------------------ */
1812 0 : if (vdataID == -1)
1813 : {
1814 0 : status = -1;
1815 0 : HEpush(DFE_GENAPP, "EHattr", __FILE__, __LINE__);
1816 0 : HEreport("Attribute %s not defined.\n", attrname);
1817 : } else
1818 : {
1819 : /* Get attribute info */
1820 : /* ------------------ */
1821 0 : VSsetfields(vdataID, "AttrValues");
1822 0 : *count = VSsizeof(vdataID, (char*) "AttrValues");
1823 0 : *numbertype = VFfieldtype(vdataID, 0);
1824 0 : VSdetach(vdataID);
1825 : }
1826 :
1827 0 : return (status);
1828 : }
1829 :
1830 :
1831 :
1832 :
1833 :
1834 : /*----------------------------------------------------------------------------|
1835 : | BEGIN_PROLOG |
1836 : | |
1837 : | FUNCTION: EHattrcat |
1838 : | |
1839 : | DESCRIPTION: Returns a listing of attributes within an HDF-EOS structure |
1840 : | |
1841 : | |
1842 : | Return Value Type Units Description |
1843 : | ============ ====== ========= ===================================== |
1844 : | nattr int32 Number of attributes in swath struct |
1845 : | |
1846 : | INPUTS: |
1847 : | fid int32 HDF-EOS file ID |
1848 : | attrVgrpID int32 Attribute Vgroup ID |
1849 : | structcode char Structure Code ("s/g/p") |
1850 : | |
1851 : | OUTPUTS: |
1852 : | attrnames char Attribute names in swath struct |
1853 : | (Comma-separated list) |
1854 : | strbufsize int32 Attributes name list string length |
1855 : | |
1856 : | NOTES: |
1857 : | |
1858 : | |
1859 : | Date Programmer Description |
1860 : | ====== ============ ================================================= |
1861 : | Jun 96 Joel Gales Original Programmer |
1862 : | Oct 96 Joel Gales Pass Vgroup id as routine parameter |
1863 : | Oct 96 Joel Gales Remove Vdetach call |
1864 : | |
1865 : | END_PROLOG |
1866 : -----------------------------------------------------------------------------*/
1867 : int32
1868 7 : EHattrcat(int32 fid, int32 attrVgrpID, char *attrnames, int32 * strbufsize)
1869 : {
1870 : intn i; /* Loop index */
1871 :
1872 : int32 nObjects; /* # of objects in Vgroup */
1873 : int32 *tags; /* Pnt to Vgroup object tags array */
1874 : int32 *refs; /* Pnt to Vgroup object refs array */
1875 : int32 vdataID; /* Attribute Vdata ID */
1876 :
1877 7 : int32 nattr = 0; /* Number of attributes */
1878 : int32 slen; /* String length */
1879 :
1880 : char name[80]; /* Attribute name */
1881 : static const char indxstr[] = "INDXMAP:"; /* Index Mapping reserved
1882 : string */
1883 : static const char fvstr[] = "_FV_"; /* Flag Value reserved string */
1884 : static const char bsom[] = "_BLKSOM:";/* Block SOM Offset reserved string */
1885 :
1886 :
1887 : /* Set string buffer size to 0 */
1888 : /* --------------------------- */
1889 7 : *strbufsize = 0;
1890 :
1891 :
1892 : /* Get number of attributes within Attribute Vgroup */
1893 : /* ------------------------------------------------ */
1894 7 : nObjects = Vntagrefs(attrVgrpID);
1895 :
1896 :
1897 : /* If attributes exist ... */
1898 : /* ----------------------- */
1899 7 : if (nObjects > 0)
1900 : {
1901 : /* Get tags and references of attribute Vdatas */
1902 : /* ------------------------------------------- */
1903 0 : tags = (int32 *) malloc(sizeof(int32) * nObjects);
1904 0 : if(tags == NULL)
1905 : {
1906 0 : HEpush(DFE_NOSPACE,"EHattrcat", __FILE__, __LINE__);
1907 0 : return(-1);
1908 : }
1909 0 : refs = (int32 *) malloc(sizeof(int32) * nObjects);
1910 0 : if(refs == NULL)
1911 : {
1912 0 : HEpush(DFE_NOSPACE,"EHattrcat", __FILE__, __LINE__);
1913 0 : free(tags);
1914 0 : return(-1);
1915 : }
1916 :
1917 0 : Vgettagrefs(attrVgrpID, tags, refs, nObjects);
1918 :
1919 : /* Get attribute vdata IDs and names */
1920 : /* --------------------------------- */
1921 0 : for (i = 0; i < nObjects; i++)
1922 : {
1923 0 : vdataID = VSattach(fid, *(refs + i), "r");
1924 0 : VSgetname(vdataID, name);
1925 :
1926 : /*
1927 : * Don't return fill value, index mapping & block SOM attributes
1928 : */
1929 0 : if (memcmp(name, indxstr, strlen(indxstr)) != 0 &&
1930 0 : memcmp(name, fvstr, strlen(fvstr)) != 0 &&
1931 0 : memcmp(name, bsom, strlen(bsom)) != 0)
1932 : {
1933 : /* Increment attribute counter and add name to list */
1934 : /* ------------------------------------------------ */
1935 0 : nattr++;
1936 0 : if (attrnames != NULL)
1937 : {
1938 0 : if (nattr == 1)
1939 : {
1940 0 : strcpy(attrnames, name);
1941 : } else
1942 : {
1943 0 : strcat(attrnames, ",");
1944 0 : strcat(attrnames, name);
1945 : }
1946 : }
1947 : /* Increment attribute names string length */
1948 : /* --------------------------------------- */
1949 0 : slen = (nattr == 1) ? (int)strlen(name) : (int)strlen(name) + 1;
1950 0 : *strbufsize += slen;
1951 : }
1952 0 : VSdetach(vdataID);
1953 : }
1954 0 : free(tags);
1955 0 : free(refs);
1956 : }
1957 7 : return (nattr);
1958 : }
1959 :
1960 :
1961 :
1962 : /*----------------------------------------------------------------------------|
1963 : | BEGIN_PROLOG |
1964 : | |
1965 : | FUNCTION: EHinquire |
1966 : | |
1967 : | DESCRIPTION: Returns number and names of HDF-EOS structures in file |
1968 : | |
1969 : | |
1970 : | Return Value Type Units Description |
1971 : | ============ ====== ========= ===================================== |
1972 : | nobj int32 Number of HDF-EOS structures in file |
1973 : | |
1974 : | INPUTS: |
1975 : | filename char HDF-EOS filename |
1976 : | type char Object Type ("SWATH/GRID/POINT") |
1977 : | |
1978 : | OUTPUTS: |
1979 : | objectlist char List of object names (comma-separated) |
1980 : | strbufsize int32 Length of objectlist |
1981 : | |
1982 : | NOTES: |
1983 : | |
1984 : | |
1985 : | Date Programmer Description |
1986 : | ====== ============ ================================================= |
1987 : | Jun 96 Joel Gales Original Programmer |
1988 : | |
1989 : | END_PROLOG |
1990 : -----------------------------------------------------------------------------*/
1991 : int32
1992 50 : EHinquire(const char *filename, const char *type, char *objectlist, int32 * strbufsize)
1993 : {
1994 : int32 HDFfid; /* HDF file ID */
1995 : int32 vgRef; /* Vgroup reference number */
1996 : int32 vGrpID; /* Vgroup ID */
1997 50 : int32 nobj = 0; /* Number of HDFEOS objects in file */
1998 : int32 slen; /* String length */
1999 :
2000 : char name[512]; /* Object name */
2001 : char class[80]; /* Object class */
2002 :
2003 :
2004 : /* Open HDFEOS file of read-only access */
2005 : /* ------------------------------------ */
2006 50 : HDFfid = Hopen(filename, DFACC_READ, 0);
2007 :
2008 :
2009 : /* Start Vgroup Interface */
2010 : /* ---------------------- */
2011 50 : Vstart(HDFfid);
2012 :
2013 :
2014 : /* If string buffer size is requested then zero out counter */
2015 : /* -------------------------------------------------------- */
2016 50 : if (strbufsize != NULL)
2017 : {
2018 50 : *strbufsize = 0;
2019 : }
2020 : /* Search for objects from beginning of HDF file */
2021 : /* -------------------------------------------- */
2022 50 : vgRef = -1;
2023 :
2024 : /* Loop through all objects */
2025 : /* ------------------------ */
2026 : while (1)
2027 : {
2028 : /* Get Vgroup reference number */
2029 : /* --------------------------- */
2030 309 : vgRef = Vgetid(HDFfid, vgRef);
2031 :
2032 : /* If no more then exist search loop */
2033 : /* --------------------------------- */
2034 309 : if (vgRef == -1)
2035 : {
2036 50 : break;
2037 : }
2038 : /* Get Vgroup ID, name, and class */
2039 : /* ------------------------------ */
2040 259 : vGrpID = Vattach(HDFfid, vgRef, "r");
2041 259 : VgetnameSafe(vGrpID, name, sizeof(name));
2042 259 : Vgetclass(vGrpID, class);
2043 :
2044 :
2045 : /* If object of desired type (SWATH, POINT, GRID) ... */
2046 : /* -------------------------------------------------- */
2047 259 : if (strcmp(class, type) == 0)
2048 : {
2049 :
2050 : /* Increment counter */
2051 : /* ----------------- */
2052 30 : nobj++;
2053 :
2054 :
2055 : /* If object list requested add name to list */
2056 : /* ----------------------------------------- */
2057 30 : if (objectlist != NULL)
2058 : {
2059 12 : if (nobj == 1)
2060 : {
2061 12 : strcpy(objectlist, name);
2062 : } else
2063 : {
2064 0 : strcat(objectlist, ",");
2065 0 : strcat(objectlist, name);
2066 : }
2067 : }
2068 : /* Compute string length of object entry */
2069 : /* ------------------------------------- */
2070 30 : slen = (nobj == 1) ? (int)strlen(name) : (int)strlen(name) + 1;
2071 :
2072 :
2073 : /* If string buffer size is requested then increment buffer size */
2074 : /* ------------------------------------------------------------- */
2075 30 : if (strbufsize != NULL)
2076 : {
2077 30 : *strbufsize += slen;
2078 : }
2079 : }
2080 : /* Detach Vgroup */
2081 : /* ------------- */
2082 259 : Vdetach(vGrpID);
2083 : }
2084 :
2085 : /* "Close" Vgroup interface and HDFEOS file */
2086 : /* ---------------------------------------- */
2087 50 : Vend(HDFfid);
2088 50 : Hclose(HDFfid);
2089 :
2090 50 : return (nobj);
2091 : }
2092 :
2093 :
2094 :
2095 : /*----------------------------------------------------------------------------|
2096 : | BEGIN_PROLOG |
2097 : | |
2098 : | FUNCTION: EHclose |
2099 : | |
2100 : | DESCRIPTION: Closes HDF-EOS file |
2101 : | |
2102 : | |
2103 : | Return Value Type Units Description |
2104 : | ============ ====== ========= ===================================== |
2105 : | status intn return status (0) SUCCEED, (-1) FAIL |
2106 : | |
2107 : | INPUTS: |
2108 : | fid int32 HDF-EOS File ID |
2109 : | |
2110 : | OUTPUTS: |
2111 : | None |
2112 : | |
2113 : | NOTES: |
2114 : | |
2115 : | |
2116 : | Date Programmer Description |
2117 : | ====== ============ ================================================= |
2118 : | Jun 96 Joel Gales Original Programmer |
2119 : | Jul 96 Joel Gales Add file id offset EHIDOFFSET |
2120 : | Aug 96 Joel Gales Add HE error report if file id out of bounds |
2121 : | Nov 96 Joel Gales Add EHXacsTable array to "garbage collection" |
2122 : | |
2123 : | END_PROLOG |
2124 : -----------------------------------------------------------------------------*/
2125 : intn
2126 40 : EHclose(int32 fid)
2127 : {
2128 40 : intn status = 0; /* routine return status variable */
2129 :
2130 : int32 HDFfid; /* HDF file ID */
2131 : int32 sdInterfaceID; /* HDF SDS interface ID */
2132 : int32 fid0; /* HDF EOS file id - offset */
2133 :
2134 :
2135 : /* Check for valid HDFEOS file ID range */
2136 : /* ------------------------------------ */
2137 40 : if (fid >= EHIDOFFSET && fid < EHXmaxfilecount + EHIDOFFSET)
2138 : {
2139 : /* Compute "reduced" file ID */
2140 : /* ------------------------- */
2141 40 : fid0 = fid % EHIDOFFSET;
2142 :
2143 :
2144 : /* Get HDF file ID and SD interface ID */
2145 : /* ----------------------------------- */
2146 40 : HDFfid = EHXfidTable[fid0];
2147 40 : sdInterfaceID = EHXsdTable[fid0];
2148 :
2149 : /* "Close" SD interface, Vgroup interface, and HDF file */
2150 : /* ---------------------------------------------------- */
2151 40 : status = SDend(sdInterfaceID);
2152 40 : if (Vend(HDFfid) < 0)
2153 0 : status = -1;
2154 40 : if (Hclose(HDFfid) < 0)
2155 0 : status = -1;
2156 :
2157 : /* Clear out external array entries */
2158 : /* -------------------------------- */
2159 40 : EHXtypeTable[fid0] = 0;
2160 40 : EHXacsTable[fid0] = 0;
2161 40 : EHXfidTable[fid0] = 0;
2162 40 : EHXsdTable[fid0] = 0;
2163 40 : if (EHget_numfiles() == 0)
2164 : {
2165 40 : free(EHXtypeTable);
2166 40 : EHXtypeTable = NULL;
2167 40 : free(EHXacsTable);
2168 40 : EHXacsTable = NULL;
2169 40 : free(EHXfidTable);
2170 40 : EHXfidTable = NULL;
2171 40 : free(EHXsdTable);
2172 40 : EHXsdTable = NULL;
2173 40 : EHXmaxfilecount = 0;
2174 : }
2175 : } else
2176 : {
2177 0 : status = -1;
2178 0 : HEpush(DFE_RANGE, "EHclose", __FILE__, __LINE__);
2179 0 : HEreport("Invalid file id: %d. ID must be >= %d and < %d.\n",
2180 : fid, EHIDOFFSET, EHXmaxfilecount + EHIDOFFSET);
2181 : }
2182 :
2183 40 : return (status);
2184 : }
2185 :
2186 : /*----------------------------------------------------------------------------|
2187 : | BEGIN_PROLOG |
2188 : | |
2189 : | FUNCTION: EHnumstr |
2190 : | |
2191 : | DESCRIPTION: Returns numerical type code of the given string |
2192 : | representation. |
2193 : | |
2194 : | |
2195 : | Return Value Type Units Description |
2196 : | ============ ====== ========= ===================================== |
2197 : | numbertype int32 numerical type code |
2198 : | |
2199 : | INPUTS: |
2200 : | strcode const char string representation of the type code |
2201 : | |
2202 : | |
2203 : | OUTPUTS: |
2204 : | None |
2205 : | |
2206 : | NOTES: |
2207 : | |
2208 : | |
2209 : | Date Programmer Description |
2210 : | ====== ============ ================================================= |
2211 : | Nov 07 Andrey Kiselev Original Programmer |
2212 : | |
2213 : | END_PROLOG |
2214 : -----------------------------------------------------------------------------*/
2215 : int32
2216 120 : EHnumstr(const char *strcode)
2217 : {
2218 120 : if (strcmp(strcode, "DFNT_UCHAR8") == 0)
2219 0 : return DFNT_UCHAR8;
2220 120 : else if (strcmp(strcode, "DFNT_CHAR8") == 0)
2221 0 : return DFNT_CHAR8;
2222 120 : else if (strcmp(strcode, "DFNT_FLOAT32") == 0)
2223 120 : return DFNT_FLOAT32;
2224 0 : else if (strcmp(strcode, "DFNT_FLOAT64") == 0)
2225 0 : return DFNT_FLOAT64;
2226 0 : else if (strcmp(strcode, "DFNT_INT8") == 0)
2227 0 : return DFNT_INT8;
2228 0 : else if (strcmp(strcode, "DFNT_UINT8") == 0)
2229 0 : return DFNT_UINT8;
2230 0 : else if (strcmp(strcode, "DFNT_INT16") == 0)
2231 0 : return DFNT_INT16;
2232 0 : else if (strcmp(strcode, "DFNT_UINT16") == 0)
2233 0 : return DFNT_UINT16;
2234 0 : else if (strcmp(strcode, "DFNT_INT32") == 0)
2235 0 : return DFNT_INT32;
2236 0 : else if (strcmp(strcode, "DFNT_UINT32") == 0)
2237 0 : return DFNT_UINT32;
2238 : else
2239 0 : return DFNT_NONE;
2240 : }
2241 :
2242 : /*----------------------------------------------------------------------------|
2243 : | BEGIN_PROLOG |
2244 : | |
2245 : | FUNCTION: EHreset_maxopenfiles |
2246 : | |
2247 : | DESCRIPTION: Change the allowed number of opened HDFEOS files. |
2248 : | |
2249 : | |
2250 : | Return Value Type Units Description |
2251 : | ============ ====== ========= ===================================== |
2252 : | numbertype intn The current maximum number of opened |
2253 : | files allowed, or -1, if unable |
2254 : | to reset it. |
2255 : | |
2256 : | INPUTS: |
2257 : | strcode intn Requested number of opened files. |
2258 : | |
2259 : | |
2260 : | OUTPUTS: |
2261 : | None |
2262 : | |
2263 : | NOTES: |
2264 : | |
2265 : | |
2266 : | Date Programmer Description |
2267 : | ========== ============ ============================================== |
2268 : | 2013.04.03 Andrey Kiselev Original Programmer |
2269 : | |
2270 : | END_PROLOG |
2271 : -----------------------------------------------------------------------------*/
2272 : static intn
2273 40 : EHreset_maxopenfiles(intn req_max)
2274 : {
2275 : intn ret_value;
2276 :
2277 40 : if (req_max <= EHXmaxfilecount)
2278 0 : return EHXmaxfilecount;
2279 :
2280 : /* Fallback to built-in NEOSHDF constant if */
2281 : /* SDreset_maxopenfiles() interface is not available */
2282 : /* ------------------------------------------------- */
2283 : #ifdef HDF4_HAS_MAXOPENFILES
2284 40 : ret_value = SDreset_maxopenfiles(req_max);
2285 : #else
2286 : ret_value = NEOSHDF;
2287 : #endif /* HDF4_HAS_MAXOPENFILES */
2288 :
2289 40 : if (ret_value > 0)
2290 : {
2291 40 : EHXtypeTable = realloc(EHXtypeTable, ret_value * sizeof(*EHXtypeTable));
2292 40 : memset(EHXtypeTable + EHXmaxfilecount, 0,
2293 40 : (ret_value - EHXmaxfilecount) * sizeof(*EHXtypeTable));
2294 40 : EHXacsTable = realloc(EHXacsTable, ret_value * sizeof(*EHXacsTable));
2295 40 : memset(EHXacsTable + EHXmaxfilecount, 0,
2296 40 : (ret_value - EHXmaxfilecount) * sizeof(*EHXacsTable));
2297 40 : EHXfidTable = realloc(EHXfidTable, ret_value * sizeof(*EHXfidTable));
2298 40 : memset(EHXfidTable + EHXmaxfilecount, 0,
2299 40 : (ret_value - EHXmaxfilecount) * sizeof(*EHXfidTable));
2300 40 : EHXsdTable = realloc(EHXsdTable, ret_value * sizeof(*EHXsdTable));
2301 40 : memset(EHXsdTable + EHXmaxfilecount, 0,
2302 40 : (ret_value - EHXmaxfilecount) * sizeof(*EHXsdTable));
2303 40 : EHXmaxfilecount = ret_value;
2304 : }
2305 :
2306 40 : return ret_value;
2307 : }
2308 :
2309 : /*----------------------------------------------------------------------------|
2310 : | BEGIN_PROLOG |
2311 : | |
2312 : | FUNCTION: EHget_maxopenfiles |
2313 : | |
2314 : | DESCRIPTION: Request the allowed number of opened HDFEOS files and maximum |
2315 : | number of opened files allowed in the system. |
2316 : | |
2317 : | |
2318 : | Return Value Type Units Description |
2319 : | ============ ====== ========= ===================================== |
2320 : | status intn return status (0) SUCCEED, (-1) FAIL |
2321 : | |
2322 : | INPUTS: |
2323 : | None |
2324 : | |
2325 : | |
2326 : | OUTPUTS: |
2327 : | curr_max intn Current number of open files allowed. |
2328 : | sys_limit intn Maximum number of open files allowed |
2329 : | in the system. |
2330 : | |
2331 : | NOTES: |
2332 : | |
2333 : | |
2334 : | Date Programmer Description |
2335 : | ========== ============ ============================================== |
2336 : | 2013.04.03 Andrey Kiselev Original Programmer |
2337 : | |
2338 : | END_PROLOG |
2339 : -----------------------------------------------------------------------------*/
2340 : static intn
2341 40 : EHget_maxopenfiles(intn *curr_max,
2342 : intn *sys_limit)
2343 : {
2344 40 : intn ret_value = 0;
2345 :
2346 : #ifdef HDF4_HAS_MAXOPENFILES
2347 40 : ret_value = SDget_maxopenfiles(curr_max, sys_limit);
2348 : #else
2349 : *sys_limit = NEOSHDF;
2350 : #endif /* HDF4_HAS_MAXOPENFILES */
2351 :
2352 40 : *curr_max = EHXmaxfilecount;
2353 :
2354 40 : return ret_value;
2355 : }
2356 :
2357 : /*----------------------------------------------------------------------------|
2358 : | BEGIN_PROLOG |
2359 : | |
2360 : | FUNCTION: EHget_numfiles |
2361 : | |
2362 : | DESCRIPTION: Request the number of HDFEOS files currently opened. |
2363 : | |
2364 : | |
2365 : | Return Value Type Units Description |
2366 : | ============ ====== ========= ===================================== |
2367 : | nfileopen intn Number of HDFEOS files already opened. |
2368 : | |
2369 : | INPUTS: |
2370 : | None |
2371 : | |
2372 : | |
2373 : | OUTPUTS: |
2374 : | None |
2375 : | in the system. |
2376 : | |
2377 : | NOTES: |
2378 : | |
2379 : | |
2380 : | Date Programmer Description |
2381 : | ========== ============ ============================================== |
2382 : | 2013.04.03 Andrey Kiselev Original Programmer |
2383 : | |
2384 : | END_PROLOG |
2385 : -----------------------------------------------------------------------------*/
2386 : static intn
2387 80 : EHget_numfiles()
2388 : {
2389 : intn i; /* Loop index */
2390 80 : intn nfileopen = 0; /* # of HDF files open */
2391 :
2392 80 : if (EHXtypeTable)
2393 : {
2394 : /* Determine number of files currently opened */
2395 : /* ------------------------------------------ */
2396 1600080 : for (i = 0; i < EHXmaxfilecount; i++)
2397 : {
2398 1600000 : nfileopen += EHXtypeTable[i];
2399 : }
2400 : }
2401 :
2402 80 : return nfileopen;
2403 : }
|