10.1 Transformation Templates

Transformation Templates are the instructions that set up the behavior definition for a virtual file. They are contained in XML and describe how the information on the system (such as the contents of a memory location) is transformed for read and write file operations.

A transformation template can also identify multiple datastreams (see Datastreams) for the virtual file. If a datastream has no name, it is used to satisfy requests that are not directed to a specific datastream.

All virtual files require a transformation template to function correctly. No read or write operations on a file will work until a virtual I/O command has been written that defines the behavior of the file to be accessed.

To define a virtual I/O command, write the following to the file followed immediately by the transformation template:

<virtualIO>
   <define/>
</virtualIO>

The template identifies each of the datastreams and how it should be rendered.

The following is the DTD for the XML that is used to define the transformation template:

<!ELEMENT transform (datastream+)>
<!ELEMENT datastream (data | location | function)>
<!ATTLIST datastream
   name CDATA #IMPLIED>

<!ELEMENT data (#PCDATA)>

<!ELEMENT location (readloc?, writeloc?)>
<!ATTLIST location 
   symname CDATA #REQUIRED
   offset CDATA #IMPLIED>
<!ELEMENT readloc (format, leadingtext?, trailingtext?)>
<!ELEMENT writeloc (format)>
<!ELEMENT format (byte | word | long | quad | raw)>
<!ELEMENT byte EMPTY>
<!ATTLIST byte
   signed (yes | no) #IMPLIED>
<!ELEMENT word EMPTY>
<!ATTLIST word
   signed (yes | no) #IMPLIED>
<!ELEMENT long EMPTY>
<!ATTLIST long
   signed (yes | no) #IMPLIED>
<!ELEMENT quad EMPTY>
<!ATTLIST quad
   signed (yes | no) #IMPLIED>
<!ELEMENT raw EMPTY>
<!ATTLIST raw
   length CDATA #REQUIRED>
<!ELEMENT leadingtext (#PCDATA)>
<!ELEMENT trailingtext (#PCDATA)>

<!ELEMENT function (readfunc, writefunc?)>
<!ELEMENT readfunc (#PCDATA)>
<!ATTLIST readfunc
   symname CDATA #REQUIRED
   cookie (yes | no) #IMPLIED>
<!ELEMENT writefunc (#PCDATA)>
<!ATTLIST writefunc
   symname CDATA #REQUIRED>

The transformation tags are interpreted as follows:

transform

Main transformation template element. It contains one or more datastream elements.

datastream

Identifies and defines a datastream. The only attribute, name, is optional. If the name attribute is not used, the datastream is used as the default datastream. If more than one datastream has no name or has the same name, the first one encountered in the template is used. The name must be less than or equal to VIRT_DATASTREAM_NAME_SIZE (currently 63 bytes). The datastream element must contain a data, location, or function element.

data

Indicates that the content of the datastream is contained in the data element itself. The data element holds the data that is to be returned for a read operation or changed for a write operation. This tag is useful for defining help text for the file.

location

Defines a memory location that will be used as the target of read and write operations. The tag has one required (symname) and one optional (offset) attribute. Symname defines a symbolic name that can be dynamically imported. Offset defines a numeric value that indicates how many bytes the memory location is from the specified symname. The location element must contain a readloc element and can optionally contain a writeloc element. If no writeloc element is defined, the location cannot be written to.

readloc

Defines the format of the result and tells VFS how to interpret the data at the given memory location. It also includes any text that will be used with the data from the memory location. The format element is required. The leadingtext and trailing text elements are optional and define the text to be used both in front of and behind the value retrieved from memory, respectively.

format

Contains one of the following five elements: byte, word, long, quad, or raw. The first four of these elements define the size of the memory location being examined and imply that the result generated will be an ASCII representation of the decimal value. The raw element does not perform any conversion.

byte

Indicates that a single byte will be converted to its ASCII decimal value. The optional attribute, signed, indicates whether the conversion should be to a signed value. This attribute should be assigned either a "yes" or "no" value. If the attribute is not specified or if its value is not "yes" or "no," it default to "yes."

word

Indicates that a single word will be converted to its ASCII decimal value. The optional attribute, signed, indicates whether the conversion should be to a signed value. This attribute should be assigned either a "yes" or "no" value. If the attribute is not specified or if its value is not "yes" or "no," it default to "yes."

long

Indicates that a four-byte memory location will be converted to its ASCII decimal value. The optional attribute, signed, indicates whether the conversion should be to a signed value. This attribute should be assigned either a "yes" or "no" value. If the attribute is not specified or if its value is not "yes" or "no," it default to "yes."

quad

Indicates that an eight-byte memory location will be converted to its ASCII decimal value. The optional attribute, signed, indicates whether the conversion should be to a signed value. This attribute should be assigned either a "yes" or "no" value. If the attribute is not specified or if its value is not "yes" or "no," it default to "yes."

raw

Indicates that the unconverted value at the previously specified memory location should be used as the virtual data. The attribute, length, is required and indicates how many bytes are retrieved for a read operation and how many bytes can be written for a write operation.

leadingtext

Contains any text that should be put in the result buffer in front of the data being rendered by the formal element.

trailingtext

Contains any text that should be put in the result buffer behind the data being rendered by the formal element.

writeloc

Contains only a format element.

function

Contains a readfunc and, optionally, a writefunc element. If no writefunc element is included, you cannot write to the datastream.

readfunc

Defines a function that will be used as the target of read operations. The tag has one required attribute, symname, which gives a symbolic name that can be dynamically imported.

writefunc

Defines a function that will be used as the target of write operations. The tag has one required attribute, symname, which gives a symbolic name that can be dynamically imported.

10.1.1 Datastreams

Each datastream has one of the following types that identifies how the data for that datastream is rendered:

Data in the template

One source of virtual data is the template itself, which is useful for descriptive text. For example, one datastream in a virtual file might return the contents of the memory location that contains the size of the file cache. Another datastream in the same file could be of the data type and contain help text that describes what the file cache size represents and how changing it may affect a system's performance.

Contents of a memory location

This datastream type renders its information from a memory location on a server. The template designates where the memory location is, how long the data is, and whether is should be converted to ASCII or returned as "raw" data.

Information rendered by a function

This type of datastream specifies two functions: one for accepting data written to the file and the other to generate data to be read from the file. This functionality gives great flexibility as to the type of virtual data that can be handled since the format of the data is determined by the function that is being called.

The functions to be used must be exported. VFS imports the symbol the first time it is encountered after the virtual file is created. It remains in an imported state until the file is deleted. Note that delete is an asynchronous operation and unimporting the symbol can occur after the return from a call to delete the file. In such cases, you should check the return code from the unexport function to ensure it successfully succeeded. The function can fail if the unimport has not yet occurred in VFS.