123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- /* Copyright (c) 2012 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- //#import <GoogleAPIClientForREST/GTLRBase64.h>
- #import "GTLRBase64.h"
- // Based on Cyrus Najmabadi's elegent little encoder and decoder from
- // http://www.cocoadev.com/index.pl?BaseSixtyFour
- static char gStandardEncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- static char gWebSafeEncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
- #pragma mark Encode
- static NSString *EncodeBase64StringCommon(NSData *data, const char *table) {
- if (data == nil) return nil;
- const uint8_t* input = data.bytes;
- NSUInteger length = data.length;
- NSUInteger bufferSize = ((length + 2) / 3) * 4;
- NSMutableData* buffer = [NSMutableData dataWithLength:bufferSize];
- int8_t *output = buffer.mutableBytes;
- for (NSUInteger i = 0; i < length; i += 3) {
- NSUInteger value = 0;
- for (NSUInteger j = i; j < (i + 3); j++) {
- value <<= 8;
- if (j < length) {
- value |= (0xFF & input[j]);
- }
- }
- NSInteger idx = (i / 3) * 4;
- output[idx + 0] = table[(value >> 18) & 0x3F];
- output[idx + 1] = table[(value >> 12) & 0x3F];
- output[idx + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '=';
- output[idx + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '=';
- }
- NSString *result = [[NSString alloc] initWithData:buffer
- encoding:NSASCIIStringEncoding];
- return result;
- }
- NSString *GTLREncodeBase64(NSData *data) {
- return EncodeBase64StringCommon(data, gStandardEncodingTable);
- }
- NSString *GTLREncodeWebSafeBase64(NSData *data) {
- return EncodeBase64StringCommon(data, gWebSafeEncodingTable);
- }
- #pragma mark Decode
- static void CreateDecodingTable(const char *encodingTable,
- size_t encodingTableSize, char *decodingTable) {
- memset(decodingTable, 0, 128);
- for (unsigned int i = 0; i < encodingTableSize; i++) {
- decodingTable[(unsigned int) encodingTable[i]] = (char)i;
- }
- }
- static NSData *DecodeBase64StringCommon(NSString *base64Str,
- char *decodingTable,
- BOOL requirePadding) {
- // The input string should be plain ASCII
- const char *cString = [base64Str cStringUsingEncoding:NSASCIIStringEncoding];
- if (cString == nil) return nil;
- NSInteger inputLength = (NSInteger)strlen(cString);
- if (requirePadding && (inputLength % 4 != 0)) return nil;
- if (inputLength == 0) return [NSData data];
- NSInteger numEquals = 0;
- while (inputLength > 0 && cString[inputLength - 1] == '=') {
- inputLength--;
- if (++numEquals > 2) return nil; // malformed input
- }
- NSInteger outputLength = inputLength * 3 / 4;
- NSMutableData* data = [NSMutableData dataWithLength:(NSUInteger)outputLength];
- uint8_t *output = data.mutableBytes;
- NSInteger inputPoint = 0;
- NSInteger outputPoint = 0;
- char *table = decodingTable;
- while (inputPoint < inputLength) {
- int i0 = cString[inputPoint++];
- int i1 = cString[inputPoint++];
- int i2 = inputPoint < inputLength ? cString[inputPoint++] : 'A'; // 'A' will decode to \0
- int i3 = inputPoint < inputLength ? cString[inputPoint++] : 'A';
- output[outputPoint++] = (uint8_t)((table[i0] << 2) | (table[i1] >> 4));
- if (outputPoint < outputLength) {
- output[outputPoint++] = (uint8_t)(((table[i1] & 0xF) << 4) | (table[i2] >> 2));
- }
- if (outputPoint < outputLength) {
- output[outputPoint++] = (uint8_t)(((table[i2] & 0x3) << 6) | table[i3]);
- }
- }
- return data;
- }
- NSData *GTLRDecodeBase64(NSString *base64Str) {
- static char decodingTable[128];
- static BOOL hasInited = NO;
- if (!hasInited) {
- CreateDecodingTable(gStandardEncodingTable, sizeof(gStandardEncodingTable),
- decodingTable);
- hasInited = YES;
- }
- return DecodeBase64StringCommon(base64Str, decodingTable, YES /* requirePadding */ );
- }
- NSData *GTLRDecodeWebSafeBase64(NSString *base64Str) {
- static char decodingTable[128];
- static BOOL hasInited = NO;
- if (!hasInited) {
- CreateDecodingTable(gWebSafeEncodingTable, sizeof(gWebSafeEncodingTable),
- decodingTable);
- hasInited = YES;
- }
- return DecodeBase64StringCommon(base64Str, decodingTable, NO /* requirePadding */);
- }
|