git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@22947 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2006-05-20 10:11:39 +00:00
parent 700375a98e
commit 80a769c27d

View file

@ -18,8 +18,7 @@
You should have received a copy of the GNU Library General Public You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA.
Boston, MA 02111 USA.
<title>NSSerializer class reference</title> <title>NSSerializer class reference</title>
$Date$ $Revision$ $Date$ $Revision$
@ -49,9 +48,21 @@
@class NSDataMalloc; @class NSDataMalloc;
@interface NSDataMalloc : NSObject // Help the compiler @interface NSDataMalloc : NSObject // Help the compiler
@end @end
@class GSInlineArray;
@class GSMutableArray; @class GSMutableArray;
@interface GSMutableArray : NSObject // Help the compiler @interface GSMutableArray : NSObject // Help the compiler
@end @end
@class GSCString;
@interface GSCString : NSObject // Help the compiler
@end
@class GSCBufferString;
@interface GSCBufferString : NSObject // Help the compiler
@end
@class GSUnicodeString;
@class GSUnicodeBufferString;
@interface GSUnicodeBufferString : NSObject // Help the compiler
@end
@class GSMutableString;
/* /*
* Setup for inline operation of string map tables. * Setup for inline operation of string map tables.
@ -112,9 +123,15 @@ static Class DataClass = 0;
static Class DateClass = 0; static Class DateClass = 0;
static Class DictionaryClass = 0; static Class DictionaryClass = 0;
static Class MutableDictionaryClass = 0; static Class MutableDictionaryClass = 0;
static Class CStringClass = 0;
static Class MStringClass = 0;
static Class StringClass = 0; static Class StringClass = 0;
static Class NumberClass = 0; static Class NumberClass = 0;
typedef struct {
@defs(GSString)
} *ivars;
typedef struct { typedef struct {
NSMutableData *data; NSMutableData *data;
void (*appImp)(NSData*,SEL,const void*,unsigned); void (*appImp)(NSData*,SEL,const void*,unsigned);
@ -179,87 +196,86 @@ serializeToInfo(id object, _NSSerializerInfo* info)
} }
c = GSObjCClass(object); c = GSObjCClass(object);
if (GSObjCIsKindOf(c, StringClass)) if ((GSObjCIsKindOf(c, CStringClass)
{ || (c == MStringClass && ((ivars)object)->_flags.wide == 0))
/* /*
We can only save it as a c-string if it only contains ASCII characters. We can only save it as a c-string if it only contains ASCII characters.
Other characters might be decoded incorrectly when deserialized since Other characters might be decoded incorrectly when deserialized since
the c-string encoding might be different then. the c-string encoding might be different then.
*/ */
if ([object canBeConvertedToEncoding: NSASCIIStringEncoding]) && [object canBeConvertedToEncoding: NSASCIIStringEncoding])
{
GSIMapNode node;
if (info->shouldUnique)
node = GSIMapNodeForKey(&info->map, (GSIMapKey)object);
else
node = 0;
if (node == 0)
{ {
GSIMapNode node; unsigned slen;
unsigned dlen;
slen = [object length] + 1;
(*info->appImp)(info->data, appSel, &st_cstring, 1);
(*info->serImp)(info->data, serSel, slen);
dlen = (*info->lenImp)(info->data, lenSel);
(*info->setImp)(info->data, setSel, dlen + slen);
[object getCString: (*info->datImp)(info->data, datSel) + dlen
maxLength: slen
encoding: NSASCIIStringEncoding];
if (info->shouldUnique) if (info->shouldUnique)
node = GSIMapNodeForKey(&info->map, (GSIMapKey)object); GSIMapAddPair(&info->map,
else (GSIMapKey)object, (GSIMapVal)info->count++);
node = 0;
if (node == 0)
{
unsigned slen;
unsigned dlen;
slen = [object length] + 1;
(*info->appImp)(info->data, appSel, &st_cstring, 1);
(*info->serImp)(info->data, serSel, slen);
dlen = (*info->lenImp)(info->data, lenSel);
(*info->setImp)(info->data, setSel, dlen + slen);
[object getCString: (*info->datImp)(info->data, datSel) + dlen
maxLength: slen
encoding: NSASCIIStringEncoding];
if (info->shouldUnique)
GSIMapAddPair(&info->map,
(GSIMapKey)object, (GSIMapVal)info->count++);
}
else
{
(*info->appImp)(info->data, appSel, &st_xref, 1);
(*info->serImp)(info->data, serSel, node->value.uint);
}
} }
else else
{ {
GSIMapNode node; (*info->appImp)(info->data, appSel, &st_xref, 1);
(*info->serImp)(info->data, serSel, node->value.uint);
}
}
else if (GSObjCIsKindOf(c, StringClass))
{
GSIMapNode node;
if (info->shouldUnique) if (info->shouldUnique)
node = GSIMapNodeForKey(&info->map, (GSIMapKey)object); node = GSIMapNodeForKey(&info->map, (GSIMapKey)object);
else else
node = 0; node = 0;
if (node == 0) if (node == 0)
{ {
unsigned slen; unsigned slen;
unsigned dlen; unsigned dlen;
slen = [object length]; slen = [object length];
(*info->appImp)(info->data, appSel, &st_string, 1); (*info->appImp)(info->data, appSel, &st_string, 1);
(*info->serImp)(info->data, serSel, slen); (*info->serImp)(info->data, serSel, slen);
dlen = (*info->lenImp)(info->data, lenSel); dlen = (*info->lenImp)(info->data, lenSel);
(*info->setImp)(info->data, setSel, dlen + slen*sizeof(unichar)); (*info->setImp)(info->data, setSel, dlen + slen*sizeof(unichar));
#if NEED_WORD_ALIGNMENT #if NEED_WORD_ALIGNMENT
/* /*
* When packing data, an item may not be aligned on a * When packing data, an item may not be aligned on a
* word boundary, so we work with an aligned buffer * word boundary, so we work with an aligned buffer
* and use memcmpy() * and use memcmpy()
*/ */
if ((dlen % __alignof__(uint32_t)) != 0) if ((dlen % __alignof__(uint32_t)) != 0)
{ {
unichar buffer[slen]; unichar buffer[slen];
[object getCharacters: buffer]; [object getCharacters: buffer];
memcpy((*info->datImp)(info->data, datSel) + dlen, buffer, memcpy((*info->datImp)(info->data, datSel) + dlen, buffer,
slen*sizeof(unichar)); slen*sizeof(unichar));
}
else
#endif
[object getCharacters: (*info->datImp)(info->data, datSel)+dlen];
if (info->shouldUnique)
GSIMapAddPair(&info->map,
(GSIMapKey)object, (GSIMapVal)info->count++);
} }
else else
{ #endif
(*info->appImp)(info->data, appSel, &st_xref, 1); [object getCharacters: (*info->datImp)(info->data, datSel) + dlen];
(*info->serImp)(info->data, serSel, node->value.uint); if (info->shouldUnique)
} GSIMapAddPair(&info->map,
(GSIMapKey)object, (GSIMapVal)info->count++);
}
else
{
(*info->appImp)(info->data, appSel, &st_xref, 1);
(*info->serImp)(info->data, serSel, node->value.uint);
} }
} }
else if (GSObjCIsKindOf(c, ArrayClass)) else if (GSObjCIsKindOf(c, ArrayClass))
@ -365,6 +381,8 @@ static BOOL shouldBeCompact = NO;
DictionaryClass = [NSDictionary class]; DictionaryClass = [NSDictionary class];
MutableDictionaryClass = [NSMutableDictionary class]; MutableDictionaryClass = [NSMutableDictionary class];
StringClass = [NSString class]; StringClass = [NSString class];
CStringClass = [GSCString class];
MStringClass = [GSMutableString class];
} }
} }
@ -434,6 +452,8 @@ static BOOL uniquing = NO; /* Make incoming strings unique */
static Class MACls = 0; /* Mutable Array */ static Class MACls = 0; /* Mutable Array */
static Class DCls = 0; /* Data */ static Class DCls = 0; /* Data */
static Class MDCls = 0; /* Mutable Dictionary */ static Class MDCls = 0; /* Mutable Dictionary */
static Class USCls = 0; /* Unicode String */
static Class CSCls = 0; /* C String */
typedef struct { typedef struct {
NSData *data; NSData *data;
@ -447,11 +467,15 @@ typedef struct {
static SEL debSel; static SEL debSel;
static SEL deiSel; static SEL deiSel;
static SEL csInitSel;
static SEL usInitSel;
static SEL dInitSel; static SEL dInitSel;
static SEL maInitSel; static SEL maInitSel;
static SEL mdInitSel; static SEL mdInitSel;
static SEL maAddSel; static SEL maAddSel;
static SEL mdSetSel; static SEL mdSetSel;
static IMP csInitImp;
static IMP usInitImp;
static IMP dInitImp; static IMP dInitImp;
static IMP maInitImp; static IMP maInitImp;
static IMP mdInitImp; static IMP mdInitImp;
@ -540,16 +564,15 @@ deserializeFromInfo(_NSDeserializerInfo* info)
case ST_CSTRING: case ST_CSTRING:
{ {
NSString *s; GSCString *s;
char *b; char *b;
size = (*info->deiImp)(info->data, deiSel, info->cursor); size = (*info->deiImp)(info->data, deiSel, info->cursor);
b = NSZoneMalloc(NSDefaultMallocZone(), size); b = NSZoneMalloc(NSDefaultMallocZone(), size);
(*info->debImp)(info->data, debSel, b, size, info->cursor); (*info->debImp)(info->data, debSel, b, size, info->cursor);
s = [[StringClass alloc] initWithBytesNoCopy: b s = (GSCString*)NSAllocateObject(CSCls, 0, NSDefaultMallocZone());
length: size s = (*csInitImp)(s, csInitSel, b, size-1, YES);
encoding: NSASCIIStringEncoding
freeWhenDone: YES];
/* /*
* If we are supposed to be doing uniquing of strings, handle it. * If we are supposed to be doing uniquing of strings, handle it.
*/ */
@ -573,15 +596,41 @@ deserializeFromInfo(_NSDeserializerInfo* info)
{ {
NSString *s; NSString *s;
unichar *b; unichar *b;
unsigned i;
size = (*info->deiImp)(info->data, deiSel, info->cursor); size = (*info->deiImp)(info->data, deiSel, info->cursor);
b = NSZoneMalloc(NSDefaultMallocZone(), size*sizeof(unichar)); b = NSZoneMalloc(NSDefaultMallocZone(), size*sizeof(unichar));
(*info->debImp)(info->data, debSel, b, size*sizeof(unichar), (*info->debImp)(info->data, debSel, b, size*sizeof(unichar),
info->cursor); info->cursor);
s = [[StringClass alloc] initWithBytesNoCopy: b
length: size*sizeof(unichar) /*
encoding: NSUnicodeStringEncoding * Check to see if this really IS unicode ... if not, use a cString
freeWhenDone: YES]; */
for (i = 0; i < size; i++)
{
if (b[i] > 127)
{
break;
}
}
if (i == size)
{
char *p = (char*)b;
for (i = 0; i < size; i++)
{
p[i] = (char)b[i];
}
p = NSZoneRealloc(NSDefaultMallocZone(), b, size);
s = (NSString*)NSAllocateObject(CSCls, 0, NSDefaultMallocZone());
s = (*csInitImp)(s, csInitSel, p, size, YES);
}
else
{
s = (NSString*)NSAllocateObject(USCls, 0, NSDefaultMallocZone());
s = (*usInitImp)(s, usInitSel, b, size, YES);
}
/* /*
* If we are supposed to be doing uniquing of strings, handle it. * If we are supposed to be doing uniquing of strings, handle it.
*/ */
@ -808,6 +857,8 @@ deserializeFromInfo(_NSDeserializerInfo* info)
{ {
debSel = @selector(deserializeBytes:length:atCursor:); debSel = @selector(deserializeBytes:length:atCursor:);
deiSel = @selector(deserializeIntAtCursor:); deiSel = @selector(deserializeIntAtCursor:);
csInitSel = @selector(initWithCStringNoCopy:length:freeWhenDone:);
usInitSel = @selector(initWithCharactersNoCopy:length:freeWhenDone:);
dInitSel = @selector(initWithBytesNoCopy:length:); dInitSel = @selector(initWithBytesNoCopy:length:);
maInitSel = @selector(initWithCapacity:); maInitSel = @selector(initWithCapacity:);
mdInitSel = @selector(initWithCapacity:); mdInitSel = @selector(initWithCapacity:);
@ -816,6 +867,10 @@ deserializeFromInfo(_NSDeserializerInfo* info)
MACls = [GSMutableArray class]; MACls = [GSMutableArray class];
DCls = [NSDataMalloc class]; DCls = [NSDataMalloc class];
MDCls = [GSMutableDictionary class]; MDCls = [GSMutableDictionary class];
USCls = [GSUnicodeBufferString class];
CSCls = [GSCBufferString class];
csInitImp = [CSCls instanceMethodForSelector: csInitSel];
usInitImp = [USCls instanceMethodForSelector: usInitSel];
dInitImp = [DCls instanceMethodForSelector: dInitSel]; dInitImp = [DCls instanceMethodForSelector: dInitSel];
maInitImp = [MACls instanceMethodForSelector: maInitSel]; maInitImp = [MACls instanceMethodForSelector: maInitSel];
mdInitImp = [MDCls instanceMethodForSelector: mdInitSel]; mdInitImp = [MDCls instanceMethodForSelector: mdInitSel];