Blockstructured Adaptive Mesh Refinement in object-oriented C++
00001 00006 #include <stdio.h> 00007 #include <stdlib.h> 00008 /*#include <bstring.h>*/ 00009 #include <strings.h> 00010 #include <time.h> 00011 00012 #include "sds.h" 00013 00014 /*@@ 00015 @file sds.c 00016 @date Wed Feb 26 20:05:00 1996 00017 @author John Shalf 00018 @desc 00019 The SDS routines are a wrapper for the HDF SD interface 00020 that allows you to refer to files by name instead of 00021 explicitly opening them and refering to them by fileID. 00022 This file contain all of the source code that implements 00023 these wrappers. 00024 @enddesc 00025 @includes sds.h 00026 @seeheader sds.h 00027 @version 0.9a 00028 @@*/ 00029 00030 static int32 DefaultNumberType=DFNT_FLOAT32; 00031 static int32 nfiles=0,maxfiles=54; 00032 00033 /* Need to set the default NumberType!!!! */ 00034 00035 typedef struct fileID { 00036 char componentname[128]; 00037 char filename[256]; 00038 char sds_name[MAX_NC_NAME]; /* to keep track of SDS name internally */ 00039 int32 id,sds_id,sdsnumber,nsds,nattrib,numbertype; 00040 int32 accessflags; 00041 clock_t lastaccess; /* in clock ticks. Uses clock(). CLOCKS_PER_SEC */ 00042 struct fileID *next; 00043 }fileID; 00044 00045 static fileID *files=NULL; 00046 00047 /*@@ 00048 @routine deactivateOldFiles 00049 @date Wed Feb 28 15:37:43 1996 00050 @desc 00051 Finds the filesID's with longest time since last reference 00052 and deactivates the worst 1/8 of them to free up some 00053 file descriptors. 00054 @enddesc 00055 @seeroutine SDSdeactivate SDSreactivate getFileID 00056 @calledby NewFileID 00057 00058 @history 00059 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00060 @hdesc Initial Version 00061 @endhistory 00062 @@*/ 00063 static 00064 void deactivateOldFiles() 00065 { 00066 fileID *tmpid; 00067 int i,ntimes; 00068 clock_t *worst_times; 00069 ntimes=maxfiles>>3; /* Ok, divide by 8 */ 00070 ntimes=ntimes?ntimes:1; /* make sure its >0 */ 00071 /* It was the best of times... it was the worst of times... */ 00072 worst_times=(clock_t *)calloc(ntimes,sizeof(clock_t)); 00073 /* first search for the top-1/8 longest times since last access */ 00074 for(tmpid=files;tmpid;tmpid=tmpid->next){ 00075 clock_t t=tmpid->lastaccess; 00076 if(tmpid->id<0) continue; 00077 for(i=0;i<ntimes;i++){ 00078 if(t<=worst_times[i]){ /* swap */ 00079 clock_t tmp=worst_times[i]; 00080 worst_times[i]=t; 00081 t=tmp; /* now looking for second-worst time */ 00082 } 00083 } 00084 } 00085 /* next deactivate those top-10% */ 00086 for(tmpid=files;tmpid;tmpid=tmpid->next) 00087 if(tmpid->id && tmpid->lastaccess<=worst_times[ntimes-1]) 00088 SDSdeactivate(tmpid->filename); /* deactivate it */ 00089 free(worst_times); 00090 } 00091 00092 /*@@ 00093 @routine NewFileID 00094 @date Wed Feb 28 15:37:43 1996 00095 @desc 00096 Creates a new fileID structure, opens the file and 00097 initializes all of the structure elements. 00098 @enddesc 00099 @calledby SDSopen getFileID 00100 @calls deactivateOldFiles 00101 00102 @par name 00103 @pdesc Name of the HDF file to open or create 00104 @ptype char* 00105 @endpar 00106 00107 @par access 00108 @pdesc Access mode for the file (uses ANSI C access modes) 00109 @ptype char* 00110 @pvalues "r","w","rw","w+","ra" 00111 @endpar 00112 00113 @history 00114 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00115 @hdesc Initial Version 00116 @endhistory 00117 @@*/ 00118 fileID *NewFileID(char *name,char *access) { 00119 fileID *id=(fileID *)calloc(sizeof(fileID),1); 00120 strcpy(id->componentname,name); 00121 strcpy(id->filename,name); 00122 /* make certain that there are enough file descriptors around */ 00123 if(nfiles==maxfiles) /* gotta deactivate a few */ 00124 deactivateOldFiles(); 00125 00126 /* open SDS */ 00127 if(*access=='r'){ 00128 if(access[1]=='w'){ 00129 id->id=SDstart(id->filename,id->accessflags=DFACC_RDWR); 00130 if(id->id<0){ 00131 /* kludge around HDF bug */ 00132 id->id=SDstart(id->filename,id->accessflags=DFACC_CREATE); 00133 } 00134 SDfileinfo(id->id,&(id->nsds),&(id->nattrib)); 00135 id->sdsnumber=0; /* end of file */ 00136 if(id->accessflags!=DFACC_CREATE) 00137 id->sds_id=SDselect(id->id,0); /* goto first */ 00138 else 00139 id->sds_id=-1; 00140 } 00141 else if (access[1]=='a' || access[1]=='+') { 00142 id->id=SDstart(id->filename,id->accessflags=DFACC_RDWR); 00143 nfiles++; 00144 if(id->id<0){ 00145 /* kludge around HDF bug */ 00146 id->id=SDstart(id->filename,id->accessflags=DFACC_CREATE); 00147 } 00148 SDfileinfo(id->id,&(id->nsds),&(id->nattrib)); 00149 id->sdsnumber=id->nsds; /* end of file */ 00150 if(id->accessflags!=DFACC_CREATE) 00151 id->sds_id=SDselect(id->id,id->sdsnumber); /* goto last */ 00152 else 00153 id->sds_id=-1; 00154 } 00155 else { 00156 id->id=SDstart(id->filename,id->accessflags=DFACC_RDONLY); 00157 SDfileinfo(id->id,&(id->nsds),&(id->nattrib)); 00158 id->sdsnumber=0; /* end of file */ 00159 id->sds_id=SDselect(id->id,id->sdsnumber); /* means, need to create */ 00160 } 00161 } 00162 else if(*access=='w'){ 00163 if(access[1]=='\0'){ 00164 id->id=SDstart(id->filename,id->accessflags=DFACC_CREATE); 00165 id->sdsnumber=id->nsds=0; /* end of file */ 00166 id->sds_id=-1; /* means, need to create */ 00167 } 00168 else{ 00169 id->id=SDstart(id->filename,id->accessflags=DFACC_ALL); 00170 SDfileinfo(id->id,&(id->nsds),&(id->nattrib)); 00171 id->sdsnumber=id->nsds; 00172 id->sds_id=SDselect(id->id,id->sdsnumber); /* goto last */ 00173 } 00174 } 00175 if(id->id >= 0) 00176 nfiles++; /* it has been opened successfully */ 00177 id->lastaccess=clock(); 00178 id->numbertype=DefaultNumberType; 00179 id->next=files; 00180 files=id; 00181 return id; 00182 } 00183 00184 /*@@ 00185 @routine findIDbyComponent 00186 @date Wed Feb 28 20:37:43 1996 00187 @desc 00188 Finds a File ID given the name of the component 00189 that the file contains. This is to support a 00190 user interface style in which the componentnames 00191 can be used as alias for the actual filename. 00192 @enddesc 00193 00194 @par name 00195 @pdesc Name of the component. 00196 @ptype char* 00197 @endpar 00198 00199 @history 00200 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00201 @hdesc Initial Version 00202 @endhistory 00203 @@*/ 00204 00205 fileID *findIDbyComponent(char *name) 00206 { 00207 fileID *id; 00208 for(id=files;id!=NULL;id=id->next) 00209 if(!strcmp(name,id->componentname)) 00210 break; 00211 return id; 00212 } 00213 00214 /*@@ 00215 @routine findIDbyFilename 00216 @date Wed Feb 28 20:37:43 1996 00217 @desc 00218 Finds a File ID given the name of the component 00219 that the file contains. This is to support a 00220 user interface style in which the componentnames 00221 can be used as alias for the actual filename. 00222 @enddesc 00223 @calledby SDSopen SDSclose SDSdeactivate SDSreactivate getFileID 00224 00225 @par name 00226 @pdesc Name of the HDF file. 00227 @ptype char* 00228 @endpar 00229 00230 @history 00231 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00232 @hdesc Initial Version 00233 @endhistory 00234 @@*/ 00235 fileID *findIDbyFilename(char *name) 00236 { 00237 fileID *id; 00238 for(id=files;id!=NULL;id=id->next) 00239 if(!strcmp(name,id->filename)) 00240 break; 00241 return id; 00242 } 00243 00244 /*@@ 00245 @routine removeFileID 00246 @date Wed Feb 28 20:37:43 1996 00247 @desc 00248 Remove a file ID reference and free associated memory. 00249 It does not close the HDF file if is left open though. 00250 @enddesc 00251 @calledby SDSclose getFileID 00252 00253 @par name 00254 @pdesc Name of the file. 00255 @ptype char* 00256 @endpar 00257 00258 @history 00259 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00260 @hdesc Initial Version 00261 @endhistory 00262 @@*/ 00263 void removeFileID(char *filename) 00264 { 00265 fileID *id,*lastid,*nextid=0; 00266 00267 for(lastid=0,id=files;id;lastid=id,id=nextid) { 00268 if(!strcmp(id->filename,filename)){ 00269 nextid=id->next; 00270 if(!lastid){ 00271 files=id->next; 00272 } 00273 else { 00274 lastid->next=id->next; 00275 } 00276 free(id); 00277 } 00278 } 00279 } 00280 00281 /*@@ 00282 @routine SDScomputeSize 00283 @date Wed Feb 28 15:37:43 1996 00284 @desc 00285 Computes the Size in bytes required to store a dataset 00286 based on its dimensions and datatype. 00287 @enddesc 00288 @seeroutine SDSgetDims SDSreadData 00289 00290 @par rank 00291 @pdesc Number of dimensions in the dataset 00292 @ptype int32 00293 @endpar 00294 00295 @par dims 00296 @pdesc The size of each dimension in the dataset (in elements). 00297 @ptype int32* 00298 @endpar 00299 00300 @par datatype 00301 @pdesc The HDF datatype for each element in the dataset. 00302 @ptype int32* 00303 @endpar 00304 00305 @history 00306 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00307 @hdesc Initial Version 00308 @endhistory 00309 @@*/ 00310 long SDScomputeSize(int32 rank,int32 *dims,int32 datatype) 00311 { 00312 register int i,n; 00313 register long nbytes; 00314 for(nbytes=1,n=rank,i=0;i<n;i++){ 00315 nbytes*=dims[i]; 00316 } 00317 nbytes*=DFKNTsize(datatype); 00318 return nbytes; 00319 } 00320 00321 /*@@ 00322 @routine SDScloseAll 00323 @date Wed Feb 28 15:37:43 1996 00324 @desc 00325 Closes and all SDS files and deallocates all 00326 in-memory datastructures used by the SDS routines. 00327 @enddesc 00328 @seeroutine SDSclose 00329 00330 @history 00331 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00332 @hdesc Initial Version 00333 @endhistory 00334 @@*/ 00335 void SDScloseAll() 00336 { 00337 fileID *id,*nextid; 00338 for(id=files;id;id=nextid) { 00339 nextid=id->next; 00340 if(id->sds_id>=0) 00341 SDendaccess(id->sds_id); 00342 id->sds_id=-1; 00343 if(id->id>=0){ 00344 nfiles--; 00345 SDend(id->id); 00346 } 00347 id->id=-1; 00348 free(id); 00349 } 00350 files=NULL; 00351 } 00352 00353 /*@@ 00354 @routine SDSdeactivate 00355 @date Wed Feb 28 15:37:43 1996 00356 @desc 00357 Closes and HDF file but preserves its access state so 00358 that it can be reactivated later. Used to free up 00359 file descriptors temporarily when more files are 00360 active than there are file descriptors availible. 00361 Used for "file descriptor juggling". 00362 @enddesc 00363 @seeroutine SDSreactivate 00364 @calledby getFileID 00365 @calls findIDbyFilename 00366 00367 @par name 00368 @pdesc Name of the HDF file 00369 @ptype char* 00370 @endpar 00371 00372 @history 00373 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00374 @hdesc Initial Version 00375 @endhistory 00376 @@*/ 00377 00378 /* make file handle inactive (use if shortage of descriptors) */ 00379 void SDSdeactivate(char *filename) 00380 { 00381 fileID *id=findIDbyFilename(filename); 00382 if(id){ 00383 if(id->sds_id) 00384 SDendaccess(id->sds_id); 00385 SDend(id->id); 00386 id->id=-1; 00387 nfiles--; 00388 if(id->accessflags==DFACC_CREATE) 00389 id->accessflags=DFACC_RDWR; /* make sure it doesn't purge the file 00390 on reactivation */ 00391 } 00392 } 00393 00394 00395 /*@@ 00396 @routine SDSreactivate 00397 @date Wed Feb 28 15:37:43 1996 00398 @desc 00399 Reopens an HDF file closed by SDSdeactivate and 00400 returns it to its original state. 00401 @enddesc 00402 @seeroutine SDSdeactivate 00403 @calledby getFileID 00404 @calls findIDbyFilename 00405 00406 @par name 00407 @pdesc Name of the HDF file 00408 @ptype char* 00409 @endpar 00410 00411 @history 00412 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00413 @hdesc Initial Version 00414 @endhistory 00415 @@*/ 00416 void SDSreactivate(char *filename) 00417 { 00418 fileID *id=findIDbyFilename(filename); 00419 if(id && id->id < 0){ 00420 id->id=SDstart(filename,id->accessflags); 00421 if(id->id) 00422 nfiles++; 00423 if(id->sds_id>=0) 00424 id->sds_id=SDselect(id->id,id->sdsnumber); 00425 } 00426 } 00427 00428 /*@@ 00429 @routine SDSclose 00430 @date Wed Feb 28 15:37:43 1996 00431 @desc 00432 Closes an HDF file and removes its state description 00433 from memory. 00434 @enddesc 00435 @seeroutine SDSopen SDSdeactivate SDSreactivate 00436 @calls findIDbyFilename 00437 00438 @par name 00439 @pdesc Name of the HDF file 00440 @ptype char* 00441 @endpar 00442 00443 @history 00444 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00445 @hdesc Initial Version 00446 @endhistory 00447 @@*/ 00448 void SDSclose(char *filename) 00449 { 00450 fileID *id=findIDbyFilename(filename); 00451 if(id) { 00452 SDend(id->id); 00453 nfiles--; 00454 removeFileID(filename); 00455 } 00456 } 00457 00458 /*@@ 00459 @routine getFileID 00460 @date Wed Feb 28 20:37:43 1996 00461 @desc 00462 Checks to see if the specified file is open. 00463 If it isn't already availbile, it opens it 00464 in read-write mode. Otherwise return the existing 00465 fileID structure. 00466 @enddesc 00467 @calls findIDbyFilename 00468 @calledby SDSopen SDSflush SDSpurge SDSseek SDSseekName SDSgetIndex 00469 SDSisCoord SDSgetFileInfo SDSgetDataName SDSgetNumDatasets 00470 SDSgetDims SDSgetNT SDSsetNT SDSreadData SDSreadChunk 00471 SDSallocateDataset SDSwriteData SDSwriteChunk 00472 SDSaddAnnotation SDSgetAnnotationSize SDSgetAnnotation 00473 SDSgetNumAttribs SDSwriteAttrib SDSreadAttrib 00474 SDSfindAttribInfo SDSgetAttribInfo SDSgetDataStrs 00475 00476 00477 @par name 00478 @pdesc Name of the HDF file. 00479 @ptype char* 00480 @endpar 00481 00482 @history 00483 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00484 @hdesc Initial Version 00485 @endhistory 00486 @@*/ 00487 fileID *getFileID(char *filename) 00488 { 00489 fileID *id=findIDbyFilename(filename); 00490 if(!id) 00491 id=NewFileID(filename,"rw"); 00492 else 00493 id->lastaccess=clock(); 00494 if(id->id<0) 00495 SDSreactivate(filename); /* could be more efficient */ 00496 return id; 00497 } 00498 00499 /*@@ 00500 @routine SDSopen 00501 @date Wed Feb 28 15:37:43 1996 00502 @desc 00503 Opens an HDF file in specified access mode. 00504 @enddesc 00505 @seeroutine SDSclose SDSdeactivate SDSreactivate 00506 @calls findIDbyFilename NewFileID 00507 00508 @par name 00509 @pdesc Name of the HDF file 00510 @ptype char* 00511 @endpar 00512 00513 @par access 00514 @pdesc Access mode for the file (uses ANSI C access modes) 00515 @ptype char* 00516 @pvalues "r","w","rw","w+","ra" 00517 @endpar 00518 00519 @history 00520 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00521 @hdesc Initial Version 00522 @endhistory 00523 @@*/ 00524 void SDSopen(char *filename,char *access) 00525 { 00526 fileID *id=findIDbyFilename(filename); 00527 if(!id) 00528 id=NewFileID(filename,access); 00529 } 00530 00531 /*@@ 00532 @routine SDSflush 00533 @date Wed Feb 28 15:37:43 1996 00534 @desc 00535 Flushes the HDF file so that if a crash occurs, 00536 the contents of the file will be preserved. (currently disabled) 00537 @enddesc 00538 @seeroutine SDSclose SDSdeactivate SDSreactivate 00539 @calls findIDbyFilename SDSdeactivate SDSreactivate 00540 00541 @par name 00542 @pdesc Name of the HDF file 00543 @ptype char* 00544 @endpar 00545 00546 @history 00547 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00548 @hdesc Initial Version 00549 @hdate Tues March 8 00550 @hdesc Commented out deactivate/reactivate due to file access mode problems (must fix later) 00551 @endhistory 00552 @@*/ 00553 void SDSflush(char *filename) 00554 { 00555 fileID *id=findIDbyFilename(filename); 00556 if(id && id->sds_id>=0) 00557 SDendaccess(id->sds_id); 00558 /* 00559 SDSdeactivate(filename); 00560 SDSreactivate(filename); 00561 */ 00562 } 00563 00564 /*@@ 00565 @routine SDSpurge 00566 @date Wed Feb 28 15:37:43 1996 00567 @desc 00568 Purges an HDF file, removing all of its contents. 00569 Can Use to garauntee that you are writing into a 00570 fresh HDF file since the default way SDS opens 00571 a file is Read/Write/Append mode. 00572 Potentially dangerous routine... 00573 @enddesc 00574 @calls SDSclose SDSopen 00575 00576 @par name 00577 @pdesc Name of the HDF file 00578 @ptype char* 00579 @endpar 00580 00581 @history 00582 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00583 @hdesc Initial Version 00584 @endhistory 00585 @@*/ 00586 void SDSpurge(char *filename) 00587 { 00588 SDSclose(filename); 00589 SDSopen(filename,"w"); 00590 } 00591 00592 /*@@ 00593 @routine SDSseek 00594 @date Wed Feb 28 15:37:43 1996 00595 @desc 00596 Allows random acces in HDF files. 00597 Moves to the sds in the file specified by setnum. 00598 @enddesc 00599 @calls getFileID 00600 00601 @par name 00602 @pdesc Name of the HDF file 00603 @ptype char* 00604 @endpar 00605 00606 @par setnum 00607 @pdesc Index of the dataset in the HDf file 00608 @ptype int 00609 @endpar 00610 00611 @history 00612 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00613 @hdesc Initial Version 00614 @endhistory 00615 @@*/ 00616 void SDSseek(char *filename,int setnum) 00617 { 00618 fileID *id=getFileID(filename); 00619 id->sdsnumber=setnum; 00620 id->sds_id=SDselect(id->id,id->sdsnumber); 00621 } 00622 00623 /*@@ 00624 @routine SDSseekName 00625 @date Wed Feb 28 15:37:43 1996 00626 @desc 00627 Allows random acces in HDF files. 00628 Moves to the sds in the file with the name specified by "dataname". 00629 @enddesc 00630 @calls getFileID 00631 00632 @par name 00633 @pdesc Name of the HDF file 00634 @ptype char* 00635 @endpar 00636 00637 @par dataname 00638 @pdesc Name of the dataset in the HDf file 00639 @ptype char* 00640 @endpar 00641 00642 @history 00643 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00644 @hdesc Initial Version 00645 @endhistory 00646 @@*/ 00647 int32 SDSseekName(char *filename,char *dataname) 00648 { 00649 fileID *id=getFileID(filename); 00650 id->sdsnumber=SDnametoindex(id->id,dataname); 00651 id->sds_id=SDselect(id->id,id->sdsnumber); 00652 return id->sdsnumber; 00653 } 00654 00655 /*@@ 00656 @routine SDSgetNT 00657 @date Wed Feb 28 15:37:43 1996 00658 @desc 00659 Gets the numbertype of the current SDS. 00660 @enddesc 00661 @calls getFileID 00662 00663 @par name 00664 @pdesc Name of the HDF file 00665 @ptype char* 00666 @endpar 00667 00668 @history 00669 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00670 @hdesc Initial Version 00671 @endhistory 00672 @@*/ 00673 /* analogue to DFSDgetDims() 00674 it gets the AMR attributes of the next SDS */ 00675 int32 SDSgetNT(char *filename) 00676 { 00677 int32 numbertype,attribs,rank,dims[MAX_VAR_DIMS]; 00678 fileID *id=getFileID(filename); 00679 if(id->sds_id<0) 00680 id->sds_id=SDselect(id->id,id->sdsnumber); 00681 if(id->sds_id<0) 00682 return -1; 00683 SDgetinfo(id->sds_id,NULL,&rank,dims,&numbertype,&attribs); 00684 id->numbertype=numbertype; 00685 return numbertype; 00686 } 00687 00688 /*@@ 00689 @routine SDSisCoord 00690 @date Wed Feb 28 15:37:43 1996 00691 @desc 00692 Returns 1 if the current dataset is a coordinate array 00693 and false if it is not. This is a direct passthru of 00694 the function SDisCoordVar(). This function has become 00695 necessary because in order to make HDF compatible with 00696 NetCDF, the files the designers had to disable its ability 00697 to tell the difference between datasets and stored coordinates 00698 for the datasets. 00699 @enddesc 00700 @calls getFileID 00701 00702 @par name 00703 @pdesc Name of the HDF file 00704 @ptype char* 00705 @endpar 00706 00707 @history 00708 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00709 @hdesc Initial Version 00710 @endhistory 00711 @@*/ 00712 int32 SDSisCoord(char *filename) 00713 { 00714 fileID *id=getFileID(filename); 00715 if(id->sds_id<0) 00716 id->sds_id=SDselect(id->id,id->sdsnumber); 00717 if(id->sds_id<0) 00718 return -1; 00719 return SDiscoordvar(id->sds_id); 00720 } 00721 00722 /*@@ 00723 @routine SDSsetNT 00724 @date Wed Feb 28 15:37:43 1996 00725 @desc 00726 Sets the default numbertype for a particular 00727 HDF file. All further write operations will assume 00728 this numbertype until SDSsetNT is used again to 00729 select a new numbertype.<p> 00730 00731 The default numbertype is DFNT_FLOAT32 (32 bit float) 00732 @enddesc 00733 @calls getFileID 00734 00735 @par name 00736 @pdesc Name of the HDF file 00737 @ptype char* 00738 @endpar 00739 00740 @par numbertype 00741 @pdesc Numbertype for subsequent data writes 00742 @ptype char* 00743 @pvalues DFNT_FLOAT32 (32-bit float), DFNT_FLOAT64 (64-bit float/double), 00744 DFNT_INT8 (char), DFNT_INT16 (short int), DFNT_INT32,(int), 00745 DFNT_UINT8 (unsigned char), DFNT_UNINT16 (unsigned short), 00746 DFNT_UINT32 (unsigned int), 00747 DFNT_NATIVE (if bit-OR'ed with the above, uses machine native format) 00748 00749 @endpar 00750 00751 @history 00752 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00753 @hdesc Initial Version 00754 @endhistory 00755 @@*/ 00756 void SDSsetNT(char *filename,int32 numbertype) 00757 { 00758 fileID *id=getFileID(filename); 00759 id->numbertype=numbertype; 00760 } 00761 00762 00763 /*@@ 00764 @routine SDSgetDims 00765 @date Wed Feb 28 15:37:43 1996 00766 @desc 00767 Reads data from an HDF file. 00768 This must be preceded by an SDSgetDims() which 00769 returns the dimensions of the data so that the user 00770 can allocate the space to read in the data. 00771 @enddesc 00772 @seeroutine SDSreadData 00773 @calls getFileID 00774 00775 @par filename 00776 @pdesc Name of the HDF file 00777 @ptype char* 00778 @endpar 00779 00780 @par name 00781 @pdesc Name of the dataset (read from the file) 00782 @ptype char* 00783 @endpar 00784 00785 @par rank 00786 @pdesc Number of dimension in the dataset 00787 @ptype int32 00788 @endpar 00789 00790 @par dims 00791 @pdesc Dimensions of the dataset 00792 @ptype int32* 00793 @endpar 00794 00795 @par data 00796 @pdesc Pointer to the actual dataset (preallocated by the user) 00797 @ptype VOIDP 00798 @endpar 00799 00800 @history 00801 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00802 @hdesc Initial Version 00803 @endhistory 00804 @@*/ 00805 long SDSgetDims (char *filename,char *dataname,int32 *rank,int32 *dims) 00806 { 00807 int32 numbertype,attribs; 00808 long status; 00809 fileID *id=getFileID(filename); 00810 if(id->sds_id>=0) 00811 SDendaccess(id->sds_id); 00812 id->sds_id=SDselect(id->id,(id->sdsnumber)++); 00813 if(id->sds_id<0) 00814 return -1; 00815 status=SDgetinfo(id->sds_id,dataname,rank,dims,&numbertype,&attribs); 00816 if(status>=0){ 00817 id->numbertype=numbertype; 00818 id->nattrib = attribs; 00819 SDScomputeSize(*rank,dims,numbertype); 00820 return 0; 00821 } 00822 else 00823 return -1; 00824 } 00825 /*@@ 00826 @routine SDSreadData 00827 @date Wed Feb 28 15:37:43 1996 00828 @desc 00829 Reads data from an HDF file. 00830 This must be preceded by an SDSgetDims() which 00831 returns the dimensions of the data so that the user 00832 can allocate the space to read in the data. 00833 @enddesc 00834 @seeroutine SDSgetDims 00835 @calls getFileID 00836 00837 @par filename 00838 @pdesc Name of the HDF file 00839 @ptype char* 00840 @endpar 00841 00842 @par dataname 00843 @pdesc Name of the dataset (read from the file) 00844 @ptype char* 00845 @endpar 00846 00847 @par rank 00848 @pdesc Number of dimension in the dataset 00849 @ptype int32 00850 @endpar 00851 00852 @par dims 00853 @pdesc Dimensions of the dataset 00854 @ptype int32* 00855 @endpar 00856 00857 @par data 00858 @pdesc Pointer to the actual dataset (preallocated by the user) 00859 @ptype VOIDP 00860 @endpar 00861 00862 @history 00863 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00864 @hdesc Initial Version 00865 @endhistory 00866 @@*/ 00867 int SDSreadData(char *filename,int32 rank,int32 *dims,VOIDP data) 00868 { 00869 static int32 originS[5]={0,0,0,0,0},*origin; 00870 int status; 00871 fileID *id=getFileID(filename); 00872 if(id->sds_id<0) 00873 id->sds_id=SDselect(id->id,id->sdsnumber); 00874 00875 if(rank > 5) { 00876 origin=(int32 *)calloc(sizeof(int),rank); /* origin is zeroed */ 00877 } 00878 else 00879 origin=originS; 00880 if(id->sds_id<0) 00881 id->sds_id=SDselect(id->id,id->sdsnumber); 00882 if(id->sds_id<0) 00883 return -1; 00884 /*SDgetinfo(id->sds_id,NULL,&rank,dims,&(id->numbertype),&(id->nattrib));*/ 00885 status = SDreaddata(id->sds_id,origin,NULL,dims,data); 00886 if(origin!=originS) 00887 free(origin); 00888 if(status>=0) 00889 return SDScomputeSize(rank,dims,id->numbertype); 00890 else 00891 return -1; 00892 } 00893 00894 00895 00896 /*@@ 00897 @routine SDSreadChunk 00898 @date Wed Feb 28 15:37:43 1996 00899 @desc 00900 Reads a subsection (chunk) of data from a selected dataset. 00901 You can specify any origin, stride, and region- 00902 of-interest within the total size of the dataset. 00903 00904 A dataset must have been selected by an SDSgetDims() which 00905 returns the total dimensions of the data. Once selected 00906 though, it can be followed by any number of reads. 00907 @enddesc 00908 @seeroutine SDSgetDims 00909 @calls getFileID 00910 00911 @par filename 00912 @pdesc Name of the HDF file 00913 @ptype char* 00914 @endpar 00915 00916 @par rank 00917 @pdesc Number of dimension in the dataset 00918 @ptype int32 00919 @endpar 00920 00921 @par dims 00922 @pdesc Dimensions of the dataset to read 00923 @ptype int32* 00924 @endpar 00925 00926 @par origin 00927 @pdesc Origin of the read within the dataset 00928 @ptype int32* 00929 @endpar 00930 00931 @par stride 00932 @pdesc Stride of the read in each dimension 00933 @ptype int32* 00934 @endpar 00935 00936 @par data 00937 @pdesc Pointer to the actual dataset (preallocated by the user) 00938 @ptype VOIDP 00939 @endpar 00940 00941 @history 00942 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 00943 @hdesc Initial Version 00944 need to eliminate chunk reading inefficiency. 00945 Basically, it needs to re-read the chunkname on every cycle 00946 which results in a lot of unneccessary seeking. To 00947 optimize, will need to store the sds name internally and 00948 only get it again if its a different sds. Either that 00949 or just separate readNamedChunk from this one. 00950 @hdate Tues Mar 8 @hauthor 00951 @hdesc Eliminated "name" from parameter list. 00952 Depends on SDSgetDims to read the name now. 00953 @endhistory 00954 @@*/ 00955 int SDSreadChunk(char *filename,int32 rank,int32 *dims, 00956 int32 *origin,int32 *stride,VOIDP data) 00957 { 00958 static int32 originS[5]={0,0,0,0,0}; 00959 int status; 00960 char name[MAX_NC_NAME]; 00961 fileID *id=getFileID(filename); 00962 if(!origin){ 00963 if(rank > 5) { 00964 origin=(int32 *)calloc(sizeof(int),rank); /* origin is zeroed */ 00965 } 00966 else 00967 origin=originS; 00968 } 00969 if(id->sds_id<0){ 00970 id->sds_id=SDselect(id->id,id->sdsnumber); 00971 if(id->sds_id<0) 00972 return -1; 00973 SDgetinfo(id->sds_id,name,&rank,dims,&(id->numbertype),&(id->nattrib)); 00974 } 00975 status = SDreaddata(id->sds_id,origin,stride,dims,data); 00976 if(origin!=originS) 00977 free(origin); 00978 return status; 00979 } 00980 00981 00982 /*@@ 00983 @routine SDSgetFileInfo 00984 @date Wed Feb 28 15:37:43 1996 00985 @desc 00986 Gets information relevant to the entire file. 00987 Namely the number datasets contained in the file as 00988 well as the number of attributes associated with the file. 00989 @enddesc 00990 @calls getFileID 00991 00992 @par filename 00993 @pdesc Name of the HDF file 00994 @ptype char* 00995 @endpar 00996 00997 @par nsds 00998 @pdesc Number of datasets (sds's) in the hdf file 00999 @ptype int32* 01000 @endpar 01001 01002 @par nattrib 01003 @pdesc Number of netcdf attributes for the file 01004 @ptype int32* 01005 @endpar 01006 01007 @history 01008 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 01009 @hdesc Initial Version 01010 @endhistory 01011 @@*/ 01012 void SDSgetFileInfo (char *filename,int32 *nsds,int32 *nattrib) 01013 { 01014 fileID *id=getFileID(filename); 01015 if(nsds) 01016 *nsds=id->nsds; 01017 if(nattrib) 01018 *nattrib=id->nattrib; 01019 } 01020 01021 /*@@ 01022 @routine SDSgetDataName 01023 @date Wed Feb 28 15:37:43 1996 01024 @desc 01025 Gets the name of the current dataset 01026 @enddesc 01027 @calls getFileID 01028 01029 @par filename 01030 @pdesc Name of the HDF file 01031 @ptype char* 01032 @endpar 01033 01034 @par dataname 01035 @pdesc Name of the current dataset 01036 @ptype char* 01037 @endpar 01038 01039 @history 01040 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 01041 @hdesc Initial Version 01042 @endhistory 01043 @@*/ 01044 int32 SDSgetDataName (char *filename,char *name) 01045 { 01046 int32 status; 01047 int32 rank,dims[MAX_NC_DIMS]; 01048 fileID *id=getFileID(filename); 01049 if(id->sds_id<0) 01050 id->sds_id=SDselect(id->id,id->sdsnumber); 01051 if(id->sds_id<0) 01052 return -1; 01053 status=SDgetinfo(id->sds_id,name,&rank,dims, 01054 &(id->numbertype), 01055 &(id->nattrib)); 01056 return status; 01057 } 01058 01059 /*@@ 01060 @routine SDSgetIndex 01061 @date Wed Feb 28 15:37:43 1996 01062 @desc 01063 Returns the index of the current dataset 01064 @enddesc 01065 @calls getFileID 01066 01067 @par filename 01068 @pdesc Name of the HDF file 01069 @ptype char* 01070 @endpar 01071 01072 @history 01073 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 01074 @hdesc Initial Version 01075 @endhistory 01076 @@*/ 01077 int32 SDSgetIndex (char *filename) 01078 { 01079 fileID *id=getFileID(filename); 01080 return id->sdsnumber; 01081 } 01082 01083 /*@@ 01084 @routine SDSgetDataStrs 01085 @date Wed Feb 28 15:37:43 1996 01086 @desc 01087 Retrieves the data strings associated with the current dataset. 01088 @enddesc 01089 @calls getFileID 01090 01091 @par filename 01092 @pdesc Name of the HDF file 01093 @ptype char* 01094 @endpar 01095 01096 @par label 01097 @pdesc Label of the current dataset 01098 @ptype char* 01099 @endpar 01100 01101 @par units 01102 @pdesc Units of the current dataset (ie. meters, millibars, foot-pounds) 01103 @ptype char* 01104 @endpar 01105 01106 @par format 01107 @pdesc Format of the current dataset 01108 @ptype char* 01109 @endpar 01110 01111 @par coordsys 01112 @pdesc Coordinate system for the current dataset. 01113 @ptype char* 01114 @endpar 01115 01116 @par maxlen 01117 @pdesc Maximum length of a string the variables can receive. 01118 @ptype int32 01119 @endpar 01120 01121 @history 01122 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 01123 @hdesc Initial Version 01124 @endhistory 01125 @@*/ 01126 01127 int32 SDSgetDataStrs (char *filename,char *label,char *units, 01128 char *format,char *coordsys,int maxlen) 01129 { 01130 fileID *id=getFileID(filename); 01131 if(id->sds_id<0) 01132 id->sds_id=SDselect(id->id,id->sdsnumber); 01133 if(id->sds_id<0) 01134 return -1; 01135 return SDgetdatastrs(id->sds_id,label,units,format,coordsys,maxlen); 01136 } 01137 01138 /*@@ 01139 @routine SDSgetNumDatasets 01140 @date Wed Feb 28 15:37:43 1996 01141 @desc 01142 Returns the number of SDS's in the current dataset 01143 @enddesc 01144 @calls getFileID 01145 01146 @par filename 01147 @pdesc Name of the HDF file 01148 @ptype char* 01149 @endpar 01150 01151 @history 01152 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 01153 @hdesc Initial Version 01154 @endhistory 01155 @@*/ 01156 int32 SDSgetNumDatasets (char *filename) 01157 { 01158 fileID *id=getFileID(filename); 01159 return id->nsds; 01160 } 01161 01162 /*@@ 01163 @routine SDSallocateDataset 01164 @date Wed Feb 28 15:37:43 1996 01165 @desc 01166 Creates and reserves a dataset to receive data in chunks. 01167 Use in conjunction with SDSwriteChunk. 01168 @enddesc 01169 @seeroutine SDSwriteChunk 01170 @calls getFileID 01171 01172 @par filename 01173 @pdesc Name of the HDF file 01174 @ptype char* 01175 @endpar 01176 01177 @par dataname 01178 @pdesc Name of the SDS 01179 @ptype char* 01180 @endpar 01181 01182 @par rank 01183 @pdesc Number of dimensions for the dataset 01184 @ptype char* 01185 @endpar 01186 01187 @par dims 01188 @pdesc The maximum dimension sizes for the dataset 01189 (can be SD_UNLIMITED in any dimension to allow the 01190 space availible to automatically grow as you write chunks) 01191 @ptype char* 01192 @endpar 01193 01194 @history 01195 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 01196 @hdesc Initial Version 01197 @endhistory 01198 @@*/ 01199 int32 SDSallocateDataset(char *filename,char *dataname,int32 rank,int32 *dims) 01200 { 01201 fileID *id=getFileID(filename); 01202 if(id->accessflags==DFACC_RDONLY) 01203 return -1; /* cant write to this file */ 01204 if(id->sds_id>=0) 01205 SDendaccess(id->sds_id); /* may no longer be a valid operation */ 01206 01207 id->sds_id=SDcreate(id->id,dataname,id->numbertype,rank,dims); 01208 if(id->sds_id>=0) 01209 (id->nsds)++; 01210 01211 return id->sdsnumber=SDreftoindex(id->id,SDidtoref(id->sds_id)); 01212 } 01213 01214 /*@@ 01215 @routine SDSwriteChunk 01216 @date Wed Feb 28 15:37:43 1996 01217 @desc 01218 Writes a chunk of data to an sds with any 01219 stride, origin, and dimension so long as the 01220 chunk falls within the bounds of the dataset 01221 reserved with SDSallocateDataset(). If any 01222 of the dimensions were declared SD_UNLIMITED 01223 for size, then the size of the chunk is only 01224 constrained by system and file size limits. 01225 @enddesc 01226 @seeroutine SDSallocateDataset 01227 @calls getFileID 01228 01229 @par filename 01230 @pdesc Name of the HDF file 01231 @ptype char* 01232 @endpar 01233 01234 @par rank 01235 @pdesc Number of dimensions for the dataset 01236 @ptype char* 01237 @endpar 01238 01239 @par dims 01240 @pdesc The maximum dimension sizes for the dataset 01241 (can be SD_UNLIMITED in any dimension to allow the 01242 space availible to automatically grow as you write chunks) 01243 @ptype char* 01244 @endpar 01245 01246 @history 01247 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 01248 @hdesc Initial Version 01249 @endhistory 01250 @@*/ 01251 int SDSwriteChunk (char *filename,int32 rank,int32 *dims, 01252 int32 *origin,int32 *stride,VOIDP data) 01253 { 01254 static int32 originS[5]={0,0,0,0,0}; 01255 int status; 01256 fileID *id=getFileID(filename); 01257 if(id->accessflags==DFACC_RDONLY) 01258 return -1; /* cant write to this file */ 01259 01260 if(!origin){ 01261 if(rank > 5) { 01262 origin=(int32 *)calloc(sizeof(int32),rank); /* origin is zeroed */ 01263 } 01264 else 01265 origin=originS; 01266 } 01267 if(id->sds_id<0) 01268 return -1; /* have to reserve the chunk first!! */ 01269 /* 01270 if(id->sds_id<0) only create if it doesn't already exist 01271 id->sds_id=SDcreate(id->id,id->dataname,id->numbertype,rank,dims); 01272 */ 01273 if(id->sds_id>=0) 01274 (id->nsds)++; 01275 id->sdsnumber=SDreftoindex(id->id,SDidtoref(id->sds_id)); 01276 status=SDwritedata(id->sds_id,origin,stride,dims,data); 01277 /* SDendaccess(id->sds_id); (might append annotation) */ 01278 if(origin!=originS) 01279 free(origin); 01280 return status; 01281 } 01282 01283 /*@@ 01284 @routine SDSwriteData 01285 @date Wed Feb 28 15:37:43 1996 01286 @desc 01287 Writes a chunk of data to an sds with any 01288 stride, origin, and dimension so long as the 01289 chunk falls within the bounds of the dataset 01290 reserved with SDSallocateDataset(). If any 01291 of the dimensions were declared SD_UNLIMITED 01292 for size, then the size of the chunk is only 01293 constrained by system and file size limits. 01294 @enddesc 01295 @seeroutine SDSreadData SDSsetNT() 01296 @calls getFileID 01297 01298 @par filename 01299 @pdesc Name of the HDF file 01300 @ptype char* 01301 @endpar 01302 01303 @par dataname 01304 @pdesc Name for the dataset 01305 @ptype char* 01306 @endpar 01307 01308 @par rank 01309 @pdesc Number of dimensions for the dataset 01310 @ptype char* 01311 @endpar 01312 01313 @par dims 01314 @pdesc The maximum dimension sizes for the dataset 01315 @ptype char* 01316 @endpar 01317 01318 @par data 01319 @pdesc Pointer to the dataset to write. 01320 Default type is DFNT_FLOAT32 (32-bit float). 01321 This default can be changed using SDSsetNT(). 01322 @ptype VOIDP 01323 @endpar 01324 01325 @history 01326 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 01327 @hdesc Initial Version 01328 @endhistory 01329 @@*/ 01330 int SDSwriteData (char *filename,char *dataname,int32 rank, 01331 int32 *dims,VOIDP data) 01332 { 01333 static int32 originS[5]={0,0,0,0,0},*origin; 01334 int status; 01335 fileID *id=getFileID(filename); 01336 if(id->accessflags==DFACC_RDONLY) 01337 return -1; /* cant write to this file */ 01338 if(id->sds_id>=0) 01339 SDendaccess(id->sds_id); 01340 01341 if(rank > 5) { 01342 origin=(int32 *)calloc(sizeof(int32),rank); /* origin is zeroed */ 01343 } 01344 else 01345 origin=originS; 01346 01347 id->sds_id=SDcreate(id->id,dataname,id->numbertype,rank,dims); 01348 if(id->sds_id>=0) 01349 (id->nsds)++; 01350 id->sdsnumber=SDreftoindex(id->id,SDidtoref(id->sds_id)); 01351 status=SDwritedata(id->sds_id,origin,NULL,dims,data); 01352 /* SDendaccess(id->sds_id); (might append annotation) */ 01353 if(origin!=originS) 01354 free(origin); 01355 return status; 01356 } 01357 01358 /*@@ 01359 @routine SDSgetAnnotationSize 01360 @date Wed Feb 28 15:37:43 1996 01361 @desc 01362 Returns the size of the current annotation attached to 01363 the current dataset 01364 @enddesc 01365 @seeroutine SDSgetAnnotation 01366 @calls getFileID 01367 01368 @par filename 01369 @pdesc Name of the HDF file 01370 @ptype char* 01371 @endpar 01372 01373 @history 01374 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 01375 @hdesc Initial Version 01376 @endhistory 01377 @@*/ 01378 int32 SDSgetAnnotationSize(char *filename) 01379 { 01380 int32 ref; 01381 fileID *id=getFileID(filename); 01382 if(id->accessflags==DFACC_RDONLY) 01383 return -1; /* cant write to this file */ 01384 if(id->sds_id<0) 01385 id->sds_id=SDselect(id->id,id->sdsnumber); 01386 ref=SDidtoref(id->sds_id); 01387 return DFANgetlablen(id->filename,DFTAG_NDG,ref); 01388 } 01389 01390 /*@@ 01391 @routine SDSgetAnnotation 01392 @date Wed Feb 28 15:37:43 1996 01393 @desc 01394 Returns the size of the current annotation attached to 01395 the current dataset. 01396 @enddesc 01397 @seeroutine SDSgetAnnotationSize SDSaddAnnotation 01398 @calls getFileID 01399 01400 @par filename 01401 @pdesc Name of the HDF file 01402 @ptype char* 01403 @endpar 01404 01405 @par annotation 01406 @pdesc buffer to store the annotation in 01407 @ptype char* 01408 @endpar 01409 01410 @par maxlen 01411 @pdesc Maximum length of the annotation (ie. the buffer size) 01412 @ptype char* 01413 @endpar 01414 01415 @history 01416 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 01417 @hdesc Initial Version 01418 @endhistory 01419 @@*/ 01420 int32 SDSgetAnnotation(char *filename,char *annotation,int32 maxlen) 01421 { 01422 int32 ref; 01423 fileID *id=getFileID(filename); 01424 if(id->accessflags==DFACC_RDONLY) 01425 return -1; /* cant write to this file */ 01426 if(id->sds_id<0) 01427 id->sds_id=SDselect(id->id,id->sdsnumber); 01428 ref=SDidtoref(id->sds_id); 01429 return DFANgetlabel(id->filename,DFTAG_NDG,ref,annotation,maxlen); 01430 } 01431 01432 /*@@ 01433 @routine SDSaddAnnotation 01434 @date Wed Feb 28 15:37:43 1996 01435 @desc 01436 Adds a text string annotation to the currently selected SDS 01437 @enddesc 01438 @seeroutine SDSgetAnnotation SDSgetAnnotationSize 01439 @calls getFileID 01440 01441 @par filename 01442 @pdesc Name of the HDF file 01443 @ptype char* 01444 @endpar 01445 01446 @par annotation 01447 @pdesc buffer to store the annotation in 01448 @ptype char* 01449 @endpar 01450 01451 @history 01452 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 01453 @hdesc Initial Version 01454 @endhistory 01455 @@*/ 01456 int32 SDSaddAnnotation(char *filename,char *annotation) 01457 { 01458 int32 ref; 01459 fileID *id=getFileID(filename); 01460 if(id->accessflags==DFACC_RDONLY) 01461 return -1; /* cant write to this file */ 01462 if(id->sds_id<0) 01463 id->sds_id=SDselect(id->id,id->sdsnumber); 01464 ref=SDidtoref(id->sds_id); 01465 return DFANputlabel(id->filename,DFTAG_NDG,ref,annotation); 01466 } 01467 01468 /*@@ 01469 @routine SDSgetNumAttribs 01470 @date Wed Feb 28 15:37:43 1996 01471 @desc 01472 Returns the number of attributes associated with the 01473 current dataset. The attributes can be retreived by 01474 name (if you already know which attributes you are 01475 looking for) or by index (if you want to step through them 01476 in order). Returns an error if no SDS is currently selected. 01477 @enddesc 01478 @seeroutine SDSreadAttrib SDSfindAttribInfo SDSgetAttribInfo 01479 @calls getFileID 01480 01481 @par filename 01482 @pdesc Name of the HDF file 01483 @ptype char* 01484 @endpar 01485 01486 @history 01487 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 01488 @hdesc Initial Version 01489 @endhistory 01490 @@*/ 01491 int32 SDSgetNumAttribs(char *filename) 01492 { 01493 fileID *id=getFileID(filename); 01494 if(id->sds_id>=0) 01495 return id->nattrib; 01496 else 01497 return -1; /* or should it return 0???? */ 01498 } 01499 01500 /*@@ 01501 @routine SDSwriteAttrib 01502 @date Wed Feb 28 15:37:43 1996 01503 @desc 01504 Writes an attribute associated with the current SDS 01505 to the HDF file. The attribute can be referred to 01506 by its name or by its index when read back in. 01507 @enddesc 01508 @seeroutine SDSreadAttrib SDSfindAttribInfo SDSgetAttribInfo SDSgetNumAttribs 01509 @calls getFileID 01510 01511 @par filename 01512 @pdesc Name of the HDF file 01513 @ptype char* 01514 @endpar 01515 01516 @par attribname 01517 @pdesc Name of the attribute. 01518 @ptype char* 01519 @endpar 01520 01521 @par numbertype 01522 @pdesc Numbertype of the attribute 01523 @pvalues DFNT_FLOAT32 (32-bit float), DFNT_FLOAT64 (64-bit float/double), 01524 DFNT_INT8 (char), DFNT_INT16 (short int), DFNT_INT32,(int), 01525 DFNT_UINT8 (unsigned char), DFNT_UNINT16 (unsigned short), 01526 DFNT_UINT32 (unsigned int), 01527 DFNT_NATIVE (if bit-OR'ed with the above, uses machine native format) 01528 @ptype int32 01529 @endpar 01530 01531 @par nelements 01532 @pdesc Number of elements (of the type specified by the numbertype param) 01533 to store in the attribute. 01534 @ptype int32 01535 @endpar 01536 01537 @par buffer 01538 @pdesc Pointer to the attribute data. 01539 @ptype VOIDP 01540 @endpar 01541 01542 @history 01543 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 01544 @hdesc Initial Version 01545 @endhistory 01546 @@*/ 01547 int32 SDSwriteAttrib(char *filename,char *attribname, 01548 int32 numbertype,int32 nelements,VOIDP buffer) 01549 { 01550 fileID *id=getFileID(filename); 01551 if(id->accessflags==DFACC_RDONLY) 01552 return -1; /* cant write to this file */ 01553 if(id->sds_id<0) 01554 return -1; /* needs to be existing writeable SDS ? */ 01555 /* 01556 id->sds_id=SDselect(id->id,id->sdsnumber); 01557 if(id->sds_id<0) 01558 return -1; 01559 */ 01560 return SDsetattr(id->sds_id,attribname,numbertype,nelements,buffer); 01561 } 01562 /*@@ 01563 @routine SDSreadAttrib 01564 @date Wed Feb 28 15:37:43 1996 01565 @desc 01566 Reads the attribute with the specified "attribname" associated 01567 with the current SDS to the HDF file. If there is no attribute 01568 by that name, it returns 0. If an attribute is found by that 01569 name, it returns the number of elements read. 01570 The attribute can be referred to by its name or by its 01571 index when read back in.<p> 01572 01573 If you want to pre-allocate the buffer to match the size of 01574 the attribute being read in, then you should use 01575 SDSfindAttribInfo() or SDSgetAttribInfo() to get the 01576 exact size of the data contained in the attribute before 01577 reading. If the size of the buffer is smaller than the 01578 amount of data that needs to be read, the read will be 01579 truncated to fit into the buffer.<p> 01580 01581 If the stored data is a character string and the returned 01582 size==the size of your buffer, you will need to null 01583 terminate the buffer yourself after it is returned. 01584 @enddesc 01585 @seeroutine SDSwriteAttrib SDSfindAttribInfo SDSgetAttribInfo SDSgetNumAttribs 01586 @calls getFileID 01587 01588 @par filename 01589 @pdesc Name of the HDF file 01590 @ptype char* 01591 @endpar 01592 01593 @par attribname 01594 @pdesc Name of the attribute. 01595 @ptype char* 01596 @endpar 01597 01598 @par nelements 01599 @pdesc The maximimum number of elements that can be read by the 01600 from the attribute (ie. the size of the buffer). 01601 @ptype int32 01602 @endpar 01603 01604 @par buffer 01605 @pdesc Pointer to the attribute data. 01606 @ptype VOIDP 01607 @endpar 01608 01609 @history 01610 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 01611 @hdesc Initial Version 01612 @endhistory 01613 @@*/ 01614 int32 SDSreadAttrib(char *filename,char *attribname2,int32 nelements,VOIDP buffer) 01615 { 01616 int status; 01617 int index; 01618 int32 nt,count,rtval; 01619 fileID *id=getFileID(filename); 01620 char *attribname; 01621 if(id->sds_id<0) 01622 id->sds_id=SDselect(id->id,id->sdsnumber); 01623 if(id->sds_id<0) 01624 return -1; 01625 /* Copied to temporary string, SDattrinfo changes data! --- RD */ 01626 attribname=(char *)malloc(HDstrlen(attribname2)); 01627 HDmemcpy(attribname, attribname2, HDstrlen(attribname2)); 01628 attribname[HDstrlen(attribname2)] = '\0'; 01629 index=SDfindattr(id->sds_id,attribname); 01630 /* Check to make sure the number of elements in the attribute 01631 is less than the number of elements in the buffer */ 01632 status=SDattrinfo(id->sds_id,index,attribname,&nt,&count); 01633 free(attribname); 01634 if(status<0) 01635 return status; 01636 if(count>nelements){ 01637 char *tmpdata=(char *)malloc(count*DFKNTsize(nt)); 01638 rtval=SDreadattr(id->sds_id,index,tmpdata); 01639 bcopy(tmpdata,buffer,DFKNTsize(nt)*nelements); 01640 free(tmpdata); 01641 /* if(nt==DFNT_INT8){ 01642 might be a string, so null terminate 01643 buffer[nelements-1]='\0'; 01644 }*/ 01645 } 01646 else 01647 rtval=SDreadattr(id->sds_id,index,buffer); 01648 return (rtval>=0)?count:rtval; 01649 } 01650 01651 /*@@ 01652 @routine SDSfindAttribInfo 01653 @date Wed Feb 28 15:37:43 1996 01654 @desc 01655 Finds the named attribute associated with the current dataset 01656 by name and retrieves information about it. It will return 01657 -1 if no attribute with that name is found. 01658 @enddesc 01659 @seeroutine SDSreadAttrib SDSgetAttribInfo SDSgetAttribInfo SDSgetNumAttribs 01660 @calls getFileID 01661 01662 @par filename 01663 @pdesc Name of the HDF file 01664 @ptype char* 01665 @endpar 01666 01667 @par attribname 01668 @pdesc Name of the attribute. 01669 @ptype char* 01670 @endpar 01671 01672 @par numbertype 01673 @pdesc Storage in which to return the numbertype of the attribute 01674 @pvalues DFNT_FLOAT32 (32-bit float), DFNT_FLOAT64 (64-bit float/double), 01675 DFNT_INT8 (char), DFNT_INT16 (short int), DFNT_INT32,(int), 01676 DFNT_UINT8 (unsigned char), DFNT_UNINT16 (unsigned short), 01677 DFNT_UINT32 (unsigned int), 01678 DFNT_NATIVE (if bit-OR'ed with the above, uses machine native format) 01679 @ptype int32* 01680 @endpar 01681 01682 @par nelements 01683 @pdesc Storage in which to return the number of elements in the attribute 01684 of the type defined by the numbertype param. 01685 01686 @ptype int32* 01687 @endpar 01688 01689 @history 01690 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 01691 @hdesc Initial Version 01692 @endhistory 01693 @@*/ 01694 int32 SDSfindAttribInfo(char *filename,char *attribname, 01695 int32 *numbertype,int32 *nelements) 01696 { 01697 int index; 01698 fileID *id=getFileID(filename); 01699 if(id->sds_id<0) 01700 id->sds_id=SDselect(id->id,id->sdsnumber); 01701 if(id->sds_id<0) 01702 return -1; 01703 index=SDfindattr(id->sds_id,attribname); 01704 return SDattrinfo(id->sds_id,index,attribname,numbertype,nelements); 01705 } 01706 /*@@ 01707 @routine SDSgetAttribInfo 01708 @date Wed Feb 28 15:37:43 1996 01709 @desc 01710 Allows you to get the attribute information by index 01711 instead of by name. 01712 @enddesc 01713 @seeroutine SDSreadAttrib SDSwriteAttrib SDSfindAttribInfo SDSgetNumAttribs 01714 @calls getFileID 01715 01716 @par filename 01717 @pdesc Name of the HDF file 01718 @ptype char* 01719 @endpar 01720 01721 @par index 01722 @pdesc Index of the attribute attached to the SDS 01723 @ptype int32 01724 @endpar 01725 01726 @par attribname 01727 @pdesc Storage area for name of the attribute (so that it can be 01728 returned to the user) 01729 @ptype char* 01730 @endpar 01731 01732 @par numbertype 01733 @pdesc Storage in which to return the numbertype of the attribute 01734 @pvalues DFNT_FLOAT32 (32-bit float), DFNT_FLOAT64 (64-bit float/double), 01735 DFNT_INT8 (char), DFNT_INT16 (short int), DFNT_INT32,(int), 01736 DFNT_UINT8 (unsigned char), DFNT_UNINT16 (unsigned short), 01737 DFNT_UINT32 (unsigned int), 01738 DFNT_NATIVE (if bit-OR'ed with the above, uses machine native format) 01739 @ptype int32* 01740 @endpar 01741 01742 @par nelements 01743 @pdesc Storage in which to return the number of elements in the attribute 01744 of the type defined by the numbertype param. 01745 01746 @ptype int32* 01747 @endpar 01748 01749 @history 01750 @hdate Wed Feb 28 20:38:57 1996 @hauthor John Shalf 01751 @hdesc Initial Version 01752 @endhistory 01753 @@*/ 01754 int32 SDSgetAttribInfo(char *filename,int32 index,char *attribname, 01755 int32 *numbertype,int32 *nelements) 01756 { 01757 fileID *id=getFileID(filename); 01758 if(id->sds_id<0) 01759 id->sds_id=SDselect(id->id,id->sdsnumber); 01760 if(id->sds_id<0) 01761 return -1; 01762 return SDattrinfo(id->sds_id,index,attribname,numbertype,nelements); 01763 }
Quickstart Users Guide Programmers Reference Installation Examples Download
AMROC Main Home Contactlast update: 06/01/04