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