Optimize Your Resource Management with Brew and XML

hy, oh why, should you use yet another file to house string, image, and binary resources? With Brew there are several good reasons. As every experienced developer knows, each handset has its own quirks, differences, and eccentricities. You also know that no project has the same specification for more than a few weeks. In small organizations, it is nearly impossible to expend engineering time to compensate for each individual handset and resource requirement change.

This article explores how the cannon of BREW’s resource files?along with the recently added XML resource file architecture?can help simplify your project’s resource management, starting with the very basic and moving to the more complex.

The Basics
The most basic resource file is the .bar file. This file allows anyone with a text editor to modify and control resources at runtime on the handset. This makes it very simple to call out the IDs for your resources and swap them out at a later time. Additionally, this ability allows for different language support, conforming to spec changes, and different screen resolutions?all without recompiling. These benefits do come with a small cost in overhead and some small drawbacks. String literals in code take up slightly less space inline than they would in the .bar file (though code with resources in-line makes comprehending source for the uninitiated straightforward and easier to read). Each call to the resource file must also make use of the files-system and that can be very slow, at times. These few drawbacks are drastically overshadowed by the benefits of the run-time resource file.

Enough talk; let’s look at how to load resources from the .bar file in code:

#define APP_RESOURCE_FILE "myapp.bar"#define MAX_STRING_SIZE 64//Returns a pointer to a newly allocated stringAECHAR * MyApp_GetString(IShell *pShell, int nStringID){	AECHAR *wszResource = MALLOC( MAX_STRING_SIZE * sizeof(AECHAR));	ISHELL_LoadResString( pShell, 		APP_RESOURCE_FILE, 		nStringID, 		MAX_STRING_SIZE * sizeof(AECHAR) )		return wszResource;}

As the above code shows, loading a string resource from the .bar file is quite simple. Create a wide-string buffer to hold the resource, pass it into the shell function with the resource name, and ID and your resource now resides in memory. To display, simply load the text resource into an IStatic and draw.

Author’s Note: A common mistake in dealing with wide-strings is to specify in the number of AECHARs in your destination string. This will result in half the buffer being filled. Be sure to specify the number of bytes used by the buffer (in this case its length times two).

Brew will also pre-load an IImage object from the resource file for you:

{	IImage *pImage;	.......	pImage = ISHELL_LoadResImage(pIShell, "myapp.bar", IDI_MYIMAGE);	if(!pImage)	{		//Error handling here	}.......}

This code is very simple and demonstrates how helpful these Brew resource files can be. Brew’s ISHELL object will do the leg work of creating an IImage object given the resource filename and the ID. The IDI and IDS are prefixes that denote types for images and strings. It’s a simple way to differentiate between your resource types at a glance.

For other ways to use the resource file, be sure to read through the documentation for the Brew SDK. The Menu and Text controls also interface directly with the resource file (information on how to use these UI objects is also found in the SDK documentation).

The New .brx and .mfx Architecture
With the advent of Brew 3 (3.1.2 and 3.1.4), Qualcomm released a powerful new method with which to interact and store resources in XML. Previously, the resource file could only be accessed through Qualcomm’s resource editor application. With this new architecture, anyone can read, manage, edit, and build the .bar and .mif files. The following code looks at what a basic resource file looks like in XML:

             Hello World!                .imagessplash.png    

In this example, you can see a string block and an object block. The string block contains one text resource “Hello World!”. The object block contains an image resource for a splash screen. When compiled, the binary data for all referenced images is copied into the output file.

This example illustrates the basic layout of the XML, which is compiled into binary for deployment. Because these files are in plain text, you can use Perl, Python, and batch scripts to manipulate and update their contents?automatically rev version numbers, manage language porting, and allow for various other powerful automation tools.

Another key feature of this latest XML architecture shift is the introduction of the .mfx file. .mfx files are to .mif files as the .brx files are to .bar files. For example, NSTL requires a unique version to appear in each True Brew testing submission?in addition to the requirement that the version match between the .mif and help dialogue (which should reside in the .bar file). The following code shows where that version number comes from in the .mfx:

            1.0    

As you can see, this is a small piece taken from the .mfx file. It compiles out to the version number in the .mif for your application. Notice that the format of the code is identical to the string resources in the .brx file listed earlier. This is because both of these files are human-readable, so it becomes trivial to write a Perl script that will rev both the .mfx and the .brx files for a new version. Include this as part of your drop scripts and you have one less reason to get a failure back from NSTL.

Building the Files
There are two basic ways to build .brx and .mfx files. The first is through the .mif and .bar editors respectively. The process is as straightforward as it is simple. Open the .mfx or .brx in the appropriate application. Pull down the build menu and select Build. A dialogue box will appear and the appropriate output files appear in the same directory.

The second, and much more interesting method, is the command line compile tool. The Brew ResourceEditor has a simple but effective command line interface. Here’s this tool in action:

"C:Program FilesBREW SDK Tools 1.0.1ResourceEditorrewrc" ./testing.brx

This is a fairly straightforward command line call. If you reference images from a folder other than where the .brx file resides, be sure to use the ‘-i’ flag and specify the path to the wayward images.

To build an .mfx file to a .mif file, simply add -o and the .mfx filename into the previous figure as shown below:

"C:Program FilesBREW SDK Tools 1.0.1ResourceEditorrewrc" -o ./mif/testing.mif-nh testing.mfx

This also specifies the name and location of the compiled output file. For this to work, you must specify the extension of your .mif file. The ‘brewrc’ application will default to ‘.bar’. For more information on building .mif and .bar files on the command line be sure to read through the “SDK Tools User Docs” included with the toolset.

Figure 1. Visual Studio Screenshot: The location and content of the custom build step, which builds the brx on every compile.

There are two very appealing places this minimal command line interface can be used. You could add this line to a batch file or as a custom build step to a Visual Studio project. These would allow you to build your resource files alongside your source code in one simple step.

Add the command line to a batch file that drives the make file for your project. This will compile and output the .bar/.mif files for you at the same time your project builds for ARM.

When you put this command line to use in Visual Studio, adding and removing resources to your project is drastically simplified.

With Figure 1’s custom build step in place, you can manipulate your resource file in plain text from within Visual Studio. Each time the code is compiled, the new .bar and .brh files are produced and used in the project.

An Essential New Resource
Now, with a complete understanding of the methodology, architecture, and implementation of Brew’s new resource files, it should be simple to create and manage the resources in your project. Dynamic runtime resources are not for all platforms. Because of the porting demands of a Brew development project, it’s almost essential to have a way to modify the look, feel, language, and layout of an application at runtime.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles: