Prev Up Next
Go backward to 5 Getting ready to write your components
Go up to Top
Go forward to 7 Implementing the DDS object

6 Subclassing the data types

The DAP defines a data type hierarchy as the core of its data model. This collection of data types includes scalar, vector and constructor types. Most of the types are available in all modern programming languages with the exceptions being Url, Sequence and Grid. In the DAP library, the class BaseType is the root of the data type tree.

6.1 A quick review of the data types supported by the DAP

The DAP supports the common scalar data types such as Byte, 16- and 32-bit signed and unsigned integers, and 32- and 64-bit floating point numbers. The DAP also supports Strings and Urls as basic scalar types. The DAP includes Arrays of unlimited size and dimensionality. The DAP also supports three type-constructors: Structure, Sequence and Grid. A Structure on the DAP mimics a struct in C. A Sequence is a table-like data structure inherited from the JGOFS data system. It can be used to hold information that might be stored in relational databases or tables, either flat or hierarchical. The JGOFS, FreeForm and HDF servers all use the Sequence data type. Lastly, the Grid data type is used to bind an array to a group of map vectors, single dimension arrays that provide non-integral values for the indices of the array. The most typical use of a Grid is to provide latitude and longitude registration for some georeferenced array data (e.g., a projected satellite image). The DAP does not have a pointer data type, but in some cases the Url data type can be used as a pointer to variables between files. More information about the DAP's data type hierarchy is given in the Programmer's Guide.

6.2 The Matlab 5 data model and the DAP

In the remainder of this tutorial the Matlab 5 OPeNDAP server will be used as an example. It is a real, non-trivial, server that you can download and run, if you choose.

The Matlab 5 server makes a good example for this tutorial because the Matlab 5 data model is very limited. Matlab 5 supports scalars, vectors and matrices. For basic types it supports only floating point numbers and strings.

In the Matlab 5 server, we treat scalar strings as attributes and all other types as variables.

6.3 Creating the subclasses

When you start building a DAP server, the first thing you must do is create a collection of data type subclasses. That is, each of the leaf classes in the preceding class diagram must be subclassed by your server. This is pretty easy since a good bit of the work is rote.

First we'll illustrate the parts that are mechanical. Here's an example from the Matlab server. The class is the Byte class. In the case of the matlab server, this class doesn't do anything beyond the bare minimum, so it's a good starting point:

Byte *
NewByte(const string &n)
{
    return new MATByte(n);
}

MATByte::MATByte(const string &n) : Byte(n)
{
}

BaseType *
MATByte::ptr_duplicate()
{
    return new MATByte(*this);
}

bool
MATByte::read(const string &)
{
    throw InternalErr(__FILE__, __LINE__, "Unimplemented read method
    called.");
}

To create a child of any of the data type leaf classes, you must define three methods and one function. Let's talk about the function first. The function NewByte is what Meyers[1] calls a virtual constructor. It's similar to a low-budget factory class ("low-budget" because it's not a class). This function is used at various places in the DAP library when it need to create instances of Byte without knowing in advance the dynamic type of the object that actually will be created. If all this sounds a little weird, just remember that your Byte, Int16, ..., Grid classes -- whatever they may be called -- must all contain an implementation of this function and each should all return a pointer to an instance of the apropriate child class. These functions will be used by the library to create instance of hte classes you have defined when writing your server. In this case of the example Matlab server, it's an instance of the MATByte class. If you look in the files for the Matlab server, you'll see that the function NewGrid returns a pointer to a new MATGrid, and so on.

Second, a constructor must be implemented and should take the name of the variable as its sole argument.

Third, your child classes should also define the ptr_duplicate() method. This method returns a pointer to a new instance of an object in the same class. Occasionally, in the DAP library, objects are declared with pointers specified as BaseType *. If the new operator was used to copy such an object, the copied object would be an instance of BaseType (the static type of the object) not the type of the thing referenced (the dynamic type)2. By using the ptr_duplicate() method the DAP library is sure that when it copies an object, it's getting an instance of the subclass defined by your server.

Finally, each of the child classes must provide an implementation of the read method. This method is called by code in the DAP library to read values from the data set. It will be explained in more detail when we get to building DataDDS responses. For now, it's enough to know that if a particular server has no use for a given data type (it happens that the Matlab server will never need to create an instance of Byte, because Matlab 5 files can only store float64 matrices) this method should throw an InternalErr object.


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

Prev Up Next