[code]static const NSArray *brandNames = nil;
static NSCharacterSet *validEncodedDigit = nil;
NSString *encodeByte(char byte)
{
char index = 0x1F & byte;
NSString *brandName = brandNames[index];
char encodedDigit =((0xe0 & byte) >> 5) + 2;
return [NSString stringWithFormat:@"%d %@ ", encodedDigit, brandName];
}
BOOL decodeByte(NSString *encodedDigit, NSString *brandName, char * byte, NSError **error)
{
// Check if encodedDigit is valid
if ([encodedDigit rangeOfCharacterFromSet:validEncodedDigit
options:NSLiteralSearch].location == NSNotFound) {
if(error) {
NSDictionary *userInfo = @{NSLocalizedDescriptionKey : [NSString stringWithFormat:@“Invalid digit ‘%@’”, encodedDigit]};
*error = [NSError errorWithDomain:@“Speakable” code:1 userInfo];
}
return NO;
}
int digit = [encodedDigit intValue];
// Check if brandName is valid;
NSUInteger index = [brandNames indexOfObject:brandName];
if (index == NSNotFound) {
if (error) {
NSDictionary *userInfo = @{NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Invalid brandname '%@'", brandName]};
*error = [NSError errorWithDomain:@"Speakable" code:1 userInfo];
}
return NO;
}
*byte = (digit - 2) << 5 | (index & 0x1f);
return YES;
}
@implementation NSData (Speakable)
-
(void)initialize {
brandNames = @[ @“Camry”,
@“Nikon”,
@“Apple”,
@“Ford”,
@“Audi”,
@“Google”,
@“Nike”,
@“Amazon”,
@“Honda”,
@“Mazda”,
@“Buick”,
@“Fiat”,
@“Jeep”,
@“Lexus”,
@“Volvo”,
@“Fuji”,
@“Sony”,
@“Delta”,
@“Focus”,
@“Puma”,
@“Samsung”,
@“Tivo”,
@“Halo”,
@“Sting”,
@“Shrek”,
@“Avatar”,
@“Shell”,
@“Visa”,
@“Vogue”,
@“Twitter”,
@“Lego”,
@“Pepsi”];validEncodedDigit = [NSCharacterSet characterSetWithCharactersInString:@“23456789”];
}
-
(NSString *)encodeAsSpeakableString
{// Copy bytes into buffer.
const NSUInteger numBytes = self.length;
char buffer[numBytes];
[self getBytes:buffer length];
NSMutableString *rtnValue = [[NSMutableString alloc] init];for (int i = 0; i < numBytes; i++) {
char byte = buffer[i];
[rtnValue appendString:encodeByte(byte)];
}
return rtnValue;
}
-
(NSData *)dataWithSpeakableString:(NSString *)s
error:(NSError **)e
{NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSArray<NSString > words = [s componentsSeparatedByCharactersInSet:whitespace];long numBytes = words.count / 2;
char bytes[numBytes];for (int i = 0; i < numBytes; i++) {
NSString *encodedDigit = words[2 * i];
NSString *brandName = words[(2 * i) + 1];if (!decodeByte(encodedDigit, brandName, &bytes[i], e)) { return nil; }
}
return [NSData dataWithBytes:bytes length];
}
@end
[/code]