NC_attr * new_x_NC_attr( NC_string *strp, nc_type type, size_t nelems) { NC_attr *attrp; const size_t xsz = ncx_len_NC_attrV(type, nelems); size_t sz = M_RNDUP(sizeof(NC_attr)); assert(!(xsz == 0 && nelems != 0)); sz += xsz; attrp = (NC_attr *) malloc(sz); if(attrp == NULL ) return NULL; attrp->xsz = xsz; attrp->name = strp; attrp->type = type; attrp->nelems = nelems; if(xsz != 0) attrp->xvalue = (char *)attrp + M_RNDUP(sizeof(NC_attr)); else attrp->xvalue = NULL; return(attrp); }
static ncio * ncio_new(const char *path, int ioflags) { size_t sz_ncio = M_RNDUP(sizeof(ncio)); size_t sz_path = M_RNDUP(strlen(path) +1); size_t sz_ncio_pvt; ncio *nciop; #if ALWAYS_NC_SHARE /* DEBUG */ fSet(ioflags, NC_SHARE); #endif if(fIsSet(ioflags, NC_SHARE)) fprintf(stderr, "NC_SHARE not implemented for fileio\n"); sz_ncio_pvt = sizeof(ncio_ffio); nciop = (ncio *) malloc(sz_ncio + sz_path + sz_ncio_pvt); if(nciop == NULL) return NULL; nciop->ioflags = ioflags; *((int *)&nciop->fd) = -1; /* cast away const */ nciop->path = (char *) ((char *)nciop + sz_ncio); (void) strcpy((char *)nciop->path, path); /* cast away const */ /* cast away const */ *((void **)&nciop->pvt) = (void *)(nciop->path + sz_path); ncio_fileio_init(nciop); return nciop; }
/* * Allocate a NC_string structure large enough * to hold slen characters. * Formerly NC_new_string(count, str) */ NC_string * new_NC_string(size_t slen, const char *str) { NC_string *ncstrp; size_t sz = M_RNDUP(sizeof(NC_string)) + slen + 1; #if 0 sz = _RNDUP(sz, X_ALIGN); #endif ncstrp = (NC_string *)malloc(sz); if( ncstrp == NULL ) return NULL; (void) memset(ncstrp, 0, sz); ncstrp->nchars = sz - M_RNDUP(sizeof(NC_string)) - 1; assert(ncstrp->nchars + 1 > slen); ncstrp->cp = (char *)ncstrp + M_RNDUP(sizeof(NC_string)); if(str != NULL && *str != 0) { (void) strncpy(ncstrp->cp, str, ncstrp->nchars +1); ncstrp->cp[ncstrp->nchars] = 0; } return(ncstrp); }
/* * Common code for new_NC_var() * and ncx_get_NC_var() */ NC_var * new_x_NC_var( NC_string *strp, size_t ndims) { NC_var *varp; const size_t o1 = M_RNDUP(ndims * sizeof(int)); const size_t o2 = M_RNDUP(ndims * sizeof(size_t)); #ifdef MALLOCHACK const size_t sz = M_RNDUP(sizeof(NC_var)) + o1 + o2 + ndims * sizeof(off_t); #else /*!MALLOCHACK*/ const size_t o3 = ndims * sizeof(off_t); const size_t sz = sizeof(NC_var); #endif /*!MALLOCHACK*/ varp = (NC_var *) malloc(sz); if(varp == NULL ) return NULL; (void) memset(varp, 0, sz); varp->name = strp; varp->ndims = ndims; varp->hash = hash_fast(strp->cp, strlen(strp->cp)); if(ndims != 0) { #ifdef MALLOCHACK /* * NOTE: lint may complain about the next 3 lines: * "pointer cast may result in improper alignment". * We use the M_RNDUP() macro to get the proper alignment. */ varp->dimids = (int *)((char *)varp + M_RNDUP(sizeof(NC_var))); varp->shape = (size_t *)((char *)varp->dimids + o1); varp->dsizes = (off_t *)((char *)varp->shape + o2); #else /*!MALLOCHACK*/ varp->dimids = (int*)malloc(o1); varp->shape = (size_t*)malloc(o2); if(varp->shape) { memset(varp->shape,0,o2); } varp->dsizes = (off_t*)malloc(o3); #endif /*!MALLOCHACK*/ } else { varp->dimids = NULL; varp->shape = NULL; varp->dsizes=NULL; } varp->xsz = 0; varp->len = 0; varp->begin = 0; return varp; }
/* * Common code for ncmpii_new_NC_var() * and ncx_get_NC_var() */ NC_var * ncmpii_new_x_NC_var(NC_string *strp, size_t ndims) { NC_var *varp; const MPI_Offset o1 = M_RNDUP(ndims * sizeof(MPI_Offset)); const MPI_Offset o2 = M_RNDUP(ndims * sizeof(MPI_Offset)); const MPI_Offset sz = M_RNDUP(sizeof(NC_var)) + o1 + o2 + ndims * sizeof(MPI_Offset); /* wkliao: this function allocates a contiguous memory space to put all * members of NC_var structure together: o1 is for shape[], o2 is for * dsizes[] ad the 3rd is for dimids[] * (I don't know why M_RNDUP is needed here and why they should be kept * in a contiguous memory space.) */ varp = (NC_var *) NCI_Malloc(sz); if (varp == NULL ) return NULL; (void) memset(varp, 0, sz); varp->name = strp; varp->ndims = ndims; if (ndims != 0) { /* * NOTE: lint may complain about the next 3 lines: * "pointer cast may result in improper alignment". * We use the M_RNDUP() macro to get the proper alignment. * roundup to a double */ varp->dimids = (int *)((char *)varp + M_RNDUP(sizeof(NC_var))); varp->shape = (MPI_Offset *)((char *)varp->dimids + o1); varp->dsizes = (MPI_Offset *)((char *)varp->shape + o2); } varp->xsz = 0; varp->len = 0; varp->begin = 0; return varp; }
/* * Common code for new_NC_var() * and ncx_get_NC_var() */ NC_var * new_x_NC_var( NC_string *strp, size_t ndims) { NC_var *varp; const size_t o1 = M_RNDUP(ndims * sizeof(int)); const size_t o2 = M_RNDUP(ndims * sizeof(size_t)); const size_t sz = M_RNDUP(sizeof(NC_var)) + o1 + o2 + ndims * sizeof(size_t); varp = (NC_var *) malloc(sz); if(varp == NULL ) return NULL; (void) memset(varp, 0, sz); varp->name = strp; varp->ndims = ndims; if(ndims != 0) { /* * NOTE: lint may complain about the next 3 lines: * "pointer cast may result in improper alignment". * We use the M_RNDUP() macro to get the proper alignment. */ varp->dimids = (int *)((char *)varp + M_RNDUP(sizeof(NC_var))); varp->shape = (size_t *)((char *)varp->dimids + o1); varp->dsizes = (size_t *)((char *)varp->shape + o2); } varp->xsz = 0; varp->len = 0; varp->begin = 0; return varp; }
int ncio_create(const char *path, int ioflags, size_t initialsz, off_t igeto, size_t igetsz, size_t *sizehintp, ncio **nciopp, void **const igetvpp) { ncio *nciop; #ifdef _WIN32_WCE char* oflags = "bw+"; /*==?(O_RDWR|O_CREAT|O_TRUNC) && binary*/ #else char* oflags = "w+"; /*==?(O_RDWR|O_CREAT|O_TRUNC);*/ #endif FILE* f; int i,fd; int status = ENOERR; if(initialsz < (size_t)igeto + igetsz) initialsz = (size_t)igeto + igetsz; fSet(ioflags, NC_WRITE); if(path == NULL || *path == 0) return EINVAL; nciop = ncio_new(path, ioflags); if(nciop == NULL) return ENOMEM; if(fIsSet(ioflags, NC_NOCLOBBER)) { /* Since we do not have use of the O_EXCL flag, we need to fake it */ #ifdef WINCE f = fopen(path,"rb"); #else f = fopen(path,"r"); #endif if(f != NULL) { /* do not overwrite */ (void)fclose(f); return EEXIST; } } f = fopen(path, oflags); if(f == NULL) { status = errno; goto unwind_new; } /* Locate an open pseudo file descriptor */ fd = -1; for(i=1;i<fdmax;i++) {if(descriptors[i] == NULL) {fd=i;break;}} if(fd < 0) {fd = fdmax; fdmax++;} descriptors[fd] = f; *((int *)&nciop->fd) = fd; /* cast away const */ if(*sizehintp < NCIO_MINBLOCKSIZE || *sizehintp > NCIO_MAXBLOCKSIZE) { /* Use default */ *sizehintp = blksize(fd); } else { *sizehintp = M_RNDUP(*sizehintp); } status = ncio_fileio_init2(nciop, sizehintp); if(status != ENOERR) goto unwind_open; if(initialsz != 0) { status = fgrow(f, (off_t)initialsz); if(status != ENOERR) goto unwind_open; } if(igetsz != 0) { status = nciop->get(nciop, igeto, igetsz, RGN_WRITE, igetvpp); if(status != ENOERR) goto unwind_open; } *nciopp = nciop; return ENOERR; unwind_open: (void) fclose(descriptors[fd]); descriptors[fd] = NULL; /* ?? unlink */ /*FALLTHRU*/ unwind_new: ncio_free(nciop); return status; }
/* This function opens the data file. It is only called from nc.c, from nc__open_mp and nc_delete_mp. path - path of data file. ioflags - flags passed into nc_open. igeto - looks like this function can do an initial page get, and igeto is going to be the offset for that. But it appears to be unused igetsz - the size in bytes of initial page get (a.k.a. extent). Not ever used in the library. sizehintp - pointer to sizehint parameter from nc__open or nc__create. This is used to set pxp->blksz. Here's what the man page has to say: "The argument referenced by chunksize controls a space versus time tradeoff, memory allocated in the netcdf library versus number of system calls. Because of internal requirements, the value may not be set to exactly the value requested. The actual value chosen is returned by reference. Using the value NC_SIZEHINT_DEFAULT causes the library to choose a default. How the system choses the default depends on the system. On many systems, the "preferred I/O block size" is available from the stat() system call, struct stat member st_blksize. If this is available it is used. Lacking that, twice the system pagesize is used. Lacking a call to discover the system pagesize, we just set default chunksize to 8192. The chunksize is a property of a given open netcdf descriptor ncid, it is not a persistent property of the netcdf dataset." nciopp - pointer to pointer that will get address of newly created and inited ncio struct. igetvpp - handle to pass back pointer to data from inital page read, if this were ever used, which it isn't. */ int posixio_open(const char *path, int ioflags, off_t igeto, size_t igetsz, size_t *sizehintp, ncio **nciopp, void **const igetvpp) { ncio *nciop; int oflags = fIsSet(ioflags, NC_WRITE) ? O_RDWR : O_RDONLY; int fd = -1; int status = 0; if(path == NULL || *path == 0) return EINVAL; nciop = ncio_px_new(path, ioflags); if(nciop == NULL) return ENOMEM; //#ifdef O_BINARY #if _MSC_VER fSet(oflags, O_BINARY); #endif #ifdef vms fd = open(path, oflags, 0, "ctx=stm"); #else fd = open(path, oflags, 0); #endif if(fd < 0) { status = errno; goto unwind_new; } *((int *)&nciop->fd) = fd; /* cast away const */ if(*sizehintp < NCIO_MINBLOCKSIZE) { /* Use default */ *sizehintp = blksize(fd); } else if(*sizehintp >= NCIO_MAXBLOCKSIZE) { /* Use maximum allowed value */ *sizehintp = NCIO_MAXBLOCKSIZE; } else { *sizehintp = M_RNDUP(*sizehintp); } if(fIsSet(nciop->ioflags, NC_SHARE)) status = ncio_spx_init2(nciop, sizehintp); else status = ncio_px_init2(nciop, sizehintp, 0); if(status != ENOERR) goto unwind_open; if(igetsz != 0) { status = nciop->get(nciop, igeto, igetsz, 0, igetvpp); if(status != ENOERR) goto unwind_open; } *nciopp = nciop; return ENOERR; unwind_open: (void) close(fd); /* assert fd >= 0 */ /*FALLTHRU*/ unwind_new: ncio_close(nciop,0); return status; }
/* Create a file, and the ncio struct to go with it. This funtion is only called from nc__create_mp. path - path of file to create. ioflags - flags from nc_create initialsz - From the netcdf man page: "The argument Iinitialsize sets the initial size of the file at creation time." igeto - igetsz - sizehintp - this eventually goes into pxp->blksz and is the size of a page of data for buffered reads and writes. nciopp - pointer to a pointer that will get location of newly created and inited ncio struct. igetvpp - pointer to pointer which will get the location of ? */ int posixio_create(const char *path, int ioflags, size_t initialsz, off_t igeto, size_t igetsz, size_t *sizehintp, ncio **nciopp, void **const igetvpp) { ncio *nciop; int oflags = (O_RDWR|O_CREAT); int fd; int status; if(initialsz < (size_t)igeto + igetsz) initialsz = (size_t)igeto + igetsz; fSet(ioflags, NC_WRITE); if(path == NULL || *path == 0) return EINVAL; nciop = ncio_px_new(path, ioflags); if(nciop == NULL) return ENOMEM; if(fIsSet(ioflags, NC_NOCLOBBER)) fSet(oflags, O_EXCL); else fSet(oflags, O_TRUNC); #ifdef O_BINARY fSet(oflags, O_BINARY); #endif #ifdef vms fd = open(path, oflags, NC_DEFAULT_CREAT_MODE, "ctx=stm"); #else /* Should we mess with the mode based on NC_SHARE ?? */ fd = open(path, oflags, NC_DEFAULT_CREAT_MODE); #endif #if 0 (void) fprintf(stderr, "ncio_create(): path=\"%s\"\n", path); (void) fprintf(stderr, "ncio_create(): oflags=0x%x\n", oflags); #endif if(fd < 0) { status = errno; goto unwind_new; } *((int *)&nciop->fd) = fd; /* cast away const */ if(*sizehintp < NCIO_MINBLOCKSIZE) { /* Use default */ *sizehintp = blksize(fd); } else if(*sizehintp >= NCIO_MAXBLOCKSIZE) { /* Use maximum allowed value */ *sizehintp = NCIO_MAXBLOCKSIZE; } else { *sizehintp = M_RNDUP(*sizehintp); } if(fIsSet(nciop->ioflags, NC_SHARE)) status = ncio_spx_init2(nciop, sizehintp); else status = ncio_px_init2(nciop, sizehintp, 1); if(status != ENOERR) goto unwind_open; if(initialsz != 0) { status = fgrow(fd, (off_t)initialsz); if(status != ENOERR) goto unwind_open; } if(igetsz != 0) { status = nciop->get(nciop, igeto, igetsz, RGN_WRITE, igetvpp); if(status != ENOERR) goto unwind_open; } *nciopp = nciop; return ENOERR; unwind_open: (void) close(fd); /* ?? unlink */ /*FALLTHRU*/ unwind_new: ncio_close(nciop,!fIsSet(ioflags, NC_NOCLOBBER)); return status; }
int ffio_open(const char *path, int ioflags, off_t igeto, size_t igetsz, size_t *sizehintp, ncio **nciopp, void **const igetvpp) { ncio *nciop; const char *ControlString; int oflags = fIsSet(ioflags, NC_WRITE) ? O_RDWR : O_RDONLY; int fd; int status; struct ffsw stat; if(path == NULL || *path == 0) return EINVAL; nciop = ncio_ffio_new(path, ioflags); if(nciop == NULL) return ENOMEM; if ((ControlString = ncio_ffio_assign(path)) == (const char *)NULL) { /* an error occured - just punt */ status = errno; goto unwind_new; } #ifdef NOFFFLUSH /* test whether the global layer is being called for * this file ... if so then can't call FFIO ffflush() * RKO 06/26/98 */ if (strstr(ControlString,"global") != (char *) NULL) { /* use no ffflush version */ *((ncio_syncfunc **)&nciop->sync) = ncio_ffio_sync_noffflush; } #endif /* Orig: fd = ffopens(path, oflags, 0, 0, &stat, ControlString); */ fd = ffopen(path, oflags, 0, 0, &stat); if(fd < 0) { status = errno; goto unwind_new; } *((int *)&nciop->fd) = fd; /* cast away const */ if(*sizehintp < NCIO_MINBLOCKSIZE || *sizehintp > NCIO_MAXBLOCKSIZE) { /* Use default */ *sizehintp = blksize(fd); } else { *sizehintp = M_RNDUP(*sizehintp); } status = ncio_ffio_init2(nciop, sizehintp); if(status != ENOERR) goto unwind_open; if(igetsz != 0) { status = nciop->get(nciop, igeto, igetsz, 0, igetvpp); if(status != ENOERR) goto unwind_open; } *nciopp = nciop; return ENOERR; unwind_open: (void) ffclose(fd); /*FALLTHRU*/ unwind_new: ncio_close(nciop,0); return status; }