Waba File Format Notes

Some external links may be obsolete -- if you have updates, please send.

Last updated: 25-Jun-2005

There many different file formats involved in Waba development and distribution, and a few of these are documented here.

source
.java, .bmp
compiled
.class
distribution: resource
.pdb, .wrp, .jar, .pkg
distribution: initialization/launch
.prc, .lnk, .htm, (.pkg)

The Warp and Exegen applications (in wextras/wababin) demonstrate how to create and access .prc, .pdb, .lnk and .wrp files.

You can see these formats used in WabaTester (NewtonScript); in setAppClasses, it extracts classes and bitmaps from .pdb, .wrp, .jar (uncompressed); in convertBitmap, it converts .bmp to Newton bitmap format; in setAppArgs, it extracts command line parameters from .prc, .lnk, .htm (some of which are described in wabanewton-api.htm), main class name, and icon (from .prc).

Some details on formats are provided next, followed by a few thoughts on which formats to use.

WinCE Warp (.wrp)

A WRP file starts with the following header:

name                type/size
-------------------------------
magic chars         char/4 bytes
number of records   int/4 bytes

The "magic chars" for the WRP file format version 1.0 are "Wrp1". This is followed by the number of records contained in the file as a 4 byte value. All integer values in the WRP file format are in network order (also known as big-endian or MSB order).

The header is followed by a number of record offset values. Each offset is 4 bytes in the format of:

name                type/size
-------------------------------
record offset       int/4 bytes

Each offset corresponds to a record in the file. The offsets are byte locations relative to the beginning of the WARP file and denote the positions of the records in the file.

The record offset section is followed by an end-of-file offset. This value is useful when determining the length of the last record. To determine the length of any record, you can subtract that records offset from the next record offset.

To get the size of the last record, you can subtract the record offset of the last record from the end-of-file offset. The end-of-file offset is a 4 byte value in the format of:

name                type/size
-------------------------------
end-of-file offset  int/4 bytes

The record offset section is followed by the records themselves. The individual records are in the same format as the records in a PDB WARP file. For reference, this is:

name                type/size
-------------------------------
path length         int/2 bytes
path (name)         char/varies
resource            byte/varies

As is the case with PDB WARP files, resources are contained in a WRP file in their original format, uncompressed and the records appear in sorted order by path name. The path name with the least value (according to the ISO C strcmp() function) will appear first.

Palm Warp (.pdb)

Several references:

Each record in the PDB file contains a resource such as a class file. The overall PDB file format is reasonably well documented by others so we'll only focus here on the format of individual records.

PDB/PRC HEADER=78
[ 0]32: name(CString)
[32] 2: flags(0)
[34] 2: version(0)
[36] 4: create time
[40] 4: mod time
[44] 4: backup time
[48] 4: mod num
[52] 4: app info		??
[56] 4: sort info
[60] 4: Type, e.g., Wrp1(PDB)
[64] 4: ID, e.g., xxxx
[68] 4: seed
[72] 4: next_rec
[76] 2: num recs
[78] 

PDB record=8 (RecordEntryType)
[0] 4: LocalChunkID
[4] 1: RecordAttributes
[5] 3: UniqueID

PRC record=10 (RsrcEntryType)
[0] 4: Type ??
[4] 2: ID
[6] 4: LocalChunkID [actually just 1st word]

Each record in the file contains the full path of the resource (the resource name) at the start of the record and the actual binary representation of the resource following the full path. The format of each record is as follows:

name                type/size
-------------------------------
path length         int/2 bytes
path (name)         char/varies
resource            byte/varies

As an example, if we had a record containing a class file named "mypackage/test.class", the record would start with the number 20 (the length of the path). The number is 2 bytes long and appears in network order (also known as big-endian or MSB order). This would be followed by the ASCII characters "mypackage/test.class" and following that would be the binary representation of the class file itself. The length of the record can be determined by examining the PDB record headers.

Jar

source: java.util.zip.ZipConstants

// Header signatures
static long LOCSIG = 0x04034b50L;	// "PK\003\004"
static long EXTSIG = 0x08074b50L;	// "PK\007\008"
static long CENSIG = 0x02014b50L;	// "PK\001\002"
static long ENDSIG = 0x06054b50L;	// "PK\005\006"

// Header sizes in bytes (including signatures)
static final int LOCHDR = 30;	// LOC header size
static final int EXTHDR = 16;	// EXT header size
static final int CENHDR = 46;	// CEN header size
static final int ENDHDR = 22;	// END header size

// Local file (LOC) header field offsets
static final int LOCVER = 4;	// version needed to extract
static final int LOCFLG = 6;	// general purpose bit flag
static final int LOCHOW = 8;	// compression method
static final int LOCTIM = 10;	// modification time
static final int LOCCRC = 14;	// uncompressed file crc-32 value
static final int LOCSIZ = 18;	// compressed size
static final int LOCLEN = 22;	// uncompressed size
static final int LOCNAM = 26;	// filename length
static final int LOCEXT = 28;	// extra field length

