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