Prev Up Next
Go backward to 7 Implementing the DDS object
Go up to Top
Go forward to 9 Implementing the DataDDS object

8 Implementing the DAS object

To implement the DAS handler, start with the same boiler-plate code used to create a main() for the DDS handler and replace the call to the function that builds the DDS with one that builds a DAS. An example of such a function from the Matlab server is shown below:

void
read_attributes(DAS &das_table, string filename)
{
    AttrTable *attr_table = das_table.add_table("MAT_GLOBAL", new AttrTable);
    
    MATFile *fp = matOpen(filename.c_str(), "r");
    if (fp == NULL)
        throw Error(string("Could not open the file: ") + filename.c_str());

    // Read all the matrices in file
    Matrix *mp;
    while ((mp = matGetNextMatrix(fp)) != NULL) {
        // String types are used as attributes
        if(mxIsString(mp)) {
            // get size
            int X = mxGetN(mp);
            int Y = mxGetM(mp);

            char *str_rep = new char [X*Y+3];
      
            // quote the string for parser
            *str_rep = '"'; 
            mxGetString(mp, str_rep+1, X*Y+1);
            *(str_rep + X*Y + 1) = '"';
            *(str_rep + X*Y + 2 )= '\0';

            if (attr_table->append_attr(mxGetName(mp),
                "String",str_rep) == 0) {
                delete [] str_rep;
                mxFreeMatrix(mp);
                matClose(fp);
                throw Error(string("Couldn't output attribute: ")
                            + mxGetName(mp));
            }

            delete [] str_rep;
        }
        else {
            das_table.add_table(mxGetName(mp), new AttrTable);
        }
        mxFreeMatrix(mp);
    }
    matClose(fp);

    return true;
}

In this example the server creates a single attribute container called MAT_GLOBAL and loads all the data set attributes into it.

Most data set types (e.g., hdf) have both global attributes (those that apply to the entire data set) and attributes that only apply to a particular variable. Such data sets have both a global attribute container and separate attribute containers for each variable3. Matlab has only global attributes.

Here's what is going on inside this function:

First a new attribute table object is created and added to the DAS object. An attribute table (AttrTable) is similar to a structure in that it holds other things which may be attributes (typed name-value pairs) or other attribute tables. The DAS is a container for AttrTable objects. Take a look at the documentation for the AttrTable and DAS classes in the Programmer's Reference Guide.

    AttrTable *attr_table = das_table.add_table("MAT_GLOBAL", new AttrTable);

Following the creation of a table for global attributes, the function handles the routine and API-dependent tasks of opening the data set and setting things up to iterate over its variables.

    MATFile *fp = matOpen(filename.c_str(), "r");
    if (fp == NULL)
        throw Error(string("Could not open the file: ") + filename.c_str());

    // Read all the matrices in file
    Matrix *mp;
    while ((mp = matGetNextMatrix(fp)) != NULL) {

Inside the while-loop that iterates over the data set's variables, we test for string variables. The Matlab server assumes that all string variables in a data set are actually global attributes for the data set (and not `data' variables). If a string variable is found, the code uses the variable's name and value as the attribute name and value (code that handles the case where a variable is not a string is explained further down).

Attributes are all string-valued in the DAP. That is, even though the DAP supports the full range of scalar data types for attributes, the values are stored as strings. The call to AttrTable::append_attr adds the attribute tuple (Name, type and value) to the AttrTable instance.

Note that if AttrTable::append_attr fails, it returns zero and the code cleans up and throws an exception. I elided that from this sniplet to focus the example.

        // String types are used as attributes
        if(mxIsString(mp)) {
            // get size
            int X = mxGetN(mp);
            int Y = mxGetM(mp);

            char *str_rep = new char [X*Y+3];
      
            // quote the string for parser
            *str_rep = '"'; 
            mxGetString(mp,str_rep+1,X*Y+1);
            *(str_rep + X*Y + 1) = '"';
            *(str_rep + X*Y + 2 )= '\0';

            if (attr_table->append_attr(mxGetName(mp), "String", str_rep) == 0) {

If the variable is not a string, then the Matlab server creates an empty attribute table for it. This is to conform to the DAP 2.0 specification which states that all variable must have an attribute table, even if it is empty.

        else {
            das_table.add_table(mxGetName(mp), new AttrTable);
        }

James Gallagher <jgallagher@gso.uri.edu>, 2006-08-17, Revision: 14349

Prev Up Next