They take the form label=value, where label is a character string containing MAX_NC_NAME or fewer characters and value contains one or more entries of the same data type as defined at the time the attribute is created. Attributes can be attached to three types of objects: files, data sets and dimensions. These are referred to, respectively, as file attributes , array attributes and dimension attributes:
For each object, a separate attribute count is maintained that identifies the number of attributes associated with the object. The attribute count begins at zero and is increased by one for every new attribute assigned to an object. Each attribute associated with an object has a unique attribute index, a value between 1 and the total number of attributes. The attribute index is used to retrieve an attribute's value or information about an attribute.
3.10.1 Writing User-defined Attributes: SDsetattr
Attributes are not actually written out to a file until access to the object is terminated. Creating an attribute increases the attribute count by one for the given object. Writing an attribute involves the following steps:
C: status = SDsetattr(sd_id, attr_name, data_type, count, value); FORTRAN: status = sfsnatt(sd_id, attr_name, data_type, count, value)
In SDsetattr the argument sd_id is the identifier for the HDF object to be assigned the attribute and it can be a file id, SDS id or dimension id. The argument attr_name is an ASCII string containing the name of the attribute. It represents the label in the label=value equation and can be no more than MAX_NC_NAME characters. If this is set to the name of an existing attribute the value portion of the attribute will be overwritten. Do not use SDsetattr to assign a name to a dimension, use SDsetdimname instead.
EXAMPLE 19. Setting Attribute Values
The following examples call SDsetattr with an SDS id as the first parameter, which assigns an SDS attribute to the selected data set. If a file id were passed instead, SDsetattr would assign a file attribute to the entire file.
#include "hdf.h" #include "mfhdf.h" main( ) { int32 sd_id, sds_id, dim_id, dim_index, status; int32 num_values[2]; /* Open the file and get the identifier for the file. */ sd_id = SDstart("Example4.hdf", DFACC_RDWR); /* Set an attribute that describes the file contents. */ status = SDsetattr(sd_id, "file_contents", DFNT_CHAR8, 16, \ (VOIDP)"storm_track_data"); /* Get the identifier for the first data set. */ sds_id = SDselect(sd_id, 0); /* Set an attribute the specifies a valid range of values. */ num_values[0] = 2; num_values[1] = 10; status = SDsetattr(sds_id, "valid_range", DFNT_INT32, 2, \ (VOIDP)num_values); /* Get the identifier for the first dimension. */ dim_id = SDgetdimid(sds_id, 0); /* Set an attribute that specifies the dimension metric. */ status = SDsetattr(dim_id, "dim_metric", DFNT_CHAR8, 9, (VOIDP)"millibars"); /* Terminate access to the array */ status = SDendaccess(sds_id); /* Terminate access to the SD interface and close the file */ status = SDend(sd_id); }
PROGRAM SET ATTRIBS integer*4 sd_id, sds_id, dim_id, status integer num_values(2) integer sfstart, sfsnatt, sfselect, sfdimid integer sfendacc, sfend integer DFACC_RDWR, DFNT_CHAR8, DFNT_INT32 parameter (DFACC_RDWR = 3, DFNT_CHAR8 = 4, DFNT_INT32 = 24) C Open the file and get the identifier for the file. sd_id = sfstart('Example4.hdf', DFACC_RDWR) C Set an attribute that describes the file contents. status = sfsnatt(sd_id, 'file_contents', DFNT_CHAR8, 16, + 'storm_track_data') C Get the identifier for the first data set. sds_id = sfselect(sd_id, 0) C Set an attribute the specifies a valid range of values. num_values(1) = 2 num_values(2) = 10 status = sfsnatt(sds_id, 'valid_range', DFNT_INT32, 2, + num_values) C Get the identifier for the first dimension. dim_id = sfdimid(sds_id, 0) C Set an attribute that specifies the dimension metric. status = sfsnatt(dim_id, 'dim_metric', DFNT_CHAR8, 9, + 'millibars') C Terminate access to the array status = sfendacc(sds_id) C Terminate access to the SD interface and close the file status = sfend(sd_id) end
3.10.2 Querying User-defined Attributes: SDfindattr and SDattrinfo
Given a file, array or dimension id and an attribute name, SDfindattr will return a valid attribute index if the corresponding attribute exists. The attribute index can then be used to retrieve information about an attribute or its values. Given a file, array or dimension id and a valid attribute index SDattrinfo returns the name, data type and count for the corresponding attribute if it exists.
C: attr_index = SDfindattr(id, attr_name); status = SDattrinfo(id, attr_index, attr_name, num_type, count); FORTRAN: attr_index = sffattr(id, attr_name) status = sfgainfo(id, attr_index, attr, name, number_type, count)
The parameters of SDfindattr and SDattrinfo are further described below. (See Table 3W.)
An attribute's index may also be determined by keeping track of the number and order of attributes as they are written or dumping the contents of a file using a dumping utility.
3.10.3 Reading User-defined Attributes: SDreadattr
SDreadattr reads the value or values of an attribute. The syntax for SDreadattr is as follows:
C: status = SDreadattr(sds_id, attr_index, data); FORTRAN: status = sfrattr(sd_id, attr_index, data)
SDreadattr takes a file, array, or dimension identifier and an attribute index specified in the attr_index parameter as input parameters and returns the attribute values in the buffer data. SDreadaddr will also read attributes and annotations created by the DFSD interface.
TABLE 3W SDsetattr, SDfindattr, SDattrinfo and SDreadattr Parameter List
C:
#include "hdf.h" #include "mfhdf.h" main( ) { int32 sd_id, sds_id, status, *buffer1; int32 attr_index, data_type, count; char attr_name[MAX_NC_NAME]; int8 *buffer; /* Open the file. */ sd_id = SDstart("Example4.hdf", DFACC_RDONLY); /* Find the file attribute named "file_contents". */ attr_index = SDfindattr(sd_id, "file_contents"); /* Get information about the file attribute. */ status = SDattrinfo(sd_id, attr_index, attr_name, &data_type, &count); /* Allocate a buffer to hold the attribute data. */ buffer = (int8 *)malloc(count * DFKNTsize(data_type)); /* Read the attribute data. */ status = SDreadattr(sd_id, attr_index, buffer); /* Get the identifier for the first data set. */ sds_id = SDselect(sd_id, 0); /* Find the data set attribute named "valid_range". */ attr_index = SDfindattr(sds_id, "valid_range"); /* Get information about the data set attribute. */ status = SDattrinfo(sds_id, attr_index, attr_name, &data_type, &count); /* Allocate a buffer to hold the attribute data. */ buffer1 = (int32 *)malloc(count * DFKNTsize(data_type)); /* Read the attribute data. */ status = SDreadattr(sd_id, attr_index, buffer1); /* Terminate access to the array */ status = SDendaccess(sds_id); /* Terminate access to the SD interface and close the file */ status = SDend(sd_id); }
PROGRAM ATTRIB INFO integer*4 sd_id, sds_id, range_buffer(2) integer attr_index, data_type, count, status character attr_name *13 character char_buffer *20 integer sfstart, sffattr, sfgainfo, sfrattr, sfselect integer sfendacc, sfend C DFACC_RDWR is defined in hdf.h. integer DFACC_RDWR parameter (DFACC_RDWR = 3) C Open the file. sd_id = sfstart('Example4.hdf', DFACC_RDONLY) C Find the file attribute named 'file_contents'. attr_index = sffattr(sd_id, 'file_contents') C Get information about the file attribute. status = sfgainfo(sd_id, attr_index, attr_name, data_type, + count) C Read the attribute data. status = sfrattr(sd_id, attr_index, char_buffer) C Get the identifier for the first data set. sds_id = sfselect(sd_id, 0) C Find the data set attribute named 'valid_range'. attr_index = sffattr(sds_id, 'valid_range') C Get information about the data set attribute. status = sfgainfo(sds_id, attr_index, attr_name, data_type, + count) C Read the attribute data. status = sfrattr(sd_id, attr_index, range_buffer) C Terminate access to the array status = sfendacc(sds_id) C Terminate access to the SD interface and close the file status = sfend(sd_id) end