To read data values from a dataset using a typical data access API, a
user would submit to some API function the name of the variable to be
read. The DODS client library version of this same function must take
that variable name and use it to construct a constraint expression.
(See Section 4.3.2 for more information on using
constraint expressions to access data.) The constraint expression
must then be appended to the dataset URL (with the suffix
.dods), and the resulting URL sent out into the internet.
For example, to get a variable called var from a dataset at:
http://blah/cgi-bin/nph-nc/weekly.nc.dods
you would use the URL:
http://blah/cgi-bin/nph-nc/weekly.nc.dods?var
The Connect class contains a member function,
request_data that performs this task. It takes the constraint
expression and the suffix to use for requesting data, appends them to
the Connect URL, and sends the entire string off to retrieve
its corresponding data.
The request_data function returns a pointer to a DDS
object, which contains the data as well as the structure description
corresponding to the data request.
Once the request_data member function has returned, the client
library must still call the deserialize member function (which
is part of the DODS Type Classes) for each returned variable. The
client library should use the variable objects contained in the
DDS object returned by request_data to invoke the
deserialize member function. Once that is done, the data values
are stored in the internal buffers of the variable objects in the new
DDS12. The
client library should store this new DDS, along with the
constraint expression passed to request_data so that future
requests by the user program for the same information can be handled
without accessing the remote data server.
The data values of variables in a DDS are accessed using the
buf2val member function for the cardinal and vector types and by
accessing the values of fields for constructor types.
For a DODS client library to be robust, it may have to be equipped to deal with data types it was not designed to use. For example, the NetCDF software cannot manipulate a DODS Sequence. But a user can use the DODS version of the NetCDF library to request data from a server that provides Sequence data. When cases like this arise (and they arise farily often), the author of the client library must choose an appropriate data type into which the served data is to be translated, and implement functions to do that translation.
Often, translation from one data type to another is a simple task. Translating an Array into Sequence format is fairly straightforward, although there are several ways to do it. (The author of the client library should choose one, and document that choice in a README file.)
Other translations are more complex, and may even require that the client library violate the semantics of the original API, or of one of the DODS data types. For example, translating a Sequence to an Array in NetCDF requires that the client know in advance the length of the Sequence, which is not necessarily known.