Blame client/iOS/Additions/TSXAdditions.m

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