Ejemplo n.º 1
0
static NC *
dup_NC(const NC *ref)
{
	NC *ncp;

#if _CRAYMPP && defined(LOCKNUMREC)
	ncp = (NC *) shmalloc(sizeof(NC));
#else
	ncp = (NC *) malloc(sizeof(NC));
#endif /* _CRAYMPP && LOCKNUMREC */
	if(ncp == NULL)
		return NULL;
	(void) memset(ncp, 0, sizeof(NC));

	if(dup_NC_dimarrayV(&ncp->dims, &ref->dims) != NC_NOERR)
		goto err;
	if(dup_NC_attrarrayV(&ncp->attrs, &ref->attrs) != NC_NOERR)
		goto err;
	if(dup_NC_vararrayV(&ncp->vars, &ref->vars) != NC_NOERR)
		goto err;

	ncp->xsz = ref->xsz;
	ncp->begin_var = ref->begin_var;
	ncp->begin_rec = ref->begin_rec;
	ncp->recsize = ref->recsize;
	NC_set_numrecs(ncp, NC_get_numrecs(ref));
	return ncp;
err:
	free_NC(ncp);
	return NULL;
}
Ejemplo n.º 2
0
int
nc_close(int ncid)
{
	int status = NC_NOERR;
	NC *ncp; 

	status = NC_check_id(ncid, &ncp); 
	if(status != NC_NOERR)
		return status;

	if(NC_indef(ncp))
	{
		status = NC_endef(ncp, 0, 1, 0, 1); /* TODO: defaults */
		if(status != NC_NOERR )
		{
			(void) nc_abort(ncid);
			return status;
		}
	}
	else if(!NC_readonly(ncp))
	{
		status = NC_sync(ncp);
		/* flush buffers before any filesize comparisons */
		(void) ncp->nciop->sync(ncp->nciop);
	}

	/* 
	 * If file opened for writing and filesize is less than
	 * what it should be (due to previous use of NOFILL mode),
	 * pad it to correct size, as reported by NC_calcsize().
	 */
	if (status == ENOERR) {
	    off_t filesize; 	/* current size of open file */
	    off_t calcsize;	/* calculated file size, from header */
	    status = ncio_filesize(ncp->nciop, &filesize);
	    if(status != ENOERR)
		return status;
	    status = NC_calcsize(ncp, &calcsize);
	    if(status != NC_NOERR)
		return status;
	    if(filesize < calcsize && !NC_readonly(ncp)) {
		status = ncio_pad_length(ncp->nciop, calcsize);
		if(status != ENOERR)
		    return status;
	    }
	}

	(void) ncio_close(ncp->nciop, 0);
	ncp->nciop = NULL;

	del_from_NCList(ncp);

	free_NC(ncp);

	return status;
}
Ejemplo n.º 3
0
Archivo: nc.c Proyecto: jpouderoux/VTK
int
new_NC(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;
}
Ejemplo n.º 4
0
/*
 * In data mode, same as ncclose.
 * In define mode, restore previous definition.
 * In create, remove the file.
 */
