mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +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
f38e27c4cb
commit
2048ee28da
2 changed files with 232 additions and 26 deletions
|
@ -538,6 +538,8 @@ static unsigned encodingVersion;
|
|||
NSUInteger offset = 0;
|
||||
unsigned int size = (unsigned int)objc_sizeof_type(type);
|
||||
unsigned char info;
|
||||
unsigned char ainfo;
|
||||
unsigned char amask;
|
||||
NSUInteger count;
|
||||
|
||||
(*tagImp)(src, tagSel, &info, 0, &cursor);
|
||||
|
@ -616,27 +618,211 @@ static unsigned encodingVersion;
|
|||
(*dValImp)(self, dValSel, type, (char*)buf + offset);
|
||||
offset += size;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
||||
(*tagImp)(src, tagSel, &ainfo, 0, &cursor);
|
||||
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))
|
||||
{
|
||||
unsigned char ainfo;
|
||||
|
||||
(*tagImp)(src, tagSel, &ainfo, 0, &cursor);
|
||||
if (info != (ainfo & _GSC_MASK))
|
||||
{
|
||||
if (info != _GSC_ID || (ainfo & _GSC_MASK) != _GSC_CID)
|
||||
{
|
||||
[NSException raise: NSInternalInconsistencyException
|
||||
format: @"expected %s and got %s",
|
||||
typeToName2(info), typeToName2(ainfo)];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
(*desImp)(src, desSel, (char*)buf + offset, type, &cursor, nil);
|
||||
offset += size;
|
||||
}
|
||||
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++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,10 +11,11 @@
|
|||
|
||||
@interface Model : NSObject <NSCoding>
|
||||
{
|
||||
int cint;
|
||||
unsigned int cuint;
|
||||
NSInteger nsint;
|
||||
NSUInteger nsuint;
|
||||
int cint;
|
||||
unsigned int cuint;
|
||||
NSInteger nsint;
|
||||
NSUInteger nsuint;
|
||||
NSInteger a[4];
|
||||
}
|
||||
@end
|
||||
@implementation Model
|
||||
|
@ -24,33 +25,51 @@
|
|||
cuint = 1234567890;
|
||||
nsint = -1234567890;
|
||||
nsuint = 1234567890;
|
||||
a[0] = 1;
|
||||
a[1] = 1000;
|
||||
a[2] = 1000000;
|
||||
a[3] = 100000000;
|
||||
}
|
||||
- (BOOL)testCInt:(Model *)o
|
||||
{
|
||||
return (cint == o->cint);
|
||||
return (cint == o->cint) ? YES : NO;
|
||||
}
|
||||
- (BOOL)testCUInt:(Model *)o
|
||||
{
|
||||
return (cuint == o->cuint);
|
||||
return (cuint == o->cuint) ? YES : NO;
|
||||
}
|
||||
- (BOOL)testNSInteger:(Model *)o
|
||||
{
|
||||
return (nsint == o->nsint);
|
||||
return (nsint == o->nsint) ? YES : NO;
|
||||
}
|
||||
- (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
|
||||
{
|
||||
[coder encodeValueOfObjCType:@encode(int) at:&cint];
|
||||
[coder encodeValueOfObjCType:@encode(unsigned int) at:&cuint];
|
||||
[coder encodeValueOfObjCType:@encode(NSInteger) at:&nsint];
|
||||
[coder encodeValueOfObjCType:@encode(NSUInteger) at:&nsuint];
|
||||
[coder encodeArrayOfObjCType: @encode(NSInteger) count: 4 at: a];
|
||||
[coder encodeValueOfObjCType: @encode(int) at: &cint];
|
||||
[coder encodeValueOfObjCType: @encode(unsigned int) at: &cuint];
|
||||
[coder encodeValueOfObjCType: @encode(NSInteger) at: &nsint];
|
||||
[coder encodeValueOfObjCType: @encode(NSUInteger) at: &nsuint];
|
||||
}
|
||||
-(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. */
|
||||
[coder decodeValueOfObjCType: @encode(NSInteger) at: &nsint];
|
||||
/* 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 testNSInteger:obj2], "archiving as NSInteger - dearchiving as 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;
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue