Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

DDL Attributes

(Back to Tutorials)

In this tutorial you will see examples on how to:

  • Use Bless to manipulate metadata in .ddl files
  • Use DynamicLibrary? to get metadata at runtime

Source Listing for this tutorial

Metadata

DDL has built-in support for metadata, by way of a key/value attribute system - or just Attributes. The DynamicLibrary? and DynamicModule? classes provide support methods for this, making it very easy to access this information.

auto registry = new DefaultRegistry();
auto lib = registry.load("mymodule.ddl");

The metadata that you get from a typical binary file (e.g. an OMF .obj file) will vary depending on the type. However, wrapping a binary file as a .ddl file (via bless) provides a uniform way to attach any kind of metadata imaginable to a given library.

Using Bless To Create a DDL

First, we need to start with a library. We'll use an empty stub to start with, since this tutorial doesn't even touch the library's contents.

module mylib;

//empty library for metatdata examples

As discussed in a few other tutorials, we turn this into an .obj file like so:

> dmd -c examples/attributes/mylib.d

Now, to turn this into a .ddl file we will use the "bless" DDL utility. To 'bless' a binary file, and wrap it as a .ddl, simply do the following:

> bless mylib.obj

This should generate a file called 'mylib.ddl'. If this filename is not desirable, simply override the output filename by using the '-f' option:

> bless mylib.obj -fmycoollib.ddl

Bless also has options for extracting the wrapped file ('-x') and provides a test-only mode ('-n'). While those are beyond the scope of this tutorial, the reader should find them fairly self-explanatory.

Using Bless To Attach An Attribute

Where Bless comes in really handy is to attach metadata. For starters, the '-a' option lets us attach key/value pairs directly on the command line:

> bless mylib.obj -ahello=world

We can test that the metadata has been attached correctly, by viewing the generated .ddl file using DDLInfo and it's '-a' option.

> ddlinfo mylib.ddl
filename: 'mylib.ddl'
type: 'DDL'
attributes:
hello - world
std.filename - mylib.obj

(DDLInfo does plenty of other interesting things, but those too are beyond the scope of this Tutorial)

The 'hello - world' part is confirmation that the key/value pair "hello=world" is a part of this .ddl. We can also confirm this by way of a custom program as well:

module attributes;
import ddl.DefaultRegistry;
import ddl.DynamicLibrary;
import tango.io.Stdout;

void main(){
	auto registry = new DefaultRegistry();
	auto lib = registry.load("mylib.ddl");
	
	auto helloWorld = lib.getAttributes["hello"];
	Stdout("value of 'hello' is "c)(helloWorld).newline;
}

Simply compile and run the above, and you should be greeted with the attribute data you placed in "mylib.ddl" earlier.

> build -full examples/attributes/attributes.d
> attributes
> value of 'hello' is world

Using Bless To Attach Multiple Attributes

The '-a' option on bless can be used as many times as needed on the command line.

> bless -afoo=bar -agorf=goat -ahello=world

Bless options a less tedious approach to adding multiple attributes: the '-p' switch. By specifying a properties file after '-p' on the command line, Bless will load and use that data to add everything specified within the file. Not only is this the preferred method for adding multiple attributes to your .ddl files, but it makes it easy to rubber stamp multiple libraries with the same data (like copyright, author, or support information).

#properties.txt
#Example properties file
foo=bar
gorf=goat
hello=world

As you might have guessed, any line in the properties file that begins with '#', is a comment. Any other line is treated as a key/value pair, separated by an equals-sign ('=').

Handing this off to bless is just a few key keystrokes away:

> bless mylib.obj -pproperties.txt

And like before DDLInfo confirms that this has done the job:

> ddlinfo mylib.ddl
filename: 'mylib.ddl'
type: 'DDL'
attributes:
hello - world
gorf - goat
std.filename - test.obj
foo - bar

Modifying .ddl Attributes Via DDL

If Bless' feature-set isn't enough for you, then DDL can manage the rest. Simply use the DDLBinary class directly to load manipulate and save an existing .ddl file.

module attributes2;

import ddl.all;
import ddl.ddl.DDLBinary;
import tango.io.Stdout;
import tango.io.FileConduit;

void main(){	
	// load the .ddl binary file
	DDLBinary binary = new DDLBinary();	
	auto inBuffer = new FileBuffer("mylib.ddl");
	binary.load(inBuffer);
	inBuffer.flush();
	inBuffer.getConduit().close();
	
	// manipulate some attributes
	binary.attributes["HaHa"] = "I'm on the internet.";
	
	// write the file out
	auto outBuffer = new FileBuffer("mylib.ddl",FileStyle.ReadWriteCreate);
	binary.save(outBuffer);	
	outBuffer.flush();
	outBuffer.getConduit().close();
}

Just build and run, and the program will modify mylib.ddl for us.

> build examples/attributes/attributes2.d
> attributes2

Once again, use DDLInfo to verify that this has performed as expected:

> ddlinfo mylib.ddl
filename: 'mylib.ddl'
type: 'DDL'
attributes:
HaHa - I'm on the internet.
hello - world
gorf - goat
std.filename - test.obj
foo - bar

Conclusion & Remarks

One thing that the developer should keep in mind, is that attributes are only available as UTF-8 text. This is really more for simplicity's sake than anything else. DDL may be upgraded in the future to allow for wider character encodings on metadata.