mirror of
https://github.com/nickshanks/ResKnife.git
synced 2024-09-28 18:55:29 +00:00
Extend LSTB/LSTE to also handle LSTZ-style zero-terminated lists.
This commit is contained in:
parent
eb2527cf0f
commit
04e81cb47d
@ -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.
|
||||
//
|
||||
|
@ -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.
|
||||
//
|
||||
@ -28,6 +30,8 @@
|
||||
if( [[obj type] isEqualToString: @"LSTE"] )
|
||||
{
|
||||
endElement = [obj retain];
|
||||
if( [type isEqualToString: @"LSTZ"] )
|
||||
[endElement setWritesZeroByte:YES];
|
||||
break;
|
||||
}
|
||||
[subElements addObject: obj];
|
||||
@ -35,19 +39,38 @@
|
||||
}
|
||||
|
||||
|
||||
-(void) readDataFrom: (NuTemplateStream*)stream
|
||||
-(void) readDataForElements: (NuTemplateStream*)stream
|
||||
{
|
||||
NSEnumerator *enny = [subElements objectEnumerator];
|
||||
NuTemplateElement *el, *nextItem;
|
||||
unsigned int bytesToGoAtStart = [stream bytesToGo];
|
||||
NuTemplateElement *el;
|
||||
|
||||
/* 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] )
|
||||
{
|
||||
[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. */
|
||||
if( isZeroTerminated )
|
||||
{
|
||||
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. */
|
||||
@ -55,6 +78,15 @@
|
||||
{
|
||||
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.
|
||||
@ -68,6 +100,7 @@
|
||||
[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.
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -40,12 +40,10 @@
|
||||
|
||||
-(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];
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,12 +51,16 @@
|
||||
// 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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -74,11 +76,23 @@
|
||||
}
|
||||
|
||||
|
||||
-(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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
||||
|
@ -108,6 +108,16 @@
|
||||
}
|
||||
|
||||
|
||||
-(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 )
|
||||
|
@ -53,6 +53,7 @@
|
||||
-(IBAction) copy: (id)sender;
|
||||
-(IBAction) paste: (id)sender;
|
||||
-(IBAction) clear: (id)sender;
|
||||
-(IBAction) saveDocument: (id)sender;
|
||||
|
||||
|
||||
@end
|
||||
|
@ -193,6 +193,7 @@
|
||||
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"];
|
||||
@ -328,6 +329,8 @@
|
||||
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;
|
||||
}
|
||||
|
||||
@ -342,6 +345,12 @@
|
||||
}
|
||||
|
||||
|
||||
-(IBAction) saveDocument: (id)sender
|
||||
{
|
||||
[self writeResData];
|
||||
}
|
||||
|
||||
|
||||
-(BOOL) windowShouldClose: (id)sender // Window delegate.
|
||||
{
|
||||
[self writeResData]; // Save resource.
|
||||
|
2
TODO.txt
2
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.
|
||||
-> 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.
|
Loading…
Reference in New Issue
Block a user