int
nc_abort(int ncid)
{
	int status;
	NC *ncp;
	int doUnlink = 0;

	status = NC_check_id(ncid, &ncp); 
	if(status != NC_NOERR)
		return status;

	doUnlink = NC_IsNew(ncp);

	if(ncp->old != NULL)
	{
		/* a plain redef, not a create */
		assert(!NC_IsNew(ncp));
		assert(fIsSet(ncp->flags, NC_INDEF));
		free_NC(ncp->old);
		ncp->old = NULL;
		fClr(ncp->flags, NC_INDEF);
	}
	else if(!NC_readonly(ncp))
	{
		status = NC_sync(ncp);
		if(status != NC_NOERR)
			return status;
	}


	(void) ncio_close(ncp->nciop, doUnlink);
	ncp->nciop = NULL;

	del_from_NCList(ncp);

	free_NC(ncp);

	return NC_NOERR;
}
Ejemplo n.º 5
0
int
nc_delete_mp(const char * path, int basepe)
{
	NC *ncp;
	int status;
	size_t chunk = 512;

	ncp = new_NC(&chunk);
	if(ncp == NULL)
		return NC_ENOMEM;
	
#if defined(LOCKNUMREC) /* && _CRAYMPP */
	if (status = NC_init_pe(ncp, basepe)) {
		return status;
	}
#else
	/*
	 * !_CRAYMPP, only pe 0 is valid
	 */
	if(basepe != 0)
		return NC_EINVAL;
#endif
	status = ncio_open(path, NC_NOWRITE,
		0, 0, &ncp->chunk,
		&ncp->nciop, 0);
	if(status)
		goto unwind_alloc;

	assert(ncp->flags == 0);

	status = nc_get_NC(ncp);
	if(status != NC_NOERR)
	{
		/* Not a netcdf file, don't delete */
		/* ??? is this the right semantic? what if it was just too big? */
		(void) ncio_close(ncp->nciop, 0);
	}
	else
	{
		/* ncio_close does the unlink */
		status = ncio_close(ncp->nciop, 1); /* ncio_close does the unlink */
	}

	ncp->nciop = NULL;
unwind_alloc:
	free_NC(ncp);
	return status;
}
Ejemplo n.º 6
0
int
nc__create_mp(const char * path, int ioflags, size_t initialsz, int basepe,
	size_t *chunksizehintp, int *ncid_ptr)
{
	NC *ncp;
	int status;
	void *xp = NULL;
	int sizeof_off_t = 0;

#if ALWAYS_NC_SHARE /* DEBUG */
	fSet(ioflags, NC_SHARE);
#endif

	ncp = new_NC(chunksizehintp);
	if(ncp == NULL)
		return NC_ENOMEM;

#if defined(LOCKNUMREC) /* && _CRAYMPP */
	if (status = NC_init_pe(ncp, basepe)) {
		return status;
	}
#else
	/*
	 * !_CRAYMPP, only pe 0 is valid
	 */
	if(basepe != 0)
		return NC_EINVAL;
#endif

	assert(ncp->flags == 0);

	/* Apply default create format. */
	if (default_create_format == NC_FORMAT_64BIT)
	  ioflags |= NC_64BIT_OFFSET;

	if (fIsSet(ioflags, NC_64BIT_OFFSET)) {
	  fSet(ncp->flags, NC_64BIT_OFFSET);
	  sizeof_off_t = 8;
	} else {
	  sizeof_off_t = 4;
	}

	assert(ncp->xsz == ncx_len_NC(ncp,sizeof_off_t));
	
	status = ncio_create(path, ioflags,
		initialsz,
		0, ncp->xsz, &ncp->chunk,
		&ncp->nciop, &xp);
	if(status != NC_NOERR)
	{
		/* translate error status */
		if(status == EEXIST)
			status = NC_EEXIST;
		goto unwind_alloc;
	}

	fSet(ncp->flags, NC_CREAT);

	if(fIsSet(ncp->nciop->ioflags, NC_SHARE))
	{
		/*
		 * NC_SHARE implies sync up the number of records as well.
		 * (File format version one.)
		 * Note that other header changes are not shared
		 * automatically.  Some sort of IPC (external to this package)
		 * would be used to trigger a call to nc_sync().
		 */
		fSet(ncp->flags, NC_NSYNC);
	}

	status = ncx_put_NC(ncp, &xp, sizeof_off_t, ncp->xsz);
	if(status != NC_NOERR)
		goto unwind_ioc;

	add_to_NCList(ncp);

	if(chunksizehintp != NULL)
		*chunksizehintp = ncp->chunk;
	*ncid_ptr = ncp->nciop->fd;
	return NC_NOERR;

unwind_ioc:
	(void) ncio_close(ncp->nciop, 1); /* N.B.: unlink */
	ncp->nciop = NULL;
	/*FALLTHRU*/
unwind_alloc:
	free_NC(ncp);
	return status;
}
Ejemplo n.º 7
0
/*
 *  End define mode.
 *  Common code for ncendef, ncclose(endef)
 *  Flushes I/O buffers.
 */
