*************************** SDStoreDirectory.h **************************
@interface SDStoreDirectory:NSObject
{
NSMutableDictionary *entries;
SDStore *storeFile;
BOOL dirty;
int blockNumber;
}
- initInStore:(SDStore *)aStoreFile;
- (id) initFromBlock: (unsigned int) blockNo inStore: (SDStore *) aStoreFile ;
- (id) openEntryNamed: (NSString *)aName ;
- (BOOL) hasEntryNamed: (NSString *)aName ;
- (id) addEntryNamed: (NSString *)aName ofClass:(Class)aClass ;
- (void) freeEntryNamed: (NSString *)aName;
- (NSArray *) entries;
- (void) getBlock:(unsigned int *)aBlock andStore:(SDStore **)aStore;
- (void) commitTransaction;
@end
*************************** SDStoreDirectory.m **************************
#import "ixCover.h"
@interface SDStoreDirectory(PrivateMethods)
- (void)setStore:(SDStore *)aStore;
@end
@implementation SDStoreDirectory:NSObject
///////////////////////////////////////////////////////////////////////////
//
// Utilities and private methods
//
///////////////////////////////////////////////////////////////////////////
- (BOOL) isDirty
{
return dirty;
}
- (void) setDirty:(BOOL)flag
{
dirty = flag;
}
///////////////////////////////////////////////////////////////////////////
//
// Implementation:
// NSDictionary to hold NSString (name) / NSEntry pairs
// NSEntry holds information necessary to create or read in
// an object
//
///////////////////////////////////////////////////////////////////////////
- initInStore:(SDStore *)aStore
{
[super init];
[self setStore:aStore];
entries = [[NSMutableDictionary allocWithZone:[self zone]] initWithCapacity:1];
[storeFile createBlock:&blockNumber withSize:0];
return self;
}
- initFromBlock: (unsigned int)blockNo inStore: (SDStore *) aStoreFile
{
NSData *blockData;
NSEnumerator *enumerator;
SDEntry *anEntry;
[super init];
[self setStore:aStoreFile];
blockNumber = blockNo;
blockData = [storeFile readBlock:blockNumber];
entries = [[NSUnarchiver unarchiveObjectWithData:blockData]retain];
enumerator = [entries objectEnumerator];
while ((anEntry = [enumerator nextObject])) {
[anEntry setStoreFile:storeFile];
}
[self setDirty:NO];
return self;
}
- (id) openEntryNamed: (NSString *)aName
{
SDEntry *theEntry = [entries objectForKey:aName];
if (!theEntry) return nil;
return [theEntry theObject];
}
- (BOOL) hasEntryNamed: (NSString *)aName
{
SDEntry *theEntry = [entries objectForKey:aName];
return theEntry?YES:NO;
}
- (id) addEntryNamed: (NSString *)aName ofClass:(Class)aClass
{
SDEntry *theEntry;
theEntry = [[SDEntry alloc] initWithName:aName class:aClass forStoreFile:storeFile];
[entries setObject:theEntry forKey:aName];
[self setDirty:YES];
return [theEntry theObject];
}
- (void) freeEntryNamed: (NSString *)aName
{
SDEntry *theEntry = [[entries objectForKey:aName] retain];
// remove the entry
[entries removeObjectForKey:aName];
// remove the "block"
[theEntry freeObjectFromBlock];
[theEntry release];
[self setDirty:YES];
}
- (void) commitTransaction
{
NSData *data;
if ([self isDirty]) {
data = [NSArchiver archivedDataWithRootObject:entries];
[storeFile writeData:data toBlock:blockNumber];
[self setDirty:NO];
}
}
- (NSArray *) entries
{
return [entries allKeys];
}
- (void) getBlock:(unsigned int *)aBlock andStore:(SDStore **)aStore
{
*aBlock = blockNumber;
*aStore = storeFile;
}
+ (void) freeFromBlock:(unsigned int) aBlockNumber inStore:(SDStore *)aStoreFile
{
[aStoreFile freeBlock:aBlockNumber];
}
- (void) freeFromStore
{
[storeFile freeBlock:blockNumber];
}
- (void) commitTransaction:(NSNotification *)aNotification
{
if ([aNotification object] == storeFile)
[self commitTransaction];
}
- (void)registerForTransactions
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commitTransaction:) name: SDStoreTransactionWasCommitted object:storeFile];
}
- (void) unregisterForTransactions
{
[[NSNotificationCenter defaultCenter]removeObserver:self name:SDStoreTransactionWasCommitted object:storeFile];
}
- (void)setStore:(SDStore *)aStore
{
storeFile = aStore;
[self registerForTransactions];
}
- (void) dealloc
{
[self unregisterForTransactions];
[entries release];
[super dealloc];
}
@end
|