1 /********************************************************************* 2 Copyright 2010, UCAR/Unidata See netcdf/COPYRIGHT file for 3 copying and redistribution conditions. 4 *********************************************************************/ 5 6 #include "config.h" 7 #include <stdlib.h> 8 #include <string.h> 9 #include <assert.h> 10 #include "nc.h" 11 12 #define ID_SHIFT (16) 13 #define NCFILELISTLENGTH 0x10000 14 15 /* Version one just allocates the max space (sizeof(NC*)*2^16)*/ 16 static NC** nc_filelist = NULL; 17 18 static int numfiles = 0; 19 20 /* Common */ 21 int count_NCList(void)22count_NCList(void) 23 { 24 return numfiles; 25 } 26 27 28 void free_NCList(void)29free_NCList(void) 30 { 31 if(numfiles > 0) return; /* not empty */ 32 if(nc_filelist != NULL) free(nc_filelist); 33 nc_filelist = NULL; 34 } 35 36 int add_to_NCList(NC * ncp)37add_to_NCList(NC* ncp) 38 { 39 int i; 40 int new_id; 41 if(nc_filelist == NULL) { 42 if (!(nc_filelist = calloc(1, sizeof(NC*)*NCFILELISTLENGTH))) 43 return NC_ENOMEM; 44 numfiles = 0; 45 } 46 #ifdef USE_REFCOUNT 47 /* Check the refcount */ 48 if(ncp->refcount > 0) 49 return NC_NOERR; 50 #endif 51 52 new_id = 0; /* id's begin at 1 */ 53 for(i=1; i < NCFILELISTLENGTH; i++) { 54 if(nc_filelist[i] == NULL) {new_id = i; break;} 55 } 56 if(new_id == 0) return NC_ENOMEM; /* no more slots */ 57 nc_filelist[new_id] = ncp; 58 numfiles++; 59 new_id = (new_id << ID_SHIFT); 60 ncp->ext_ncid = new_id; 61 return NC_NOERR; 62 } 63 64 void del_from_NCList(NC * ncp)65del_from_NCList(NC* ncp) 66 { 67 unsigned int ncid = ((unsigned int)ncp->ext_ncid) >> ID_SHIFT; 68 if(numfiles == 0 || ncid == 0 || nc_filelist == NULL) return; 69 if(nc_filelist[ncid] != ncp) return; 70 #ifdef USE_REFCOUNT 71 /* Check the refcount */ 72 if(ncp->refcount > 0) 73 return; /* assume caller has decrecmented */ 74 #endif 75 76 nc_filelist[ncid] = NULL; 77 numfiles--; 78 79 /* If all files have been closed, release the filelist memory. */ 80 if (numfiles == 0) 81 free_NCList(); 82 } 83 84 NC * find_in_NCList(int ext_ncid)85find_in_NCList(int ext_ncid) 86 { 87 NC* f = NULL; 88 unsigned int ncid = ((unsigned int)ext_ncid) >> ID_SHIFT; 89 if(numfiles > 0 && nc_filelist != NULL && ncid < NCFILELISTLENGTH) 90 f = nc_filelist[ncid]; 91 return f; 92 } 93 94 /* 95 Added to support open by name 96 */ 97 NC* find_in_NCList_by_name(const char * path)98find_in_NCList_by_name(const char* path) 99 { 100 int i; 101 NC* f = NULL; 102 if(nc_filelist == NULL) 103 return NULL; 104 for(i=1; i < NCFILELISTLENGTH; i++) { 105 if(nc_filelist[i] != NULL) { 106 if(strcmp(nc_filelist[i]->path,path)==0) { 107 f = nc_filelist[i]; 108 break; 109 } 110 } 111 } 112 return f; 113 } 114 115 int iterate_NCList(int index,NC ** ncp)116iterate_NCList(int index, NC** ncp) 117 { 118 /* Walk from 0 ...; 0 return => stop */ 119 if(index < 0 || index >= NCFILELISTLENGTH) 120 return NC_ERANGE; 121 if(ncp) *ncp = nc_filelist[index]; 122 return NC_NOERR; 123 } 124 125