/* * Copyright 2022, University Corporation for Atmospheric Research * See netcdf/COPYRIGHT file for copying and redistribution conditions. */ /** * @file * @internal * * This file contains functions that work with the NC struct. There is * an NC struct for every open netCDF file. * * @author Glenn Davis */ #include "config.h" #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include "ncdispatch.h" #ifndef nulldup #define nulldup(x) ((x)?strdup(x):(x)) #endif /** This is the default create format for nc_create and nc__create. */ static int default_create_format = NC_FORMAT_CLASSIC; /** * Find the NC struct for an open file, using the ncid. * * @param ncid The ncid to find. * @param ncpp Pointer that gets a pointer to the NC. * * @return ::NC_NOERR No error. * @return ::NC_EBADID ncid not found. * @author Glenn Davis, Dennis Heimbigner */ int NC_check_id(int ncid, NC** ncpp) { NC* nc = find_in_NCList(ncid); if(nc == NULL) return NC_EBADID; if(ncpp) *ncpp = nc; return NC_NOERR; } /** * Free an NC struct and its related resources. Before this is done, * be sure to remove the NC from the open file list with * del_from_NCList(). * * @param ncp Pointer to the NC struct to be freed. * * @author Glenn Davis, Dennis Heimbigner */ void free_NC(NC *ncp) { if(ncp == NULL) return; if(ncp->path) free(ncp->path); /* We assume caller has already cleaned up ncp->dispatchdata */ free(ncp); } /** * Create and initialize a new NC struct. The ncid is assigned later. * * @param dispatcher An pointer to the NC_Dispatch table that should * be used by this NC. * @param path The name of the file. * @param mode The open or create mode. * @param model An NCmodel instance, provided by NC_infermodel(). * @param ncpp A pointer that gets a pointer to the newlly allocacted * and initialized NC struct. * * @return ::NC_NOERR No error. * @return ::NC_ENOMEM Out of memory. * @author Glenn Davis, Dennis Heimbigner */ int new_NC(const NC_Dispatch* dispatcher, const char* path, int mode, NC** ncpp) { NC *ncp = (NC*)calloc(1,sizeof(NC)); if(ncp == NULL) return NC_ENOMEM; ncp->dispatch = dispatcher; ncp->path = nulldup(path); ncp->mode = mode; if(ncp->path == NULL) { /* fail */ free_NC(ncp); return NC_ENOMEM; } if(ncpp) { *ncpp = ncp; } else { free_NC(ncp); } return NC_NOERR; } /** * This function sets a default create flag that will be logically * or'd to whatever flags are passed into nc_create for all future * calls to nc_create. * * @param format The format that should become the default. * @param old_formatp Pointer that gets the previous default. Ignored * if NULL. * * @return ::NC_NOERR No error. * @return ::NC_ENOTBUILD Requested format not built with this install. * @return ::NC_EINVAL Invalid input. * @author Ed Hartnett, Dennis Heimbigner */ int nc_set_default_format(int format, int *old_formatp) { /* Return existing format if desired. */ if (old_formatp) *old_formatp = default_create_format; /* Make sure only valid format is set. */ #ifndef ENABLE_CDF5 if (format == NC_FORMAT_CDF5) return NC_ENOTBUILT; #endif #ifdef USE_HDF5 if (format != NC_FORMAT_CLASSIC && format != NC_FORMAT_64BIT_OFFSET && format != NC_FORMAT_NETCDF4 && format != NC_FORMAT_NETCDF4_CLASSIC && format != NC_FORMAT_CDF5) return NC_EINVAL; #else if (format == NC_FORMAT_NETCDF4 || format == NC_FORMAT_NETCDF4_CLASSIC) return NC_ENOTBUILT; if (format != NC_FORMAT_CLASSIC && format != NC_FORMAT_64BIT_OFFSET && format != NC_FORMAT_CDF5) return NC_EINVAL; #endif default_create_format = format; return NC_NOERR; } /** * Get the current default format. * * @return the default format. * @author Ed Hartnett */ int nc_get_default_format(void) { return default_create_format; }