|
Packit |
1fb8d4 |
/*
|
|
Packit |
1fb8d4 |
Additions to Cocoa touch classes
|
|
Packit Service |
5a9772 |
|
|
Packit |
1fb8d4 |
Copyright 2013 Thincast Technologies GmbH, Authors: Dorian Johnson, Martin Fleisz
|
|
Packit Service |
5a9772 |
|
|
Packit |
1fb8d4 |
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
Packit Service |
5a9772 |
If a copy of the MPL was not distributed with this file, You can obtain one at
|
|
Packit Service |
5a9772 |
http://mozilla.org/MPL/2.0/.
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#import "TSXAdditions.h"
|
|
Packit |
1fb8d4 |
#include <openssl/bio.h>
|
|
Packit |
1fb8d4 |
#include <openssl/evp.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
@implementation NSObject (TSXAdditions)
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
- (void)setValuesForKeyPathsWithDictionary:(NSDictionary *)keyedValues
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
for (id keyPath in keyedValues)
|
|
Packit |
1fb8d4 |
[self setValue:[keyedValues objectForKey:keyPath] forKeyPath:keyPath];
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
- mutableDeepCopy
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
if ([self respondsToSelector:@selector(mutableCopyWithZone:)])
|
|
Packit Service |
5a9772 |
return [self mutableCopy];
|
|
Packit Service |
5a9772 |
else if ([self respondsToSelector:@selector(copyWithZone:)])
|
|
Packit Service |
5a9772 |
return [self copy];
|
|
Packit Service |
5a9772 |
else
|
|
Packit Service |
5a9772 |
return [self retain];
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
@end
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#pragma mark -
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
@implementation NSString (TSXAdditions)
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#pragma mark Creation routines
|
|
Packit Service |
5a9772 |
+ (NSString *)stringWithUUID
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
CFUUIDRef uuidObj = CFUUIDCreate(nil);
|
|
Packit Service |
5a9772 |
NSString *uuidString = (NSString *)CFUUIDCreateString(nil, uuidObj);
|
|
Packit |
1fb8d4 |
CFRelease(uuidObj);
|
|
Packit |
1fb8d4 |
return [uuidString autorelease];
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
/* Code from
|
|
Packit Service |
5a9772 |
* http://code.google.com/p/google-toolbox-for-mac/source/browse/trunk/Foundation/GTMNSData%2BHex.m?r=344
|
|
Packit Service |
5a9772 |
*/
|
|
Packit Service |
5a9772 |
- (NSData *)dataFromHexString
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
NSData *hexData = [self dataUsingEncoding:NSASCIIStringEncoding];
|
|
Packit Service |
5a9772 |
const char *hexBuf = [hexData bytes];
|
|
Packit Service |
5a9772 |
NSUInteger hexLen = [hexData length];
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
// This indicates an error converting to ASCII.
|
|
Packit Service |
5a9772 |
if (!hexData)
|
|
Packit Service |
5a9772 |
return nil;
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if ((hexLen % 2) != 0)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
return nil;
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
NSMutableData *binaryData = [NSMutableData dataWithLength:(hexLen / 2)];
|
|
Packit Service |
5a9772 |
unsigned char *binaryPtr = [binaryData mutableBytes];
|
|
Packit Service |
5a9772 |
unsigned char value = 0;
|
|
Packit Service |
5a9772 |
for (NSUInteger i = 0; i < hexLen; i++)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
char c = hexBuf[i];
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (!isxdigit(c))
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
return nil;
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (isdigit(c))
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
value += c - '0';
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
else if (islower(c))
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
value += 10 + c - 'a';
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
else
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
value += 10 + c - 'A';
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (i & 1)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
*binaryPtr++ = value;
|
|
Packit Service |
5a9772 |
value = 0;
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
else
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
value <<= 4;
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
return [NSData dataWithData:binaryData];
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
+ (NSString *)hexStringFromData:(const unsigned char *)data
|
|
Packit Service |
5a9772 |
ofSize:(unsigned int)size
|
|
Packit Service |
5a9772 |
withSeparator:(NSString *)sep
|
|
Packit Service |
5a9772 |
afterNthChar:(int)sepnth
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
int i;
|
|
Packit |
1fb8d4 |
NSMutableString *result;
|
|
Packit |
1fb8d4 |
NSString *immutableResult;
|
|
Packit Service |
5a9772 |
|
|
Packit |
1fb8d4 |
result = [[NSMutableString alloc] init];
|
|
Packit Service |
5a9772 |
for (i = 0; i < size; i++)
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
if (i && sep && sepnth && i % sepnth == 0)
|
|
Packit |
1fb8d4 |
[result appendString:sep];
|
|
Packit |
1fb8d4 |
[result appendFormat:@"%02X", data[i]];
|
|
Packit |
1fb8d4 |
}
|
|
Packit Service |
5a9772 |
|
|
Packit |
1fb8d4 |
immutableResult = [NSString stringWithString:result];
|
|
Packit |
1fb8d4 |
[result release];
|
|
Packit |
1fb8d4 |
return immutableResult;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
@end
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#pragma mark Mutable deep copy for dicionary, array and set
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
@implementation NSDictionary (TSXAdditions)
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
- mutableDeepCopy
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
NSMutableDictionary *newDictionary = [[NSMutableDictionary alloc] init];
|
|
Packit Service |
5a9772 |
NSEnumerator *enumerator = [self keyEnumerator];
|
|
Packit Service |
5a9772 |
id key;
|
|
Packit Service |
5a9772 |
while ((key = [enumerator nextObject]))
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
id obj = [[self objectForKey:key] mutableDeepCopy];
|
|
Packit Service |
5a9772 |
[newDictionary setObject:obj forKey:key];
|
|
Packit Service |
5a9772 |
[obj release];
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
return newDictionary;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
@end
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
@implementation NSArray (TSXAdditions)
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
- mutableDeepCopy
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
NSMutableArray *newArray = [[NSMutableArray alloc] init];
|
|
Packit Service |
5a9772 |
NSEnumerator *enumerator = [self objectEnumerator];
|
|
Packit Service |
5a9772 |
id obj;
|
|
Packit Service |
5a9772 |
while ((obj = [enumerator nextObject]))
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
obj = [obj mutableDeepCopy];
|
|
Packit Service |
5a9772 |
[newArray addObject:obj];
|
|
Packit Service |
5a9772 |
[obj release];
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
return newArray;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
@end
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
@implementation NSSet (TSXAdditions)
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
- mutableDeepCopy
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
NSMutableSet *newSet = [[NSMutableSet alloc] init];
|
|
Packit Service |
5a9772 |
NSEnumerator *enumerator = [self objectEnumerator];
|
|
Packit Service |
5a9772 |
id obj;
|
|
Packit Service |
5a9772 |
while ((obj = [enumerator nextObject]))
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
obj = [obj mutableDeepCopy];
|
|
Packit Service |
5a9772 |
[newSet addObject:obj];
|
|
Packit Service |
5a9772 |
[obj release];
|
|
Packit Service |
5a9772 |
}
|
|
Packit Service |
5a9772 |
return newSet;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
@end
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#pragma mark -
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
/* Code from
|
|
Packit Service |
5a9772 |
* http://stackoverflow.com/questions/1305225/best-way-to-serialize-a-nsdata-into-an-hexadeximal-string
|
|
Packit Service |
5a9772 |
*/
|
|
Packit |
1fb8d4 |
@implementation NSData (TSXAdditions)
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#pragma mark - String Conversion
|
|
Packit Service |
5a9772 |
- (NSString *)hexadecimalString
|
|
Packit Service |
5a9772 |
{
|
|
Packit Service |
5a9772 |
/* Returns hexadecimal string of NSData. Empty string if data is empty. */
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
const unsigned char *dataBuffer = (const unsigned char *)[self bytes];
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
if (!dataBuffer)
|
|
Packit Service |
5a9772 |
return [NSString string];
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
NSUInteger dataLength = [self length];
|
|
Packit Service |
5a9772 |
NSMutableString *hexString = [NSMutableString stringWithCapacity:(dataLength * 2)];
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
for (int i = 0; i < dataLength; ++i)
|
|
Packit Service |
5a9772 |
[hexString appendString:[NSString stringWithFormat:@"%02lx", (unsigned long)dataBuffer[i]]];
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
return [NSString stringWithString:hexString];
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
/* Code from http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html */
|
|
Packit |
1fb8d4 |
- (NSString *)base64EncodedString
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
// Construct an OpenSSL context
|
|
Packit Service |
5a9772 |
BIO *context = BIO_new(BIO_s_mem());
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
// Tell the context to encode base64
|
|
Packit Service |
5a9772 |
BIO *command = BIO_new(BIO_f_base64());
|
|
Packit Service |
5a9772 |
context = BIO_push(command, context);
|
|
Packit Service |
5a9772 |
BIO_set_flags(context, BIO_FLAGS_BASE64_NO_NL);
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
// Encode all the data
|
|
Packit Service |
5a9772 |
BIO_write(context, [self bytes], [self length]);
|
|
Packit Service |
5a9772 |
(void)BIO_flush(context);
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
// Get the data out of the context
|
|
Packit Service |
5a9772 |
char *outputBuffer;
|
|
Packit Service |
5a9772 |
long outputLength = BIO_get_mem_data(context, &outputBuffer);
|
|
Packit Service |
5a9772 |
NSString *encodedString = [[NSString alloc] initWithBytes:outputBuffer
|
|
Packit Service |
5a9772 |
length:outputLength
|
|
Packit Service |
5a9772 |
encoding:NSASCIIStringEncoding];
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
BIO_free_all(context);
|
|
Packit Service |
5a9772 |
|
|
Packit Service |
5a9772 |
return encodedString;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
@end
|