mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-25 17:51:01 +00:00
fix for word size issues with arrays
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@36905 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
a18df9e51c
commit
a6ae2d4a2d
2 changed files with 232 additions and 26 deletions
|
@ -538,6 +538,8 @@ static unsigned encodingVersion;
|
||||||
NSUInteger offset = 0;
|
NSUInteger offset = 0;
|
||||||
unsigned int size = (unsigned int)objc_sizeof_type(type);
|
unsigned int size = (unsigned int)objc_sizeof_type(type);
|
||||||
unsigned char info;
|
unsigned char info;
|
||||||
|
unsigned char ainfo;
|
||||||
|
unsigned char amask;
|
||||||
NSUInteger count;
|
NSUInteger count;
|
||||||
|
|
||||||
(*tagImp)(src, tagSel, &info, 0, &cursor);
|
(*tagImp)(src, tagSel, &info, 0, &cursor);
|
||||||
|
@ -616,25 +618,209 @@ static unsigned encodingVersion;
|
||||||
(*dValImp)(self, dValSel, type, (char*)buf + offset);
|
(*dValImp)(self, dValSel, type, (char*)buf + offset);
|
||||||
offset += size;
|
offset += size;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned char ainfo;
|
|
||||||
|
|
||||||
(*tagImp)(src, tagSel, &ainfo, 0, &cursor);
|
(*tagImp)(src, tagSel, &ainfo, 0, &cursor);
|
||||||
if (info != (ainfo & _GSC_MASK))
|
amask = (ainfo & _GSC_MASK);
|
||||||
|
|
||||||
|
/* If we have a perfect type match or we are coding a class as an ID,
|
||||||
|
* we can just decode the array simply.
|
||||||
|
*/
|
||||||
|
if (info == amask || (info == _GSC_ID && amask == _GSC_CID))
|
||||||
{
|
{
|
||||||
if (info != _GSC_ID || (ainfo & _GSC_MASK) != _GSC_CID)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
[NSException raise: NSInternalInconsistencyException
|
(*desImp)(src, desSel, (char*)buf + offset, type, &cursor, nil);
|
||||||
format: @"expected %s and got %s",
|
offset += size;
|
||||||
typeToName2(info), typeToName2(ainfo)];
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This will raise an exception if the types don't match at all.
|
||||||
|
*/
|
||||||
|
typeCheck(*type, ainfo);
|
||||||
|
|
||||||
|
/* We fall through to here only when we have to decode a value
|
||||||
|
* whose natural size on this system is not the same as on the
|
||||||
|
* machine on which the archive was created.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (*type == _C_FLT)
|
||||||
|
{
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
double d;
|
||||||
|
|
||||||
|
(*desImp)(src, desSel, &d, @encode(double), &cursor, nil);
|
||||||
|
*(float*)(buf + offset) = (float)d;
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*type == _C_DBL)
|
||||||
|
{
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
float f;
|
||||||
|
|
||||||
|
(*desImp)(src, desSel, &f, @encode(float), &cursor, nil);
|
||||||
|
*(double*)(buf + offset) = (double)f;
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*type == _C_SHT
|
||||||
|
|| *type == _C_INT
|
||||||
|
|| *type == _C_LNG
|
||||||
|
|| *type == _C_LNG_LNG)
|
||||||
|
{
|
||||||
|
int64_t big;
|
||||||
|
int64_t max;
|
||||||
|
int64_t min;
|
||||||
|
|
||||||
|
switch (size)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
max = 0x80;
|
||||||
|
min = 0x7f;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
max = 0x8000;
|
||||||
|
min = 0x7fff;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
max = 0x80000000;
|
||||||
|
min = 0x7fffffff;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
max = 0x8000000000000000;
|
||||||
|
min = 0x7fffffffffffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
(*desImp)(src, desSel, (char*)buf + offset, type, &cursor, nil);
|
void *address = (void*)buf + offset;
|
||||||
|
|
||||||
|
switch (ainfo & _GSC_SIZE)
|
||||||
|
{
|
||||||
|
case _GSC_I16: /* Encoded as 16-bit */
|
||||||
|
{
|
||||||
|
int16_t val;
|
||||||
|
|
||||||
|
(*desImp)(src, desSel, &val, @encode(int16_t), &cursor, nil);
|
||||||
|
big = val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case _GSC_I32: /* Encoded as 32-bit */
|
||||||
|
{
|
||||||
|
int32_t val;
|
||||||
|
|
||||||
|
(*desImp)(src, desSel, &val, @encode(int32_t), &cursor, nil);
|
||||||
|
big = val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case _GSC_I64: /* Encoded as 64-bit */
|
||||||
|
{
|
||||||
|
(*desImp)(src, desSel, &big, @encode(int64_t), &cursor, nil);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Now we copy from the big value to the destination location.
|
||||||
|
*/
|
||||||
|
switch (size)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
*(int8_t*)address = (int8_t)big;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*(int16_t*)address = (int16_t)big;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
*(int32_t*)address = (int32_t)big;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*(int64_t*)address = big;
|
||||||
|
}
|
||||||
|
if (big < min || big > max)
|
||||||
|
{
|
||||||
|
NSLog(@"Loss of information converting large decoded value");
|
||||||
|
}
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint64_t big;
|
||||||
|
uint64_t max;
|
||||||
|
|
||||||
|
switch (size)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
max = 0xff;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
max = 0xffff;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
max = 0xffffffff;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
max = 0xffffffffffffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
void *address = (void*)buf + offset;
|
||||||
|
|
||||||
|
switch (info & _GSC_SIZE)
|
||||||
|
{
|
||||||
|
case _GSC_I16: /* Encoded as 16-bit */
|
||||||
|
{
|
||||||
|
uint16_t val;
|
||||||
|
|
||||||
|
(*desImp)(src, desSel, &val, @encode(uint16_t), &cursor, nil);
|
||||||
|
big = val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case _GSC_I32: /* Encoded as 32-bit */
|
||||||
|
{
|
||||||
|
uint32_t val;
|
||||||
|
|
||||||
|
(*desImp)(src, desSel, &val, @encode(uint32_t), &cursor, nil);
|
||||||
|
big = val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case _GSC_I64: /* Encoded as 64-bit */
|
||||||
|
{
|
||||||
|
(*desImp)(src, desSel, &big, @encode(uint64_t), &cursor, nil);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Now we copy from the big value to the destination location.
|
||||||
|
*/
|
||||||
|
switch (size)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
*(uint8_t*)address = (uint8_t)big;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*(uint16_t*)address = (uint16_t)big;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
*(uint32_t*)address = (uint32_t)big;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
*(uint64_t*)address = big;
|
||||||
|
}
|
||||||
|
if (big > max)
|
||||||
|
{
|
||||||
|
NSLog(@"Loss of information converting large decoded value");
|
||||||
|
}
|
||||||
offset += size;
|
offset += size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
unsigned int cuint;
|
unsigned int cuint;
|
||||||
NSInteger nsint;
|
NSInteger nsint;
|
||||||
NSUInteger nsuint;
|
NSUInteger nsuint;
|
||||||
|
NSInteger a[4];
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
@implementation Model
|
@implementation Model
|
||||||
|
@ -24,26 +25,38 @@
|
||||||
cuint = 1234567890;
|
cuint = 1234567890;
|
||||||
nsint = -1234567890;
|
nsint = -1234567890;
|
||||||
nsuint = 1234567890;
|
nsuint = 1234567890;
|
||||||
|
a[0] = 1;
|
||||||
|
a[1] = 1000;
|
||||||
|
a[2] = 1000000;
|
||||||
|
a[3] = 100000000;
|
||||||
}
|
}
|
||||||
- (BOOL)testCInt:(Model *)o
|
- (BOOL)testCInt:(Model *)o
|
||||||
{
|
{
|
||||||
return (cint == o->cint);
|
return (cint == o->cint) ? YES : NO;
|
||||||
}
|
}
|
||||||
- (BOOL)testCUInt:(Model *)o
|
- (BOOL)testCUInt:(Model *)o
|
||||||
{
|
{
|
||||||
return (cuint == o->cuint);
|
return (cuint == o->cuint) ? YES : NO;
|
||||||
}
|
}
|
||||||
- (BOOL)testNSInteger:(Model *)o
|
- (BOOL)testNSInteger:(Model *)o
|
||||||
{
|
{
|
||||||
return (nsint == o->nsint);
|
return (nsint == o->nsint) ? YES : NO;
|
||||||
}
|
}
|
||||||
- (BOOL)testNSUInteger:(Model *)o
|
- (BOOL)testNSUInteger:(Model *)o
|
||||||
{
|
{
|
||||||
return (nsuint == o->nsuint);
|
return (nsuint == o->nsuint) ? YES : NO;
|
||||||
|
}
|
||||||
|
- (BOOL)testArray:(Model *)o
|
||||||
|
{
|
||||||
|
return (a[0] == o->a[0]
|
||||||
|
&& a[1] == o->a[1]
|
||||||
|
&& a[2] == o->a[2]
|
||||||
|
&& a[3] == o->a[3]) ? YES : NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)encodeWithCoder:(NSCoder *)coder
|
-(void)encodeWithCoder:(NSCoder *)coder
|
||||||
{
|
{
|
||||||
|
[coder encodeArrayOfObjCType: @encode(NSInteger) count: 4 at: a];
|
||||||
[coder encodeValueOfObjCType: @encode(int) at: &cint];
|
[coder encodeValueOfObjCType: @encode(int) at: &cint];
|
||||||
[coder encodeValueOfObjCType: @encode(unsigned int) at: &cuint];
|
[coder encodeValueOfObjCType: @encode(unsigned int) at: &cuint];
|
||||||
[coder encodeValueOfObjCType: @encode(NSInteger) at: &nsint];
|
[coder encodeValueOfObjCType: @encode(NSInteger) at: &nsint];
|
||||||
|
@ -51,6 +64,12 @@
|
||||||
}
|
}
|
||||||
-(id)initWithCoder:(NSCoder *)coder
|
-(id)initWithCoder:(NSCoder *)coder
|
||||||
{
|
{
|
||||||
|
long long ia[4];
|
||||||
|
[coder decodeArrayOfObjCType: @encode(long long) count: 4 at: ia];
|
||||||
|
a[0] = ia[0];
|
||||||
|
a[1] = ia[1];
|
||||||
|
a[2] = ia[2];
|
||||||
|
a[3] = ia[3];
|
||||||
/* encoded as int - decoded as NSInteger. */
|
/* encoded as int - decoded as NSInteger. */
|
||||||
[coder decodeValueOfObjCType: @encode(NSInteger) at: &nsint];
|
[coder decodeValueOfObjCType: @encode(NSInteger) at: &nsint];
|
||||||
/* encoded as unsinged int - decoded as NSUInteger. */
|
/* encoded as unsinged int - decoded as NSUInteger. */
|
||||||
|
@ -212,6 +231,7 @@ int main()
|
||||||
PASS([obj1 testCUInt:obj2], "archiving as unsigned int - dearchiving as NSUInteger");
|
PASS([obj1 testCUInt:obj2], "archiving as unsigned int - dearchiving as NSUInteger");
|
||||||
PASS([obj1 testNSInteger:obj2], "archiving as NSInteger - dearchiving as int");
|
PASS([obj1 testNSInteger:obj2], "archiving as NSInteger - dearchiving as int");
|
||||||
PASS([obj1 testNSUInteger:obj2], "archiving as NSUInteger - dearchiving as unsigned int");
|
PASS([obj1 testNSUInteger:obj2], "archiving as NSUInteger - dearchiving as unsigned int");
|
||||||
|
PASS([obj1 testArray:obj2], "archiving as NSInteger array - dearchiving as long long");
|
||||||
|
|
||||||
[pool release]; pool = nil;
|
[pool release]; pool = nil;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue