Skip to content

Commit

Permalink
Extend LSTB/LSTE to also handle LSTZ-style zero-terminated lists.
Browse files Browse the repository at this point in the history
  • Loading branch information
uliwitness committed Aug 16, 2003
1 parent eb2527c commit 04e81cb
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 10 deletions.
2 changes: 2 additions & 0 deletions NuTemplateEditor/NuTemplateLSTBElement.h
Expand Up @@ -2,6 +2,8 @@
// NuTemplateLSTBElement.h
// ResKnife (PB2)
//
// Implements LSTB and LSTZ fields.
//
// Created by Uli Kusterer on Tue Aug 05 2003.
// Copyright (c) 2003 M. Uli Kusterer. All rights reserved.
//
Expand Down
37 changes: 35 additions & 2 deletions NuTemplateEditor/NuTemplateLSTBElement.m
Expand Up @@ -2,6 +2,8 @@
// NuTemplateLSTBElement.m
// ResKnife (PB2)
//
// Implements LSTB and LSTZ fields.
//
// Created by Uli Kusterer on Tue Aug 05 2003.
// Copyright (c) 2003 M. Uli Kusterer. All rights reserved.
//
Expand All @@ -28,33 +30,63 @@ -(void) readSubElementsFrom: (NuTemplateStream*)stream
if( [[obj type] isEqualToString: @"LSTE"] )
{
endElement = [obj retain];
if( [type isEqualToString: @"LSTZ"] )
[endElement setWritesZeroByte:YES];
break;
}
[subElements addObject: obj];
}
}


-(void) readDataForElements: (NuTemplateStream*)stream
{
NSEnumerator *enny = [subElements objectEnumerator];
NuTemplateElement *el;

while( el = [enny nextObject] )
{
[el readDataFrom: stream];
}
}


