Line data Source code
1 : /*****************************************************************************
2 : * $Id$
3 : *
4 : * This module has a number of additions and improvements over the original
5 : * implementation to be suitable for usage in GDAL HDF driver.
6 : *
7 : * Andrey Kiselev <dron@ak4719.spb.edu> is responsible for all the changes.
8 : ****************************************************************************/
9 :
10 : /*
11 : Copyright (C) 1996 Hughes and Applied Research Corporation
12 :
13 : Permission to use, modify, and distribute this software and its documentation
14 : for any purpose without fee is hereby granted, provided that the above
15 : copyright notice appear in all copies and that both that copyright notice and
16 : this permission notice appear in supporting documentation.
17 : */
18 :
19 : #include "cpl_port.h"
20 : #include <errno.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 EHmetalist(const char *, char *);
50 : static intn EHreset_maxopenfiles(intn);
51 : static intn EHget_maxopenfiles(intn *, intn *);
52 : static intn EHget_numfiles(void);
53 :
54 : /*----------------------------------------------------------------------------|
55 : | BEGIN_PROLOG |
56 : | |
57 : | FUNCTION: EHopen |
58 : | |
59 : | DESCRIPTION: Opens HDF-EOS file and returns file handle |
60 : | |
61 : | |
62 : | Return Value Type Units Description |
63 : | ============ ====== ========= ===================================== |
64 : | fid int32 HDF-EOS file ID |
65 : | |
66 : | INPUTS: |
67 : | filename char Filename |
68 : | access intn HDF access code |
69 : | |
70 : | OUTPUTS: |
71 : | None |
72 : | |
73 : | NOTES: |
74 : | |
75 : | |
76 : | Date Programmer Description |
77 : | ====== ============ ================================================= |
78 : | Jun 96 Joel Gales Original Programmer |
79 : | Jul 96 Joel Gales Add file id offset EHIDOFFSET |
80 : | Aug 96 Joel Gales Add "END" statement to structural metadata |
81 : | Sep 96 Joel Gales Reverse order of Hopen ane SDstart statements |
82 : | for RDWR and READ access |
83 : | Oct 96 Joel Gales Trap CREATE & RDWR (no write permission) |
84 : | access errors |
85 : | Apr 97 Joel Gales Fix problem with RDWR open when file previously |
86 : | open for READONLY access |
87 : | |
88 : | END_PROLOG |
89 : -----------------------------------------------------------------------------*/
90 : int32
91 8 : EHopen(const char *filename, intn access)
92 :
93 : {
94 : intn i; /* Loop index */
95 8 : intn status = 0; /* routine return status variable */
96 : intn dum; /* Dummy variable */
97 8 : intn curr_max = 0; /* maximum # of HDF files to open */
98 8 : intn sys_limit = 0; /* OS limit for maximum # of opened files */
99 :
100 8 : int32 HDFfid = 0; /* HDF file ID */
101 8 : int32 fid = -1; /* HDF-EOS file ID */
102 8 : int32 sdInterfaceID = 0; /* HDF SDS interface ID */
103 : int32 attrIndex; /* Structural Metadata attribute index */
104 :
105 8 : uint8 acs = 0; /* Read (0) / Write (1) access code */
106 :
107 : char *testname; /* Test filename */
108 : char errbuf[256];/* Error report buffer */
109 : char *metabuf; /* Pointer to structural metadata buffer */
110 : char hdfeosVersion[32]; /* HDFEOS version string */
111 :
112 : intn retryCount;
113 :
114 : /* Request the system allowed number of opened files */
115 : /* and increase HDFEOS file tables to the same size */
116 : /* ------------------------------------------------- */
117 8 : if (EHget_maxopenfiles(&curr_max, &sys_limit) >= 0
118 8 : && curr_max < sys_limit)
119 : {
120 8 : if (EHreset_maxopenfiles(sys_limit) < 0)
121 : {
122 0 : HEpush(DFE_ALROPEN, "EHopen", __FILE__, __LINE__);
123 0 : HEreport("Can't set maximum opened files number to \"%d\".\n", curr_max);
124 0 : return -1;
125 : }
126 : }
127 :
128 : /* Setup file interface */
129 : /* -------------------- */
130 8 : if (EHget_numfiles() < EHXmaxfilecount)
131 : {
132 :
133 : /*
134 : * Check that file has not been previously opened for write access if
135 : * current open request is not READONLY
136 : */
137 8 : if (access != DFACC_READ)
138 : {
139 : /* Loop through all files */
140 : /* ---------------------- */
141 0 : for (i = 0; i < EHXmaxfilecount; i++)
142 : {
143 : /* if entry is active file opened for write access ... */
144 : /* --------------------------------------------------- */
145 0 : if (EHXtypeTable[i] != 0 && EHXacsTable[i] == 1)
146 : {
147 : /* Get filename (testname) */
148 : /* ----------------------- */
149 0 : Hfidinquire(EHXfidTable[i], &testname, &dum, &dum);
150 :
151 :
152 : /* if same as filename then report error */
153 : /* ------------------------------------- */
154 0 : if (strcmp(testname, filename) == 0)
155 : {
156 0 : status = -1;
157 0 : fid = -1;
158 0 : HEpush(DFE_ALROPEN, "EHopen", __FILE__, __LINE__);
159 0 : HEreport("\"%s\" already open.\n", filename);
160 0 : break;
161 : }
162 : }
163 : }
164 : }
165 8 : if (status == 0)
166 : {
167 : /* Create HDF-EOS file */
168 : /* ------------------- */
169 8 : switch (access)
170 : {
171 0 : case DFACC_CREATE:
172 :
173 : /* Get SDS interface ID */
174 : /* -------------------- */
175 0 : sdInterfaceID = SDstart(filename, DFACC_CREATE);
176 :
177 : /* If SDstart successful ... */
178 : /* ------------------------- */
179 0 : if (sdInterfaceID != -1)
180 : {
181 : /* Set HDFEOS version number in file */
182 : /* --------------------------------- */
183 0 : snprintf(hdfeosVersion, sizeof(hdfeosVersion), "%s%s", "HDFEOS_V",
184 : HDFEOSVERSION1);
185 0 : SDsetattr(sdInterfaceID, "HDFEOSVersion", DFNT_CHAR8,
186 0 : (int)strlen(hdfeosVersion), hdfeosVersion);
187 :
188 :
189 : /* Get HDF file ID */
190 : /* --------------- */
191 0 : HDFfid = Hopen(filename, DFACC_RDWR, 0);
192 :
193 : /* Set open access to write */
194 : /* ------------------------ */
195 0 : acs = 1;
196 :
197 : /* Setup structural metadata */
198 : /* ------------------------- */
199 0 : metabuf = (char *) calloc(32000, 1);
200 0 : if(metabuf == NULL)
201 : {
202 0 : HEpush(DFE_NOSPACE,"EHopen", __FILE__, __LINE__);
203 0 : return(-1);
204 : }
205 :
206 0 : strcpy(metabuf, "GROUP=SwathStructure\n");
207 0 : strcat(metabuf, "END_GROUP=SwathStructure\n");
208 0 : strcat(metabuf, "GROUP=GridStructure\n");
209 0 : strcat(metabuf, "END_GROUP=GridStructure\n");
210 0 : strcat(metabuf, "GROUP=PointStructure\n");
211 0 : strcat(metabuf, "END_GROUP=PointStructure\n");
212 0 : strcat(metabuf, "END\n");
213 :
214 : /* Write Structural metadata */
215 : /* ------------------------- */
216 0 : SDsetattr(sdInterfaceID, "StructMetadata.0",
217 : DFNT_CHAR8, 32000, metabuf);
218 0 : free(metabuf);
219 : } else
220 : {
221 : /* If error in SDstart then report */
222 : /* ------------------------------- */
223 0 : fid = -1;
224 0 : status = -1;
225 0 : HEpush(DFE_FNF, "EHopen", __FILE__, __LINE__);
226 0 : snprintf(errbuf, sizeof(errbuf), "%s%s%s", "\"", filename,
227 : "\" cannot be created.");
228 0 : HEreport("%s\n", errbuf);
229 : }
230 :
231 0 : break;
232 :
233 : /* Open existing HDF-EOS file for read/write access */
234 : /* ------------------------------------------------ */
235 0 : case DFACC_RDWR:
236 :
237 : /* Get HDF file ID */
238 : /* --------------- */
239 : #ifndef _PGS_OLDNFS
240 : /* The following loop around the function Hopen is intended to deal with the NFS cache
241 : problem when opening file fails with errno = 150 or 151. When NFS cache is updated,
242 : this part of change is no longer necessary. 10/18/1999 */
243 0 : retryCount = 0;
244 0 : HDFfid = -1;
245 0 : while ((HDFfid == -1) && (retryCount < MAX_RETRIES))
246 : {
247 0 : HDFfid = Hopen(filename, DFACC_RDWR, 0);
248 0 : if((HDFfid == -1) && (errno == 150 || errno == 151))
249 : {
250 0 : HEpush(DFE_FNF, "EHopen", __FILE__, __LINE__);
251 0 : snprintf(errbuf, sizeof(errbuf), "\"%s\" cannot be opened for READ/WRITE access, will retry %d times.", filename, (MAX_RETRIES - retryCount - 1));
252 0 : HEreport("%s\n", errbuf);
253 : }
254 0 : retryCount++;
255 : }
256 : #else
257 : HDFfid = Hopen(filename, DFACC_RDWR, 0);
258 : #endif
259 :
260 : /* If Hopen successful ... */
261 : /* ----------------------- */
262 0 : if (HDFfid != -1)
263 : {
264 : /* Get SDS interface ID */
265 : /* -------------------- */
266 0 : sdInterfaceID = SDstart(filename, DFACC_RDWR);
267 :
268 : /* If SDstart successful ... */
269 : /* ------------------------- */
270 0 : if (sdInterfaceID != -1)
271 : {
272 : /* Set HDFEOS version number in file */
273 : /* --------------------------------- */
274 :
275 0 : attrIndex = SDfindattr(sdInterfaceID, "HDFEOSVersion");
276 0 : if (attrIndex == -1)
277 : {
278 0 : snprintf(hdfeosVersion, sizeof(hdfeosVersion), "%s%s", "HDFEOS_V",
279 : HDFEOSVERSION1);
280 0 : SDsetattr(sdInterfaceID, "HDFEOSVersion", DFNT_CHAR8,
281 0 : (int)strlen(hdfeosVersion), hdfeosVersion);
282 : }
283 : /* Set open access to write */
284 : /* ------------------------ */
285 0 : acs = 1;
286 :
287 : /* Get structural metadata attribute ID */
288 : /* ------------------------------------ */
289 0 : attrIndex = SDfindattr(sdInterfaceID, "StructMetadata.0");
290 :
291 : /* Write structural metadata if it doesn't exist */
292 : /* --------------------------------------------- */
293 0 : if (attrIndex == -1)
294 : {
295 0 : metabuf = (char *) calloc(32000, 1);
296 0 : if(metabuf == NULL)
297 : {
298 0 : HEpush(DFE_NOSPACE,"EHopen", __FILE__, __LINE__);
299 0 : return(-1);
300 : }
301 :
302 0 : strcpy(metabuf, "GROUP=SwathStructure\n");
303 0 : strcat(metabuf, "END_GROUP=SwathStructure\n");
304 0 : strcat(metabuf, "GROUP=GridStructure\n");
305 0 : strcat(metabuf, "END_GROUP=GridStructure\n");
306 0 : strcat(metabuf, "GROUP=PointStructure\n");
307 0 : strcat(metabuf, "END_GROUP=PointStructure\n");
308 0 : strcat(metabuf, "END\n");
309 :
310 0 : SDsetattr(sdInterfaceID, "StructMetadata.0",
311 : DFNT_CHAR8, 32000, metabuf);
312 0 : free(metabuf);
313 : }
314 : } else
315 : {
316 : /* If error in SDstart then report */
317 : /* ------------------------------- */
318 0 : fid = -1;
319 0 : status = -1;
320 0 : HEpush(DFE_FNF, "EHopen", __FILE__, __LINE__);
321 0 : snprintf(errbuf, sizeof(errbuf), "%s%s%s", "\"", filename,
322 : "\" cannot be opened for read/write access.");
323 0 : HEreport("%s\n", errbuf);
324 : }
325 : } else
326 : {
327 : /* If error in Hopen then report */
328 : /* ----------------------------- */
329 0 : fid = -1;
330 0 : status = -1;
331 0 : HEpush(DFE_FNF, "EHopen", __FILE__, __LINE__);
332 0 : snprintf(errbuf, sizeof(errbuf), "%s%s%s", "\"", filename,
333 : "\" cannot be opened for RDWR access.");
334 0 : HEreport("%s\n", errbuf);
335 : }
336 :
337 0 : break;
338 :
339 :
340 : /* Open existing HDF-EOS file for read-only access */
341 : /* ----------------------------------------------- */
342 8 : case DFACC_READ:
343 :
344 : /* Get HDF file ID */
345 : /* --------------- */
346 : #ifndef _PGS_OLDNFS
347 : /* The following loop around the function Hopen is intended to deal with the NFS cache
348 : problem when opening file fails with errno = 150 or 151. When NFS cache is updated,
349 : this part of change is no longer necessary. 10/18/1999 */
350 8 : retryCount = 0;
351 8 : HDFfid = -1;
352 16 : while ((HDFfid == -1) && (retryCount < MAX_RETRIES))
353 : {
354 8 : HDFfid = Hopen(filename, DFACC_READ, 0);
355 8 : if((HDFfid == -1) && (errno == 150 || errno == 151))
356 : {
357 0 : HEpush(DFE_FNF, "EHopen", __FILE__, __LINE__);
358 0 : snprintf(errbuf, sizeof(errbuf), "\"%s\" cannot be opened for READONLY access, will retry %d times.", filename, (MAX_RETRIES - retryCount - 1));
359 0 : HEreport("%s\n", errbuf);
360 : }
361 8 : retryCount++;
362 : }
363 : #else
364 : HDFfid = Hopen(filename, DFACC_READ, 0);
365 : #endif
366 :
367 : /* If file does not exist report error */
368 : /* ----------------------------------- */
369 8 : if (HDFfid == -1)
370 : {
371 0 : fid = -1;
372 0 : status = -1;
373 0 : HEpush(DFE_FNF, "EHopen", __FILE__, __LINE__);
374 0 : strcpy(errbuf, "\"");
375 0 : strcat(errbuf, filename);
376 0 : strcat(errbuf, "\" (opened for READONLY access)");
377 0 : strcat(errbuf, " does not exist.");
378 0 : HEreport("%s\n", errbuf);
379 : } else
380 : {
381 : /* If file exists then get SD interface ID */
382 : /* --------------------------------------- */
383 8 : sdInterfaceID = SDstart(filename, DFACC_RDONLY);
384 :
385 : /* If SDstart successful ... */
386 : /* ------------------------- */
387 8 : if (sdInterfaceID != -1)
388 : {
389 :
390 : /* Set open access to read-only */
391 : /* ---------------------------- */
392 8 : acs = 0;
393 : } else
394 : {
395 : /* If error in SDstart then report */
396 : /* ------------------------------- */
397 0 : fid = -1;
398 0 : status = -1;
399 0 : HEpush(DFE_FNF, "EHopen", __FILE__, __LINE__);
400 0 : snprintf(errbuf, sizeof(errbuf), "%s%s%s", "\"", filename,
401 : "\" cannot be opened for read access.");
402 0 : HEreport("%s\n", errbuf);
403 : }
404 : }
405 :
406 8 : break;
407 :
408 0 : default:
409 : /* Invalid Access Code */
410 : /* ------------------- */
411 0 : fid = -1;
412 0 : status = -1;
413 0 : HEpush(DFE_BADACC, "EHopen", __FILE__, __LINE__);
414 0 : HEreport("Access Code: %d (%s).\n", access, filename);
415 : }
416 :
417 0 : }
418 : } else
419 : {
420 : /* Too many files opened */
421 : /* --------------------- */
422 0 : status = -1;
423 0 : fid = -1;
424 0 : HEpush(DFE_TOOMANY, "EHopen", __FILE__, __LINE__);
425 0 : HEreport("No more than %d files may be open simultaneously (%s).\n",
426 : EHXmaxfilecount, filename);
427 : }
428 :
429 :
430 :
431 :
432 8 : if (status == 0)
433 : {
434 : /* Initialize Vgroup Access */
435 : /* ------------------------ */
436 8 : Vstart(HDFfid);
437 :
438 :
439 : /* Assign HDFEOS fid # & Load HDF fid and sdInterfaceID tables */
440 : /* ----------------------------------------------------------- */
441 8 : for (i = 0; i < EHXmaxfilecount; i++)
442 : {
443 8 : if (EHXtypeTable[i] == 0)
444 : {
445 8 : fid = i + EHIDOFFSET;
446 8 : EHXacsTable[i] = acs;
447 8 : EHXtypeTable[i] = 1;
448 8 : EHXfidTable[i] = HDFfid;
449 8 : EHXsdTable[i] = sdInterfaceID;
450 8 : break;
451 : }
452 : }
453 :
454 : }
455 8 : return (fid);
456 : }
457 :
458 :
459 :
460 :
461 : /*----------------------------------------------------------------------------|
462 : | BEGIN_PROLOG |
463 : | |
464 : | FUNCTION: EHchkfid |
465 : | |
466 : | DESCRIPTION: Checks for valid file id and returns HDF file ID and |
467 : | SD interface ID |
468 : | |
469 : | |
470 : | Return Value Type Units Description |
471 : | ============ ====== ========= ===================================== |
472 : | status intn return status (0) SUCCEED, (-1) FAIL |
473 : | |
474 : | INPUTS: |
475 : | fid int32 HDF-EOS file ID |
476 : | name char Structure name |
477 : | |
478 : | OUTPUTS: |
479 : | HDFfid int32 HDF File ID |
480 : | sdInterfaceID int32 SDS interface ID |
481 : | access uint8 access code |
482 : | |
483 : | NOTES: |
484 : | |
485 : | |
486 : | Date Programmer Description |
487 : | ====== ============ ================================================= |
488 : | Jun 96 Joel Gales Original Programmer |
489 : | Jul 96 Joel Gales set status=-1 if failure |
490 : | Jul 96 Joel Gales Add file id offset EHIDOFFSET |
491 : | |
492 : | END_PROLOG |
493 : -----------------------------------------------------------------------------*/
494 : intn
495 0 : EHchkfid(int32 fid, const char *name, int32 * HDFfid, int32 * sdInterfaceID,
496 : uint8 * access)
497 :
498 : {
499 0 : intn status = 0; /* routine return status variable */
500 : intn fid0; /* HDFEOS file ID - Offset */
501 :
502 :
503 : /* Check for valid HDFEOS file ID range */
504 : /* ------------------------------------ */
505 0 : if (fid < EHIDOFFSET || fid > EHXmaxfilecount + EHIDOFFSET)
506 : {
507 0 : status = -1;
508 0 : HEpush(DFE_RANGE, "EHchkfid", __FILE__, __LINE__);
509 0 : HEreport("Invalid file id: %d. ID must be >= %d and < %d (%s).\n",
510 : fid, EHIDOFFSET, EHXmaxfilecount + EHIDOFFSET, name);
511 : } else
512 : {
513 : /* Compute "reduced" file ID */
514 : /* ------------------------- */
515 0 : fid0 = fid % EHIDOFFSET;
516 :
517 :
518 : /* Check that HDFEOS file ID is active */
519 : /* ----------------------------------- */
520 0 : if (EHXtypeTable[fid0] == 0)
521 : {
522 0 : status = -1;
523 0 : HEpush(DFE_GENAPP, "EHchkfid", __FILE__, __LINE__);
524 0 : HEreport("File id %d not active (%s).\n", fid, name);
525 : } else
526 : {
527 : /*
528 : * Get HDF file ID, SD interface ID and file access from external
529 : * arrays
530 : */
531 0 : *HDFfid = EHXfidTable[fid0];
532 0 : *sdInterfaceID = EHXsdTable[fid0];
533 0 : *access = EHXacsTable[fid0];
534 : }
535 : }
536 :
537 0 : return (status);
538 : }
539 :
540 :
541 :
542 :
543 : /*----------------------------------------------------------------------------|
544 : | BEGIN_PROLOG |
545 : | |
546 : | FUNCTION: EHidinfo |
547 : | |
548 : | DESCRIPTION: Gets Hopen and SD interface IDs from HDF-EOS id |
549 : | |
550 : | |
551 : | Return Value Type Units Description |
552 : | ============ ====== ========= ===================================== |
553 : | status intn return status (0) SUCCEED, (-1) FAIL |
554 : | |
555 : | INPUTS: |
556 : | fid int32 HDF-EOS file ID |
557 : | |
558 : | OUTPUTS: |
559 : | HDFfid int32 HDF File ID |
560 : | sdInterfaceID int32 SDS interface ID |
561 : | |
562 : | NOTES: |
563 : | |
564 : | |
565 : | Date Programmer Description |
566 : | ====== ============ ================================================= |
567 : | Jul 96 Joel Gales Original Programmer |
568 : | |
569 : | END_PROLOG |
570 : -----------------------------------------------------------------------------*/
571 : intn
572 0 : EHidinfo(int32 fid, int32 * HDFfid, int32 * sdInterfaceID)
573 :
574 : {
575 0 : intn status = 0; /* routine return status variable */
576 : uint8 dum; /* Dummy variable */
577 :
578 : /* Call EHchkfid to get HDF and SD interface IDs */
579 : /* --------------------------------------------- */
580 0 : status = EHchkfid(fid, "EHidinfo", HDFfid, sdInterfaceID, &dum);
581 :
582 0 : return (status);
583 : }
584 :
585 :
586 :
587 : /*----------------------------------------------------------------------------|
588 : | BEGIN_PROLOG |
589 : | |
590 : | FUNCTION: EHfilename |
591 : | |
592 : | DESCRIPTION: Returns HDF filename |
593 : | |
594 : | |
595 : | Return Value Type Units Description |
596 : | ============ ====== ========= ===================================== |
597 : | status intn return status (0) SUCCEED, (-1) FAIL |
598 : | |
599 : | INPUTS: |
600 : | fid int32 HDF-EOS file id |
601 : | |
602 : | OUTPUTS: |
603 : | filename char HDF-EOS file name |
604 : | |
605 : | NOTES: |
606 : | |
607 : | |
608 : | Date Programmer Description |
609 : | ====== ============ ================================================= |
610 : | Sep 96 Joel Gales Original Programmer |
611 : | |
612 : | END_PROLOG |
613 : -----------------------------------------------------------------------------*/
614 : intn
615 0 : EHfilename(int32 fid, char *filename)
616 : {
617 0 : intn status = 0; /* routine return status variable */
618 : intn dum; /* Dummy variable */
619 :
620 : char *fname; /* Pointer to filename */
621 :
622 : /* Get point to filename from Hfidinquire */
623 : /* -------------------------------------- */
624 0 : Hfidinquire(EHXfidTable[fid % EHIDOFFSET], &fname, &dum, &dum);
625 0 : strcpy(filename, fname);
626 :
627 0 : return (status);
628 : }
629 :
630 :
631 :
632 :
633 : /*----------------------------------------------------------------------------|
634 : | BEGIN_PROLOG |
635 : | |
636 : | FUNCTION: EHgetversion |
637 : | |
638 : | DESCRIPTION: Returns HDF-EOS version string |
639 : | |
640 : | |
641 : | Return Value Type Units Description |
642 : | ============ ====== ========= ===================================== |
643 : | status intn return status (0) SUCCEED, (-1) FAIL |
644 : | |
645 : | INPUTS: |
646 : | fid int32 HDF-EOS file id |
647 : | |
648 : | OUTPUTS: |
649 : | version char HDF-EOS version string |
650 : | |
651 : | NOTES: |
652 : | |
653 : | |
654 : | Date Programmer Description |
655 : | ====== ============ ================================================= |
656 : | Mar 97 Joel Gales Original Programmer |
657 : | |
658 : | END_PROLOG |
659 : -----------------------------------------------------------------------------*/
660 : intn
661 0 : EHgetversion(int32 fid, char *version)
662 : {
663 0 : intn status = 0; /* routine return status variable */
664 :
665 : uint8 access; /* Access code */
666 : int32 dum; /* Dummy variable */
667 0 : int32 sdInterfaceID = 0; /* HDF SDS interface ID */
668 : int32 attrIndex; /* HDFEOS version attribute index */
669 : int32 count; /* Version string size */
670 :
671 : char attrname[16]; /* Attribute name */
672 :
673 :
674 : /* Get SDS interface ID */
675 : /* -------------------- */
676 0 : status = EHchkfid(fid, "EHgetversion", &dum, &sdInterfaceID, &access);
677 :
678 :
679 : /* Get attribute index number */
680 : /* -------------------------- */
681 0 : attrIndex = SDfindattr(sdInterfaceID, "HDFEOSVersion");
682 :
683 : /* No such attribute */
684 : /* ----------------- */
685 0 : if (attrIndex < 0)
686 0 : return (-1);
687 :
688 : /* Get attribute size */
689 : /* ------------------ */
690 0 : status = SDattrinfo(sdInterfaceID, attrIndex, attrname, &dum, &count);
691 :
692 : /* Check return status */
693 : /* ------------------- */
694 0 : if (status < 0)
695 0 : return (-1);
696 :
697 : /* Read version attribute */
698 : /* ---------------------- */
699 0 : status = SDreadattr(sdInterfaceID, attrIndex, (VOIDP) version);
700 :
701 :
702 : /* Place string terminator on version string */
703 : /* ----------------------------------------- */
704 0 : version[count] = 0;
705 :
706 :
707 0 : return (status);
708 : }
709 :
710 :
711 :
712 :
713 : /*----------------------------------------------------------------------------|
714 : | BEGIN_PROLOG |
715 : | |
716 : | FUNCTION: EHconvAng |
717 : | |
718 : | DESCRIPTION: Angle conversion Utility |
719 : | |
720 : | |
721 : | Return Value Type Units Description |
722 : | ============ ====== ========= ===================================== |
723 : | outAngle float64 Output Angle value |
724 : | |
725 : | INPUTS: |
726 : | inAngle float64 Input Angle value |
727 : | code intn Conversion code |
728 : ! HDFE_RAD_DEG (0) |
729 : | HDFE_DEG_RAD (1) |
730 : | HDFE_DMS_DEG (2) |
731 : | HDFE_DEG_DMS (3) |
732 : | HDFE_RAD_DMS (4) |
733 : | HDFE_DMS_RAD (5) |
734 : | |
735 : | OUTPUTS: |
736 : | None |
737 : | |
738 : | NOTES: |
739 : | |
740 : | |
741 : | Date Programmer Description |
742 : | ====== ============ ================================================= |
743 : | Jun 96 Joel Gales Original Programmer |
744 : | Feb 97 Joel Gales Correct "60" min & "60" sec in _DMS conversion |
745 : | |
746 : | END_PROLOG |
747 : -----------------------------------------------------------------------------*/
748 : float64
749 0 : EHconvAng(float64 inAngle, intn code)
750 : {
751 : #define RADIANS_TO_DEGREES 180. / 3.14159265358979324
752 : #define DEGREES_TO_RADIANS 3.14159265358979324 / 180.
753 :
754 : int32 min; /* Truncated Minutes */
755 : int32 deg; /* Truncated Degrees */
756 :
757 : float64 sec; /* Seconds */
758 0 : float64 outAngle = 0.0; /* Angle in desired units */
759 :
760 0 : switch (code)
761 : {
762 :
763 : /* Convert radians to degrees */
764 : /* -------------------------- */
765 0 : case HDFE_RAD_DEG:
766 0 : outAngle = inAngle * RADIANS_TO_DEGREES;
767 0 : break;
768 :
769 :
770 : /* Convert degrees to radians */
771 : /* -------------------------- */
772 0 : case HDFE_DEG_RAD:
773 0 : outAngle = inAngle * DEGREES_TO_RADIANS;
774 0 : break;
775 :
776 :
777 : /* Convert packed degrees to degrees */
778 : /* --------------------------------- */
779 0 : case HDFE_DMS_DEG:
780 0 : deg = (int32)(inAngle / 1000000);
781 0 : min = (int32)((inAngle - deg * 1000000) / 1000);
782 0 : sec = (inAngle - deg * 1000000 - min * 1000);
783 0 : outAngle = deg + min / 60.0 + sec / 3600.0;
784 0 : break;
785 :
786 :
787 : /* Convert degrees to packed degrees */
788 : /* --------------------------------- */
789 0 : case HDFE_DEG_DMS:
790 0 : deg = (int32)(inAngle);
791 0 : min = (int32)((inAngle - deg) * 60);
792 0 : sec = (inAngle - deg - min / 60.0) * 3600;
793 :
794 0 : if ((intn) sec == 60)
795 : {
796 0 : sec = sec - 60;
797 0 : min = min + 1;
798 : }
799 0 : if (min == 60)
800 : {
801 0 : min = min - 60;
802 0 : deg = deg + 1;
803 : }
804 0 : outAngle = deg * 1000000 + min * 1000 + sec;
805 0 : break;
806 :
807 :
808 : /* Convert radians to packed degrees */
809 : /* --------------------------------- */
810 0 : case HDFE_RAD_DMS:
811 0 : inAngle = inAngle * RADIANS_TO_DEGREES;
812 0 : deg = (int32)(inAngle);
813 0 : min = (int32)((inAngle - deg) * 60);
814 0 : sec = (inAngle - deg - min / 60.0) * 3600;
815 :
816 0 : if ((intn) sec == 60)
817 : {
818 0 : sec = sec - 60;
819 0 : min = min + 1;
820 : }
821 0 : if (min == 60)
822 : {
823 0 : min = min - 60;
824 0 : deg = deg + 1;
825 : }
826 0 : outAngle = deg * 1000000 + min * 1000 + sec;
827 0 : break;
828 :
829 :
830 : /* Convert packed degrees to radians */
831 : /* --------------------------------- */
832 0 : case HDFE_DMS_RAD:
833 0 : deg = (int32)(inAngle / 1000000);
834 0 : min = (int32)((inAngle - deg * 1000000) / 1000);
835 0 : sec = (inAngle - deg * 1000000 - min * 1000);
836 0 : outAngle = deg + min / 60.0 + sec / 3600.0;
837 0 : outAngle = outAngle * DEGREES_TO_RADIANS;
838 0 : break;
839 : }
840 0 : return (outAngle);
841 : }
842 :
843 : #undef TO_DEGREES
844 : #undef TO_RADIANS
845 :
846 :
847 : /*----------------------------------------------------------------------------|
848 : | BEGIN_PROLOG |
849 : | |
850 : | FUNCTION: EHparsestr |
851 : | |
852 : | DESCRIPTION: String Parser Utility |
853 : | |
854 : | |
855 : | Return Value Type Units Description |
856 : | ============ ====== ========= ===================================== |
857 : | count int32 Number of string entries |
858 : | |
859 : | INPUTS: |
860 : | instring const char Input string |
861 : | delim const char string delimiter |
862 : | |
863 : | OUTPUTS: |
864 : | pntr char * Pointer array to beginning of each |
865 : | string entry |
866 : | len int32 Array of string entry lengths |
867 : | |
868 : | NOTES: |
869 : | |
870 : | |
871 : | Date Programmer Description |
872 : | ====== ============ ================================================= |
873 : | Jun 96 Joel Gales Original Programmer |
874 : | Aug 96 Joel Gales NULL pointer array returns count only |
875 : | |
876 : | END_PROLOG |
877 : -----------------------------------------------------------------------------*/
878 : int32
879 0 : EHparsestr(const char *instring, const char delim, char *pntr[], int32 len[])
880 : {
881 : int32 i; /* Loop index */
882 0 : int32 prevDelimPos = 0; /* Previous delimiter position */
883 : int32 count; /* Number of elements in string list */
884 : int32 slen; /* String length */
885 :
886 : char *delimitor; /* Pointer to delimiter */
887 :
888 :
889 : /* Get length of input string list & Point to first delimiter */
890 : /* ---------------------------------------------------------- */
891 0 : slen = (int)strlen(instring);
892 0 : delimitor = strchr(instring, delim);
893 :
894 : /* If NULL string set count to zero otherwise set to 1 */
895 : /* --------------------------------------------------- */
896 0 : count = (slen == 0) ? 0 : 1;
897 :
898 :
899 : /* if string pointers are requested set first one to beginning of string */
900 : /* --------------------------------------------------------------------- */
901 0 : if (&pntr[0] != NULL)
902 : {
903 0 : pntr[0] = (char *)instring;
904 : }
905 : /* If delimiter not found ... */
906 : /* ---------------------------- */
907 0 : if (delimitor == NULL)
908 : {
909 : /* if string length requested then set to input string length */
910 : /* ---------------------------------------------------------- */
911 0 : if (len != NULL)
912 : {
913 0 : len[0] = slen;
914 : }
915 : } else
916 : /* Delimiters Found */
917 : /* ---------------- */
918 : {
919 : /* Loop through all characters in string */
920 : /* ------------------------------------- */
921 0 : for (i = 1; i < slen; i++)
922 : {
923 : /* If character is a delimiter ... */
924 : /* ------------------------------- */
925 0 : if (instring[i] == delim)
926 : {
927 :
928 : /* If string pointer requested */
929 : /* --------------------------- */
930 0 : if (&pntr[0] != NULL)
931 : {
932 : /* if requested then compute string length of entry */
933 : /* ------------------------------------------------ */
934 0 : if (len != NULL)
935 : {
936 0 : len[count - 1] = i - prevDelimPos;
937 : }
938 : /* Point to beginning of string entry */
939 : /* ---------------------------------- */
940 0 : pntr[count] = (char *)instring + i + 1;
941 : }
942 : /* Reset previous delimiter position and increment counter */
943 : /* ------------------------------------------------------- */
944 0 : prevDelimPos = i + 1;
945 0 : count++;
946 : }
947 : }
948 :
949 : /* Compute string length of last entry */
950 : /* ----------------------------------- */
951 0 : if (&pntr[0] != NULL && len != NULL)
952 : {
953 0 : len[count - 1] = i - prevDelimPos;
954 : }
955 : }
956 :
957 0 : return (count);
958 : }
959 :
960 :
961 :
962 :
963 : /*----------------------------------------------------------------------------|
964 : | BEGIN_PROLOG |
965 : | |
966 : | FUNCTION: EHstrwithin |
967 : | |
968 : | DESCRIPTION: Searches for string within target string |
969 : | |
970 : | |
971 : | Return Value Type Units Description |
972 : | ============ ====== ========= ===================================== |
973 : | indx int32 Element index (0 - based) |
974 : | |
975 : | INPUTS: |
976 : | target const char Target string |
977 : | search const char Search string |
978 : | delim const char Delimiter |
979 : | |
980 : | OUTPUTS: |
981 : | None |
982 : | |
983 : | NOTES: |
984 : | |
985 : | |
986 : | Date Programmer Description |
987 : | ====== ============ ================================================= |
988 : | Jun 96 Joel Gales Original Programmer |
989 : | Jan 97 Joel Gales Change ptr & slen to dynamic arrays |
990 : | |
991 : | END_PROLOG |
992 : -----------------------------------------------------------------------------*/
993 : int32
994 0 : EHstrwithin(const char *target, const char *search, const char delim)
995 : {
996 0 : intn found = 0; /* Target string found flag */
997 :
998 : int32 indx; /* Loop index */
999 : int32 nentries; /* Number of entries in search string */
1000 : int32 *slen; /* Pointer to string length array */
1001 :
1002 : char **ptr; /* Pointer to string pointer array */
1003 : char buffer[128];/* Buffer to hold "test" string entry */
1004 :
1005 :
1006 : /* Count number of entries in search string list */
1007 : /* --------------------------------------------- */
1008 0 : nentries = EHparsestr(search, delim, NULL, NULL);
1009 :
1010 :
1011 : /* Allocate string pointer and length arrays */
1012 : /* ----------------------------------------- */
1013 0 : ptr = (char **) calloc(nentries, sizeof(char *));
1014 0 : if(ptr == NULL)
1015 : {
1016 0 : HEpush(DFE_NOSPACE,"EHstrwithin", __FILE__, __LINE__);
1017 0 : return(-1);
1018 : }
1019 0 : slen = (int32 *) calloc(nentries, sizeof(int32));
1020 0 : if(slen == NULL)
1021 : {
1022 0 : HEpush(DFE_NOSPACE,"EHstrwithin", __FILE__, __LINE__);
1023 0 : free(ptr);
1024 0 : return(-1);
1025 : }
1026 :
1027 :
1028 : /* Parse search string */
1029 : /* ------------------- */
1030 0 : nentries = EHparsestr(search, delim, ptr, slen);
1031 :
1032 :
1033 : /* Loop through all elements in search string list */
1034 : /* ----------------------------------------------- */
1035 0 : for (indx = 0; indx < nentries; indx++)
1036 : {
1037 : /* Copy string entry into buffer */
1038 : /* ----------------------------- */
1039 0 : memcpy(buffer, ptr[indx], slen[indx]);
1040 0 : buffer[slen[indx]] = 0;
1041 :
1042 :
1043 : /* Compare target string with string entry */
1044 : /* --------------------------------------- */
1045 0 : if (strcmp(target, buffer) == 0)
1046 : {
1047 0 : found = 1;
1048 0 : break;
1049 : }
1050 : }
1051 :
1052 : /* If not found set return to -1 */
1053 : /* ----------------------------- */
1054 0 : if (found == 0)
1055 : {
1056 0 : indx = -1;
1057 : }
1058 0 : free(slen);
1059 0 : free(ptr);
1060 :
1061 0 : return (indx);
1062 : }
1063 :
1064 :
1065 :
1066 :
1067 :
1068 : /*----------------------------------------------------------------------------|
1069 : | BEGIN_PROLOG |
1070 : | |
1071 : | FUNCTION: EHloadliststr |
1072 : | |
1073 : | DESCRIPTION: Builds list string from string array |
1074 : | |
1075 : | |
1076 : | Return Value Type Units Description |
1077 : | ============ ====== ========= ===================================== |
1078 : | status intn return status (0) SUCCEED, (-1) FAIL |
1079 : | |
1080 : | INPUTS: |
1081 : | ptr char String pointer array |
1082 : | nentries int32 Number of string array elements |
1083 : | delim char Delimiter |
1084 : | |
1085 : | OUTPUTS: |
1086 : | liststr char Output list string |
1087 : | |
1088 : | NOTES: |
1089 : | |
1090 : | |
1091 : | Date Programmer Description |
1092 : | ====== ============ ================================================= |
1093 : | Jun 96 Joel Gales Original Programmer |
1094 : | |
1095 : | END_PROLOG |
1096 : -----------------------------------------------------------------------------*/
1097 : intn
1098 0 : EHloadliststr(char *ptr[], int32 nentries, char *liststr, char delim)
1099 : {
1100 0 : intn status = 0; /* routine return status variable */
1101 :
1102 : int32 i; /* Loop index */
1103 : int32 slen; /* String entry length */
1104 0 : int32 off = 0; /* Position of next entry along string list */
1105 : char dstr[2]; /* string version of input variable "delim" */
1106 :
1107 0 : dstr[0] = delim;
1108 0 : dstr[1] = '\0';
1109 :
1110 :
1111 : /* Loop through all entries in string array */
1112 : /* ---------------------------------------- */
1113 0 : for (i = 0; i < nentries; i++)
1114 : {
1115 : /* Get string length of string array entry */
1116 : /* --------------------------------------- */
1117 0 : slen = (int)strlen(ptr[i]);
1118 :
1119 :
1120 : /* Copy string entry to string list */
1121 : /* -------------------------------- */
1122 0 : memcpy(liststr + off, ptr[i], slen + 1);
1123 :
1124 :
1125 : /* Concatenate with delimiter */
1126 : /* -------------------------- */
1127 0 : if (i != nentries - 1)
1128 : {
1129 0 : strcat(liststr, dstr);
1130 : }
1131 : /* Get position of next entry for string list */
1132 : /* ------------------------------------------ */
1133 0 : off += slen + 1;
1134 : }
1135 :
1136 0 : return (status);
1137 : }
1138 :
1139 :
1140 :
1141 :
1142 :
1143 : /*----------------------------------------------------------------------------|
1144 : | BEGIN_PROLOG |
1145 : | |
1146 : | FUNCTION: EHgetid |
1147 : | |
1148 : | DESCRIPTION: Get Vgroup/Vdata ID from name |
1149 : | |
1150 : | |
1151 : | Return Value Type Units Description |
1152 : | ============ ====== ========= ===================================== |
1153 : | outID int32 Output ID |
1154 : | |
1155 : | INPUTS: |
1156 : | fid int32 HDF-EOS file ID |
1157 : | vgid int32 Vgroup ID |
1158 : | objectname const char object name |
1159 : | code intn object code (0 - Vgroup, 1 - Vdata) |
1160 : | access const char access ("w/r") |
1161 : | |
1162 : | |
1163 : | OUTPUTS: |
1164 : | None |
1165 : | |
1166 : | NOTES: |
1167 : | |
1168 : | |
1169 : | Date Programmer Description |
1170 : | ====== ============ ================================================= |
1171 : | Jun 96 Joel Gales Original Programmer |
1172 : | |
1173 : | END_PROLOG |
1174 : -----------------------------------------------------------------------------*/
1175 : int32
1176 0 : EHgetid(int32 fid, int32 vgid, const char *objectname, intn code,
1177 : const char *access)
1178 : {
1179 : intn i; /* Loop index */
1180 :
1181 : int32 nObjects; /* # of objects in Vgroup */
1182 : int32 *tags; /* Pnt to Vgroup object tags array */
1183 : int32 *refs; /* Pnt to Vgroup object refs array */
1184 : int32 id; /* Object ID */
1185 0 : int32 outID = -1; /* Desired object ID */
1186 :
1187 : char name[128]; /* Object name */
1188 :
1189 :
1190 : /* Get Number of objects */
1191 : /* --------------------- */
1192 0 : nObjects = Vntagrefs(vgid);
1193 :
1194 : /* If objects exist ... */
1195 : /* -------------------- */
1196 0 : if (nObjects != 0)
1197 : {
1198 :
1199 : /* Get tags and references of objects */
1200 : /* ---------------------------------- */
1201 0 : tags = (int32 *) malloc(sizeof(int32) * nObjects);
1202 0 : if(tags == NULL)
1203 : {
1204 0 : HEpush(DFE_NOSPACE,"EHgetid", __FILE__, __LINE__);
1205 0 : return(-1);
1206 : }
1207 0 : refs = (int32 *) malloc(sizeof(int32) * nObjects);
1208 0 : if(refs == NULL)
1209 : {
1210 0 : HEpush(DFE_NOSPACE,"EHgetid", __FILE__, __LINE__);
1211 0 : free(tags);
1212 0 : return(-1);
1213 : }
1214 :
1215 0 : Vgettagrefs(vgid, tags, refs, nObjects);
1216 :
1217 :
1218 : /* Vgroup ID Section */
1219 : /* ----------------- */
1220 0 : if (code == 0)
1221 : {
1222 : /* Loop through objects */
1223 : /* -------------------- */
1224 0 : for (i = 0; i < nObjects; i++)
1225 : {
1226 :
1227 : /* If object is Vgroup ... */
1228 : /* ----------------------- */
1229 0 : if (*(tags + i) == DFTAG_VG)
1230 : {
1231 :
1232 : /* Get ID and name */
1233 : /* --------------- */
1234 0 : id = Vattach(fid, *(refs + i), access);
1235 0 : Vgetname(id, name);
1236 :
1237 : /* If name equals desired object name get ID */
1238 : /* ----------------------------------------- */
1239 0 : if (strcmp(name, objectname) == 0)
1240 : {
1241 0 : outID = id;
1242 0 : break;
1243 : }
1244 : /* If not desired object then detach */
1245 : /* --------------------------------- */
1246 0 : Vdetach(id);
1247 : }
1248 : }
1249 0 : } else if (code == 1)
1250 : {
1251 :
1252 : /* Loop through objects */
1253 : /* -------------------- */
1254 0 : for (i = 0; i < nObjects; i++)
1255 : {
1256 :
1257 : /* If object is Vdata ... */
1258 : /* ---------------------- */
1259 0 : if (*(tags + i) == DFTAG_VH)
1260 : {
1261 :
1262 : /* Get ID and name */
1263 : /* --------------- */
1264 0 : id = VSattach(fid, *(refs + i), access);
1265 0 : VSgetname(id, name);
1266 :
1267 : /* If name equals desired object name get ID */
1268 : /* ----------------------------------------- */
1269 0 : if (EHstrwithin(objectname, name, ',') != -1)
1270 : {
1271 0 : outID = id;
1272 0 : break;
1273 : }
1274 : /* If not desired object then detach */
1275 : /* --------------------------------- */
1276 0 : VSdetach(id);
1277 : }
1278 : }
1279 : }
1280 0 : free(tags);
1281 0 : free(refs);
1282 : }
1283 0 : return (outID);
1284 : }
1285 :
1286 :
1287 :
1288 :
1289 :
1290 : /*----------------------------------------------------------------------------|
1291 : | BEGIN_PROLOG |
1292 : | |
1293 : | FUNCTION: EHrevflds |
1294 : | |
1295 : | DESCRIPTION: Reverses elements in a string list |
1296 : | |
1297 : | |
1298 : | Return Value Type Units Description |
1299 : | ============ ====== ========= ===================================== |
1300 : | status intn return status (0) SUCCEED, (-1) FAIL |
1301 : | |
1302 : | INPUTS: |
1303 : | dimlist char Original dimension list |
1304 : | |
1305 : | OUTPUTS: |
1306 : | revdimlist char Reversed dimension list |
1307 : | |
1308 : | NOTES: |
1309 : | |
1310 : | |
1311 : | Date Programmer Description |
1312 : | ====== ============ ================================================= |
1313 : | Jun 96 Joel Gales Original Programmer |
1314 : | |
1315 : | END_PROLOG |
1316 : -----------------------------------------------------------------------------*/
1317 : intn
1318 0 : EHrevflds(const char *dimlist, char *revdimlist)
1319 : {
1320 0 : intn status = 0; /* routine return status variable */
1321 :
1322 : int32 indx; /* Loop index */
1323 : int32 nentries; /* Number of entries in search string */
1324 : int32 *slen; /* Pointer to string length array */
1325 :
1326 : char **ptr; /* Pointer to string pointer array */
1327 : char *tempPtr; /* Temporary string pointer */
1328 : char *tempdimlist;/* Temporary dimension list */
1329 :
1330 :
1331 : /* Copy dimlist into temp dimlist */
1332 : /* ------------------------------ */
1333 0 : tempdimlist = (char *) malloc(strlen(dimlist) + 1);
1334 0 : if(tempdimlist == NULL)
1335 : {
1336 0 : HEpush(DFE_NOSPACE,"EHrevflds", __FILE__, __LINE__);
1337 0 : return(-1);
1338 : }
1339 0 : strcpy(tempdimlist, dimlist);
1340 :
1341 :
1342 : /* Count number of entries in search string list */
1343 : /* --------------------------------------------- */
1344 0 : nentries = EHparsestr(tempdimlist, ',', NULL, NULL);
1345 :
1346 :
1347 : /* Allocate string pointer and length arrays */
1348 : /* ----------------------------------------- */
1349 0 : ptr = (char **) calloc(nentries, sizeof(char *));
1350 0 : if(ptr == NULL)
1351 : {
1352 0 : HEpush(DFE_NOSPACE,"EHrevflds", __FILE__, __LINE__);
1353 0 : free(tempdimlist);
1354 0 : return(-1);
1355 : }
1356 0 : slen = (int32 *) calloc(nentries, sizeof(int32));
1357 0 : if(slen == NULL)
1358 : {
1359 0 : HEpush(DFE_NOSPACE,"EHrevflds", __FILE__, __LINE__);
1360 0 : free(ptr);
1361 0 : free(tempdimlist);
1362 0 : return(-1);
1363 : }
1364 :
1365 :
1366 : /* Parse search string */
1367 : /* ------------------- */
1368 0 : nentries = EHparsestr(tempdimlist, ',', ptr, slen);
1369 :
1370 :
1371 : /* Reverse entries in string pointer array */
1372 : /* --------------------------------------- */
1373 0 : for (indx = 0; indx < nentries / 2; indx++)
1374 : {
1375 0 : tempPtr = ptr[indx];
1376 0 : ptr[indx] = ptr[nentries - 1 - indx];
1377 0 : ptr[nentries - 1 - indx] = tempPtr;
1378 : }
1379 :
1380 :
1381 : /* Replace comma delimiters by nulls */
1382 : /* --------------------------------- */
1383 0 : for (indx = 0; indx < nentries - 1; indx++)
1384 : {
1385 0 : *(ptr[indx] - 1) = 0;
1386 : }
1387 :
1388 :
1389 : /* Build new string list */
1390 : /* --------------------- */
1391 0 : status = EHloadliststr(ptr, nentries, revdimlist, ',');
1392 :
1393 :
1394 0 : free(slen);
1395 0 : free(ptr);
1396 0 : free(tempdimlist);
1397 :
1398 0 : return (status);
1399 : }
1400 :
1401 :
1402 : /*----------------------------------------------------------------------------|
1403 : | BEGIN_PROLOG |
1404 : | |
1405 : | FUNCTION: EHcntOBJECT |
1406 : | |
1407 : | DESCRIPTION: Determines number of OBJECTs in metadata GROUP |
1408 : | |
1409 : | |
1410 : | Return Value Type Units Description |
1411 : | ============ ====== ========= ===================================== |
1412 : | count int32 Number of OBJECTs in GROUP |
1413 : | |
1414 : | INPUTS: |
1415 : | metabuf char Begin & end metadata pointer array |
1416 : | |
1417 : | OUTPUTS: |
1418 : | None |
1419 : | |
1420 : | NOTES: |
1421 : | |
1422 : | |
1423 : | Date Programmer Description |
1424 : | ====== ============ ================================================= |
1425 : | Sep 96 Joel Gales Original Programmer |
1426 : | |
1427 : | END_PROLOG |
1428 : -----------------------------------------------------------------------------*/
1429 : int32
1430 0 : EHcntOBJECT(char *metabuf[])
1431 : {
1432 0 : int32 count = 0; /* Counter */
1433 :
1434 : char *metaptr; /* Beginning of metadata section */
1435 : char *endptr; /* End of metadata section */
1436 : char *tempptr; /* Pointer within metadata section */
1437 :
1438 :
1439 : /* Get Pointers to beginning and ending of metadata section */
1440 : /* -------------------------------------------------------- */
1441 0 : metaptr = metabuf[0];
1442 0 : endptr = metabuf[1];
1443 :
1444 :
1445 : /* Find number of "END_OBJECT" strings within section */
1446 : /* -------------------------------------------------- */
1447 0 : tempptr = metaptr;
1448 0 : while (tempptr < endptr && tempptr != NULL)
1449 : {
1450 0 : tempptr = strstr(tempptr + 1, "END_OBJECT");
1451 0 : count++;
1452 : }
1453 0 : count--;
1454 :
1455 0 : return (count);
1456 : }
1457 :
1458 :
1459 :
1460 :
1461 :
1462 : /*----------------------------------------------------------------------------|
1463 : | BEGIN_PROLOG |
1464 : | |
1465 : | FUNCTION: EHcntGROUP |
1466 : | |
1467 : | DESCRIPTION: Determines number of GROUPs in metadata GROUP |
1468 : | |
1469 : | |
1470 : | Return Value Type Units Description |
1471 : | ============ ====== ========= ===================================== |
1472 : | count int32 Number of GROUPs in GROUP |
1473 : | |
1474 : | INPUTS: |
1475 : | metabuf char Begin & end metadata pointer array |
1476 : | |
1477 : | OUTPUTS: |
1478 : | None |
1479 : | |
1480 : | NOTES: |
1481 : | |
1482 : | |
1483 : | Date Programmer Description |
1484 : | ====== ============ ================================================= |
1485 : | Sep 96 Joel Gales Original Programmer |
1486 : | |
1487 : | END_PROLOG |
1488 : -----------------------------------------------------------------------------*/
1489 : int32
1490 0 : EHcntGROUP(char *metabuf[])
1491 : {
1492 0 : int32 count = 0; /* Counter */
1493 :
1494 : char *metaptr; /* Beginning of metadata section */
1495 : char *endptr; /* End of metadata section */
1496 : char *tempptr; /* Pointer within metadata section */
1497 :
1498 :
1499 : /* Get Pointers to beginning and ending of metadata section */
1500 : /* -------------------------------------------------------- */
1501 0 : metaptr = metabuf[0];
1502 0 : endptr = metabuf[1];
1503 :
1504 :
1505 : /* Find number of "END_GROUP" strings within section */
1506 : /* ------------------------------------------------- */
1507 0 : tempptr = metaptr;
1508 0 : while (tempptr < endptr && tempptr != NULL)
1509 : {
1510 0 : tempptr = strstr(tempptr + 1, "END_GROUP");
1511 0 : count++;
1512 : }
1513 0 : count--;
1514 :
1515 0 : return (count);
1516 : }
1517 :
1518 :
1519 :
1520 :
1521 : /*----------------------------------------------------------------------------|
1522 : | BEGIN_PROLOG |
1523 : | |
1524 : | FUNCTION: EHmetalist |
1525 : | |
1526 : | DESCRIPTION: Converts string list to metadata list |
1527 : | |
1528 : | |
1529 : | Return Value Type Units Description |
1530 : | ============ ====== ========= ===================================== |
1531 : | status intn return status (0) SUCCEED, (-1) FAIL |
1532 : | |
1533 : | INPUTS: |
1534 : | instring char Input string list |
1535 : | |
1536 : | OUTPUTS: |
1537 : | outstring char Output metadata string |
1538 : | |
1539 : | NOTES: |
1540 : | |
1541 : | |
1542 : | Date Programmer Description |
1543 : | ====== ============ ================================================= |
1544 : | Jun 96 Joel Gales Original Programmer |
1545 : | |
1546 : | END_PROLOG |
1547 : -----------------------------------------------------------------------------*/
1548 : intn
1549 0 : EHmetalist(const char *instring, char *outstring)
1550 : {
1551 : intn i; /* Loop index */
1552 0 : intn status = 0; /* routine return status variable */
1553 :
1554 : int32 nentries; /* Number of entries in search string */
1555 0 : int32 listlen = 1;/* String list length */
1556 : int32 *slen; /* Pointer to string length array */
1557 :
1558 : char **ptr; /* Pointer to string pointer array */
1559 :
1560 :
1561 : /* Count number of entries in search string list */
1562 : /* --------------------------------------------- */
1563 0 : nentries = EHparsestr(instring, ',', NULL, NULL);
1564 :
1565 :
1566 : /* Allocate string pointer and length arrays */
1567 : /* ----------------------------------------- */
1568 0 : ptr = (char **) calloc(nentries, sizeof(char *));
1569 0 : if(ptr == NULL)
1570 : {
1571 0 : HEpush(DFE_NOSPACE,"EHmetalist", __FILE__, __LINE__);
1572 0 : return(-1);
1573 : }
1574 0 : slen = (int32 *) calloc(nentries, sizeof(int32));
1575 0 : if(slen == NULL)
1576 : {
1577 0 : HEpush(DFE_NOSPACE,"EHmetalist", __FILE__, __LINE__);
1578 0 : free(ptr);
1579 0 : return(-1);
1580 : }
1581 :
1582 :
1583 : /* Parse input string */
1584 : /* ------------------ */
1585 0 : nentries = EHparsestr(instring, ',', ptr, slen);
1586 :
1587 :
1588 : /* Start output string with leading "(" */
1589 : /* ------------------------------------ */
1590 0 : strcpy(outstring, "(");
1591 :
1592 :
1593 : /* Loop through all entries */
1594 : /* ------------------------ */
1595 0 : for (i = 0; i < nentries; i++)
1596 : {
1597 : /* Add double quote (") to output string */
1598 : /* ------------------------------------- */
1599 0 : strcat(outstring, "\"");
1600 0 : listlen++;
1601 :
1602 : /* Add input string entry to output string */
1603 : /* --------------------------------------- */
1604 0 : memcpy(outstring + listlen, ptr[i], slen[i]);
1605 0 : listlen += slen[i];
1606 0 : outstring[listlen] = 0;
1607 :
1608 :
1609 : /* Add closing double quote (") to output string */
1610 : /* --------------------------------------------- */
1611 0 : strcat(outstring, "\"");
1612 0 : listlen++;
1613 0 : outstring[listlen] = 0;
1614 :
1615 :
1616 : /* Add comma delimiter to output string */
1617 : /* ------------------------------------ */
1618 0 : if (i != (nentries - 1))
1619 : {
1620 0 : strcat(outstring, ",");
1621 0 : listlen++;
1622 : }
1623 : /* Place null terminator in output string */
1624 : /* -------------------------------------- */
1625 0 : outstring[listlen] = 0;
1626 : }
1627 :
1628 :
1629 : /* End output string with trailing ")" */
1630 : /* ----------------------------------- */
1631 0 : strcat(outstring, ")");
1632 :
1633 0 : free(ptr);
1634 0 : free(slen);
1635 :
1636 0 : return (status);
1637 : }
1638 :
1639 :
1640 :
1641 :
1642 :
1643 : /*----------------------------------------------------------------------------|
1644 : | BEGIN_PROLOG |
1645 : | |
1646 : | FUNCTION: EHinsertmeta |
1647 : | |
1648 : | DESCRIPTION: Writes metadata |
1649 : | |
1650 : | |
1651 : | Return Value Type Units Description |
1652 : | ============ ====== ========= ===================================== |
1653 : | status intn return status (0) SUCCEED, (-1) FAIL |
1654 : | |
1655 : | INPUTS: |
1656 : | sdInterfaceID int32 SDS interface ID |
1657 : | structname char HDF-EOS structure name |
1658 : | structcode char Structure code ("s/g/p") |
1659 : | metacode int32 Metadata code type |
1660 : | metastr char Metadata input string |
1661 : | metadata int32 Metadata utility array |
1662 : | |
1663 : | OUTPUTS: |
1664 : | None |
1665 : | |
1666 : | NOTES: |
1667 : | |
1668 : | |
1669 : | Date Programmer Description |
1670 : | ====== ============ ================================================= |
1671 : | Jun 96 Joel Gales Original Programmer |
1672 : | Aug 96 Joel Gales Make metadata ODL compliant |
1673 : | Sep 96 Joel Gales Allow new metadata object to be written in |
1674 : | old metadata. |
1675 : | Dec 96 Joel Gales Fix Point metadata problem |
1676 : | Oct 98 David Wynne Change utlstr/utlstr2 to dynamic allocation from |
1677 : | static |
1678 : | |
1679 : | END_PROLOG |
1680 : -----------------------------------------------------------------------------*/
1681 : intn
1682 0 : EHinsertmeta(int32 sdInterfaceID, const char *structname, const char *structcode,
1683 : int32 metacode, char *metastr, int32 metadata[])
1684 : {
1685 : intn i; /* Loop index */
1686 0 : intn status = 0; /* routine return status variable */
1687 :
1688 : int32 attrIndex; /* Structural metadata attribute index */
1689 : int32 slen[8]; /* String length array (for dim map parsing) */
1690 : int32 nmeta; /* Number of 32000 byte metadata sections */
1691 : int32 metalen; /* Length of structural metadata */
1692 : int32 seglen; /* Length of metadata string to insert */
1693 : int32 count; /* Objects/Groups counter */
1694 : int32 offset; /* Offset insertion position of new metadata
1695 : * section within existing metadata */
1696 :
1697 : char *metabuf; /* Pointer (handle) to structural metadata */
1698 : char *begptr; /* Pointer to beginning of metadata section */
1699 : char *metaptr; /* Metadata pointer */
1700 : char *prevmetaptr;/* Previous position of metadata pointer */
1701 : char *ptr[8]; /* String pointer array (for dim map parsing) */
1702 : char type[32]; /* Number type descriptor string */
1703 : char *metaArr[2]; /* Array of metadata positions */
1704 : char *colon; /* Colon position */
1705 : char *colon2; /* 2nd colon position */
1706 : char *slash; /* Slash position */
1707 : char *utlstr; /* Utility string */
1708 : char *utlstr2; /* Utility string 2 */
1709 :
1710 :
1711 : /* Allocate space for utility strings */
1712 : /* ---------------------------------- */
1713 0 : utlstr = (char *) calloc(UTLSTRSIZE, sizeof(char));
1714 0 : if(utlstr == NULL)
1715 : {
1716 0 : HEpush(DFE_NOSPACE,"EHinsertmeta", __FILE__, __LINE__);
1717 0 : return(-1);
1718 : }
1719 :
1720 0 : utlstr2 = (char *) calloc(UTLSTRSIZE, sizeof(char));
1721 0 : if(utlstr2 == NULL)
1722 : {
1723 0 : HEpush(DFE_NOSPACE,"EHinsertmeta", __FILE__, __LINE__);
1724 0 : free(utlstr);
1725 0 : return(-1);
1726 : }
1727 :
1728 : /* Determine number of structural metadata "sections" */
1729 : /* -------------------------------------------------- */
1730 0 : nmeta = 0;
1731 : while (1)
1732 : {
1733 : /* Search for "StructMetadata.x" attribute */
1734 : /* --------------------------------------- */
1735 0 : snprintf(utlstr, UTLSTRSIZE, "%s%d", "StructMetadata.", (int)nmeta);
1736 0 : attrIndex = SDfindattr(sdInterfaceID, utlstr);
1737 :
1738 :
1739 : /* If found then increment metadata section counter else exit loop */
1740 : /* --------------------------------------------------------------- */
1741 0 : if (attrIndex != -1)
1742 : {
1743 0 : nmeta++;
1744 : } else
1745 : {
1746 0 : break;
1747 : }
1748 : }
1749 :
1750 :
1751 : /* Allocate space for metadata (in units of 32000 bytes) */
1752 : /* ----------------------------------------------------- */
1753 0 : metabuf = (char *) calloc(32000 * nmeta, 1);
1754 0 : if(metabuf == NULL)
1755 : {
1756 0 : HEpush(DFE_NOSPACE,"EHinsertmeta", __FILE__, __LINE__);
1757 0 : free(utlstr);
1758 0 : free(utlstr2);
1759 0 : return(-1);
1760 : }
1761 :
1762 :
1763 : /* Read structural metadata */
1764 : /* ------------------------ */
1765 0 : for (i = 0; i < nmeta; i++)
1766 : {
1767 0 : snprintf(utlstr, UTLSTRSIZE, "%s%d", "StructMetadata.", i);
1768 0 : attrIndex = SDfindattr(sdInterfaceID, utlstr);
1769 0 : metalen = (int)strlen(metabuf);
1770 0 : SDreadattr(sdInterfaceID, attrIndex, metabuf + metalen);
1771 : }
1772 :
1773 : /* Determine length (# of characters) of metadata */
1774 : /* ---------------------------------------------- */
1775 0 : metalen = (int)strlen(metabuf);
1776 :
1777 :
1778 :
1779 : /* Find HDF-EOS structure "root" group in metadata */
1780 : /* ----------------------------------------------- */
1781 :
1782 : /* Setup proper search string */
1783 : /* -------------------------- */
1784 0 : if (strcmp(structcode, "s") == 0)
1785 : {
1786 0 : strcpy(utlstr, "GROUP=SwathStructure");
1787 0 : } else if (strcmp(structcode, "g") == 0)
1788 : {
1789 0 : strcpy(utlstr, "GROUP=GridStructure");
1790 0 : } else if (strcmp(structcode, "p") == 0)
1791 : {
1792 0 : strcpy(utlstr, "GROUP=PointStructure");
1793 : }
1794 : /* Use string search routine (strstr) to move through metadata */
1795 : /* ----------------------------------------------------------- */
1796 0 : metaptr = strstr(metabuf, utlstr);
1797 :
1798 :
1799 :
1800 : /* Find specific (named) structure */
1801 : /* ------------------------------- */
1802 0 : if (metacode < 1000)
1803 : {
1804 : /* Save current metadata pointer */
1805 : /* ----------------------------- */
1806 0 : prevmetaptr = metaptr;
1807 :
1808 :
1809 : /* First loop for "old-style" (non-ODL) metadata string */
1810 : /* ---------------------------------------------------- */
1811 0 : if (strcmp(structcode, "s") == 0)
1812 : {
1813 0 : snprintf(utlstr, UTLSTRSIZE, "%s%s", "SwathName=\"", structname);
1814 0 : } else if (strcmp(structcode, "g") == 0)
1815 : {
1816 0 : snprintf(utlstr, UTLSTRSIZE, "%s%s", "GridName=\"", structname);
1817 0 : } else if (strcmp(structcode, "p") == 0)
1818 : {
1819 0 : snprintf(utlstr, UTLSTRSIZE, "%s%s", "PointName=\"", structname);
1820 : }
1821 : /* Do string search */
1822 : /* ---------------- */
1823 0 : metaptr = strstr(metaptr, utlstr);
1824 :
1825 :
1826 : /*
1827 : * If not found then return to previous position in metadata and look
1828 : * for "new-style" (ODL) metadata string
1829 : */
1830 0 : if (metaptr == NULL)
1831 : {
1832 0 : snprintf(utlstr, UTLSTRSIZE, "%s%s", "GROUP=\"", structname);
1833 0 : metaptr = strstr(prevmetaptr, utlstr);
1834 : }
1835 : }
1836 : /*
1837 : * If searching for geo fields (3), data fields (4), or point fields (11)
1838 : * convert type code to string designator.
1839 : */
1840 0 : if (metacode == 3 || metacode == 4 || metacode == 11)
1841 : {
1842 0 : switch (metadata[0])
1843 : {
1844 0 : case 3:
1845 0 : strcpy(type, "DFNT_UCHAR8");
1846 0 : break;
1847 0 : case 4:
1848 0 : strcpy(type, "DFNT_CHAR8");
1849 0 : break;
1850 0 : case 5:
1851 0 : strcpy(type, "DFNT_FLOAT32");
1852 0 : break;
1853 0 : case 6:
1854 0 : strcpy(type, "DFNT_FLOAT64");
1855 0 : break;
1856 0 : case 20:
1857 0 : strcpy(type, "DFNT_INT8");
1858 0 : break;
1859 0 : case 21:
1860 0 : strcpy(type, "DFNT_UINT8");
1861 0 : break;
1862 0 : case 22:
1863 0 : strcpy(type, "DFNT_INT16");
1864 0 : break;
1865 0 : case 23:
1866 0 : strcpy(type, "DFNT_UINT16");
1867 0 : break;
1868 0 : case 24:
1869 0 : strcpy(type, "DFNT_INT32");
1870 0 : break;
1871 0 : case 25:
1872 0 : strcpy(type, "DFNT_UINT32");
1873 0 : break;
1874 : }
1875 0 : }
1876 : /* Metadata Section Switch */
1877 : /* ----------------------- */
1878 0 : switch (abs(metacode))
1879 : {
1880 :
1881 0 : case 0:
1882 : /* Dimension Section */
1883 : /* ----------------- */
1884 :
1885 : /* Find beginning and ending of metadata section */
1886 : /* --------------------------------------------- */
1887 0 : strcpy(utlstr, "\t\tGROUP=Dimension");
1888 0 : begptr = strstr(metaptr, utlstr);
1889 :
1890 0 : strcpy(utlstr, "\t\tEND_GROUP=Dimension");
1891 0 : metaptr = strstr(metaptr, utlstr);
1892 :
1893 :
1894 : /* Count number of existing entries and increment */
1895 : /* ---------------------------------------------- */
1896 0 : metaArr[0] = begptr;
1897 0 : metaArr[1] = metaptr;
1898 0 : count = EHcntOBJECT(metaArr) + 1;
1899 :
1900 :
1901 : /* Build metadata entry string */
1902 : /* --------------------------- */
1903 0 : snprintf(utlstr, UTLSTRSIZE, "%s%d%s%s%s%d%s%d%s",
1904 : "\t\t\tOBJECT=Dimension_", (int)count,
1905 : "\n\t\t\t\tDimensionName=\"", &metastr[0],
1906 : "\"\n\t\t\t\tSize=", (int)metadata[0],
1907 : "\n\t\t\tEND_OBJECT=Dimension_", (int)count, "\n");
1908 0 : break;
1909 :
1910 :
1911 0 : case 1:
1912 : /* Dimension Map Section */
1913 : /* --------------------- */
1914 :
1915 : /* Find beginning and ending of metadata section */
1916 : /* --------------------------------------------- */
1917 0 : strcpy(utlstr, "\t\tGROUP=DimensionMap");
1918 0 : begptr = strstr(metaptr, utlstr);
1919 :
1920 0 : strcpy(utlstr, "\t\tEND_GROUP=DimensionMap");
1921 0 : metaptr = strstr(metaptr, utlstr);
1922 :
1923 :
1924 : /* Count number of existing entries and increment */
1925 : /* ---------------------------------------------- */
1926 0 : metaArr[0] = begptr;
1927 0 : metaArr[1] = metaptr;
1928 0 : count = EHcntOBJECT(metaArr) + 1;
1929 :
1930 :
1931 : /* Find slash within input mapping string and replace with NULL */
1932 : /* ------------------------------------------------------------ */
1933 0 : EHparsestr(metastr, '/', ptr, slen);
1934 0 : metastr[slen[0]] = 0;
1935 :
1936 :
1937 : /* Build metadata entry string */
1938 : /* --------------------------- */
1939 0 : snprintf(utlstr, UTLSTRSIZE, "%s%d%s%s%s%s%s%d%s%d%s%d%s",
1940 : "\t\t\tOBJECT=DimensionMap_", (int)count,
1941 : "\n\t\t\t\tGeoDimension=\"", &metastr[0],
1942 0 : "\"\n\t\t\t\tDataDimension=\"", &metastr[slen[0] + 1],
1943 : "\"\n\t\t\t\tOffset=", (int)metadata[0],
1944 0 : "\n\t\t\t\tIncrement=", (int)metadata[1],
1945 : "\n\t\t\tEND_OBJECT=DimensionMap_", (int)count, "\n");
1946 0 : break;
1947 :
1948 :
1949 0 : case 2:
1950 : /* Index Dimension Map Section */
1951 : /* --------------------------- */
1952 :
1953 : /* Find beginning and ending of metadata section */
1954 : /* --------------------------------------------- */
1955 0 : strcpy(utlstr, "\t\tGROUP=IndexDimensionMap");
1956 0 : begptr = strstr(metaptr, utlstr);
1957 :
1958 0 : strcpy(utlstr, "\t\tEND_GROUP=IndexDimensionMap");
1959 0 : metaptr = strstr(metaptr, utlstr);
1960 :
1961 :
1962 : /* Count number of existing entries and increment */
1963 : /* ---------------------------------------------- */
1964 0 : metaArr[0] = begptr;
1965 0 : metaArr[1] = metaptr;
1966 0 : count = EHcntOBJECT(metaArr) + 1;
1967 :
1968 :
1969 : /* Find slash within input mapping string and replace with NULL */
1970 : /* ------------------------------------------------------------ */
1971 0 : EHparsestr(metastr, '/', ptr, slen);
1972 0 : metastr[slen[0]] = 0;
1973 :
1974 :
1975 : /* Build metadata entry string */
1976 : /* --------------------------- */
1977 0 : snprintf(utlstr, UTLSTRSIZE, "%s%d%s%s%s%s%s%d%s",
1978 : "\t\t\tOBJECT=IndexDimensionMap_", (int)count,
1979 : "\n\t\t\t\tGeoDimension=\"", &metastr[0],
1980 0 : "\"\n\t\t\t\tDataDimension=\"", &metastr[slen[0] + 1],
1981 : "\"\n\t\t\tEND_OBJECT=IndexDimensionMap_", (int)count, "\n");
1982 0 : break;
1983 :
1984 :
1985 0 : case 3:
1986 : /* Geolocation Field Section */
1987 : /* ------------------------- */
1988 :
1989 : /* Find beginning and ending of metadata section */
1990 : /* --------------------------------------------- */
1991 0 : strcpy(utlstr, "\t\tGROUP=GeoField");
1992 0 : begptr = strstr(metaptr, utlstr);
1993 :
1994 0 : strcpy(utlstr, "\t\tEND_GROUP=GeoField");
1995 0 : metaptr = strstr(metaptr, utlstr);
1996 :
1997 :
1998 : /* Count number of existing entries and increment */
1999 : /* ---------------------------------------------- */
2000 0 : metaArr[0] = begptr;
2001 0 : metaArr[1] = metaptr;
2002 0 : count = EHcntOBJECT(metaArr) + 1;
2003 :
2004 :
2005 : /* Find colon (parse off field name) */
2006 : /* --------------------------------- */
2007 0 : colon = strchr(metastr, ':');
2008 0 : *colon = 0;
2009 :
2010 :
2011 : /* Search for next colon (compression and/or tiling parameters) */
2012 : /* ------------------------------------------------------------ */
2013 0 : colon2 = strchr(colon + 1, ':');
2014 0 : if (colon2 != NULL)
2015 : {
2016 0 : *colon2 = 0;
2017 : }
2018 : /* Make metadata string list for dimension list */
2019 : /* -------------------------------------------- */
2020 0 : EHmetalist(colon + 1, utlstr2);
2021 :
2022 :
2023 : /* Build metadata entry string */
2024 : /* --------------------------- */
2025 0 : snprintf(utlstr, UTLSTRSIZE, "%s%d%s%s%s%s%s%s",
2026 : "\t\t\tOBJECT=GeoField_", (int)count,
2027 : "\n\t\t\t\tGeoFieldName=\"", metastr,
2028 : "\"\n\t\t\t\tDataType=", type,
2029 : "\n\t\t\t\tDimList=", utlstr2);
2030 :
2031 :
2032 : /* If compression and/or tiling parameters add to string */
2033 : /* ----------------------------------------------------- */
2034 0 : if (colon2 != NULL)
2035 : {
2036 0 : strcat(utlstr, colon2 + 1);
2037 : }
2038 : /* Add END_OBJECT terminator to metadata string */
2039 : /* -------------------------------------------- */
2040 0 : snprintf(utlstr2, UTLSTRSIZE, "%s%d%s",
2041 : "\n\t\t\tEND_OBJECT=GeoField_", (int)count, "\n");
2042 0 : strcat(utlstr, utlstr2);
2043 :
2044 0 : break;
2045 :
2046 :
2047 0 : case 4:
2048 : /* Data Field Section */
2049 : /* ------------------ */
2050 :
2051 : /* Find beginning and ending of metadata section */
2052 : /* --------------------------------------------- */
2053 0 : strcpy(utlstr, "\t\tGROUP=DataField");
2054 0 : begptr = strstr(metaptr, utlstr);
2055 :
2056 0 : strcpy(utlstr, "\t\tEND_GROUP=DataField");
2057 0 : metaptr = strstr(metaptr, utlstr);
2058 :
2059 :
2060 : /* Count number of existing entries and increment */
2061 : /* ---------------------------------------------- */
2062 0 : metaArr[0] = begptr;
2063 0 : metaArr[1] = metaptr;
2064 0 : count = EHcntOBJECT(metaArr) + 1;
2065 :
2066 :
2067 : /* Find colon (parse off field name) */
2068 : /* --------------------------------- */
2069 0 : colon = strchr(metastr, ':');
2070 0 : *colon = 0;
2071 :
2072 :
2073 : /* Search for next colon (compression and/or tiling parameters) */
2074 : /* ------------------------------------------------------------ */
2075 0 : colon2 = strchr(colon + 1, ':');
2076 0 : if (colon2 != NULL)
2077 : {
2078 0 : *colon2 = 0;
2079 : }
2080 : /* Make metadata string list from dimension list */
2081 : /* --------------------------------------------- */
2082 0 : EHmetalist(colon + 1, utlstr2);
2083 :
2084 :
2085 : /* Build metadata entry string */
2086 : /* --------------------------- */
2087 0 : snprintf(utlstr, UTLSTRSIZE, "%s%d%s%s%s%s%s%s",
2088 : "\t\t\tOBJECT=DataField_", (int)count,
2089 : "\n\t\t\t\tDataFieldName=\"", metastr,
2090 : "\"\n\t\t\t\tDataType=", type,
2091 : "\n\t\t\t\tDimList=", utlstr2);
2092 :
2093 :
2094 : /* If compression and/or tiling parameters add to string */
2095 : /* ----------------------------------------------------- */
2096 0 : if (colon2 != NULL)
2097 : {
2098 0 : strcat(utlstr, colon2 + 1);
2099 : }
2100 : /* Add END_OBJECT terminator to metadata string */
2101 : /* -------------------------------------------- */
2102 0 : snprintf(utlstr2, UTLSTRSIZE, "%s%d%s",
2103 : "\n\t\t\tEND_OBJECT=DataField_", (int)count, "\n");
2104 0 : strcat(utlstr, utlstr2);
2105 :
2106 0 : break;
2107 :
2108 :
2109 0 : case 6:
2110 : /* Merged Field Section */
2111 : /* -------------------- */
2112 :
2113 : /* Find beginning and ending of metadata section */
2114 : /* --------------------------------------------- */
2115 0 : strcpy(utlstr, "\t\tGROUP=MergedFields");
2116 0 : begptr = strstr(metaptr, utlstr);
2117 :
2118 0 : strcpy(utlstr, "\t\tEND_GROUP=MergedFields");
2119 0 : metaptr = strstr(metaptr, utlstr);
2120 :
2121 :
2122 : /* Count number of existing entries and increment */
2123 : /* ---------------------------------------------- */
2124 0 : metaArr[0] = begptr;
2125 0 : metaArr[1] = metaptr;
2126 0 : count = EHcntOBJECT(metaArr) + 1;
2127 :
2128 :
2129 : /* Find colon (parse off merged fieldname) */
2130 : /* --------------------------------------- */
2131 0 : colon = strchr(metastr, ':');
2132 :
2133 :
2134 : /* Make metadata string list from field list */
2135 : /* ----------------------------------------- */
2136 0 : EHmetalist(colon + 1, utlstr2);
2137 0 : *colon = 0;
2138 :
2139 :
2140 : /* Build metadata entry string */
2141 : /* --------------------------- */
2142 0 : snprintf(utlstr, UTLSTRSIZE, "%s%d%s%s%s%s%s%s%d%s",
2143 : "\t\t\tOBJECT=MergedFields_", (int)count,
2144 : "\n\t\t\t\tMergedFieldName=\"", metastr, "\"",
2145 : "\n\t\t\t\tFieldList=", utlstr2,
2146 : "\n\t\t\tEND_OBJECT=MergedFields_", (int)count, "\n");
2147 0 : break;
2148 :
2149 :
2150 0 : case 10:
2151 : /* Point Level Section */
2152 : /* ------------------- */
2153 :
2154 : /* Find beginning and ending of metadata section */
2155 : /* --------------------------------------------- */
2156 0 : strcpy(utlstr, "\t\tGROUP=Level");
2157 0 : begptr = strstr(metaptr, utlstr);
2158 :
2159 0 : strcpy(utlstr, "\n\t\tEND_GROUP=Level");
2160 0 : metaptr = strstr(metaptr, utlstr) + 1;
2161 :
2162 :
2163 : /* Count number of existing entries and increment */
2164 : /* ---------------------------------------------- */
2165 0 : metaArr[0] = begptr;
2166 0 : metaArr[1] = metaptr;
2167 0 : count = EHcntGROUP(metaArr);
2168 :
2169 :
2170 : /* Build metadata entry string */
2171 : /* --------------------------- */
2172 0 : snprintf(utlstr, UTLSTRSIZE, "%s%d%s%s%s%d%s",
2173 : "\t\t\tGROUP=Level_", (int)count,
2174 : "\n\t\t\t\tLevelName=\"", metastr,
2175 : "\"\n\t\t\tEND_GROUP=Level_", (int)count, "\n");
2176 0 : break;
2177 :
2178 :
2179 0 : case 11:
2180 : /* Point Field Section */
2181 : /* ------------------- */
2182 :
2183 : /* Find colon (parse off point field name) */
2184 : /* --------------------------------------- */
2185 0 : colon = strchr(metastr, ':');
2186 0 : *colon = 0;
2187 :
2188 :
2189 : /* Find beginning and ending of metadata section */
2190 : /* --------------------------------------------- */
2191 0 : strcpy(utlstr, "\t\t\t\tLevelName=\"");
2192 0 : strcat(utlstr, colon + 1);
2193 0 : begptr = strstr(metaptr, utlstr);
2194 :
2195 0 : strcpy(utlstr, "\t\t\tEND_GROUP=Level_");
2196 0 : metaptr = strstr(begptr, utlstr);
2197 :
2198 :
2199 : /* Count number of existing entries and increment */
2200 : /* ---------------------------------------------- */
2201 0 : metaArr[0] = begptr;
2202 0 : metaArr[1] = metaptr;
2203 0 : count = EHcntOBJECT(metaArr) + 1;
2204 :
2205 :
2206 : /* Build metadata entry string */
2207 : /* --------------------------- */
2208 0 : snprintf(utlstr, UTLSTRSIZE, "%s%d%s%s%s%s%s%d%s%d%s",
2209 : "\t\t\t\tOBJECT=PointField_", (int)count,
2210 : "\n\t\t\t\t\tPointFieldName=\"", metastr,
2211 : "\"\n\t\t\t\t\tDataType=", type,
2212 0 : "\n\t\t\t\t\tOrder=", (int)metadata[1],
2213 : "\n\t\t\t\tEND_OBJECT=PointField_", (int)count, "\n");
2214 0 : break;
2215 :
2216 :
2217 :
2218 0 : case 12:
2219 : /* Level Link Section */
2220 : /* ------------------ */
2221 :
2222 : /* Find beginning and ending of metadata section */
2223 : /* --------------------------------------------- */
2224 0 : strcpy(utlstr, "\t\tGROUP=LevelLink");
2225 0 : begptr = strstr(metaptr, utlstr);
2226 :
2227 0 : strcpy(utlstr, "\t\tEND_GROUP=LevelLink");
2228 0 : metaptr = strstr(metaptr, utlstr);
2229 :
2230 :
2231 : /* Count number of existing entries and increment */
2232 : /* ---------------------------------------------- */
2233 0 : metaArr[0] = begptr;
2234 0 : metaArr[1] = metaptr;
2235 0 : count = EHcntOBJECT(metaArr) + 1;
2236 :
2237 :
2238 : /* Find colon (parse off parent/child level names from link field) */
2239 : /* --------------------------------------------------------------- */
2240 0 : colon = strchr(metastr, ':');
2241 0 : *colon = 0;
2242 :
2243 :
2244 : /* Find slash (divide parent and child levels) */
2245 : /* ------------------------------------------- */
2246 0 : slash = strchr(metastr, '/');
2247 0 : *slash = 0;
2248 :
2249 :
2250 : /* Build metadata entry string */
2251 : /* --------------------------- */
2252 0 : snprintf(utlstr, UTLSTRSIZE, "%s%d%s%s%s%s%s%s%s%d%s",
2253 : "\t\t\tOBJECT=LevelLink_", (int)count,
2254 : "\n\t\t\t\tParent=\"", metastr,
2255 : "\"\n\t\t\t\tChild=\"", slash + 1,
2256 : "\"\n\t\t\t\tLinkField=\"", colon + 1,
2257 : "\"\n\t\t\tEND_OBJECT=LevelLink_", (int)count, "\n");
2258 :
2259 0 : break;
2260 :
2261 :
2262 0 : case 101:
2263 : /* Position metadata pointer for Grid proj parms, pix reg, origin */
2264 : /* -------------------------------------------------------------- */
2265 0 : strcpy(utlstr, "\t\tGROUP=Dimension");
2266 0 : metaptr = strstr(metaptr, utlstr);
2267 0 : strcpy(utlstr, metastr);
2268 :
2269 0 : break;
2270 :
2271 :
2272 0 : case 1001:
2273 : /* Position metadata pointer for new swath structure (SWcreate) */
2274 : /* ------------------------------------------------------------ */
2275 0 : strcpy(utlstr, "END_GROUP=SwathStructure");
2276 0 : metaptr = strstr(metaptr, utlstr);
2277 0 : strcpy(utlstr, metastr);
2278 0 : break;
2279 :
2280 :
2281 0 : case 1002:
2282 : /* Position metadata pointer for new grid structure (GDcreate) */
2283 : /* ----------------------------------------------------------- */
2284 0 : strcpy(utlstr, "END_GROUP=GridStructure");
2285 0 : metaptr = strstr(metaptr, utlstr);
2286 0 : strcpy(utlstr, metastr);
2287 0 : break;
2288 :
2289 :
2290 0 : case 1003:
2291 : /* Position metadata pointer for new point structure (PTcreate) */
2292 : /* ------------------------------------------------------------ */
2293 0 : strcpy(utlstr, "END_GROUP=PointStructure");
2294 0 : metaptr = strstr(metaptr, utlstr);
2295 0 : strcpy(utlstr, metastr);
2296 0 : break;
2297 : }
2298 :
2299 :
2300 :
2301 : /* Get length of metadata string to insert */
2302 : /* --------------------------------------- */
2303 0 : seglen = (int)strlen(utlstr);
2304 :
2305 : /* Get offset of entry position within existing metadata */
2306 : /* ----------------------------------------------------- */
2307 0 : offset = (int)(metaptr - metabuf);
2308 :
2309 :
2310 : /* If end of new metadata string outside of current metadata buffer ... */
2311 : /* -------------------------------------------------------------------- */
2312 0 : if (metalen + seglen > 32000 * nmeta - 1)
2313 : {
2314 : /* Reallocate metadata buffer with additional 32000 bytes */
2315 : /* ------------------------------------------------------ */
2316 0 : metabuf = (char *) realloc((void *) metabuf, 32000 * (nmeta + 1));
2317 0 : if(metabuf == NULL)
2318 : {
2319 0 : HEpush(DFE_NOSPACE,"EHinsertmeta", __FILE__, __LINE__);
2320 0 : free(utlstr);
2321 0 : free(utlstr2);
2322 0 : return(-1);
2323 : }
2324 :
2325 : /* Increment metadata section counter */
2326 : /* ---------------------------------- */
2327 0 : nmeta++;
2328 :
2329 : /* Reposition metadata pointer (entry position) */
2330 : /* -------------------------------------------- */
2331 0 : metaptr = metabuf + offset;
2332 : }
2333 : /* Move metadata following entry point to its new position */
2334 : /* ------------------------------------------------------- */
2335 0 : for (i = metalen - 1; i > offset - 1; i--)
2336 : {
2337 0 : *(metabuf + seglen + i) = *(metabuf + i);
2338 : }
2339 :
2340 : /* Copy new metadata string (utlstr) into metadata */
2341 : /* ---------------------------------------------- */
2342 0 : memcpy(metaptr, utlstr, seglen);
2343 :
2344 : /* set to null character remaining of the metabuf */
2345 :
2346 0 : memset((metabuf + metalen + seglen), '\0', (nmeta*32000 -1 - (metalen +
2347 : seglen)));
2348 : /* Add new null string terminator */
2349 : /* ------------------------------ */
2350 0 : metabuf[metalen + seglen] = 0;
2351 :
2352 :
2353 : /* Write Back to Global Attribute(s) */
2354 : /* --------------------------------- */
2355 0 : for (i = 0; i < nmeta; i++)
2356 : {
2357 0 : snprintf(utlstr, UTLSTRSIZE, "%s%d", "StructMetadata.", i);
2358 0 : SDsetattr(sdInterfaceID, utlstr, DFNT_CHAR8,
2359 0 : 32000, metabuf + i * 32000);
2360 : }
2361 :
2362 0 : free(metabuf);
2363 0 : free(utlstr);
2364 0 : free(utlstr2);
2365 :
2366 0 : return (status);
2367 : }
2368 :
2369 :
2370 : /*----------------------------------------------------------------------------|
2371 : | BEGIN_PROLOG |
2372 : | |
2373 : | FUNCTION: EHgetmetavalue |
2374 : | |
2375 : | DESCRIPTION: Returns metadata value |
2376 : | |
2377 : | |
2378 : | Return Value Type Units Description |
2379 : | ============ ====== ========= ===================================== |
2380 : | status intn return status (0) SUCCEED, (-1) FAIL |
2381 : | |
2382 : | INPUTS: |
2383 : | metaptrs char Begin and end of metadata section |
2384 : | parameter char parameter to access |
2385 : | |
2386 : | OUTPUTS: |
2387 : | metaptr char Ptr to (updated) beginning of metadata |
2388 : | retstr char return string containing value |
2389 : | |
2390 : | NOTES: |
2391 : | |
2392 : | |
2393 : | Date Programmer Description |
2394 : | ====== ============ ================================================= |
2395 : | Jun 96 Joel Gales Original Programmer |
2396 : | Jan 97 Joel Gales Check string pointer against end of meta section |
2397 : | |
2398 : | END_PROLOG |
2399 : -----------------------------------------------------------------------------*/
2400 : intn
2401 0 : EHgetmetavalue(char *metaptrs[], const char *parameter, char *retstr)
2402 : {
2403 0 : intn status = 0; /* routine return status variable */
2404 :
2405 : int32 slen; /* String length */
2406 : char *newline; /* Position of new line character */
2407 : char *sptr; /* string pointer within metadata */
2408 :
2409 :
2410 : /* Get string length of parameter string + 1 */
2411 : /* ----------------------------------------- */
2412 0 : slen = (int)strlen(parameter) + 1;
2413 :
2414 :
2415 : /* Build search string (parameter string + "=") */
2416 : /* -------------------------------------------- */
2417 0 : strcpy(retstr, parameter);
2418 0 : strcat(retstr, "=");
2419 :
2420 :
2421 : /* Search for string within metadata (beginning at metaptrs[0]) */
2422 : /* ------------------------------------------------------------ */
2423 0 : sptr = strstr(metaptrs[0], retstr);
2424 :
2425 :
2426 : /* If string found within desired section ... */
2427 : /* ------------------------------------------ */
2428 0 : if (sptr != NULL && sptr < metaptrs[1])
2429 : {
2430 : /* Store position of string within metadata */
2431 : /* ---------------------------------------- */
2432 0 : metaptrs[0] = sptr;
2433 :
2434 : /* Find newline "\n" character */
2435 : /* --------------------------- */
2436 0 : newline = strchr(metaptrs[0], '\n');
2437 :
2438 : /* Copy from "=" to "\n" (exclusive) into return string */
2439 : /* ---------------------------------------------------- */
2440 0 : memcpy(retstr, metaptrs[0] + slen, newline - metaptrs[0] - slen);
2441 :
2442 : /* Terminate return string with null */
2443 : /* --------------------------------- */
2444 0 : retstr[newline - metaptrs[0] - slen] = 0;
2445 : } else
2446 : {
2447 : /*
2448 : * if parameter string not found within section, null return string
2449 : * and set status to -1.
2450 : */
2451 0 : retstr[0] = 0;
2452 0 : status = -1;
2453 : }
2454 :
2455 0 : return (status);
2456 : }
2457 :
2458 :
2459 :
2460 :
2461 : /*----------------------------------------------------------------------------|
2462 : | BEGIN_PROLOG |
2463 : | |
2464 : | FUNCTION: EHmetagroup |
2465 : | |
2466 : | DESCRIPTION: Returns pointers to beginning and end of metadata group |
2467 : | |
2468 : | |
2469 : | Return Value Type Units Description |
2470 : | ============ ====== ========= ===================================== |
2471 : | metabuf char Pointer to HDF-EOS object in metadata |
2472 : | |
2473 : | INPUTS: |
2474 : | sdInterfaceID int32 SDS interface ID |
2475 : | structname char HDF-EOS structure name |
2476 : | structcode char Structure code ("s/g/p") |
2477 : | groupname char Metadata group name |
2478 : | |
2479 : | OUTPUTS: |
2480 : | metaptrs char pointers to begin and end of metadata |
2481 : | |
2482 : | NOTES: |
2483 : | |
2484 : | |
2485 : | Date Programmer Description |
2486 : | ====== ============ ================================================= |
2487 : | Jun 96 Joel Gales Original Programmer |
2488 : | Aug 96 Joel Gales Make metadata ODL compliant |
2489 : | |
2490 : | END_PROLOG |
2491 : -----------------------------------------------------------------------------*/
2492 : char *
2493 0 : EHmetagroup(int32 sdInterfaceID, const char *structname, const char *structcode,
2494 : const char *groupname, char *metaptrs[])
2495 : {
2496 : intn i; /* Loop index */
2497 :
2498 : int32 attrIndex; /* Structural metadata attribute index */
2499 : int32 nmeta; /* Number of 32000 byte metadata sections */
2500 : int32 metalen; /* Length of structural metadata */
2501 :
2502 : char *metabuf; /* Pointer (handle) to structural metadata */
2503 : char *endptr; /* Pointer to end of metadata section */
2504 : char *metaptr; /* Metadata pointer */
2505 : char *prevmetaptr;/* Previous position of metadata pointer */
2506 : char *utlstr; /* Utility string */
2507 :
2508 :
2509 :
2510 : /* Allocate memory for utility string */
2511 : /* ---------------------------------- */
2512 0 : utlstr = (char *) calloc(UTLSTR_MAX_SIZE,sizeof(char));
2513 0 : if(utlstr == NULL)
2514 : {
2515 0 : HEpush(DFE_NOSPACE,"EHEHmetagroup", __FILE__, __LINE__);
2516 :
2517 0 : return( NULL);
2518 : }
2519 : /* Determine number of structural metadata "sections" */
2520 : /* -------------------------------------------------- */
2521 0 : nmeta = 0;
2522 : while (1)
2523 : {
2524 : /* Search for "StructMetadata.x" attribute */
2525 : /* --------------------------------------- */
2526 0 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%d", "StructMetadata.", (int)nmeta);
2527 0 : attrIndex = SDfindattr(sdInterfaceID, utlstr);
2528 :
2529 :
2530 : /* If found then increment metadata section counter else exit loop */
2531 : /* --------------------------------------------------------------- */
2532 0 : if (attrIndex != -1)
2533 : {
2534 0 : nmeta++;
2535 : } else
2536 : {
2537 0 : break;
2538 : }
2539 : }
2540 :
2541 :
2542 : /* Allocate space for metadata (in units of 32000 bytes) */
2543 : /* ----------------------------------------------------- */
2544 0 : metabuf = (char *) calloc(32000 * nmeta, 1);
2545 :
2546 0 : if(metabuf == NULL)
2547 : {
2548 0 : HEpush(DFE_NOSPACE,"EHmetagroup", __FILE__, __LINE__);
2549 0 : free(utlstr);
2550 0 : return(metabuf);
2551 : }
2552 :
2553 :
2554 : /* Read structural metadata */
2555 : /* ------------------------ */
2556 0 : for (i = 0; i < nmeta; i++)
2557 : {
2558 0 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%d", "StructMetadata.", i);
2559 0 : attrIndex = SDfindattr(sdInterfaceID, utlstr);
2560 0 : metalen = (int)strlen(metabuf);
2561 0 : SDreadattr(sdInterfaceID, attrIndex, metabuf + metalen);
2562 : }
2563 :
2564 : /* Determine length (# of characters) of metadata */
2565 : /* ---------------------------------------------- */
2566 0 : metalen = (int)strlen(metabuf);
2567 :
2568 :
2569 :
2570 : /* Find HDF-EOS structure "root" group in metadata */
2571 : /* ----------------------------------------------- */
2572 :
2573 : /* Setup proper search string */
2574 : /* -------------------------- */
2575 0 : if (strcmp(structcode, "s") == 0)
2576 : {
2577 0 : strcpy(utlstr, "GROUP=SwathStructure");
2578 0 : } else if (strcmp(structcode, "g") == 0)
2579 : {
2580 0 : strcpy(utlstr, "GROUP=GridStructure");
2581 0 : } else if (strcmp(structcode, "p") == 0)
2582 : {
2583 0 : strcpy(utlstr, "GROUP=PointStructure");
2584 : }
2585 : /* Use string search routine (strstr) to move through metadata */
2586 : /* ----------------------------------------------------------- */
2587 0 : metaptr = strstr(metabuf, utlstr);
2588 :
2589 :
2590 :
2591 : /* Save current metadata pointer */
2592 : /* ----------------------------- */
2593 0 : prevmetaptr = metaptr;
2594 :
2595 :
2596 : /* First loop for "old-style" (non-ODL) metadata string */
2597 : /* ---------------------------------------------------- */
2598 0 : if (strcmp(structcode, "s") == 0)
2599 : {
2600 0 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s", "SwathName=\"", structname);
2601 0 : } else if (strcmp(structcode, "g") == 0)
2602 : {
2603 0 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s", "GridName=\"", structname);
2604 0 : } else if (strcmp(structcode, "p") == 0)
2605 : {
2606 0 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s", "PointName=\"", structname);
2607 : }
2608 : /* Do string search */
2609 : /* ---------------- */
2610 0 : metaptr = strstr(metaptr, utlstr);
2611 :
2612 :
2613 : /*
2614 : * If not found then return to previous position in metadata and look for
2615 : * "new-style" (ODL) metadata string
2616 : */
2617 0 : if (metaptr == NULL)
2618 : {
2619 0 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s", "GROUP=\"", structname);
2620 0 : metaptr = strstr(prevmetaptr, utlstr);
2621 : }
2622 : /* Find group within structure */
2623 : /* --------------------------- */
2624 0 : if (groupname != NULL)
2625 : {
2626 0 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s", "GROUP=", groupname);
2627 0 : metaptr = strstr(metaptr, utlstr);
2628 :
2629 0 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s%s", "\t\tEND_GROUP=", groupname);
2630 0 : endptr = strstr(metaptr, utlstr);
2631 : } else
2632 : {
2633 : /* If groupname == NULL then find end of structure in metadata */
2634 : /* ----------------------------------------------------------- */
2635 0 : snprintf(utlstr, UTLSTR_MAX_SIZE, "%s", "\n\tEND_GROUP=");
2636 0 : endptr = strstr(metaptr, utlstr);
2637 : }
2638 :
2639 :
2640 : /* Return beginning and ending pointers */
2641 : /* ------------------------------------ */
2642 0 : metaptrs[0] = metaptr;
2643 0 : metaptrs[1] = endptr;
2644 :
2645 0 : free(utlstr);
2646 :
2647 0 : return (metabuf);
2648 : }
2649 :
2650 :
2651 :
2652 :
2653 :
2654 : /*----------------------------------------------------------------------------|
2655 : | BEGIN_PROLOG |
2656 : | |
2657 : | FUNCTION: EHfillfld |
2658 : | |
2659 : | DESCRIPTION: Fills field with fill value |
2660 : | |
2661 : | |
2662 : | Return Value Type Units Description |
2663 : | ============ ====== ========= ===================================== |
2664 : | status intn return status (0) SUCCEED, (-1) FAIL |
2665 : | |
2666 : | INPUTS: |
2667 : | sdid int32 SD element ID |
2668 : | rank int32 Rank of field |
2669 : | truerank int32 True rank of field (merging) |
2670 : | size int32 size of fill element |
2671 : | off int32 Offset of field within merged field |
2672 : | dims int32 Dimensions of field |
2673 : | fillval void fill value |
2674 : | |
2675 : | |
2676 : | OUTPUTS: |
2677 : | None |
2678 : | |
2679 : | NOTES: |
2680 : | |
2681 : | |
2682 : | Date Programmer Description |
2683 : | ====== ============ ================================================= |
2684 : | Jun 96 Joel Gales Original Programmer |
2685 : | |
2686 : | END_PROLOG |
2687 : -----------------------------------------------------------------------------*/
2688 : intn
2689 0 : EHfillfld(int32 sdid, int32 rank, CPL_UNUSED int32 truerank, int32 size, int32 off,
2690 : int32 dims[], VOIDP fillval)
2691 : {
2692 : intn i; /* Loop index */
2693 : intn j; /* Loop index */
2694 0 : intn status = 0; /* routine return status variable */
2695 :
2696 : int32 n; /* Max number of planes or rows in fill
2697 : * buffer */
2698 0 : int32 start[3] = {0, 0, 0}; /* Start array (SDwritedata) */
2699 : int32 edge[3]; /* Edge (count) array (SDwritedata) */
2700 : int32 totN; /* Total number of elements in field */
2701 : int32 planeN; /* Number of elements in plane */
2702 :
2703 : char *fillbuf; /* Fill buffer */
2704 :
2705 :
2706 : /* Get total number of elements in field */
2707 : /* ------------------------------------- */
2708 0 : totN = dims[0];
2709 0 : for (i = 1; i < rank; i++)
2710 : {
2711 0 : totN *= dims[i];
2712 : }
2713 :
2714 :
2715 : /* Get number of elements in a plane of the field */
2716 : /* ---------------------------------------------- */
2717 0 : planeN = dims[1] * dims[2];
2718 :
2719 :
2720 :
2721 : /* Allocate & Write Fill buffer */
2722 : /* ---------------------------- */
2723 0 : if (totN * size < HDFE_MAXMEMBUF)
2724 : {
2725 : /* Entire field size (in bytes) smaller than max fill buffer */
2726 : /* --------------------------------------------------------- */
2727 :
2728 :
2729 : /* Allocate fill buffer */
2730 : /* -------------------- */
2731 0 : fillbuf = (char *) malloc(totN * size);
2732 0 : if(fillbuf == NULL)
2733 : {
2734 0 : HEpush(DFE_NOSPACE,"EHfillfld", __FILE__, __LINE__);
2735 0 : return(-1);
2736 : }
2737 :
2738 :
2739 : /* Fill buffer with fill value */
2740 : /* --------------------------- */
2741 0 : for (i = 0; i < totN; i++)
2742 : {
2743 0 : memcpy(fillbuf + i * size, fillval, size);
2744 : }
2745 :
2746 :
2747 : /* Write fill buffer to field */
2748 : /* -------------------------- */
2749 0 : start[0] = off;
2750 0 : edge[0] = dims[0];
2751 0 : edge[1] = dims[1];
2752 0 : edge[2] = dims[2];
2753 0 : status = SDwritedata(sdid, start, NULL, edge,
2754 : (VOIDP) fillbuf);
2755 :
2756 0 : free(fillbuf);
2757 :
2758 0 : } else if (planeN * size < HDFE_MAXMEMBUF)
2759 : {
2760 : /* Single plane size (in bytes) smaller than max fill buffer */
2761 : /* --------------------------------------------------------- */
2762 :
2763 :
2764 : /* Compute number of planes that can be written at one time */
2765 : /* -------------------------------------------------------- */
2766 0 : n = HDFE_MAXMEMBUF / (planeN * size);
2767 :
2768 :
2769 : /* Allocate fill buffer */
2770 : /* -------------------- */
2771 0 : fillbuf = (char *) malloc(planeN * size * n);
2772 0 : if(fillbuf == NULL)
2773 : {
2774 0 : HEpush(DFE_NOSPACE,"EHfillfld", __FILE__, __LINE__);
2775 0 : return(-1);
2776 : }
2777 :
2778 :
2779 : /* Fill buffer with fill value */
2780 : /* --------------------------- */
2781 0 : for (i = 0; i < planeN * n; i++)
2782 : {
2783 0 : memcpy(fillbuf + i * size, fillval, size);
2784 : }
2785 :
2786 :
2787 : /* Write (full) fill buffer to field */
2788 : /* --------------------------------- */
2789 0 : for (i = 0; i < (dims[0] / n); i++)
2790 : {
2791 0 : start[0] = off + i * n;
2792 0 : edge[0] = n;
2793 0 : edge[1] = dims[1];
2794 0 : edge[2] = dims[2];
2795 0 : status = SDwritedata(sdid, start, NULL, edge,
2796 : (VOIDP) fillbuf);
2797 : }
2798 :
2799 :
2800 : /* Write (partial) last fill buffer to field (if necessary) */
2801 : /* -------------------------------------------------------- */
2802 0 : if (i * n != dims[0])
2803 : {
2804 0 : start[0] = off + i * n;
2805 0 : edge[0] = dims[0] - i * n;
2806 0 : edge[1] = dims[1];
2807 0 : edge[2] = dims[2];
2808 0 : status = SDwritedata(sdid, start, NULL, edge,
2809 : (VOIDP) fillbuf);
2810 : }
2811 0 : free(fillbuf);
2812 :
2813 : } else
2814 : {
2815 : /* Single plane size (in bytes) greater than max fill buffer */
2816 : /* --------------------------------------------------------- */
2817 :
2818 :
2819 : /* Compute number of "rows" than can be written at one time */
2820 : /* -------------------------------------------------------- */
2821 0 : n = HDFE_MAXMEMBUF / (dims[rank - 1] * size);
2822 :
2823 :
2824 : /* Allocate fill buffer */
2825 : /* -------------------- */
2826 0 : fillbuf = (char *) malloc(dims[rank - 1] * size * n);
2827 0 : if(fillbuf == NULL)
2828 : {
2829 0 : HEpush(DFE_NOSPACE,"EHfillfld", __FILE__, __LINE__);
2830 0 : return(-1);
2831 : }
2832 :
2833 :
2834 : /* Fill buffer with fill value */
2835 : /* --------------------------- */
2836 0 : for (i = 0; i < dims[rank - 1] * n; i++)
2837 : {
2838 0 : memcpy(fillbuf + i * size, fillval, size);
2839 : }
2840 :
2841 :
2842 : /* For every plane in field ... */
2843 : /* ---------------------------- */
2844 0 : for (j = 0; j < dims[0]; j++)
2845 : {
2846 :
2847 : /* Write (full) fill buffer to field */
2848 : /* --------------------------------- */
2849 0 : for (i = 0; i < (dims[1] / n); i++)
2850 : {
2851 0 : start[0] = off + j;
2852 0 : start[1] = i * n;
2853 0 : edge[0] = 1;
2854 0 : edge[1] = n;
2855 0 : edge[2] = dims[2];
2856 0 : status = SDwritedata(sdid, start, NULL, edge,
2857 : (VOIDP) fillbuf);
2858 : }
2859 :
2860 :
2861 : /* Write (partial) last fill buffer to field (if necessary) */
2862 : /* -------------------------------------------------------- */
2863 0 : if (i * n != dims[1])
2864 : {
2865 0 : start[0] = off + j;
2866 0 : start[1] = i * n;
2867 0 : edge[0] = 1;
2868 0 : edge[1] = dims[1] - i * n;
2869 0 : edge[2] = dims[2];
2870 0 : status = SDwritedata(sdid, start, NULL, edge,
2871 : (VOIDP) fillbuf);
2872 : }
2873 : }
2874 :
2875 0 : free(fillbuf);
2876 :
2877 : }
2878 :
2879 0 : return (status);
2880 : }
2881 :
2882 :
2883 :
2884 :
2885 :
2886 :
2887 : /*----------------------------------------------------------------------------|
2888 : | BEGIN_PROLOG |
2889 : | |
2890 : | FUNCTION: EHbisect |
2891 : | |
2892 : | DESCRIPTION: Finds root of function using bisection |
2893 : | |
2894 : | |
2895 : | Return Value Type Units Description |
2896 : | ============ ====== ========= ===================================== |
2897 : | status intn return status (0) SUCCEED, (-1) FAIL |
2898 : | |
2899 : | INPUTS: |
2900 : | func() float64 Function to bisect |
2901 : | funcParms float64 Function parameters (fixed) |
2902 : | nParms int32 Number of function parameters |
2903 : | limLft float64 Lower limit of function argument |
2904 : | limRgt float64 Upper limit of function argument |
2905 : | convCrit float64 Convergence criterion |
2906 : | |
2907 : | OUTPUTS: |
2908 : | root float64 Function root |
2909 : | |
2910 : | NOTES: |
2911 : | |
2912 : | |
2913 : | Date Programmer Description |
2914 : | ====== ============ ================================================= |
2915 : | Nov 96 Joel Gales Original Programmer |
2916 : | |
2917 : | END_PROLOG |
2918 : -----------------------------------------------------------------------------*/
2919 : intn
2920 0 : EHbisect(float64(*func) (float64[]), float64 funcParms[], int32 nParms,
2921 : float64 limLft, float64 limRgt, float64 convCrit, float64 * root)
2922 : {
2923 : intn i; /* Loop index */
2924 0 : intn status = 0; /* routine return status variable */
2925 :
2926 : float64 midPnt; /* Mid-point value */
2927 : float64 newmidPnt; /* New mid-point value */
2928 : float64 funcLft; /* Function value at left-hand limit */
2929 : float64 funcMid; /* Function value at mid-point */
2930 : float64 funcRgt; /* Function value at right-hand limit */
2931 : float64 *parms; /* Function parameters */
2932 :
2933 :
2934 : /* Allocate space for function parameters */
2935 : /* -------------------------------------- */
2936 0 : parms = (float64 *) calloc(nParms + 1, sizeof(float64));
2937 0 : if(parms == NULL)
2938 : {
2939 0 : HEpush(DFE_NOSPACE, "EHbisect", __FILE__, __LINE__);
2940 0 : return(-1);
2941 : }
2942 :
2943 :
2944 : /* Copy (fixed) function parameters */
2945 : /* -------------------------------- */
2946 0 : for (i = 0; i < nParms; i++)
2947 : {
2948 0 : parms[i + 1] = funcParms[i];
2949 : }
2950 :
2951 :
2952 : /* Copy left-hand limit to "floating" parameter */
2953 : /* -------------------------------------------- */
2954 0 : parms[0] = limLft;
2955 :
2956 :
2957 : /* Determine function value */
2958 : /* ------------------------ */
2959 0 : funcLft = (*func) (parms);
2960 :
2961 :
2962 : /* Copy right-hand limit to "floating" parameter */
2963 : /* --------------------------------------------- */
2964 0 : parms[0] = limRgt;
2965 :
2966 :
2967 : /* Determine function value */
2968 : /* ------------------------ */
2969 0 : funcRgt = (*func) (parms);
2970 :
2971 :
2972 : /* If left and right limits function values of same sign then no root */
2973 : /* ------------------------------------------------------------------ */
2974 0 : if (funcLft * funcRgt > 0)
2975 : {
2976 0 : free(parms);
2977 0 : return (-1);
2978 : }
2979 : /* Compute (initial) mid-point */
2980 : /* --------------------------- */
2981 0 : newmidPnt = 0.5 * (limLft + limRgt);
2982 :
2983 :
2984 : /* Bisection Loop */
2985 : /* -------------- */
2986 : while (1)
2987 : {
2988 : /* Compute function at new mid-point */
2989 : /* --------------------------------- */
2990 0 : midPnt = newmidPnt;
2991 0 : parms[0] = midPnt;
2992 0 : funcMid = (*func) (parms);
2993 :
2994 :
2995 : /* If left limit same sign as mid-point move it to mid-point */
2996 : /* --------------------------------------------------------- */
2997 0 : if (funcLft * funcMid > 0.0)
2998 : {
2999 0 : limLft = midPnt;
3000 : } else
3001 : {
3002 : /* Otherwise move over right-hand limit */
3003 : /* ------------------------------------ */
3004 0 : limRgt = midPnt;
3005 : }
3006 :
3007 :
3008 : /* Compute new mid-point */
3009 : /* --------------------- */
3010 0 : newmidPnt = 0.5 * (limLft + limRgt);
3011 :
3012 :
3013 : /* If relative change in midpoint < convergence crit then exit loop */
3014 : /* ---------------------------------------------------------------- */
3015 0 : if (fabs((newmidPnt - midPnt) / midPnt) < convCrit)
3016 : {
3017 0 : break;
3018 : }
3019 : }
3020 :
3021 : /* Save root */
3022 : /* --------- */
3023 0 : *root = newmidPnt;
3024 :
3025 :
3026 0 : free(parms);
3027 :
3028 0 : return (status);
3029 : }
3030 :
3031 :
3032 :
3033 :
3034 : /*----------------------------------------------------------------------------|
3035 : | BEGIN_PROLOG |
3036 : | |
3037 : | FUNCTION: EHattr |
3038 : | |
3039 : | DESCRIPTION: Reads/Writes attributes for HDF-EOS structures |
3040 : | |
3041 : | |
3042 : | Return Value Type Units Description |
3043 : | ============ ====== ========= ===================================== |
3044 : | status intn return status (0) SUCCEED, (-1) FAIL |
3045 : | |
3046 : | INPUTS: |
3047 : | fid int32 HDF-EOS file ID |
3048 : | attrVgrpID int32 Attribute Vgroup ID |
3049 : | attrname char attribute name |
3050 : | numbertype int32 attribute HDF numbertype |
3051 : | count int32 Number of attribute elements |
3052 : | wrcode char Read/Write Code "w/r" |
3053 : | datbuf void I/O buffer |
3054 : | |
3055 : | |
3056 : | OUTPUTS: |
3057 : | datbuf void I/O buffer |
3058 : | |
3059 : | NOTES: |
3060 : | |
3061 : | |
3062 : | Date Programmer Description |
3063 : | ====== ============ ================================================= |
3064 : | Jun 96 Joel Gales Original Programmer |
3065 : | Oct 96 Joel Gales Pass Vgroup id as routine parameter |
3066 : | Oct 96 Joel Gales Remove Vdetach call |
3067 : | |
3068 : | END_PROLOG |
3069 : -----------------------------------------------------------------------------*/
3070 : intn
3071 0 : EHattr(int32 fid, int32 attrVgrpID, const char *attrname, int32 numbertype,
3072 : int32 count, const char *wrcode, VOIDP datbuf)
3073 :
3074 : {
3075 0 : intn status = 0; /* routine return status variable */
3076 : int32 vdataID; /* Attribute Vdata ID */
3077 :
3078 : /*
3079 : * Attributes are stored as Vdatas with name given by the user, class:
3080 : * "Attr0.0" and fieldname: "AttrValues"
3081 : */
3082 :
3083 :
3084 : /* Get Attribute Vdata ID and "open" with appropriate I/O code */
3085 : /* ----------------------------------------------------------- */
3086 0 : vdataID = EHgetid(fid, attrVgrpID, attrname, 1, wrcode);
3087 :
3088 : /* Write Attribute Section */
3089 : /* ----------------------- */
3090 0 : if (strcmp(wrcode, "w") == 0)
3091 : {
3092 : /* Create Attribute Vdata (if it doesn't exist) */
3093 : /* -------------------------------------------- */
3094 0 : if (vdataID == -1)
3095 : {
3096 0 : vdataID = VSattach(fid, -1, "w");
3097 0 : VSsetname(vdataID, attrname);
3098 0 : VSsetclass(vdataID, "Attr0.0");
3099 :
3100 0 : VSfdefine(vdataID, "AttrValues", numbertype, count);
3101 0 : Vinsert(attrVgrpID, vdataID);
3102 : }
3103 : /* Write Attribute */
3104 : /* --------------- */
3105 0 : VSsetfields(vdataID, "AttrValues");
3106 0 : (void) VSsizeof(vdataID, (char*) "AttrValues");
3107 0 : VSwrite(vdataID, datbuf, 1, FULL_INTERLACE);
3108 :
3109 0 : VSdetach(vdataID);
3110 : }
3111 : /* Read Attribute Section */
3112 : /* ---------------------- */
3113 0 : if (strcmp(wrcode, "r") == 0)
3114 : {
3115 : /* If attribute doesn't exist report error */
3116 : /* --------------------------------------- */
3117 0 : if (vdataID == -1)
3118 : {
3119 0 : status = -1;
3120 0 : HEpush(DFE_GENAPP, "EHattr", __FILE__, __LINE__);
3121 0 : HEreport("Attribute %s not defined.\n", attrname);
3122 : } else
3123 : {
3124 0 : VSsetfields(vdataID, "AttrValues");
3125 0 : (void) VSsizeof(vdataID, (char*) "AttrValues");
3126 0 : VSread(vdataID, datbuf, 1, FULL_INTERLACE);
3127 0 : VSdetach(vdataID);
3128 : }
3129 : }
3130 0 : return (status);
3131 : }
3132 :
3133 :
3134 :
3135 :
3136 : /*----------------------------------------------------------------------------|
3137 : | BEGIN_PROLOG |
3138 : | |
3139 : | FUNCTION: EHattrinfo |
3140 : | |
3141 : | DESCRIPTION: Returns numbertype and count of given HDF-EOS attribute |
3142 : | |
3143 : | |
3144 : | Return Value Type Units Description |
3145 : | ============ ====== ========= ===================================== |
3146 : | status intn return status (0) SUCCEED, (-1) FAIL |
3147 : | |
3148 : | INPUTS: |
3149 : | fid int32 HDF-EOS file ID |
3150 : | attrVgrpID int32 Attribute Vgroup ID |
3151 : | attrname char attribute name |
3152 : | |
3153 : | OUTPUTS: |
3154 : | numbertype int32 attribute HDF numbertype |
3155 : | count int32 Number of attribute elements |
3156 : | |
3157 : | NOTES: |
3158 : | |
3159 : | |
3160 : | Date Programmer Description |
3161 : | ====== ============ ================================================= |
3162 : | Jun 96 Joel Gales Original Programmer |
3163 : | Oct 96 Joel Gales Pass Vgroup id as routine parameter |
3164 : | Oct 96 Joel Gales Remove Vdetach call |
3165 : | |
3166 : | END_PROLOG |
3167 : -----------------------------------------------------------------------------*/
3168 : intn
3169 0 : EHattrinfo(int32 fid, int32 attrVgrpID, const char *attrname, int32 * numbertype,
3170 : int32 * count)
3171 :
3172 : {
3173 0 : intn status = 0; /* routine return status variable */
3174 : int32 vdataID; /* Attribute Vdata ID */
3175 :
3176 : /* Get Attribute Vdata ID */
3177 : /* ---------------------- */
3178 0 : vdataID = EHgetid(fid, attrVgrpID, attrname, 1, "r");
3179 :
3180 : /* If attribute not defined then report error */
3181 : /* ------------------------------------------ */
3182 0 : if (vdataID == -1)
3183 : {
3184 0 : status = -1;
3185 0 : HEpush(DFE_GENAPP, "EHattr", __FILE__, __LINE__);
3186 0 : HEreport("Attribute %s not defined.\n", attrname);
3187 : } else
3188 : {
3189 : /* Get attribute info */
3190 : /* ------------------ */
3191 0 : VSsetfields(vdataID, "AttrValues");
3192 0 : *count = VSsizeof(vdataID, (char*) "AttrValues");
3193 0 : *numbertype = VFfieldtype(vdataID, 0);
3194 0 : VSdetach(vdataID);
3195 : }
3196 :
3197 0 : return (status);
3198 : }
3199 :
3200 :
3201 :
3202 :
3203 :
3204 : /*----------------------------------------------------------------------------|
3205 : | BEGIN_PROLOG |
3206 : | |
3207 : | FUNCTION: EHattrcat |
3208 : | |
3209 : | DESCRIPTION: Returns a listing of attributes within an HDF-EOS structure |
3210 : | |
3211 : | |
3212 : | Return Value Type Units Description |
3213 : | ============ ====== ========= ===================================== |
3214 : | nattr int32 Number of attributes in swath struct |
3215 : | |
3216 : | INPUTS: |
3217 : | fid int32 HDF-EOS file ID |
3218 : | attrVgrpID int32 Attribute Vgroup ID |
3219 : | structcode char Structure Code ("s/g/p") |
3220 : | |
3221 : | OUTPUTS: |
3222 : | attrnames char Attribute names in swath struct |
3223 : | (Comma-separated list) |
3224 : | strbufsize int32 Attributes name list string length |
3225 : | |
3226 : | NOTES: |
3227 : | |
3228 : | |
3229 : | Date Programmer Description |
3230 : | ====== ============ ================================================= |
3231 : | Jun 96 Joel Gales Original Programmer |
3232 : | Oct 96 Joel Gales Pass Vgroup id as routine parameter |
3233 : | Oct 96 Joel Gales Remove Vdetach call |
3234 : | |
3235 : | END_PROLOG |
3236 : -----------------------------------------------------------------------------*/
3237 : int32
3238 0 : EHattrcat(int32 fid, int32 attrVgrpID, char *attrnames, int32 * strbufsize)
3239 : {
3240 : intn i; /* Loop index */
3241 :
3242 : int32 nObjects; /* # of objects in Vgroup */
3243 : int32 *tags; /* Pnt to Vgroup object tags array */
3244 : int32 *refs; /* Pnt to Vgroup object refs array */
3245 : int32 vdataID; /* Attribute Vdata ID */
3246 :
3247 0 : int32 nattr = 0; /* Number of attributes */
3248 : int32 slen; /* String length */
3249 :
3250 : char name[80]; /* Attribute name */
3251 : static const char indxstr[] = "INDXMAP:"; /* Index Mapping reserved
3252 : string */
3253 : static const char fvstr[] = "_FV_"; /* Flag Value reserved string */
3254 : static const char bsom[] = "_BLKSOM:";/* Block SOM Offset reserved string */
3255 :
3256 :
3257 : /* Set string buffer size to 0 */
3258 : /* --------------------------- */
3259 0 : *strbufsize = 0;
3260 :
3261 :
3262 : /* Get number of attributes within Attribute Vgroup */
3263 : /* ------------------------------------------------ */
3264 0 : nObjects = Vntagrefs(attrVgrpID);
3265 :
3266 :
3267 : /* If attributes exist ... */
3268 : /* ----------------------- */
3269 0 : if (nObjects > 0)
3270 : {
3271 : /* Get tags and references of attribute Vdatas */
3272 : /* ------------------------------------------- */
3273 0 : tags = (int32 *) malloc(sizeof(int32) * nObjects);
3274 0 : if(tags == NULL)
3275 : {
3276 0 : HEpush(DFE_NOSPACE,"EHattrcat", __FILE__, __LINE__);
3277 0 : return(-1);
3278 : }
3279 0 : refs = (int32 *) malloc(sizeof(int32) * nObjects);
3280 0 : if(refs == NULL)
3281 : {
3282 0 : HEpush(DFE_NOSPACE,"EHattrcat", __FILE__, __LINE__);
3283 0 : free(tags);
3284 0 : return(-1);
3285 : }
3286 :
3287 0 : Vgettagrefs(attrVgrpID, tags, refs, nObjects);
3288 :
3289 : /* Get attribute vdata IDs and names */
3290 : /* --------------------------------- */
3291 0 : for (i = 0; i < nObjects; i++)
3292 : {
3293 0 : vdataID = VSattach(fid, *(refs + i), "r");
3294 0 : VSgetname(vdataID, name);
3295 :
3296 : /*
3297 : * Don't return fill value, index mapping & block SOM attributes
3298 : */
3299 0 : if (memcmp(name, indxstr, strlen(indxstr)) != 0 &&
3300 0 : memcmp(name, fvstr, strlen(fvstr)) != 0 &&
3301 0 : memcmp(name, bsom, strlen(bsom)) != 0)
3302 : {
3303 : /* Increment attribute counter and add name to list */
3304 : /* ------------------------------------------------ */
3305 0 : nattr++;
3306 0 : if (attrnames != NULL)
3307 : {
3308 0 : if (nattr == 1)
3309 : {
3310 0 : strcpy(attrnames, name);
3311 : } else
3312 : {
3313 0 : strcat(attrnames, ",");
3314 0 : strcat(attrnames, name);
3315 : }
3316 : }
3317 : /* Increment attribute names string length */
3318 : /* --------------------------------------- */
3319 0 : slen = (nattr == 1) ? (int)strlen(name) : (int)strlen(name) + 1;
3320 0 : *strbufsize += slen;
3321 : }
3322 0 : VSdetach(vdataID);
3323 : }
3324 0 : free(tags);
3325 0 : free(refs);
3326 : }
3327 0 : return (nattr);
3328 : }
3329 :
3330 :
3331 :
3332 : /*----------------------------------------------------------------------------|
3333 : | BEGIN_PROLOG |
3334 : | |
3335 : | FUNCTION: EHinquire |
3336 : | |
3337 : | DESCRIPTION: Returns number and names of HDF-EOS structures in file |
3338 : | |
3339 : | |
3340 : | Return Value Type Units Description |
3341 : | ============ ====== ========= ===================================== |
3342 : | nobj int32 Number of HDF-EOS structures in file |
3343 : | |
3344 : | INPUTS: |
3345 : | filename char HDF-EOS filename |
3346 : | type char Object Type ("SWATH/GRID/POINT") |
3347 : | |
3348 : | OUTPUTS: |
3349 : | objectlist char List of object names (comma-separated) |
3350 : | strbufsize int32 Length of objectlist |
3351 : | |
3352 : | NOTES: |
3353 : | |
3354 : | |
3355 : | Date Programmer Description |
3356 : | ====== ============ ================================================= |
3357 : | Jun 96 Joel Gales Original Programmer |
3358 : | |
3359 : | END_PROLOG |
3360 : -----------------------------------------------------------------------------*/
3361 : int32
3362 8 : EHinquire(const char *filename, const char *type, char *objectlist, int32 * strbufsize)
3363 : {
3364 : int32 HDFfid; /* HDF file ID */
3365 : int32 vgRef; /* Vgroup reference number */
3366 : int32 vGrpID; /* Vgroup ID */
3367 8 : int32 nobj = 0; /* Number of HDFEOS objects in file */
3368 : int32 slen; /* String length */
3369 :
3370 : char name[512]; /* Object name */
3371 : char class[80]; /* Object class */
3372 :
3373 :
3374 : /* Open HDFEOS file of read-only access */
3375 : /* ------------------------------------ */
3376 8 : HDFfid = Hopen(filename, DFACC_READ, 0);
3377 :
3378 :
3379 : /* Start Vgroup Interface */
3380 : /* ---------------------- */
3381 8 : Vstart(HDFfid);
3382 :
3383 :
3384 : /* If string buffer size is requested then zero out counter */
3385 : /* -------------------------------------------------------- */
3386 8 : if (strbufsize != NULL)
3387 : {
3388 8 : *strbufsize = 0;
3389 : }
3390 : /* Search for objects from beginning of HDF file */
3391 : /* -------------------------------------------- */
3392 8 : vgRef = -1;
3393 :
3394 : /* Loop through all objects */
3395 : /* ------------------------ */
3396 : while (1)
3397 : {
3398 : /* Get Vgroup reference number */
3399 : /* --------------------------- */
3400 36 : vgRef = Vgetid(HDFfid, vgRef);
3401 :
3402 : /* If no more then exist search loop */
3403 : /* --------------------------------- */
3404 36 : if (vgRef == -1)
3405 : {
3406 8 : break;
3407 : }
3408 : /* Get Vgroup ID, name, and class */
3409 : /* ------------------------------ */
3410 28 : vGrpID = Vattach(HDFfid, vgRef, "r");
3411 28 : Vgetname(vGrpID, name);
3412 28 : Vgetclass(vGrpID, class);
3413 :
3414 :
3415 : /* If object of desired type (SWATH, POINT, GRID) ... */
3416 : /* -------------------------------------------------- */
3417 28 : if (strcmp(class, type) == 0)
3418 : {
3419 :
3420 : /* Increment counter */
3421 : /* ----------------- */
3422 0 : nobj++;
3423 :
3424 :
3425 : /* If object list requested add name to list */
3426 : /* ----------------------------------------- */
3427 0 : if (objectlist != NULL)
3428 : {
3429 0 : if (nobj == 1)
3430 : {
3431 0 : strcpy(objectlist, name);
3432 : } else
3433 : {
3434 0 : strcat(objectlist, ",");
3435 0 : strcat(objectlist, name);
3436 : }
3437 : }
3438 : /* Compute string length of object entry */
3439 : /* ------------------------------------- */
3440 0 : slen = (nobj == 1) ? (int)strlen(name) : (int)strlen(name) + 1;
3441 :
3442 :
3443 : /* If string buffer size is requested then increment buffer size */
3444 : /* ------------------------------------------------------------- */
3445 0 : if (strbufsize != NULL)
3446 : {
3447 0 : *strbufsize += slen;
3448 : }
3449 : }
3450 : /* Detach Vgroup */
3451 : /* ------------- */
3452 28 : Vdetach(vGrpID);
3453 : }
3454 :
3455 : /* "Close" Vgroup interface and HDFEOS file */
3456 : /* ---------------------------------------- */
3457 8 : Vend(HDFfid);
3458 8 : Hclose(HDFfid);
3459 :
3460 8 : return (nobj);
3461 : }
3462 :
3463 :
3464 :
3465 : /*----------------------------------------------------------------------------|
3466 : | BEGIN_PROLOG |
3467 : | |
3468 : | FUNCTION: EHclose |
3469 : | |
3470 : | DESCRIPTION: Closes HDF-EOS file |
3471 : | |
3472 : | |
3473 : | Return Value Type Units Description |
3474 : | ============ ====== ========= ===================================== |
3475 : | status intn return status (0) SUCCEED, (-1) FAIL |
3476 : | |
3477 : | INPUTS: |
3478 : | fid int32 HDF-EOS File ID |
3479 : | |
3480 : | OUTPUTS: |
3481 : | None |
3482 : | |
3483 : | NOTES: |
3484 : | |
3485 : | |
3486 : | Date Programmer Description |
3487 : | ====== ============ ================================================= |
3488 : | Jun 96 Joel Gales Original Programmer |
3489 : | Jul 96 Joel Gales Add file id offset EHIDOFFSET |
3490 : | Aug 96 Joel Gales Add HE error report if file id out of bounds |
3491 : | Nov 96 Joel Gales Add EHXacsTable array to "garbage collection" |
3492 : | |
3493 : | END_PROLOG |
3494 : -----------------------------------------------------------------------------*/
3495 : intn
3496 8 : EHclose(int32 fid)
3497 : {
3498 8 : intn status = 0; /* routine return status variable */
3499 :
3500 : int32 HDFfid; /* HDF file ID */
3501 : int32 sdInterfaceID; /* HDF SDS interface ID */
3502 : int32 fid0; /* HDF EOS file id - offset */
3503 :
3504 :
3505 : /* Check for valid HDFEOS file ID range */
3506 : /* ------------------------------------ */
3507 8 : if (fid >= EHIDOFFSET && fid < EHXmaxfilecount + EHIDOFFSET)
3508 : {
3509 : /* Compute "reduced" file ID */
3510 : /* ------------------------- */
3511 8 : fid0 = fid % EHIDOFFSET;
3512 :
3513 :
3514 : /* Get HDF file ID and SD interface ID */
3515 : /* ----------------------------------- */
3516 8 : HDFfid = EHXfidTable[fid0];
3517 8 : sdInterfaceID = EHXsdTable[fid0];
3518 :
3519 : /* "Close" SD interface, Vgroup interface, and HDF file */
3520 : /* ---------------------------------------------------- */
3521 8 : status = SDend(sdInterfaceID);
3522 8 : status = Vend(HDFfid);
3523 8 : status = Hclose(HDFfid);
3524 :
3525 : /* Clear out external array entries */
3526 : /* -------------------------------- */
3527 8 : EHXtypeTable[fid0] = 0;
3528 8 : EHXacsTable[fid0] = 0;
3529 8 : EHXfidTable[fid0] = 0;
3530 8 : EHXsdTable[fid0] = 0;
3531 8 : if (EHget_numfiles() == 0)
3532 : {
3533 8 : free(EHXtypeTable);
3534 8 : EHXtypeTable = NULL;
3535 8 : free(EHXacsTable);
3536 8 : EHXacsTable = NULL;
3537 8 : free(EHXfidTable);
3538 8 : EHXfidTable = NULL;
3539 8 : free(EHXsdTable);
3540 8 : EHXsdTable = NULL;
3541 8 : EHXmaxfilecount = 0;
3542 : }
3543 : } else
3544 : {
3545 0 : status = -1;
3546 0 : HEpush(DFE_RANGE, "EHclose", __FILE__, __LINE__);
3547 0 : HEreport("Invalid file id: %d. ID must be >= %d and < %d.\n",
3548 : fid, EHIDOFFSET, EHXmaxfilecount + EHIDOFFSET);
3549 : }
3550 :
3551 8 : return (status);
3552 : }
3553 :
3554 : /*----------------------------------------------------------------------------|
3555 : | BEGIN_PROLOG |
3556 : | |
3557 : | FUNCTION: EHnumstr |
3558 : | |
3559 : | DESCRIPTION: Returns numerical type code of the given string |
3560 : | representation. |
3561 : | |
3562 : | |
3563 : | Return Value Type Units Description |
3564 : | ============ ====== ========= ===================================== |
3565 : | numbertype int32 numerical type code |
3566 : | |
3567 : | INPUTS: |
3568 : | strcode const char string representation of the type code |
3569 : | |
3570 : | |
3571 : | OUTPUTS: |
3572 : | None |
3573 : | |
3574 : | NOTES: |
3575 : | |
3576 : | |
3577 : | Date Programmer Description |
3578 : | ====== ============ ================================================= |
3579 : | Nov 07 Andrey Kiselev Original Programmer |
3580 : | |
3581 : | END_PROLOG |
3582 : -----------------------------------------------------------------------------*/
3583 : int32
3584 0 : EHnumstr(const char *strcode)
3585 : {
3586 0 : if (strcmp(strcode, "DFNT_UCHAR8") == 0)
3587 0 : return DFNT_UCHAR8;
3588 0 : else if (strcmp(strcode, "DFNT_CHAR8") == 0)
3589 0 : return DFNT_CHAR8;
3590 0 : else if (strcmp(strcode, "DFNT_FLOAT32") == 0)
3591 0 : return DFNT_FLOAT32;
3592 0 : else if (strcmp(strcode, "DFNT_FLOAT64") == 0)
3593 0 : return DFNT_FLOAT64;
3594 0 : else if (strcmp(strcode, "DFNT_INT8") == 0)
3595 0 : return DFNT_INT8;
3596 0 : else if (strcmp(strcode, "DFNT_UINT8") == 0)
3597 0 : return DFNT_UINT8;
3598 0 : else if (strcmp(strcode, "DFNT_INT16") == 0)
3599 0 : return DFNT_INT16;
3600 0 : else if (strcmp(strcode, "DFNT_UINT16") == 0)
3601 0 : return DFNT_UINT16;
3602 0 : else if (strcmp(strcode, "DFNT_INT32") == 0)
3603 0 : return DFNT_INT32;
3604 0 : else if (strcmp(strcode, "DFNT_UINT32") == 0)
3605 0 : return DFNT_UINT32;
3606 : else
3607 0 : return DFNT_NONE;
3608 : }
3609 :
3610 : /*----------------------------------------------------------------------------|
3611 : | BEGIN_PROLOG |
3612 : | |
3613 : | FUNCTION: EHreset_maxopenfiles |
3614 : | |
3615 : | DESCRIPTION: Change the allowed number of opened HDFEOS files. |
3616 : | |
3617 : | |
3618 : | Return Value Type Units Description |
3619 : | ============ ====== ========= ===================================== |
3620 : | numbertype intn The current maximum number of opened |
3621 : | files allowed, or -1, if unable |
3622 : | to reset it. |
3623 : | |
3624 : | INPUTS: |
3625 : | strcode intn Requested number of opened files. |
3626 : | |
3627 : | |
3628 : | OUTPUTS: |
3629 : | None |
3630 : | |
3631 : | NOTES: |
3632 : | |
3633 : | |
3634 : | Date Programmer Description |
3635 : | ========== ============ ============================================== |
3636 : | 2013.04.03 Andrey Kiselev Original Programmer |
3637 : | |
3638 : | END_PROLOG |
3639 : -----------------------------------------------------------------------------*/
3640 : static intn
3641 8 : EHreset_maxopenfiles(intn req_max)
3642 : {
3643 : intn ret_value;
3644 :
3645 8 : if (req_max <= EHXmaxfilecount)
3646 0 : return EHXmaxfilecount;
3647 :
3648 : /* Falback to built-in NEOSHDF constant if */
3649 : /* SDreset_maxopenfiles() interface is not available */
3650 : /* ------------------------------------------------- */
3651 : #ifdef HDF4_HAS_MAXOPENFILES
3652 8 : ret_value = SDreset_maxopenfiles(req_max);
3653 : #else
3654 : ret_value = NEOSHDF;
3655 : #endif /* HDF4_HAS_MAXOPENFILES */
3656 :
3657 8 : if (ret_value > 0)
3658 : {
3659 8 : EHXtypeTable = realloc(EHXtypeTable, ret_value * sizeof(*EHXtypeTable));
3660 8 : memset(EHXtypeTable + EHXmaxfilecount, 0,
3661 8 : (ret_value - EHXmaxfilecount) * sizeof(*EHXtypeTable));
3662 8 : EHXacsTable = realloc(EHXacsTable, ret_value * sizeof(*EHXacsTable));
3663 8 : memset(EHXacsTable + EHXmaxfilecount, 0,
3664 8 : (ret_value - EHXmaxfilecount) * sizeof(*EHXacsTable));
3665 8 : EHXfidTable = realloc(EHXfidTable, ret_value * sizeof(*EHXfidTable));
3666 8 : memset(EHXfidTable + EHXmaxfilecount, 0,
3667 8 : (ret_value - EHXmaxfilecount) * sizeof(*EHXfidTable));
3668 8 : EHXsdTable = realloc(EHXsdTable, ret_value * sizeof(*EHXsdTable));
3669 8 : memset(EHXsdTable + EHXmaxfilecount, 0,
3670 8 : (ret_value - EHXmaxfilecount) * sizeof(*EHXsdTable));
3671 8 : EHXmaxfilecount = ret_value;
3672 : }
3673 :
3674 8 : return ret_value;
3675 : }
3676 :
3677 : /*----------------------------------------------------------------------------|
3678 : | BEGIN_PROLOG |
3679 : | |
3680 : | FUNCTION: EHget_maxopenfiles |
3681 : | |
3682 : | DESCRIPTION: Request the allowed number of opened HDFEOS files and maximum |
3683 : | number of opened files allowed in the system. |
3684 : | |
3685 : | |
3686 : | Return Value Type Units Description |
3687 : | ============ ====== ========= ===================================== |
3688 : | status intn return status (0) SUCCEED, (-1) FAIL |
3689 : | |
3690 : | INPUTS: |
3691 : | None |
3692 : | |
3693 : | |
3694 : | OUTPUTS: |
3695 : | curr_max intn Current number of open files allowed. |
3696 : | sys_limit intn Maximum number of open files allowed |
3697 : | in the system. |
3698 : | |
3699 : | NOTES: |
3700 : | |
3701 : | |
3702 : | Date Programmer Description |
3703 : | ========== ============ ============================================== |
3704 : | 2013.04.03 Andrey Kiselev Original Programmer |
3705 : | |
3706 : | END_PROLOG |
3707 : -----------------------------------------------------------------------------*/
3708 : static intn
3709 8 : EHget_maxopenfiles(intn *curr_max,
3710 : intn *sys_limit)
3711 : {
3712 8 : intn ret_value = 0;
3713 :
3714 : #ifdef HDF4_HAS_MAXOPENFILES
3715 8 : ret_value = SDget_maxopenfiles(curr_max, sys_limit);
3716 : #else
3717 : *sys_limit = NEOSHDF;
3718 : #endif /* HDF4_HAS_MAXOPENFILES */
3719 :
3720 8 : *curr_max = EHXmaxfilecount;
3721 :
3722 8 : return ret_value;
3723 : }
3724 :
3725 : /*----------------------------------------------------------------------------|
3726 : | BEGIN_PROLOG |
3727 : | |
3728 : | FUNCTION: EHget_numfiles |
3729 : | |
3730 : | DESCRIPTION: Request the number of HDFEOS files currently opened. |
3731 : | |
3732 : | |
3733 : | Return Value Type Units Description |
3734 : | ============ ====== ========= ===================================== |
3735 : | nfileopen intn Number of HDFEOS files already opened. |
3736 : | |
3737 : | INPUTS: |
3738 : | None |
3739 : | |
3740 : | |
3741 : | OUTPUTS: |
3742 : | None |
3743 : | in the system. |
3744 : | |
3745 : | NOTES: |
3746 : | |
3747 : | |
3748 : | Date Programmer Description |
3749 : | ========== ============ ============================================== |
3750 : | 2013.04.03 Andrey Kiselev Original Programmer |
3751 : | |
3752 : | END_PROLOG |
3753 : -----------------------------------------------------------------------------*/
3754 : static intn
3755 16 : EHget_numfiles()
3756 : {
3757 : intn i; /* Loop index */
3758 16 : intn nfileopen = 0; /* # of HDF files open */
3759 :
3760 16 : if (EHXtypeTable)
3761 : {
3762 : /* Determine number of files currently opened */
3763 : /* ------------------------------------------ */
3764 320016 : for (i = 0; i < EHXmaxfilecount; i++)
3765 : {
3766 320000 : nfileopen += EHXtypeTable[i];
3767 : }
3768 : }
3769 :
3770 16 : return nfileopen;
3771 : }
|