Fix keyed archiving and unarchiving of (mutable) attributed strings

with multiple attribute ranges.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@30488 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
wlux 2010-05-30 15:16:36 +00:00
parent b8ce43f9e7
commit c4a0051b20
2 changed files with 91 additions and 26 deletions

View file

@ -1,3 +1,9 @@
2010-05-30 Wolfgang Lux <wolfgang.lux@gmail.com>
* Source/NSAttributedString.m (-initWithCoder:, -encodeWithCoder:):
Fix keyed archiving and unarchiving of (mutable) attributed
strings with multiple attribute ranges.
2010-05-30 Richard Frith-Macdonald <rfm@gnu.org> 2010-05-30 Richard Frith-Macdonald <rfm@gnu.org>
* NSTimeZones/NSTimeZones.tar: Update to latest zone info. * NSTimeZones/NSTimeZones.tar: Update to latest zone info.

View file

@ -151,19 +151,70 @@ static Class GSMutableAttributedStringClass;
return NSAttributedStringClass; return NSAttributedStringClass;
} }
static void
appendUIntData(NSMutableData *d, NSUInteger i)
{
unsigned int aux = i;
unsigned int len = 1;
while (aux >= 128)
{
aux /= 128;
len++;
}
{
unsigned char *p, buf[len];
p = buf;
while (i >= 128)
{
*p++ = (i & 0x7f) + 128;
i /= 128;
}
*p = i;
[d appendBytes: buf length: len];
}
}
- (void) encodeWithCoder: (NSCoder*)aCoder - (void) encodeWithCoder: (NSCoder*)aCoder
{ {
if ([aCoder allowsKeyedCoding]) if ([aCoder allowsKeyedCoding])
{ {
NSUInteger length = [self length];
[aCoder encodeObject: [self string] forKey: @"NSString"]; [aCoder encodeObject: [self string] forKey: @"NSString"];
if ([self length] > 0) if (length > 0)
{ {
NSRange range;
NSDictionary *attrs; NSDictionary *attrs;
// FIXME: This doesn't handle the case of different attributes attrs = [self attributesAtIndex: 0 effectiveRange: &range];
attrs = [self attributesAtIndex: 0 effectiveRange: NULL]; if (range.length == length)
{
[aCoder encodeObject: attrs forKey: @"NSAttributes"];
}
else
{
NSUInteger i = 0;
NSUInteger pos = 0;
NSMutableArray *attrs = [NSMutableArray arrayWithCapacity: 1];
NSMutableData *info = [NSMutableData dataWithCapacity: 2];
[aCoder encodeObject: attrs forKey: @"NSAttributes"]; while (pos < length)
{
[attrs addObject: [self attributesAtIndex: pos
effectiveRange: &range]];
appendUIntData(info, range.length);
appendUIntData(info, i++);
pos = NSMaxRange(range);
}
[aCoder encodeObject: [[attrs copy] autorelease]
forKey: @"NSAttributes"];
[aCoder encodeObject: [[info copy] autorelease]
forKey: @"NSAttributeInfo"];
}
} }
} }
else else
@ -211,20 +262,24 @@ static Class GSMutableAttributedStringClass;
{ {
unsigned int idx; unsigned int idx;
unsigned int len; unsigned int len;
unsigned int shift;
NSRange r; NSRange r;
// FIXME: For huge strings we may need more bytes len = shift = 0;
len = *p++; while (*p & 0x80)
if (len & 0x8) {
{ len += (*p++ - 128) << shift;
len = (len - 128) + ((*p++) << 7); shift += 7;
} }
len += *p++ << shift;
idx = *p++; idx = shift = 0;
if (idx & 0x8) while (*p & 0x80)
{ {
idx = (idx - 128) + ((*p++) << 7); idx += (*p++ - 128) << shift;
} shift += 7;
}
idx += *p++ << shift;
r = NSMakeRange(pos, len); r = NSMakeRange(pos, len);
[m setAttributes: [attributes objectAtIndex: idx] range: r]; [m setAttributes: [attributes objectAtIndex: idx] range: r];
@ -707,20 +762,24 @@ static Class GSMutableAttributedStringClass;
{ {
unsigned int idx; unsigned int idx;
unsigned int len; unsigned int len;
unsigned int shift;
NSRange r; NSRange r;
// FIXME: For huge strings we may need more bytes len = shift = 0;
len = *p++; while (*p & 0x80)
if (len & 0x8) {
{ len += (*p++ - 128) << shift;
len = (len - 128) + ((*p++) << 7); shift += 7;
} }
len += *p++ << shift;
idx = *p++; idx = shift = 0;
if (idx & 0x8) while (*p & 0x80)
{ {
idx = (idx - 128) + ((*p++) << 7); idx += (*p++ - 128) << shift;
} shift += 7;
}
idx += *p++ << shift;
r = NSMakeRange(pos, len); r = NSMakeRange(pos, len);
[self setAttributes: [attributes objectAtIndex: idx] range: r]; [self setAttributes: [attributes objectAtIndex: idx] range: r];