Blame client/iOS/Additions/TSXAdditions.m

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