aboutsummaryrefslogtreecommitdiffstats
path: root/Source/SPDataBase64EncodingAdditions.m
diff options
context:
space:
mode:
Diffstat (limited to 'Source/SPDataBase64EncodingAdditions.m')
-rw-r--r--Source/SPDataBase64EncodingAdditions.m117
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