Go to the first, previous, next, last section, table of contents.

Computing File Offsets

To calculate the offset (position within the file) of a specified data value, let external_sizeof be the external size in bytes of one data value of the appropriate type for the specified variable, nc_type:

NC_BYTE         1
NC_CHAR         1
NC_SHORT        2
NC_LONG         4
NC_FLOAT        4
NC_DOUBLE       8

On open() (or endef()), scan through the array of variables, denoted var_array above, and sum the vsize fields of "record" variables to compute recsize.

Form the the products of the dimension sizes for the variable from right to left, skipping the leftmost (record) dimension for record variables, and storing the results in a product array for each variable. For example:

Non-record variable:

        dimension sizes:        [  5  3  2 7]
        product:                [210 42 14 7]

Record variable:

        dimension sizes:        [0  2  9 4]
        product:                [0 72 36 4]

At this point, the left-most product, when rounded up to the next multiple of 4, is the variable size, vsize, in the grammar above. For example, in the non-record variable above, the value of the vsize field is 212 (210 rounded up to a multiple of 4). For the record variable, the value of vsize is just 72, since this is already a multiple of 4.

Let coord be an array of the coordinates of the desired data value, and offset be the desired result. Then offset is just the file offset of the first data value of the desired variable (its begin field) added to the inner product of the coord and product vectors times the size, in bytes, of each datum for the variable. Finally, if the variable is a record variable, the product of the record number, `coord[0]', and the record size, recsize is added to yield the final offset value.

In pseudo-C code, here's the calculation of offset:

for (innerProduct = i = 0; i < var.rank; i++)
        innerProduct += product[i] * coord[i]
offset = var.begin;
offset += external_sizeof * innerProduct
if(IS_RECVAR(var))
        offset += coord[0] * recsize;

So, to get the data value (in external representation):

lseek(fd, offset, SEEK_SET);
read(fd, buf, external_sizeof);

A special case: Where there is exactly one record variable, we drop the restriction that each record be four-byte aligned, so in this case there is no record padding.


Go to the first, previous, next, last section, table of contents.