// Extra local (EXT) header field offsets
static final int EXTCRC = 4;	// uncompressed file crc-32 value
static final int EXTSIZ = 8;	// compressed size
static final int EXTLEN = 12;	// uncompressed size

// Central directory (CEN) header field offsets
static final int CENVEM = 4;	// version made by
static final int CENVER = 6;	// version needed to extract
static final int CENFLG = 8;	// encrypt, decrypt flags
static final int CENHOW = 10;	// compression method
static final int CENTIM = 12;	// modification time
static final int CENCRC = 16;	// uncompressed file crc-32 value
static final int CENSIZ = 20;	// compressed size
static final int CENLEN = 24;	// uncompressed size
static final int CENNAM = 28;	// filename length
static final int CENEXT = 30;	// extra field length
static final int CENCOM = 32;	// comment length
static final int CENDSK = 34;	// disk number start
static final int CENATT = 36;	// internal file attributes
static final int CENATX = 38;	// external file attributes
static final int CENOFF = 42;	// LOC header offset

// End of central directory (END) header field offsets
static final int ENDSUB = 8;	// number of entries on this disk
static final int ENDTOT = 10;	// total number of entries
static final int ENDSIZ = 12;	// central directory size in bytes
static final int ENDOFF = 16;	// offset of first CEN header
static final int ENDCOM = 20;	// zip file comment length

.bmp

WORD Type;              File type. Set to "BM".
DWORD Size;             Size in BYTES of the file.
DWORD Reserved;         Reserved. Set to zero.
DWORD Offset;           Offset to the data.
DWORD headerSize;       Size of rest of header. Set to 40.
DWORD Width;            Width of bitmap in pixels.
DWORD Height;           Height of bitmap in pixels.
WORD Planes;            Number of Planes. Set to 1.
WORD BitsPerPixel;      Number of bits per pixel.
DWORD Compression;      Compression. Usually set to 0.
DWORD SizeImage;        Size in bytes of the bitmap. 
DWORD XPixelsPerMeter;  Horizontal pixels per meter.
DWORD YPixelsPerMeter;  Vertical pixels per meter.
DWORD ColorsUsed;       Number of colors used.
DWORD ColorsImportant;  Number of "important" colors.

.pkg

Newton package format is generated by Newton ToolKit (NTK) on desktop, and by NewtPack, provided with WabaTester on the Newton. If someone can contribute some existing or write new desktop (preferably Java-based) .pkg generation code, that would be great. Otherwise, someone (probably Steve) might eventually add it to Warp/Exegen.

Discussion of different formats

This is mostly relevant to WabaTester which saves the entire original file in the Newton package.

When you compile Waba source files (.java), this creates one or more .class files. To distribute this application on Palm (or WinCE), you would use "warpgen" tool (see Waba SDK) to package the .class files into .pdb file for Palm (.wrp for WinCE); use "exegen" to add initialization parameters to a launch .prc file for Palm (.lnk for WinCE).

To run this application in AppletViewer or in a web browser, if it consists of a single .class file, you can use it directly; if there are multiple .class files, combine then using the "jar" utility (see Java SDK) to create a .jar file (basically, a .zip file); you can provide initialization parameters via an APPLET tag in a .htm file (this may be necessary if your classpath does not include the core waba classes, i.e., waba.jar).

If you create a Newton .pkg file from any of these formats, it combines the .class files and initialization information in a single package.

For developing just for web and for Newton, it's probably easiest to use the .jar format (uncompressed!) (and someone else could always extract your .class files to recreate a different platform-specific format). Plus you can include icon.bmp and 'yourclass'.htm.

Each class entry contains a fully qualified class name, and the .class file itself. These sizes would be the same for all formats. What is different is the overall file overhead, and the header for each record; there may also be a little padding to next word/block boundary; N is number of classes.

Overhead in bytes	HelloWorld[1]	Scribble[3]		lib/Waba[39]
.class = 0			410				NA				NA
.wrp =  12 +  6*N	444				3081			45899
.pdb =  78 + 10*N	516				3161
.jar =  76 + 46*N	548				3348			49455

HelloWorld has 1 class (16 chars in name, 410 class bytes). Note: .class files are ~15% smaller if debugging information is omitted, i.e., javac -g:none

There is more overhead for .jar files, though for a small number of classes the size increase is probably worth the more standard/convenient format. For library archives that contain a large number of classes, e.g., lib/waba or lib/wextras, it might be best to use .wrp as the basis (when saving via WabaTester).

Valid HTML 4.01 Transitional