Use [GSModelLoaderFactory modelLoaderForData:] to generically implement methods that unarchive a model purely from data since we cannot use the file extension to determine which loader to instantiate.

This commit is contained in:
Gregory John Casamento 2021-04-24 08:51:32 -04:00
parent 0d3c3d1b2a
commit d9921efd8e
6 changed files with 138 additions and 16 deletions

View file

@ -1,3 +1,21 @@
2021-04-24 Gregory John Casamento <greg.casamento@gmail.com>
* Headers/Additions/GNUstepGUI/GSModelLoaderFactory.h:
Declaration of canReadData: in the GSModelLoader class and
declaration of modelLoaderForData: in GSModelLoaderFactory.
* Source/GSGModelLoader.m: Prototype method for canReadData:
Implementation of modelLoaderForData:.
* Source/GSGormLoader.m
* Source/GSModelLoaderFactory.m
* Source/GSNibLoader.m
* Source/GSXibLoader.m: Implement -canReadData: method to
determine for each loader if that loader can handle the data
passed into it.
* Source/NSNib.m: Use of [GSModelLoaderFactory modelLoaderForData:]
to more generically implement methods that initialize an archive from
archived data since we have no file extention to rely on to identify
the archive contents.
2021-04-23 Gregory John Casamento <greg.casamento@gmail.com>
* Source/Functions.m: QuickFix. Remove unecessary warning

View file

@ -29,6 +29,7 @@
#import <Foundation/NSArray.h>
#import <Foundation/NSBundle.h>
#import <Foundation/NSDebug.h>
#import <Foundation/NSData.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSEnumerator.h>
#import <Foundation/NSException.h>
@ -80,6 +81,33 @@ Class gmodel_class(void)
// register for the gmodel type.
}
+ (BOOL) canReadData: (NSData *)theData
{
char *header = calloc(1024, sizeof(char));
if (header != NULL)
{
NSUInteger len = [theData length];
NSRange r = NSMakeRange(len - 1024, len - 1);
NSString *hdr = nil;
[theData getBytes: header
range: r];
hdr = [[NSString alloc] initWithBytes: header
length: 1024
encoding: NSUTF8StringEncoding];
AUTORELEASE(hdr);
if ([hdr containsString: @"GMModel"])
{
return YES;
}
free(header);
}
return NO;
}
+ (NSString *) type
{
return @"gmodel";
@ -119,7 +147,7 @@ Class gmodel_class(void)
if ([ext isEqualToString: @"gmodel"])
{
return [gmodel_class() loadIMFile: fileName
owner: [context objectForKey: NSNibOwner]];
owner: [context objectForKey: NSNibOwner]];
}
return NO;

View file

@ -81,6 +81,26 @@
}
}
+ (BOOL) canReadData: (NSData *)theData
{
char *header = calloc(16, sizeof(char));
if (header != NULL)
{
[theData getBytes: header
length: 16];
if (strncmp("GNUstep archive",header,15) == 0)
{
return YES;
}
free(header);
}
return NO;
}
+ (NSString *)type
{
return @"gorm";

View file

@ -49,6 +49,39 @@
// should do something...
}
+ (BOOL) canReadData: (NSData *)theData
{
char *header = calloc(1024, sizeof(char));
if (header != NULL)
{
[theData getBytes: header
length: 1024];
if (strncmp("bplist00",header,8) == 0)
{
free(header);
return YES;
}
else
{
NSString *hdr = [[NSString alloc] initWithBytes: header
length: 1024
encoding: NSUTF8StringEncoding];
AUTORELEASE(hdr);
if ([hdr containsString: @"NSKeyedArchiver"])
{
free(header);
return YES;
}
}
free(header);
}
return NO;
}
+ (NSString *)type
{
return @"nib";

View file

@ -70,6 +70,31 @@
@implementation GSXibLoader
+ (BOOL) canReadData: (NSData *)theData
{
char *header = calloc(1024, sizeof(char));
if (header != NULL)
{
[theData getBytes: header
length: 1024];
NSString *hdr = [[NSString alloc] initWithBytes: header
length: 1024
encoding: NSUTF8StringEncoding];
AUTORELEASE(hdr);
if ([hdr containsString: @"Cocoa.XIB"])
{
free(header);
return YES;
}
free(header);
}
return NO;
}
+ (NSString*) type
{
return @"xib";

View file

@ -150,8 +150,7 @@
{
ASSIGN(_bundle, bundle);
ASSIGN(_nibData, nibData);
// FIXME: Hardcode the most likely loader
ASSIGN(_loader, [GSModelLoaderFactory modelLoaderForFileType: @"nib"]);
ASSIGN(_loader, [GSModelLoaderFactory modelLoaderForData: nibData]);
}
return self;
}
@ -178,7 +177,7 @@
- (BOOL) instantiateNibWithExternalNameTable: (NSDictionary *)externalNameTable
{
return [self instantiateNibWithExternalNameTable: externalNameTable
withZone: NSDefaultMallocZone()];
withZone: NSDefaultMallocZone()];
}
/**
@ -198,7 +197,8 @@
if (topLevelObjects != 0)
{
*topLevelObjects = [NSMutableArray array];
[externalNameTable setObject: *topLevelObjects forKey: NSNibTopLevelObjects];
[externalNameTable setObject: *topLevelObjects
forKey: NSNibTopLevelObjects];
}
return [self instantiateNibWithExternalNameTable: externalNameTable];
@ -207,32 +207,30 @@
- (BOOL) instantiateWithOwner: (id)owner
topLevelObjects: (NSArray **)topLevelObjects
{
return [self instantiateNibWithOwner: owner topLevelObjects: topLevelObjects];
return [self instantiateNibWithOwner: owner
topLevelObjects: topLevelObjects];
}
- (id) initWithCoder: (NSCoder *)coder
{
if ((self = [super init]) != nil)
{
//
// NOTE: This is okay, since the only encodings which will ever be built into
// the gui library are nib and gorm. GModel only supports certain
// objects and is going to be deprecated in the future. There just so
// happens to be a one to one correspondence here.
//
if ([coder allowsKeyedCoding])
{
// TODO_NIB: Need to verify this key...
// TODO_NIB: Need to verify this key...
ASSIGN(_nibData, [coder decodeObjectForKey: @"NSData"]);
ASSIGN(_loader, [GSModelLoaderFactory modelLoaderForFileType: @"nib"]);
}
else
{
// this is sort of a kludge...
[coder decodeValueOfObjCType: @encode(id)
at: &_nibData];
ASSIGN(_loader, [GSModelLoaderFactory modelLoaderForFileType: @"gorm"]);
at: &_nibData];
}
if (_nibData != nil)
{
ASSIGN(_loader, [GSModelLoaderFactory modelLoaderForData: _nibData]);
}
}
return self;
}