| OLD | NEW |
| (Empty) |
| 1 /* libs/graphics/animator/SkBase64.cpp | |
| 2 ** | |
| 3 ** Copyright 2006, The Android Open Source Project | |
| 4 ** | |
| 5 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
| 6 ** you may not use this file except in compliance with the License. | |
| 7 ** You may obtain a copy of the License at | |
| 8 ** | |
| 9 ** http://www.apache.org/licenses/LICENSE-2.0 | |
| 10 ** | |
| 11 ** Unless required by applicable law or agreed to in writing, software | |
| 12 ** distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 ** See the License for the specific language governing permissions and | |
| 15 ** limitations under the License. | |
| 16 */ | |
| 17 | |
| 18 #include "SkBase64.h" | |
| 19 | |
| 20 #define DecodePad -2 | |
| 21 #define EncodePad 64 | |
| 22 | |
| 23 static const char encode[] = | |
| 24 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | |
| 25 "abcdefghijklmnopqrstuvwxyz" | |
| 26 "0123456789+/="; | |
| 27 | |
| 28 static const signed char decodeData[] = { | |
| 29 62, -1, -1, -1, 63, | |
| 30 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, DecodePad, -1, -1, | |
| 31 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, | |
| 32 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, | |
| 33 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, | |
| 34 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 | |
| 35 }; | |
| 36 | |
| 37 SkBase64::SkBase64() : fLength((size_t) -1), fData(NULL) { | |
| 38 } | |
| 39 | |
| 40 #if defined _WIN32 && _MSC_VER >= 1300 // disable 'two', etc. may be used witho
ut having been initialized | |
| 41 #pragma warning ( push ) | |
| 42 #pragma warning ( disable : 4701 ) | |
| 43 #endif | |
| 44 | |
| 45 SkBase64::Error SkBase64::decode(const void* srcPtr, size_t size, bool writeDest
ination) { | |
| 46 unsigned char* dst = (unsigned char*) fData; | |
| 47 const unsigned char* dstStart = (const unsigned char*) fData; | |
| 48 const unsigned char* src = (const unsigned char*) srcPtr; | |
| 49 bool padTwo = false; | |
| 50 bool padThree = false; | |
| 51 const unsigned char* end = src + size; | |
| 52 while (src < end) { | |
| 53 unsigned char bytes[4]; | |
| 54 int byte = 0; | |
| 55 do { | |
| 56 unsigned char srcByte = *src++; | |
| 57 if (srcByte == 0) | |
| 58 goto goHome; | |
| 59 if (srcByte <= ' ') | |
| 60 continue; // treat as white space | |
| 61 if (srcByte < '+' || srcByte > 'z') | |
| 62 return kBadCharError; | |
| 63 signed char decoded = decodeData[srcByte - '+']; | |
| 64 bytes[byte] = decoded; | |
| 65 if (decoded < 0) { | |
| 66 if (decoded == DecodePad) | |
| 67 goto handlePad; | |
| 68 return kBadCharError; | |
| 69 } else | |
| 70 byte++; | |
| 71 if (*src) | |
| 72 continue; | |
| 73 if (byte == 0) | |
| 74 goto goHome; | |
| 75 if (byte == 4) | |
| 76 break; | |
| 77 handlePad: | |
| 78 if (byte < 2) | |
| 79 return kPadError; | |
| 80 padThree = true; | |
| 81 if (byte == 2) | |
| 82 padTwo = true; | |
| 83 break; | |
| 84 } while (byte < 4); | |
| 85 int two, three; | |
| 86 if (writeDestination) { | |
| 87 int one = (uint8_t) (bytes[0] << 2); | |
| 88 two = bytes[1]; | |
| 89 one |= two >> 4; | |
| 90 two = (uint8_t) (two << 4); | |
| 91 three = bytes[2]; | |
| 92 two |= three >> 2; | |
| 93 three = (uint8_t) (three << 6); | |
| 94 three |= bytes[3]; | |
| 95 SkASSERT(one < 256 && two < 256 && three < 256); | |
| 96 *dst = (unsigned char) one; | |
| 97 } | |
| 98 dst++; | |
| 99 if (padTwo) | |
| 100 break; | |
| 101 if (writeDestination) | |
| 102 *dst = (unsigned char) two; | |
| 103 dst++; | |
| 104 if (padThree) | |
| 105 break; | |
| 106 if (writeDestination) | |
| 107 *dst = (unsigned char) three; | |
| 108 dst++; | |
| 109 } | |
| 110 goHome: | |
| 111 fLength = dst - dstStart; | |
| 112 return kNoError; | |
| 113 } | |
| 114 | |
| 115 #if defined _WIN32 && _MSC_VER >= 1300 | |
| 116 #pragma warning ( pop ) | |
| 117 #endif | |
| 118 | |
| 119 size_t SkBase64::Encode(const void* srcPtr, size_t length, void* dstPtr) { | |
| 120 const unsigned char* src = (const unsigned char*) srcPtr; | |
| 121 unsigned char* dst = (unsigned char*) dstPtr; | |
| 122 if (dst) { | |
| 123 size_t remainder = length % 3; | |
| 124 const unsigned char* end = &src[length - remainder]; | |
| 125 while (src < end) { | |
| 126 unsigned a = *src++; | |
| 127 unsigned b = *src++; | |
| 128 unsigned c = *src++; | |
| 129 int d = c & 0x3F; | |
| 130 c = (c >> 6 | b << 2) & 0x3F; | |
| 131 b = (b >> 4 | a << 4) & 0x3F; | |
| 132 a = a >> 2; | |
| 133 *dst++ = encode[a]; | |
| 134 *dst++ = encode[b]; | |
| 135 *dst++ = encode[c]; | |
| 136 *dst++ = encode[d]; | |
| 137 } | |
| 138 if (remainder > 0) { | |
| 139 int k1 = 0; | |
| 140 int k2 = EncodePad; | |
| 141 int a = (uint8_t) *src++; | |
| 142 if (remainder == 2) | |
| 143 { | |
| 144 int b = *src++; | |
| 145 k1 = b >> 4; | |
| 146 k2 = (b << 2) & 0x3F; | |
| 147 } | |
| 148 *dst++ = encode[a >> 2]; | |
| 149 *dst++ = encode[(k1 | a << 4) & 0x3F]; | |
| 150 *dst++ = encode[k2]; | |
| 151 *dst++ = encode[EncodePad]; | |
| 152 } | |
| 153 } | |
| 154 return (length + 2) / 3 * 4; | |
| 155 } | |
| 156 | |
| 157 SkBase64::Error SkBase64::decode(const char* src, size_t len) { | |
| 158 Error err = decode(src, len, false); | |
| 159 SkASSERT(err == kNoError); | |
| 160 if (err != kNoError) | |
| 161 return err; | |
| 162 fData = new char[fLength]; // should use sk_malloc/sk_free | |
| 163 decode(src, len, true); | |
| 164 return kNoError; | |
| 165 } | |
| 166 | |
| 167 #ifdef SK_SUPPORT_UNITTEST | |
| 168 void SkBase64::UnitTest() { | |
| 169 signed char all[256]; | |
| 170 for (int index = 0; index < 256; index++) | |
| 171 all[index] = (signed char) (index + 1); | |
| 172 for (int offset = 0; offset < 6; offset++) { | |
| 173 size_t length = 256 - offset; | |
| 174 size_t encodeLength = Encode(all + offset, length, NULL); | |
| 175 char* src = (char*)sk_malloc_throw(encodeLength + 1); | |
| 176 Encode(all + offset, length, src); | |
| 177 src[encodeLength] = '\0'; | |
| 178 SkBase64 tryMe; | |
| 179 tryMe.decode(src, encodeLength); | |
| 180 SkASSERT(length == tryMe.fLength); | |
| 181 SkASSERT(strcmp((const char*) (all + offset), tryMe.fData) == 0); | |
| 182 sk_free(src); | |
| 183 delete[] tryMe.fData; | |
| 184 } | |
| 185 } | |
| 186 #endif | |
| 187 | |
| 188 | |
| OLD | NEW |