-(void) readDataFrom: (NuTemplateStream*)stream
{
BOOL isZeroTerminated = [type isEqualToString: @"LSTZ"];
NSEnumerator *enny = [subElements objectEnumerator];
NuTemplateElement *el, *nextItem;
unsigned int bytesToGoAtStart = [stream bytesToGo];
char termByte = 0;

/* Fill this first list element with data:
If there is no more data in the stream, the items will
fill themselves with default values. */
while( el = [enny nextObject] )
if( isZeroTerminated )
{
[el readDataFrom: stream];
termByte = 0;
[stream peekAmount:1 toBuffer:&termByte]; // "Peek" doesn't change the read offset.
if( termByte != 0 )
[self readDataForElements: stream];
}
else
[self readDataForElements: stream];

/* Read additional elements until we have enough items,
except if we're not the first item in our list. */
if( containing != nil )
{
while( [stream bytesToGo] > 0 )
{
if( isZeroTerminated ) // Is zero-terminated list? Check whether there is a termination byte.
{
termByte = 0;
[stream peekAmount:1 toBuffer:&termByte]; // "Peek" doesn't change the read offset.
if( termByte == 0 )
break; // No need to actually read the peeked byte, LSTE will do that.
}

// Actually read the item:
nextItem = [[self copy] autorelease]; // Make another list item just like this one.
[nextItem setContaining: nil]; // Make sure it doesn't get into this "if" clause.
[containing addObject: nextItem]; // Add it below ourselves.
Expand All @@ -68,6 +100,7 @@ -(void) readDataFrom: (NuTemplateStream*)stream
[containing addObject: tlee];
[tlee setContaining: containing];
[tlee setGroupElemTemplate: self];
[tlee readDataFrom: stream]; // If LSTE has data to read (e.g. if we're an LSTZ, the terminating byte), let it do that!

if( bytesToGoAtStart == 0 ) // It's an empty list. Delete this LSTB again, so we only have the empty LSTE.
{
Expand Down
4 changes: 4 additions & 0 deletions NuTemplateEditor/NuTemplateLSTEElement.h
Expand Up @@ -13,10 +13,14 @@
@interface NuTemplateLSTEElement : NuTemplateGroupElement
{
NuTemplateGroupElement* groupElemTemplate; // The item of which we're to create a copy.
BOOL writesZeroByte; // Write a terminating zero-byte when writing out this item (used by LSTZ).
}

-(IBAction) showCreateResourceSheet: (id)sender;

-(void) setWritesZeroByte: (BOOL)n;
-(BOOL) writesZeroByte;

-(void) setGroupElemTemplate: (NuTemplateGroupElement*)e;
-(NuTemplateGroupElement*) groupElemTemplate;

Expand Down
28 changes: 21 additions & 7 deletions NuTemplateEditor/NuTemplateLSTEElement.m
Expand Up @@ -40,25 +40,27 @@ -(void) readSubElementsFrom: (NuTemplateStream*)stream

-(void) readDataFrom: (NuTemplateStream*)stream
{
NSEnumerator* enny = [subElements objectEnumerator];
NuTemplateElement* el;

while( el = [enny nextObject] )
if( writesZeroByte )
{
[el readDataFrom: stream];
char termByte;
[stream readAmount:1 toBuffer: &termByte];
}
}


// Doesn't write any sub-elements because this is simply a placeholder to allow for empty lists:
-(unsigned int) sizeOnDisk
{
return 0;
return writesZeroByte ? 1 : 0;
}

-(void) writeDataTo: (NuTemplateStream*)stream
{

if( writesZeroByte )
{
char fillByte = 0;
[stream writeAmount:sizeof(fillByte) fromBuffer: &fillByte];
}
}


Expand All @@ -74,11 +76,23 @@ -(NSString*) stringValue
}


-(void) setWritesZeroByte: (BOOL)n
{
writesZeroByte = n;
}

-(BOOL) writesZeroByte
{
return writesZeroByte;
}


-(id) copyWithZone: (NSZone*)zone
{
NuTemplateLSTEElement* el = [super copyWithZone: zone];

[el setGroupElemTemplate: [self groupElemTemplate]];
[el setWritesZeroByte: [self writesZeroByte]];

return el;
}
Expand Down
1 change: 1 addition & 0 deletions NuTemplateEditor/NuTemplateStream.h
Expand Up @@ -31,6 +31,7 @@

-(NuTemplateElement*) readOneElement; // For parsing of 'TMPL' resource as template.
-(void) readAmount: (unsigned int)l toBuffer: (void*)buf; // For reading data from the resource.
-(void) peekAmount: (unsigned int)l toBuffer: (void*)buf; // For examining data w/o advancing the read/write mark.

-(void) writeAmount: (unsigned int)l fromBuffer: (void*)buf; // For writing data back to the resource.

Expand Down
10 changes: 10 additions & 0 deletions NuTemplateEditor/NuTemplateStream.m
Expand Up @@ -108,6 +108,16 @@ -(void) readAmount: (unsigned int)l toBuffer: (void*)buf
}


-(void) peekAmount: (unsigned int)l toBuffer: (void*)buf
{
if( l > bytesToGo )
l = bytesToGo;

if( l > 0 )
memmove( buf, data, l );
}


-(void) writeAmount: (unsigned int)l fromBuffer: (void*)buf
{
if( l > bytesToGo )
Expand Down
1 change: 1 addition & 0 deletions NuTemplateEditor/NuTemplateWindowController.h
Expand Up @@ -53,6 +53,7 @@
-(IBAction) copy: (id)sender;
-(IBAction) paste: (id)sender;
-(IBAction) clear: (id)sender;
-(IBAction) saveDocument: (id)sender;


@end
9 changes: 9 additions & 0 deletions NuTemplateEditor/NuTemplateWindowController.m
Expand Up @@ -193,6 +193,7 @@ -(void) readTemplate: (id <ResKnifeResourceProtocol>)tmplRes
if( [fieldReg count] == 0 )
{
[fieldReg setObject: [NuTemplateLSTBElement class] forKey: @"LSTB"];
[fieldReg setObject: [NuTemplateLSTBElement class] forKey: @"LSTZ"];
[fieldReg setObject: [NuTemplateLSTEElement class] forKey: @"LSTE"];
[fieldReg setObject: [NuTemplateTNAMElement class] forKey: @"TNAM"];
[fieldReg setObject: [NuTemplatePSTRElement class] forKey: @"PSTR"];
Expand Down Expand Up @@ -328,6 +329,8 @@ -(BOOL) validateMenuItem: (NSMenuItem*)item
return( [selElement validateMenuItem: item] );
else if( [item action] == @selector(clear:) )
return( selElement != nil && [selElement respondsToSelector: @selector(clear:)] );
else if( [item action] == @selector(saveDocument:) )
return YES;
else return NO;
}

Expand All @@ -342,6 +345,12 @@ -(void) windowDidResignKey: (NSNotification*)notification
}


-(IBAction) saveDocument: (id)sender
{
[self writeResData];
}


-(BOOL) windowShouldClose: (id)sender // Window delegate.
{
[self writeResData]; // Save resource.
Expand Down
4 changes: 3 additions & 1 deletion TODO.txt
@@ -1,3 +1,5 @@
-> "Open as Hex" displays "(null)" as the document name. Why?
-> Changing the type/creator of a file isn't written to disk by ResourceDocument.
-> Create small versions of the doc icons in Photoshop instead of letting IconComposer use its cheap scaling on them.
-> Create small versions of the doc icons in Photoshop instead of letting IconComposer use its cheap scaling on them.
-> Auto-uncollapse list items in template editor when they are created and when a resource is opened.
-> Template editor should maintain "dirty" flag for resource.

0 comments on commit 04e81cb

Please sign in to comment.