Esempio n. 1
0
/*
 * Read just the numrecs member.
 * (A relatively expensive way to do things.)
 */
int
read_numrecs(NC *ncp)
{
	int status = NC_NOERR;
	const void *xp = NULL;
	size_t nrecs = NC_get_numrecs(ncp);

	assert(!NC_indef(ncp));

#define NC_NUMRECS_OFFSET 4
#define NC_NUMRECS_EXTENT 4
	status = ncp->nciop->get(ncp->nciop,
		 NC_NUMRECS_OFFSET, NC_NUMRECS_EXTENT, 0, (void **)&xp);
					/* cast away const */
	if(status != NC_NOERR)
		return status;

	status = ncx_get_size_t(&xp, &nrecs);

	(void) ncp->nciop->rel(ncp->nciop, NC_NUMRECS_OFFSET, 0);

	if(status == NC_NOERR)
	{
		NC_set_numrecs(ncp, nrecs);
		fClr(ncp->flags, NC_NDIRTY);
	}

	return status;
}
Esempio n. 2
0
/* Read a size_t from the header */
static int
v1h_get_size_t(v1hs *gsp, size_t *sp)
{
	int status = check_v1hs(gsp, X_SIZEOF_SIZE_T);
	if(status != ENOERR)
		return status;
	return ncx_get_size_t((const void **)(&gsp->pos), sp);
}
Esempio n. 3
0
/* Read a size_t from the header */
static int
v1h_get_size_t(v1hs *gsp, size_t *sp)
{
	int status;
	if (gsp->version == 5) /* all integers in CDF-5 are 64 bits */
		status = check_v1hs(gsp, X_SIZEOF_INT64);
	else
		status = check_v1hs(gsp, X_SIZEOF_SIZE_T);
	if(status != ENOERR)
		return status;
        if (gsp->version == 5) {
		long long tmp=0;
		status = ncx_get_int64((const void **)(&gsp->pos), &tmp);
		*sp = (size_t)tmp;
		return status;
        }
        else
	    return ncx_get_size_t((const void **)(&gsp->pos), sp);
}
Esempio n. 4
0
/* Make the in-memory NC structure from reading the file header */
int
nc_get_NC(NC3_INFO* ncp)
{
	int status;
	v1hs gs; /* the get stream */

	assert(ncp != NULL);

	/* Initialize stream gs */

	gs.nciop = ncp->nciop;
	gs.offset = 0; /* beginning of file */
	gs.extent = 0;
	gs.flags = 0;
	gs.version = 0;
	gs.base = NULL;
	gs.pos = gs.base;

	{
		/*
		 * Come up with a reasonable stream read size.
		 */
	        off_t filesize;
		size_t extent = ncp->xsz;
		
		if(extent <= ((fIsSet(ncp->flags, NC_64BIT_DATA))?MIN_NC5_XSZ:MIN_NC3_XSZ))
		{
		        status = ncio_filesize(ncp->nciop, &filesize);
			if(status)
			    return status;
			if(filesize < sizeof(ncmagic)) { /* too small, not netcdf */

			    status = NC_ENOTNC;
			    return status;
			}
			/* first time read */
			extent = ncp->chunk;
			/* Protection for when ncp->chunk is huge;
			 * no need to read hugely. */
	      		if(extent > 4096)
				extent = 4096;
			if(extent > filesize)
			        extent = filesize;
		}
		else if(extent > ncp->chunk)
		    extent = ncp->chunk;

		/*
		 * Invalidate the I/O buffers to force a read of the header
		 * region.
		 */
		status = ncio_sync(gs.nciop);
		if(status)
			return status;

		status = fault_v1hs(&gs, extent);
		if(status)
			return status;
	}

	/* get the header from the stream gs */

	{
		/* Get & check magic number */
		schar magic[sizeof(ncmagic)];
		(void) memset(magic, 0, sizeof(magic));

		status = ncx_getn_schar_schar(
			(const void **)(&gs.pos), sizeof(magic), magic);
		if(status != ENOERR)
			goto unwind_get;
	
		if(memcmp(magic, ncmagic, sizeof(ncmagic)-1) != 0)
		{
			status = NC_ENOTNC;
			goto unwind_get;
		}
		/* Check version number in last byte of magic */
		if (magic[sizeof(ncmagic)-1] == 0x1) {
		  gs.version = 1;
		} else if (magic[sizeof(ncmagic)-1] == 0x2) {
		  gs.version = 2;
		  fSet(ncp->flags, NC_64BIT_OFFSET);
		  /* Now we support version 2 file access on non-LFS systems -- rkr */
#if 0
		  if (sizeof(off_t) != 8) {
		    fprintf(stderr, "NETCDF WARNING: Version 2 file on 32-bit system.\n");
		  }
#endif
		} else if (magic[sizeof(ncmagic)-1] == 0x5) {
		  gs.version = 5;
		  fSet(ncp->flags, NC_64BIT_DATA);
		} else {
			status = NC_ENOTNC;
			goto unwind_get;
		}
	}
	
	{
	size_t nrecs = 0;
       	if (gs.version == 5) {
		long long tmp = 0;
		status = ncx_get_int64((const void **)(&gs.pos), &tmp);
		nrecs = (size_t)tmp;
       	}
       	else
	    status = ncx_get_size_t((const void **)(&gs.pos), &nrecs);
	if(status != ENOERR)
		goto unwind_get;
	NC_set_numrecs(ncp, nrecs);
	}

	assert((char *)gs.pos < (char *)gs.end);

	status = v1h_get_NC_dimarray(&gs, &ncp->dims);
	if(status != ENOERR)
		goto unwind_get;

	status = v1h_get_NC_attrarray(&gs, &ncp->attrs);
	if(status != ENOERR)
		goto unwind_get;

	status = v1h_get_NC_vararray(&gs, &ncp->vars);
	if(status != ENOERR)
		goto unwind_get;
		
	ncp->xsz = ncx_len_NC(ncp, (gs.version == 1) ? 4 : 8);

	status = NC_computeshapes(ncp);
	if(status != ENOERR)
		goto unwind_get;

unwind_get:
	(void) rel_v1hs(&gs);
	return status;
}