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 /* Version one just allocates the max space (sizeof(NC*)*2^16)*/
15 static NC** nc_filelist = NULL;
16 
17 static int numfiles = 0;
18 
19 /* Common */
20 int
count_NCList(void)21 count_NCList(void)
22 {
23     return numfiles;
24 }
25 
26 
27 void
free_NCList(void)28 free_NCList(void)
29 {
30     if(numfiles > 0) return; /* not empty */
31     if(nc_filelist != NULL) free(nc_filelist);
32     nc_filelist = NULL;
33 }
34 
35 int
add_to_NCList(NC * ncp)36 add_to_NCList(NC* ncp)
37 {
38     int i;
39     int new_id;
40     if(nc_filelist == NULL) {
41 	if (!(nc_filelist = calloc(1, sizeof(NC*)*NCFILELISTLENGTH)))
42 	    return NC_ENOMEM;
43 	numfiles = 0;
44     }
45     new_id = 0; /* id's begin at 1 */
46     for(i=1;i<0x10000;i++) {
47 	if(nc_filelist[i] == NULL) {new_id = i; break;}
48     }
49     if(new_id == 0) return NC_ENOMEM; /* no more slots */
50     nc_filelist[new_id] = ncp;
51     numfiles++;
52     new_id = (new_id << ID_SHIFT);
53     ncp->ext_ncid = new_id;
54     return NC_NOERR;
55 }
56 
57 void
del_from_NCList(NC * ncp)58 del_from_NCList(NC* ncp)
59 {
60    unsigned int ncid = ((unsigned int)ncp->ext_ncid) >> ID_SHIFT;
61    if(numfiles == 0 || ncid == 0 || nc_filelist == NULL) return;
62    if(nc_filelist[ncid] != ncp) return;
63    nc_filelist[ncid] = NULL;
64    numfiles--;
65 
66    /* If all files have been closed, release the filelist memory. */
67    if (numfiles == 0)
68       free_NCList();
69 }
70 
71 NC *
find_in_NCList(int ext_ncid)72 find_in_NCList(int ext_ncid)
73 {
74    NC* f = NULL;
75    unsigned int ncid = ((unsigned int)ext_ncid) >> ID_SHIFT;
76    if(numfiles > 0 && nc_filelist != NULL && ncid < NCFILELISTLENGTH)
77 	f = nc_filelist[ncid];
78    return f;
79 }
80 
81