[sword-devel] To DM and Troy: Questions about making a module , an extract byte

Troy A. Griffitts scribe at crosswire.org
Sat Aug 25 01:53:40 MST 2007

Dear Zj Li,

If you are looking to write sword modules, the only supported way is to 
use the SWORD engine.  We neither encourage nor support manipulation of 
the data files directly.  Not to thwart your efforts, but can you not 
merely use a few simple calls to the sword engine to write your data? 
There is a very short, basic console application for interactively 
writing genbook data here:


It exercises every function of genbook editing.  If you cannot call the 
C++ engine directly or through any of the many binding swig produces, 
you should easily be able to change the interactive menu at the bottom 
of this short program into command line parameters, creating a simple 
utility you can call from your application.

Regarding your specific question.  The null which separates the node 
name from user data associated with the node is written here:

void TreeKeyIdx::saveTreeNode(TreeNode *node) {
		datfd->write(node->name, strlen(node->name));
		char null = 0;
		datfd->write(&null, 1);

Which is actually silly; all three lines should be reduced to:

		datfd->write(node->name, strlen(node->name)+1);

But I guess it does read easier the current way.

Blessings in your work for our Lord!

DM Smith wrote:
> JZ,
> I'll have to leave the answer to Troy to answer. I don't know the  
> original reason. My guess would be that it was influenced by C where  
> a byte with a 0 value is a string terminator. Rather than storing a  
> length byte the data starts at the expected location and stops when 0  
> is encountered.
> May I ask why you want to know this? Is there a bug to fix or a  
> feature you would like to add?
> DM
> On Aug 24, 2007, at 1:32 PM, ZJ Li wrote:
>> DM ,
>> I notice that for genbook, we have the following code to read dat  
>> file:
>>  byte[] buffer = SwordUtil.readRAF(datRaf, offset, 12);
>>        node.setParent(SwordUtil.decodeLittleEndian32(buffer, 0));
>>        node.setNextSibling(SwordUtil.decodeLittleEndian32(buffer, 4));
>>        node.setFirstChild(SwordUtil.decodeLittleEndian32(buffer, 8));
>>        buffer = SwordUtil.readUntilRAF(datRaf, (byte) 0);
>>        int size = buffer.length;
>>        if (buffer[size - 1] == 0)
>>        {
>>            size--;
>>        }
>>        Key key = new DefaultKeyList(null, bmd.getName());
>>        // Some of the keys have extraneous whitespace, so remove it.
>>        node.setName(SwordUtil.decode(key, buffer, size,
>> bmd.getBookCharset()).trim());
>>        buffer = SwordUtil.readNextRAF(datRaf, 2);
>> at this line:
>>   buffer = SwordUtil.readUntilRAF(datRaf, (byte) 0);
>> we look for the byte 0 for stop position. so we can get the node name
>> from data file.
>> My question is did we originally put this extract byte after the name?
>> Troy, can you confirm this?
>> Thx.
> _______________________________________________
> sword-devel mailing list: sword-devel at crosswire.org
> http://www.crosswire.org/mailman/listinfo/sword-devel
> Instructions to unsubscribe/change your settings at above page

More information about the sword-devel mailing list