git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@3633 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 1999-02-01 12:05:15 +00:00
parent c0c45390f5
commit 2a46f64ffa
2 changed files with 612 additions and 456 deletions

View file

@ -1,7 +1,9 @@
Mon Feb 1 9:55:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk> Mon Feb 1 11:25:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* src/NSArray.m: ([-initWithContentsOfFile:]) Fixed memory leak. * src/NSArray.m: ([-initWithContentsOfFile:]) Fixed memory leak.
* src/NSDictionary.m: ([-initWithContentsOfFile:]) Fixed memory leak. * src/NSDictionary.m: ([-initWithContentsOfFile:]) Fixed memory leak.
* src/NSData.m: Tidied indentation and 64-bit clean serialization of
strings, classes, and selectors.
Sat Jan 30 5:55:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk> Sat Jan 30 5:55:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>

View file

@ -612,8 +612,14 @@ failure:
} }
case _C_CHARPTR: case _C_CHARPTR:
{ {
int length = [self deserializeIntAtCursor: cursor]; gss32 length;
[self deserializeBytes: &length
length: sizeof(length)
atCursor: cursor];
#ifndef GS_WORDS_BIGENDIAN
length = GSSwapI32(length);
#endif
if (length == -1) if (length == -1)
{ {
*(const char**)data = NULL; *(const char**)data = NULL;
@ -779,12 +785,14 @@ failure:
} }
case _C_CLASS: case _C_CLASS:
{ {
unsigned ni; gsu16 ni;
[self deserializeBytes: &ni [self deserializeBytes: &ni
length: sizeof(unsigned) length: sizeof(ni)
atCursor: cursor]; atCursor: cursor];
ni = NSSwapBigIntToHost(ni); #ifndef GS_WORDS_BIGENDIAN
ni = GSSwapI16(ni);
#endif
if (ni == 0) if (ni == 0)
{ {
*(Class*)data = 0; *(Class*)data = 0;
@ -810,17 +818,21 @@ failure:
} }
case _C_SEL: case _C_SEL:
{ {
unsigned ln; gsu16 ln;
unsigned lt; gsu16 lt;
[self deserializeBytes: &ln [self deserializeBytes: &ln
length: sizeof(unsigned) length: sizeof(ln)
atCursor: cursor]; atCursor: cursor];
ln = NSSwapBigIntToHost(ln); #ifndef GS_WORDS_BIGENDIAN
ln = GSSwapI16(ln);
#endif
[self deserializeBytes: &lt [self deserializeBytes: &lt
length: sizeof(unsigned) length: sizeof(lt)
atCursor: cursor]; atCursor: cursor];
lt = NSSwapBigIntToHost(lt); #ifndef GS_WORDS_BIGENDIAN
lt = GSSwapI16(lt);
#endif
if (ln == 0) if (ln == 0)
{ {
*(SEL*)data = 0; *(SEL*)data = 0;
@ -1223,37 +1235,53 @@ failure:
if (!data || !type) if (!data || !type)
return; return;
switch (*type) { switch (*type)
{
case _C_ID: case _C_ID:
[callback serializeObjectAt: (id*)data [callback serializeObjectAt: (id*)data
ofObjCType: type ofObjCType: type
intoData: self]; intoData: self];
return; return;
case _C_CHARPTR: { case _C_CHARPTR:
int len; {
unsigned len;
gss32 ni;
if (!*(void**)data) { if (!*(void**)data)
[self serializeInt: -1]; {
ni = -1;
#ifndef GS_WORDS_BIGENDIAN
ni = GSSwapI32(ni);
#endif
[self appendBytes: (void*)&ni length: sizeof(ni)];
return; return;
} }
len = strlen(*(void**)data); len = strlen(*(void**)data);
[self serializeInt: len]; #ifndef GS_WORDS_BIGENDIAN
ni = GSSwapI32(len);
#else
ni = len;
#endif
[self appendBytes: (void*)&ni length: sizeof(ni)];
[self appendBytes: *(void**)data length: len]; [self appendBytes: *(void**)data length: len];
return; return;
} }
case _C_ARY_B: { case _C_ARY_B:
{
unsigned offset = 0; unsigned offset = 0;
unsigned size; unsigned size;
unsigned count = atoi(++type); unsigned count = atoi(++type);
unsigned i; unsigned i;
while (isdigit(*type)) { while (isdigit(*type))
{
type++; type++;
} }
size = objc_sizeof_type(type); size = objc_sizeof_type(type);
for (i = 0; i < count; i++) { for (i = 0; i < count; i++)
{
[self serializeDataAt: (char*)data + offset [self serializeDataAt: (char*)data + offset
ofObjCType: type ofObjCType: type
context: callback]; context: callback];
@ -1261,18 +1289,21 @@ failure:
} }
return; return;
} }
case _C_STRUCT_B: { case _C_STRUCT_B:
{
int offset = 0; int offset = 0;
int align, rem; int align, rem;
while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */ while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */
for (;;) { for (;;)
{
[self serializeDataAt: ((char*)data) + offset [self serializeDataAt: ((char*)data) + offset
ofObjCType: type ofObjCType: type
context: callback]; context: callback];
offset += objc_sizeof_type(type); offset += objc_sizeof_type(type);
type = objc_skip_typespec(type); type = objc_skip_typespec(type);
if (*type != _C_STRUCT_E) { if (*type != _C_STRUCT_E)
{
align = objc_alignof_type(type); align = objc_alignof_type(type);
if ((rem = offset % align)) if ((rem = offset % align))
offset += align - rem; offset += align - rem;
@ -1291,26 +1322,30 @@ failure:
[self appendBytes: data length: sizeof(unsigned char)]; [self appendBytes: data length: sizeof(unsigned char)];
return; return;
case _C_SHT: case _C_SHT:
case _C_USHT: { case _C_USHT:
{
unsigned short ns = NSSwapHostShortToBig(*(unsigned short*)data); unsigned short ns = NSSwapHostShortToBig(*(unsigned short*)data);
[self appendBytes: &ns length: sizeof(unsigned short)]; [self appendBytes: &ns length: sizeof(unsigned short)];
return; return;
} }
case _C_INT: case _C_INT:
case _C_UINT: { case _C_UINT:
{
unsigned ni = NSSwapHostIntToBig(*(unsigned int*)data); unsigned ni = NSSwapHostIntToBig(*(unsigned int*)data);
[self appendBytes: &ni length: sizeof(unsigned)]; [self appendBytes: &ni length: sizeof(unsigned)];
return; return;
} }
case _C_LNG: case _C_LNG:
case _C_ULNG: { case _C_ULNG:
{
unsigned long nl = NSSwapHostLongToBig(*(unsigned long*)data); unsigned long nl = NSSwapHostLongToBig(*(unsigned long*)data);
[self appendBytes: &nl length: sizeof(unsigned long)]; [self appendBytes: &nl length: sizeof(unsigned long)];
return; return;
} }
#ifdef _C_LNG_LNG #ifdef _C_LNG_LNG
case _C_LNG_LNG: case _C_LNG_LNG:
case _C_ULNG_LNG: { case _C_ULNG_LNG:
{
unsigned long long nl; unsigned long long nl;
nl = NSSwapHostLongLongToBig(*(unsigned long long*)data); nl = NSSwapHostLongLongToBig(*(unsigned long long*)data);
@ -1318,43 +1353,64 @@ failure:
return; return;
} }
#endif #endif
case _C_FLT: { case _C_FLT:
{
NSSwappedFloat nf = NSSwapHostFloatToBig(*(float*)data); NSSwappedFloat nf = NSSwapHostFloatToBig(*(float*)data);
[self appendBytes: &nf length: sizeof(NSSwappedFloat)]; [self appendBytes: &nf length: sizeof(NSSwappedFloat)];
return; return;
} }
case _C_DBL: { case _C_DBL:
{
NSSwappedDouble nd = NSSwapHostDoubleToBig(*(double*)data); NSSwappedDouble nd = NSSwapHostDoubleToBig(*(double*)data);
[self appendBytes: &nd length: sizeof(NSSwappedDouble)]; [self appendBytes: &nd length: sizeof(NSSwappedDouble)];
return; return;
} }
case _C_CLASS: { case _C_CLASS:
{
const char *name = *(Class*)data?fastClassName(*(Class*)data):""; const char *name = *(Class*)data?fastClassName(*(Class*)data):"";
unsigned ln = strlen(name); gsu16 ln = (gsu16)strlen(name);
unsigned ni; gsu16 ni;
ni = NSSwapHostIntToBig(ln); #ifndef GS_WORDS_BIGENDIAN
[self appendBytes: &ni length: sizeof(unsigned)]; ni = GSSwapI16(ln);
if (ln) { #else
ni = ln;
#endif
[self appendBytes: &ni length: sizeof(ni)];
if (ln)
{
[self appendBytes: name length: ln]; [self appendBytes: name length: ln];
} }
return; return;
} }
case _C_SEL: { case _C_SEL:
{
const char *name = *(SEL*)data?fastSelectorName(*(SEL*)data):""; const char *name = *(SEL*)data?fastSelectorName(*(SEL*)data):"";
unsigned ln = strlen(name); gsu16 ln = (gsu16)strlen(name);
const char *types = *(SEL*)data?fastSelectorTypes(*(SEL*)data):""; const char *types = *(SEL*)data?fastSelectorTypes(*(SEL*)data):"";
unsigned lt = strlen(types); gsu16 lt = (gsu16)strlen(types);
unsigned ni; gsu16 ni;
ni = NSSwapHostIntToBig(ln); #ifndef GS_WORDS_BIGENDIAN
[self appendBytes: &ni length: sizeof(unsigned)]; ni = GSSwapI16(ln);
ni = NSSwapHostIntToBig(lt); #else
[self appendBytes: &ni length: sizeof(unsigned)]; ni = ln;
if (ln) { #endif
[self appendBytes: &ni length: sizeof(ni)];
#ifndef GS_WORDS_BIGENDIAN
ni = GSSwapI16(lt);
#else
ni = lt;
#endif
[self appendBytes: &ni length: sizeof(ni)];
if (ln)
{
[self appendBytes: name length: ln]; [self appendBytes: name length: ln];
} }
if (lt) { if (lt)
{
[self appendBytes: types length: lt]; [self appendBytes: types length: lt];
} }
return; return;
@ -1375,6 +1431,7 @@ failure:
{ {
unsigned ni = NSSwapHostIntToBig(value); unsigned ni = NSSwapHostIntToBig(value);
NSRange range = { index, sizeof(int) }; NSRange range = { index, sizeof(int) };
[self replaceBytesInRange: range withBytes: &ni]; [self replaceBytesInRange: range withBytes: &ni];
} }
@ -1385,7 +1442,8 @@ failure:
SEL sel = @selector(serializeInt:); SEL sel = @selector(serializeInt:);
IMP imp = [self methodForSelector: sel]; IMP imp = [self methodForSelector: sel];
for (i = 0; i < numInts; i++) { for (i = 0; i < numInts; i++)
{
(*imp)(self, sel, intBuffer[i]); (*imp)(self, sel, intBuffer[i]);
} }
} }
@ -1398,7 +1456,8 @@ failure:
SEL sel = @selector(serializeInt:atIndex:); SEL sel = @selector(serializeInt:atIndex:);
IMP imp = [self methodForSelector: sel]; IMP imp = [self methodForSelector: sel];
for (i = 0; i < numInts; i++) { for (i = 0; i < numInts; i++)
{
(*imp)(self, sel, intBuffer[i], index++); (*imp)(self, sel, intBuffer[i], index++);
} }
} }
@ -1628,30 +1687,46 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
atCursor: (unsigned*)cursor atCursor: (unsigned*)cursor
context: (id <NSObjCTypeSerializationCallBack>)callback context: (id <NSObjCTypeSerializationCallBack>)callback
{ {
if (data == 0 || type == 0) { if (data == 0 || type == 0)
if (data == 0) { {
if (data == 0)
{
NSLog(@"attempt to deserialize to a nul pointer"); NSLog(@"attempt to deserialize to a nul pointer");
} }
if (type == 0) { if (type == 0)
{
NSLog(@"attempt to deserialize with a nul type encoding"); NSLog(@"attempt to deserialize with a nul type encoding");
} }
return; return;
} }
switch (*type) { switch (*type)
case _C_ID: { {
[callback deserializeObjectAt: data ofObjCType: type case _C_ID:
fromData: self atCursor: cursor]; {
[callback deserializeObjectAt: data
ofObjCType: type
fromData: self
atCursor: cursor];
return; return;
} }
case _C_CHARPTR: { case _C_CHARPTR:
int len = [self deserializeIntAtCursor: cursor]; {
gss32 len;
if (len == -1) { [self deserializeBytes: &len
length: sizeof(len)
atCursor: cursor];
#ifndef GS_WORDS_BIGENDIAN
len = GSSwapI32(len);
#endif
if (len == -1)
{
*(const char**)data = NULL; *(const char**)data = NULL;
return; return;
} }
else { else
{
NSZone *z = [self zone]; NSZone *z = [self zone];
*(char**)data = (char*)NSZoneMalloc(z, len+1); *(char**)data = (char*)NSZoneMalloc(z, len+1);
@ -1664,18 +1739,21 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
(*(char**)data)[len] = '\0'; (*(char**)data)[len] = '\0';
return; return;
} }
case _C_ARY_B: { case _C_ARY_B:
{
unsigned offset = 0; unsigned offset = 0;
unsigned size; unsigned size;
unsigned count = atoi(++type); unsigned count = atoi(++type);
unsigned i; unsigned i;
while (isdigit(*type)) { while (isdigit(*type))
{
type++; type++;
} }
size = objc_sizeof_type(type); size = objc_sizeof_type(type);
for (i = 0; i < count; i++) { for (i = 0; i < count; i++)
{
[self deserializeDataAt: (char*)data + offset [self deserializeDataAt: (char*)data + offset
ofObjCType: type ofObjCType: type
atCursor: cursor atCursor: cursor
@ -1684,22 +1762,26 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
} }
return; return;
} }
case _C_STRUCT_B: { case _C_STRUCT_B:
{
int offset = 0; int offset = 0;
while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */ while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */
for (;;) { for (;;)
{
[self deserializeDataAt: ((char*)data) + offset [self deserializeDataAt: ((char*)data) + offset
ofObjCType: type ofObjCType: type
atCursor: cursor atCursor: cursor
context: callback]; context: callback];
offset += objc_sizeof_type(type); offset += objc_sizeof_type(type);
type = objc_skip_typespec(type); type = objc_skip_typespec(type);
if (*type != _C_STRUCT_E) { if (*type != _C_STRUCT_E)
{
int align = objc_alignof_type(type); int align = objc_alignof_type(type);
int rem = offset % align; int rem = offset % align;
if (rem != 0) { if (rem != 0)
{
offset += align - rem; offset += align - rem;
} }
} }
@ -1707,7 +1789,8 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
} }
return; return;
} }
case _C_PTR: { case _C_PTR:
{
unsigned len = objc_sizeof_type(++type); unsigned len = objc_sizeof_type(++type);
NSZone *z = [self zone]; NSZone *z = [self zone];
@ -1723,13 +1806,14 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
return; return;
} }
case _C_CHR: case _C_CHR:
case _C_UCHR: { case _C_UCHR:
getBytes(data, bytes, sizeof(unsigned char), {
length, cursor); getBytes(data, bytes, sizeof(unsigned char), length, cursor);
return; return;
} }
case _C_SHT: case _C_SHT:
case _C_USHT: { case _C_USHT:
{
unsigned short ns; unsigned short ns;
getBytes((void*)&ns, bytes, sizeof(ns), length, cursor); getBytes((void*)&ns, bytes, sizeof(ns), length, cursor);
@ -1737,7 +1821,8 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
return; return;
} }
case _C_INT: case _C_INT:
case _C_UINT: { case _C_UINT:
{
unsigned ni; unsigned ni;
getBytes((void*)&ni, bytes, sizeof(ni), length, cursor); getBytes((void*)&ni, bytes, sizeof(ni), length, cursor);
@ -1745,7 +1830,8 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
return; return;
} }
case _C_LNG: case _C_LNG:
case _C_ULNG: { case _C_ULNG:
{
unsigned long nl; unsigned long nl;
getBytes((void*)&nl, bytes, sizeof(nl), length, cursor); getBytes((void*)&nl, bytes, sizeof(nl), length, cursor);
@ -1754,7 +1840,8 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
} }
#ifdef _C_LNG_LNG #ifdef _C_LNG_LNG
case _C_LNG_LNG: case _C_LNG_LNG:
case _C_ULNG_LNG: { case _C_ULNG_LNG:
{
unsigned long long nl; unsigned long long nl;
getBytes((void*)&nl, bytes, sizeof(nl), length, cursor); getBytes((void*)&nl, bytes, sizeof(nl), length, cursor);
@ -1762,36 +1849,44 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
return; return;
} }
#endif #endif
case _C_FLT: { case _C_FLT:
{
NSSwappedFloat nf; NSSwappedFloat nf;
getBytes((void*)&nf, bytes, sizeof(nf), length, cursor); getBytes((void*)&nf, bytes, sizeof(nf), length, cursor);
*(float*)data = NSSwapBigFloatToHost(nf); *(float*)data = NSSwapBigFloatToHost(nf);
return; return;
} }
case _C_DBL: { case _C_DBL:
{
NSSwappedDouble nd; NSSwappedDouble nd;
getBytes((void*)&nd, bytes, sizeof(nd), length, cursor); getBytes((void*)&nd, bytes, sizeof(nd), length, cursor);
*(double*)data = NSSwapBigDoubleToHost(nd); *(double*)data = NSSwapBigDoubleToHost(nd);
return; return;
} }
case _C_CLASS: { case _C_CLASS:
unsigned ni; {
gsu16 ni;
getBytes((void*)&ni, bytes, sizeof(ni), length, cursor); getBytes((void*)&ni, bytes, sizeof(ni), length, cursor);
ni = NSSwapBigIntToHost(ni); #ifndef GS_WORDS_BIGENDIAN
if (ni == 0) { ni = GSSwapI16(ni);
#endif
if (ni == 0)
{
*(Class*)data = 0; *(Class*)data = 0;
} }
else { else
{
char name[ni+1]; char name[ni+1];
Class c; Class c;
getBytes((void*)name, bytes, ni, length, cursor); getBytes((void*)name, bytes, ni, length, cursor);
name[ni] = '\0'; name[ni] = '\0';
c = objc_get_class(name); c = objc_get_class(name);
if (c == 0) { if (c == 0)
{
[NSException raise: NSInternalInconsistencyException [NSException raise: NSInternalInconsistencyException
format: @"can't find class - %s", name]; format: @"can't find class - %s", name];
} }
@ -1799,18 +1894,25 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
} }
return; return;
} }
case _C_SEL: { case _C_SEL:
unsigned ln; {
unsigned lt; gsu16 ln;
gsu16 lt;
getBytes((void*)&ln, bytes, sizeof(ln), length, cursor); getBytes((void*)&ln, bytes, sizeof(ln), length, cursor);
ln = NSSwapBigIntToHost(ln); #ifndef GS_WORDS_BIGENDIAN
ln = GSSwapI16(ln);
#endif
getBytes((void*)&lt, bytes, sizeof(lt), length, cursor); getBytes((void*)&lt, bytes, sizeof(lt), length, cursor);
lt = NSSwapBigIntToHost(lt); #ifndef GS_WORDS_BIGENDIAN
if (ln == 0) { lt = GSSwapI16(lt);
#endif
if (ln == 0)
{
*(SEL*)data = 0; *(SEL*)data = 0;
} }
else { else
{
char name[ln+1]; char name[ln+1];
char types[lt+1]; char types[lt+1];
SEL sel; SEL sel;
@ -1820,13 +1922,16 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
getBytes((void*)types, bytes, lt, length, cursor); getBytes((void*)types, bytes, lt, length, cursor);
types[lt] = '\0'; types[lt] = '\0';
if (lt) { if (lt)
{
sel = sel_get_typed_uid(name, types); sel = sel_get_typed_uid(name, types);
} }
else { else
{
sel = sel_get_any_typed_uid(name); sel = sel_get_any_typed_uid(name);
} }
if (sel == 0) { if (sel == 0)
{
[NSException raise: NSInternalInconsistencyException [NSException raise: NSInternalInconsistencyException
format: @"can't find sel with name '%s' " format: @"can't find sel with name '%s' "
@"and types '%s'", name, types]; @"and types '%s'", name, types];
@ -2505,53 +2610,71 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
ofObjCType: (const char*)type ofObjCType: (const char*)type
context: (id <NSObjCTypeSerializationCallBack>)callback context: (id <NSObjCTypeSerializationCallBack>)callback
{ {
if (data == 0 || type == 0) { if (data == 0 || type == 0)
if (data == 0) { {
if (data == 0)
{
NSLog(@"attempt to serialize from a nul pointer"); NSLog(@"attempt to serialize from a nul pointer");
} }
if (type == 0) { if (type == 0)
{
NSLog(@"attempt to serialize with a nul type encoding"); NSLog(@"attempt to serialize with a nul type encoding");
} }
return; return;
} }
switch (*type) { switch (*type)
{
case _C_ID: case _C_ID:
[callback serializeObjectAt: (id*)data [callback serializeObjectAt: (id*)data
ofObjCType: type ofObjCType: type
intoData: self]; intoData: self];
return; return;
case _C_CHARPTR: { case _C_CHARPTR:
{
unsigned len; unsigned len;
unsigned ni; gss32 ni;
unsigned minimum; unsigned minimum;
if (!*(void**)data) { if (!*(void**)data)
[self serializeInt: -1]; {
ni = -1;
#ifndef GS_WORDS_BIGENDIAN
ni = GSSwapI32(ni);
#endif
[self appendBytes: (void*)&len length: sizeof(len)];
return; return;
} }
len = strlen(*(void**)data); len = strlen(*(void**)data);
ni = NSSwapHostIntToBig(len); #ifndef GS_WORDS_BIGENDIAN
minimum = length + len + sizeof(unsigned); ni = GSSwapI32(len);
if (minimum > capacity) { #else
ni = len;
#endif
minimum = length + len + sizeof(ni);
if (minimum > capacity)
{
[self _grow: minimum]; [self _grow: minimum];
} }
memcpy(bytes+length, &ni, sizeof(unsigned)); memcpy(bytes+length, &ni, sizeof(ni));
length += sizeof(unsigned); length += sizeof(ni);
if (len) { if (len)
{
memcpy(bytes+length, *(void**)data, len); memcpy(bytes+length, *(void**)data, len);
length += len; length += len;
} }
return; return;
} }
case _C_ARY_B: { case _C_ARY_B:
{
unsigned offset = 0; unsigned offset = 0;
unsigned size; unsigned size;
unsigned count = atoi(++type); unsigned count = atoi(++type);
unsigned i; unsigned i;
unsigned minimum; unsigned minimum;
while (isdigit(*type)) { while (isdigit(*type))
{
type++; type++;
} }
size = objc_sizeof_type(type); size = objc_sizeof_type(type);
@ -2562,11 +2685,13 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
* we are going to need and make sure our buffer is big enough. * we are going to need and make sure our buffer is big enough.
*/ */
minimum = length + size*count; minimum = length + size*count;
if (minimum > capacity) { if (minimum > capacity)
{
[self _grow: minimum]; [self _grow: minimum];
} }
for (i = 0; i < count; i++) { for (i = 0; i < count; i++)
{
[self serializeDataAt: (char*)data + offset [self serializeDataAt: (char*)data + offset
ofObjCType: type ofObjCType: type
context: callback]; context: callback];
@ -2574,21 +2699,25 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
} }
return; return;
} }
case _C_STRUCT_B: { case _C_STRUCT_B:
{
int offset = 0; int offset = 0;
while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */ while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */
for (;;) { for (;;)
{
[self serializeDataAt: ((char*)data) + offset [self serializeDataAt: ((char*)data) + offset
ofObjCType: type ofObjCType: type
context: callback]; context: callback];
offset += objc_sizeof_type(type); offset += objc_sizeof_type(type);
type = objc_skip_typespec(type); type = objc_skip_typespec(type);
if (*type != _C_STRUCT_E) { if (*type != _C_STRUCT_E)
{
unsigned align = objc_alignof_type(type); unsigned align = objc_alignof_type(type);
unsigned rem = offset % align; unsigned rem = offset % align;
if (rem != 0) { if (rem != 0)
{
offset += align - rem; offset += align - rem;
} }
} }
@ -2606,26 +2735,30 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
(*appendImp)(self, appendSel, data, sizeof(unsigned char)); (*appendImp)(self, appendSel, data, sizeof(unsigned char));
return; return;
case _C_SHT: case _C_SHT:
case _C_USHT: { case _C_USHT:
{
unsigned short ns = NSSwapHostShortToBig(*(unsigned short*)data); unsigned short ns = NSSwapHostShortToBig(*(unsigned short*)data);
(*appendImp)(self, appendSel, &ns, sizeof(unsigned short)); (*appendImp)(self, appendSel, &ns, sizeof(unsigned short));
return; return;
} }
case _C_INT: case _C_INT:
case _C_UINT: { case _C_UINT:
{
unsigned ni = NSSwapHostIntToBig(*(unsigned int*)data); unsigned ni = NSSwapHostIntToBig(*(unsigned int*)data);
(*appendImp)(self, appendSel, &ni, sizeof(unsigned)); (*appendImp)(self, appendSel, &ni, sizeof(unsigned));
return; return;
} }
case _C_LNG: case _C_LNG:
case _C_ULNG: { case _C_ULNG:
{
unsigned long nl = NSSwapHostLongToBig(*(unsigned long*)data); unsigned long nl = NSSwapHostLongToBig(*(unsigned long*)data);
(*appendImp)(self, appendSel, &nl, sizeof(unsigned long)); (*appendImp)(self, appendSel, &nl, sizeof(unsigned long));
return; return;
} }
#ifdef _C_LNG_LNG #ifdef _C_LNG_LNG
case _C_LNG_LNG: case _C_LNG_LNG:
case _C_ULNG_LNG: { case _C_ULNG_LNG:
{
unsigned long long nl; unsigned long long nl;
nl = NSSwapHostLongLongToBig(*(unsigned long long*)data); nl = NSSwapHostLongLongToBig(*(unsigned long long*)data);
@ -2633,56 +2766,77 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
return; return;
} }
#endif #endif
case _C_FLT: { case _C_FLT:
{
NSSwappedFloat nf = NSSwapHostFloatToBig(*(float*)data); NSSwappedFloat nf = NSSwapHostFloatToBig(*(float*)data);
(*appendImp)(self, appendSel, &nf, sizeof(NSSwappedFloat)); (*appendImp)(self, appendSel, &nf, sizeof(NSSwappedFloat));
return; return;
} }
case _C_DBL: { case _C_DBL:
{
NSSwappedDouble nd = NSSwapHostDoubleToBig(*(double*)data); NSSwappedDouble nd = NSSwapHostDoubleToBig(*(double*)data);
(*appendImp)(self, appendSel, &nd, sizeof(NSSwappedDouble)); (*appendImp)(self, appendSel, &nd, sizeof(NSSwappedDouble));
return; return;
} }
case _C_CLASS: { case _C_CLASS:
{
const char *name = *(Class*)data?fastClassName(*(Class*)data):""; const char *name = *(Class*)data?fastClassName(*(Class*)data):"";
unsigned ln = strlen(name); gsu16 ln = (gsu16)strlen(name);
unsigned minimum = length + ln + sizeof(unsigned); gsu16 minimum = length + ln + sizeof(gsu16);
unsigned ni; gsu16 ni;
if (minimum > capacity) { if (minimum > capacity)
{
[self _grow: minimum]; [self _grow: minimum];
} }
ni = NSSwapHostIntToBig(ln); #ifndef GS_WORDS_BIGENDIAN
memcpy(bytes+length, &ni, sizeof(unsigned)); ni = GSSwapI16(ln);
length += sizeof(unsigned); #else
if (ln) { ni = ln;
#endif
memcpy(bytes+length, &ni, sizeof(ni));
length += sizeof(ni);
if (ln)
{
memcpy(bytes+length, name, ln); memcpy(bytes+length, name, ln);
length += ln; length += ln;
} }
return; return;
} }
case _C_SEL: { case _C_SEL:
{
const char *name = *(SEL*)data?fastSelectorName(*(SEL*)data):""; const char *name = *(SEL*)data?fastSelectorName(*(SEL*)data):"";
unsigned ln = strlen(name); gsu16 ln = (gsu16)strlen(name);
const char *types = *(SEL*)data?fastSelectorTypes(*(SEL*)data):""; const char *types = *(SEL*)data?fastSelectorTypes(*(SEL*)data):"";
unsigned lt = strlen(types); gsu16 lt = (gsu16)strlen(types);
unsigned minimum = length + ln + lt + 2*sizeof(unsigned); gsu16 minimum = length + ln + lt + 2*sizeof(gsu16);
unsigned ni; gsu16 ni;
if (minimum > capacity) { if (minimum > capacity)
{
[self _grow: minimum]; [self _grow: minimum];
} }
ni = NSSwapHostIntToBig(ln); #ifndef GS_WORDS_BIGENDIAN
memcpy(bytes+length, &ni, sizeof(unsigned)); ni = GSSwapI16(ln);
length += sizeof(unsigned); #else
ni = NSSwapHostIntToBig(lt); ni = ln;
memcpy(bytes+length, &ni, sizeof(unsigned)); #endif
length += sizeof(unsigned); memcpy(bytes+length, &ni, sizeof(ni));
if (ln) { length += sizeof(ni);
#ifndef GS_WORDS_BIGENDIAN
ni = GSSwapI16(lt);
#else
ni = lt;
#endif
memcpy(bytes+length, &ni, sizeof(ni));
length += sizeof(ni);
if (ln)
{
memcpy(bytes+length, name, ln); memcpy(bytes+length, name, ln);
length += ln; length += ln;
} }
if (lt) { if (lt)
{
memcpy(bytes+length, types, lt); memcpy(bytes+length, types, lt);
length += lt; length += lt;
} }