gfx/skia/trunk/src/utils/SkBase64.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1
michael@0 2 /*
michael@0 3 * Copyright 2006 The Android Open Source Project
michael@0 4 *
michael@0 5 * Use of this source code is governed by a BSD-style license that can be
michael@0 6 * found in the LICENSE file.
michael@0 7 */
michael@0 8
michael@0 9
michael@0 10 #include "SkBase64.h"
michael@0 11
michael@0 12 #define DecodePad -2
michael@0 13 #define EncodePad 64
michael@0 14
michael@0 15 static const char default_encode[] =
michael@0 16 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
michael@0 17 "abcdefghijklmnopqrstuvwxyz"
michael@0 18 "0123456789+/=";
michael@0 19
michael@0 20 static const signed char decodeData[] = {
michael@0 21 62, -1, -1, -1, 63,
michael@0 22 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, DecodePad, -1, -1,
michael@0 23 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
michael@0 24 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
michael@0 25 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
michael@0 26 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
michael@0 27 };
michael@0 28
michael@0 29 SkBase64::SkBase64() : fLength((size_t) -1), fData(NULL) {
michael@0 30 }
michael@0 31
michael@0 32 #if defined _WIN32 && _MSC_VER >= 1300 // disable 'two', etc. may be used without having been initialized
michael@0 33 #pragma warning ( push )
michael@0 34 #pragma warning ( disable : 4701 )
michael@0 35 #endif
michael@0 36
michael@0 37 SkBase64::Error SkBase64::decode(const void* srcPtr, size_t size, bool writeDestination) {
michael@0 38 unsigned char* dst = (unsigned char*) fData;
michael@0 39 const unsigned char* dstStart = (const unsigned char*) fData;
michael@0 40 const unsigned char* src = (const unsigned char*) srcPtr;
michael@0 41 bool padTwo = false;
michael@0 42 bool padThree = false;
michael@0 43 const unsigned char* end = src + size;
michael@0 44 while (src < end) {
michael@0 45 unsigned char bytes[4];
michael@0 46 int byte = 0;
michael@0 47 do {
michael@0 48 unsigned char srcByte = *src++;
michael@0 49 if (srcByte == 0)
michael@0 50 goto goHome;
michael@0 51 if (srcByte <= ' ')
michael@0 52 continue; // treat as white space
michael@0 53 if (srcByte < '+' || srcByte > 'z')
michael@0 54 return kBadCharError;
michael@0 55 signed char decoded = decodeData[srcByte - '+'];
michael@0 56 bytes[byte] = decoded;
michael@0 57 if (decoded < 0) {
michael@0 58 if (decoded == DecodePad)
michael@0 59 goto handlePad;
michael@0 60 return kBadCharError;
michael@0 61 } else
michael@0 62 byte++;
michael@0 63 if (*src)
michael@0 64 continue;
michael@0 65 if (byte == 0)
michael@0 66 goto goHome;
michael@0 67 if (byte == 4)
michael@0 68 break;
michael@0 69 handlePad:
michael@0 70 if (byte < 2)
michael@0 71 return kPadError;
michael@0 72 padThree = true;
michael@0 73 if (byte == 2)
michael@0 74 padTwo = true;
michael@0 75 break;
michael@0 76 } while (byte < 4);
michael@0 77 int two = 0;
michael@0 78 int three = 0;
michael@0 79 if (writeDestination) {
michael@0 80 int one = (uint8_t) (bytes[0] << 2);
michael@0 81 two = bytes[1];
michael@0 82 one |= two >> 4;
michael@0 83 two = (uint8_t) (two << 4);
michael@0 84 three = bytes[2];
michael@0 85 two |= three >> 2;
michael@0 86 three = (uint8_t) (three << 6);
michael@0 87 three |= bytes[3];
michael@0 88 SkASSERT(one < 256 && two < 256 && three < 256);
michael@0 89 *dst = (unsigned char) one;
michael@0 90 }
michael@0 91 dst++;
michael@0 92 if (padTwo)
michael@0 93 break;
michael@0 94 if (writeDestination)
michael@0 95 *dst = (unsigned char) two;
michael@0 96 dst++;
michael@0 97 if (padThree)
michael@0 98 break;
michael@0 99 if (writeDestination)
michael@0 100 *dst = (unsigned char) three;
michael@0 101 dst++;
michael@0 102 }
michael@0 103 goHome:
michael@0 104 fLength = dst - dstStart;
michael@0 105 return kNoError;
michael@0 106 }
michael@0 107
michael@0 108 #if defined _WIN32 && _MSC_VER >= 1300
michael@0 109 #pragma warning ( pop )
michael@0 110 #endif
michael@0 111
michael@0 112 size_t SkBase64::Encode(const void* srcPtr, size_t length, void* dstPtr, const char* encodeMap) {
michael@0 113 const char* encode;
michael@0 114 if (NULL == encodeMap) {
michael@0 115 encode = default_encode;
michael@0 116 } else {
michael@0 117 encode = encodeMap;
michael@0 118 }
michael@0 119 const unsigned char* src = (const unsigned char*) srcPtr;
michael@0 120 unsigned char* dst = (unsigned char*) dstPtr;
michael@0 121 if (dst) {
michael@0 122 size_t remainder = length % 3;
michael@0 123 const unsigned char* end = &src[length - remainder];
michael@0 124 while (src < end) {
michael@0 125 unsigned a = *src++;
michael@0 126 unsigned b = *src++;
michael@0 127 unsigned c = *src++;
michael@0 128 int d = c & 0x3F;
michael@0 129 c = (c >> 6 | b << 2) & 0x3F;
michael@0 130 b = (b >> 4 | a << 4) & 0x3F;
michael@0 131 a = a >> 2;
michael@0 132 *dst++ = encode[a];
michael@0 133 *dst++ = encode[b];
michael@0 134 *dst++ = encode[c];
michael@0 135 *dst++ = encode[d];
michael@0 136 }
michael@0 137 if (remainder > 0) {
michael@0 138 int k1 = 0;
michael@0 139 int k2 = EncodePad;
michael@0 140 int a = (uint8_t) *src++;
michael@0 141 if (remainder == 2)
michael@0 142 {
michael@0 143 int b = *src++;
michael@0 144 k1 = b >> 4;
michael@0 145 k2 = (b << 2) & 0x3F;
michael@0 146 }
michael@0 147 *dst++ = encode[a >> 2];
michael@0 148 *dst++ = encode[(k1 | a << 4) & 0x3F];
michael@0 149 *dst++ = encode[k2];
michael@0 150 *dst++ = encode[EncodePad];
michael@0 151 }
michael@0 152 }
michael@0 153 return (length + 2) / 3 * 4;
michael@0 154 }
michael@0 155
michael@0 156 SkBase64::Error SkBase64::decode(const char* src, size_t len) {
michael@0 157 Error err = decode(src, len, false);
michael@0 158 SkASSERT(err == kNoError);
michael@0 159 if (err != kNoError)
michael@0 160 return err;
michael@0 161 fData = new char[fLength]; // should use sk_malloc/sk_free
michael@0 162 decode(src, len, true);
michael@0 163 return kNoError;
michael@0 164 }

mercurial