Friday, June 14, 2013

NSCharacterSet bitmapRepresentation example in Objective C (iOS).


NSCharacterSet bitmapRepresentation

Returns an NSData object encoding the receiver in binary format.

- (NSData *)bitmapRepresentation

Return Value
An NSData object encoding the receiver in binary format.

Discussion of [NSCharacterSet bitmapRepresentation]
This format is suitable for saving to a file or otherwise transmitting or archiving.

A raw bitmap representation of a character set is a byte array of 2^16 bits (that is, 8192 bytes). The value of the bit at position n represents the presence in the character set of the character with decimal Unicode value n. To test for the presence of a character with decimal Unicode value n in a raw bitmap representation, use an expression such as the following:

unsigned char bitmapRep[8192];
if (bitmapRep[n >> 3] & (((unsigned int)1) << (n & 7))) {
/* Character is present. */
}

NSCharacterSet bitmapRepresentation example.
@interface StringWrapper : NSObject
@property (nonatomic, copy) NSString *string;
@property (nonatomic, copy) NSData *charSetBitmap;
- (id)initWithString:(NSString*)aString;
@end

@implementation StringWrapper
@synthesize string, charSetBitmap;

- (id)initWithString:(NSString*)aString;
{
    if ((self = [super init]))
    {
        self.string = aString;
    }
    return self;
}

- (void)setString:(NSString *)aString;
{
    string = [aString copy];
    self.charSetBitmap = [[NSCharacterSet characterSetWithCharactersInString:aString] bitmapRepresentation];
}

- (BOOL)isEqual:(id)object;
{
    return [self.charSetBitmap isEqual:[object charSetBitmap]];
}

- (NSUInteger)hash;
{
    return [self.charSetBitmap hash];
}

Example of [NSCharacterSet bitmapRepresentation].
// this doesn't seem to be available
#define UNICHAR_MAX (1 << (CHAR_BIT * sizeof(unichar) - 1))

NSData *data = [[NSCharacterSet uppercaseLetterCharacterSet] bitmapRepresentation];
uint8_t *ptr = [data bytes];
NSMutableArray *allCharsInSet = [NSMutableArray array];
// following from Apple's sample code
for (unichar i = 0; i < UNICHAR_MAX; i++) {
    if (ptr[i >> 3] & (((unsigned int)1) << (i & 7))) {
        [allCharsInSet addObject:[NSString stringWithCharacters:&i length:1]];
    }
}

NSCharacterSet bitmapRepresentation example.
NSArray * charactersInCharacterSet(NSCharacterSet *charSet)
{
  NSMutableArray * array = [NSMutableArray array];
  NSData * data = [charSet bitmapRepresentation];
  const char* bytes = [data bytes];

  for (int i = 0; i < 8192; ++i)
  {
    if (bytes[i >> 3] & (((unsigned int)1) << (i & 7)))
    {
      [array addObject:[NSString stringWithFormat:@"%C", i]];
    }
  }
  return [NSArray arrayWithArray:array];
}

NSCharacterSet * charSet = [[[[NSLocale alloc] initWithLocaleIdentifier:@"sr_Cyrl_ME"] autorelease] objectForKey:NSLocaleExemplarCharacterSet];
NSArray * chars = charactersInCharacterSet(charSet);
for (NSString *str in chars)
{
  NSLog(@"%@", str);
}

End of NSCharacterSet bitmapRepresentation example article.