mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 16:30:41 +00:00
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:
parent
b8ce43f9e7
commit
c4a0051b20
2 changed files with 91 additions and 26 deletions
|
@ -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.
|
||||||
|
|
|
@ -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];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue