| 8 Getting Data: Accessing the DataDDS object |
Up till now we have talked about access to a data source's meta data. The DDS provides access to the syntactic meta data and the DAS provides semantic meta data. Use the DataDDS to access data values held by the data source.
The DataDDS class is an extension of class DDS which
contains the binary data values returned by the remote server. It supports
the same methods as the class DDS, but the BaseType::buf2val()
methods can be used to extract data held in the variable instances of
BaseType. Use the DDS, BaseType and their iterators
to access the variables.
Use Connect to ask a remote server for a DataDDS. The
Connect provides Connect::request_data() to get the
DataDDS. The request_data() method accepts a constraint
expression which can be used to restrict the data returned by the remote
server. See The OPeNDAP User Guide for more information about constraint expression
syntax.7
Use iterators to traverse the DataDDS and access the individual DAP data variable objects. The following example prints the DAP data objects declaration, to access the binary data returned by the server the DAP provides access methods to retrieve the data object's buffer contents.
static void
process_data(Connect &url, DDS *dds)
{
if (verbose)
cerr << "Server version: " << url.server_version() << endl;
for (DDS::Vars_iter i = dds.var_begin(); i != dds.var_end(); i++) {
BaseType *v = *i ;
v->print_decl(cout, "", true);
smart_newline(cout, v->type());
}
}
The binary data returned by the server is stored in the _buf member of
each of the DAP's atomic data types. To retrieve the atomic data type's
buffer contents the BaseType::buf2val method is used.
n_bytes = dds->var(q)->buf2val((void **) &localVar);
The following C++ example is from the C++ Matlab client application and illustrates the use of the C++ DAP classes and methods to access elements from a Sequence data type.
void
ClientSequence::print_one_row(ostream &os, int row, string space,
bool print_row_num)
{
const int elements = element_count();
for (int j = 0; j < elements; ++j) {
BaseType *bt_ptr = var_value(row, j);
if (bt_ptr) { // data
bt_ptr->print_val(os, space, true);
}
}
}
void
ClientSequence::print_val_by_rows(ostream &os, string space,
bool print_decl_p,
bool print_row_numners)
{
const int rows = number_of_rows();
for (int i = 0; i < rows; ++i) {
print_one_row(os, i, space, false);
}
}
The C++ client uses rows and columns to access the individual elements of the
Sequence. The C++ Matlab client uses two methods to accomplish the
extraction, the first, print_val_by_row() determines the number of
rows in the Sequence and calls the print_one_row() for each
of the rows in the Sequence. The C++ DAP implementation of the
Sequence data type provides the var_value(row,col) method to
access the individual elements of the Sequence. The
var_value() method returns a BaseType pointer to the row,
column element of the Sequence. To access the binary data value
stored in that element, the BaseType method buf2val() can be
used. The preceding example simply prints the contents of the element, most
client applications would assign the contents to a local variable in the
workspace.
void
ClientArray::print_val(ostream &os, string, bool print_decl_p)
{
if (print_decl_p) {
os << type_name() << endl << var()->type_name() << " "
<< get_matlab_name() << " " << dimensions(true)
<< endl;
// Write the actual dimension sizes on a separate line.
for (Pix p = first_dim(); p; next_dim(p))
os << dimension_size(p, true) << " ";
os << endl;
}
for (int i = 0; i < length(); ++i)
var(i)->print_val(os, "", false);
}
| 8 Getting Data: Accessing the DataDDS object |