static int
NC_endef(NC *ncp,
	size_t h_minfree, size_t v_align,
	size_t v_minfree, size_t r_align)
{
	int status = NC_NOERR;

	assert(!NC_readonly(ncp));
	assert(NC_indef(ncp));

	status = NC_check_vlens(ncp);
	if(status != NC_NOERR)
	    return status;
	status = NC_begins(ncp, h_minfree, v_align, v_minfree, r_align);
	if(status != NC_NOERR)
	    return status;

	if(ncp->old != NULL)
	{
		/* a plain redef, not a create */
		assert(!NC_IsNew(ncp));
		assert(fIsSet(ncp->flags, NC_INDEF));
		assert(ncp->begin_rec >= ncp->old->begin_rec);
		assert(ncp->begin_var >= ncp->old->begin_var);

		if(ncp->vars.nelems != 0)
		{
		if(ncp->begin_rec > ncp->old->begin_rec)
		{
			status = move_recs_r(ncp, ncp->old);
			if(status != NC_NOERR)
				return status;
			if(ncp->begin_var > ncp->old->begin_var)
			{
				status = move_vars_r(ncp, ncp->old);
				if(status != NC_NOERR)
					return status;
			} 
			/* else if (ncp->begin_var == ncp->old->begin_var) { NOOP } */
		}
		else
		{	/* Even if (ncp->begin_rec == ncp->old->begin_rec)
			   and     (ncp->begin_var == ncp->old->begin_var)
			   might still have added a new record variable */
		        if(ncp->recsize > ncp->old->recsize)
			{
			        status = move_recs_r(ncp, ncp->old);
				if(status != NC_NOERR)
				      return status;
			}
		}
		}
	}

	status = write_NC(ncp);
	if(status != NC_NOERR)
		return status;

	if(NC_dofill(ncp))
	{
		if(NC_IsNew(ncp))
		{
			status = fillerup(ncp);
			if(status != NC_NOERR)
				return status;
			
		}
		else if(ncp->vars.nelems > ncp->old->vars.nelems)
		{
			status = fill_added(ncp, ncp->old);
			if(status != NC_NOERR)
				return status;
			status = fill_added_recs(ncp, ncp->old);
			if(status != NC_NOERR)
				return status;
		}
	}

	if(ncp->old != NULL)
	{
		free_NC(ncp->old);
		ncp->old = NULL;
	}

	fClr(ncp->flags, NC_CREAT | NC_INDEF);

	return ncp->nciop->sync(ncp->nciop);
}
Ejemplo n.º 8
0
int
nc__open_mp(const char * path, int ioflags, int basepe,
	size_t *chunksizehintp, int *ncid_ptr)
{
	NC *ncp;
	int status;

#if ALWAYS_NC_SHARE /* DEBUG */
	fSet(ioflags, NC_SHARE);
#endif

	ncp = new_NC(chunksizehintp);
	if(ncp == NULL)
		return NC_ENOMEM;

#if defined(LOCKNUMREC) /* && _CRAYMPP */
	if (status = NC_init_pe(ncp, basepe)) {
		return status;
	}
#else
	/*
	 * !_CRAYMPP, only pe 0 is valid
	 */
	if(basepe != 0)
		return NC_EINVAL;
#endif

	status = ncio_open(path, ioflags,
		0, 0, &ncp->chunk,
		&ncp->nciop, 0);
	if(status)
		goto unwind_alloc;

	assert(ncp->flags == 0);

	if(fIsSet(ncp->nciop->ioflags, NC_SHARE))
	{
		/*
		 * NC_SHARE implies sync up the number of records as well.
		 * (File format version one.)
		 * Note that other header changes are not shared
		 * automatically.  Some sort of IPC (external to this package)
		 * would be used to trigger a call to nc_sync().
		 */
		fSet(ncp->flags, NC_NSYNC);
	}

	status = nc_get_NC(ncp);
	if(status != NC_NOERR)
		goto unwind_ioc;

	add_to_NCList(ncp);

	if(chunksizehintp != NULL)
		*chunksizehintp = ncp->chunk;
	*ncid_ptr = ncp->nciop->fd;
	return NC_NOERR;

unwind_ioc:
	(void) ncio_close(ncp->nciop, 0);
	ncp->nciop = NULL;
	/*FALLTHRU*/
unwind_alloc:
	free_NC(ncp);
	return status;
}