diff options
Diffstat (limited to 'Source/SPDataBase64EncodingAdditions.m')
-rw-r--r-- | Source/SPDataBase64EncodingAdditions.m | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/Source/SPDataBase64EncodingAdditions.m b/Source/SPDataBase64EncodingAdditions.m new file mode 100644 index 00000000..9ca32b14 --- /dev/null +++ b/Source/SPDataBase64EncodingAdditions.m @@ -0,0 +1,117 @@ +// +// $Id$ +// +// SPDataBase64EncodingAdditions.m +// sequel-pro +// +// Created by Rowan Beentje on March 18th, 2012 +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at <http://code.google.com/p/sequel-pro/> + + +#import "SPDataBase64EncodingAdditions.h" + +static const char _base64EncodingTable[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +@implementation NSData (SPDataBase64EncodingAdditions) + +/** + * Returns a base64-encoded representation of the NSData as an NSString, + * on a single line. + */ +- (NSString *)base64Encoding +{ + return [self base64EncodingWithLineLength:NSNotFound]; +} + +/** + * Returns a base64-encoded representation of the NSData as an NSString. + * Takes an argument for the maximum output line length; supply 0 or NSNotFound + * to have the results on a single line. + * + * Derived from the MIT-licensed Quasidea Development QSUtilities implementation, + * available in its original form at https://github.com/mikeho/QSUtilities ; + * QSUtilities implementation author Mike Ho, Copyright (c) 2010 - 2011 + * Quasidea Development, LLC . + * + * That implementation is itself an implementation ported from the PHP core; + * the PHP implementation is covered by the PHP license, a BSD-alike which + * is available at http://www.php.net/license/3_01.txt . + * PHP implementation author Jim Winstead <jimw@php.net>, Copyright (c) 1997-2012 + * The PHP Group. + */ +- (NSString *)base64EncodingWithLineLength:(NSUInteger)lineLength +{ + const unsigned char *objRawData = [self bytes]; + char *objPointer; + char *strResult; + + // Line length details - record bool and tweak to account for 3-octet processing + BOOL hasMaxLineLength = (lineLength && lineLength != NSNotFound); + NSUInteger maxLineLengthChunks = hasMaxLineLength ? floorf(lineLength / 4) : 1; + if (!maxLineLengthChunks) maxLineLengthChunks++; + + // Get the Raw Data length and ensure we actually have data + size_t intLength = [self length]; + if (intLength == 0) return nil; + + // Setup the String-based result placeholder and pointer within that placeholder + size_t encodedLength = ceilf((intLength + 2) / 3) * 4; + if (hasMaxLineLength) encodedLength += ceilf(encodedLength / (maxLineLengthChunks * 4)) - 1; + strResult = (char *)calloc(encodedLength, sizeof(char)); + objPointer = strResult; + + // Iterate through everything + NSUInteger octetsOnLine = 0; + while (intLength > 2) { // keep going until we have less than 24 bits + *objPointer++ = _base64EncodingTable[objRawData[0] >> 2]; + *objPointer++ = _base64EncodingTable[((objRawData[0] & 0x03) << 4) + (objRawData[1] >> 4)]; + *objPointer++ = _base64EncodingTable[((objRawData[1] & 0x0f) << 2) + (objRawData[2] >> 6)]; + *objPointer++ = _base64EncodingTable[objRawData[2] & 0x3f]; + + // we just handled 3 octets (24 bits) of data + objRawData += 3; + intLength -= 3; + + if (hasMaxLineLength) { + octetsOnLine++; + if (octetsOnLine >= maxLineLengthChunks) { + *objPointer++ = '\n'; + octetsOnLine = 0; + } + } + } + + // now deal with the tail end of things + if (intLength != 0) { + *objPointer++ = _base64EncodingTable[objRawData[0] >> 2]; + if (intLength > 1) { + *objPointer++ = _base64EncodingTable[((objRawData[0] & 0x03) << 4) + (objRawData[1] >> 4)]; + *objPointer++ = _base64EncodingTable[(objRawData[1] & 0x0f) << 2]; + *objPointer++ = '='; + } else { + *objPointer++ = _base64EncodingTable[(objRawData[0] & 0x03) << 4]; + *objPointer++ = '='; + *objPointer++ = '='; + } + } + + NSString *strToReturn = [[NSString alloc] initWithBytesNoCopy:strResult length:objPointer - strResult encoding:NSASCIIStringEncoding freeWhenDone:YES]; + return [strToReturn autorelease]; +} + +@end |