/*!
@header BDBDatabaseEntry
@abstract BDB
@availability OS X, GNUstep
@copyright (C) 2004, 2005, 2006 Oliver Langer
Author: Oliver Langer
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-------------------------------------------------------------------------
Modification history
03.01.2005 ola initial version
22.08.2006 ola license changed
-------------------------------------------------------------------------
*/
#include
/**
* Key used to store the data of an entry
*/
#define __archiveKey @"__BDBDatabaseEntry"
/*!
* @enum __deserialization_method_t
* @abstract Stores information at the beginning of each NSData block which
* tells this implementation, how the NSData should be handled in order to
* return the correct object via the method "object"
* @constant SER_METHOD_NONE No serialization has been used. That is, an
* instance of NSData has originally been hand-off and has to be returned.
* @constant SER_METHOD_KEYED_ARCHIVER NSKeyedArchiver has to be used for
* deserialization.
*/
enum __deserialization_method_t {
SER_METHOD_NONE = 0,
SER_METHOD_KEYED_ARCHIVER
//SER_METHOD_BINARY_ARCHIVER
};
@implementation BDBDatabaseEntry
- initWithObject: (id ) object {
self = [super init];
EC_AUTORELEASEPOOL_BEGIN
if( [((NSObject *) object) isKindOfClass: [NSData class]] ) {
[self setData: ((NSData *) object)
usedSerializationMethod: SER_METHOD_NONE];
} else {
NSKeyedArchiver *archiver;
NSMutableData *objData = [[[NSMutableData alloc] init] autorelease];
archiver = [[[NSKeyedArchiver alloc]
initForWritingWithMutableData: objData]
autorelease];
[archiver
encodeObject: object
forKey: __archiveKey];
[archiver finishEncoding];
[self setData: objData usedSerializationMethod: SER_METHOD_KEYED_ARCHIVER];
}
return self;
EC_AUTORELEASEPOOL_END
}
- (NSData *) dataWithDeserializationMethodInfo: (int *) deserializationInfo {
NSData *data;
NSData *toReturn = nil;
int tmp;
data = [self data];
if( nil != data ) {
NSRange userDataRange;
// read hint about deserialization method first, then the rest:
[data getBytes: &tmp length: sizeof(int)];
if( NULL != deserializationInfo ) {
*deserializationInfo = tmp;
}
userDataRange.location = sizeof(int);
userDataRange.length = [data length] - sizeof(int);
if( 0 < userDataRange.length ) {
toReturn = [data subdataWithRange: userDataRange];
}
} else {
if( NULL != deserializationInfo ) {
*deserializationInfo = SER_METHOD_NONE;
}
}
return toReturn;
}
- object {
id toReturn = nil;
int deserializationInfo;
NSData *userData;
/**
* Does not run under GS:
NS_DURING
toReturn = [ NSUnarchiver unarchiveObjectWithData: [ self data ] ];
NS_HANDLER
NSLog( @"BDBDatabaseEntry::object: gotException %@",
[localException name] );
[localException raise];
NS_ENDHANDLER
*/
userData = [self dataWithDeserializationMethodInfo: &deserializationInfo];
if( nil != userData ) {
if( SER_METHOD_NONE == deserializationInfo ) {
toReturn = userData;
} else
if( SER_METHOD_KEYED_ARCHIVER == deserializationInfo ) {
NSKeyedUnarchiver *unarchiver;
unarchiver = [[[NSKeyedUnarchiver alloc]
initForReadingWithData: userData]
autorelease];
toReturn = [unarchiver decodeObjectForKey: __archiveKey];
[unarchiver finishDecoding];
} else {
[[[ECIllegalStateException alloc]
initWithIllegalStateInfo: @"BDBDatabaseEntry::object: Data buffer "\
"contains unknown flag value at offset 0"] raise];
}
}
return toReturn;
}
- setData: (NSData *) dataToSet
usedSerializationMethod: (int) serializationMethod {
NSMutableData *data = [[NSMutableData init] alloc];
[data appendBytes: &serializationMethod length: sizeof(int)];
[data appendData: dataToSet];
[self setData: data];
[data release];
return self;
}
@end