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

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/utils/SkBase64.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,164 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2006 The Android Open Source Project
     1.7 + *
     1.8 + * Use of this source code is governed by a BSD-style license that can be
     1.9 + * found in the LICENSE file.
    1.10 + */
    1.11 +
    1.12 +
    1.13 +#include "SkBase64.h"
    1.14 +
    1.15 +#define DecodePad -2
    1.16 +#define EncodePad 64
    1.17 +
    1.18 +static const char default_encode[] =
    1.19 +    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    1.20 +    "abcdefghijklmnopqrstuvwxyz"
    1.21 +    "0123456789+/=";
    1.22 +
    1.23 +static const signed char decodeData[] = {
    1.24 +    62, -1, -1, -1, 63,
    1.25 +    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, DecodePad, -1, -1,
    1.26 +    -1,  0,  1,  2,  3,  4,  5,  6, 7,  8,  9, 10, 11, 12, 13, 14,
    1.27 +    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
    1.28 +    -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    1.29 +    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
    1.30 +};
    1.31 +
    1.32 +SkBase64::SkBase64() : fLength((size_t) -1), fData(NULL) {
    1.33 +}
    1.34 +
    1.35 +#if defined _WIN32 && _MSC_VER >= 1300  // disable 'two', etc. may be used without having been initialized
    1.36 +#pragma warning ( push )
    1.37 +#pragma warning ( disable : 4701 )
    1.38 +#endif
    1.39 +
    1.40 +SkBase64::Error SkBase64::decode(const void* srcPtr, size_t size, bool writeDestination) {
    1.41 +    unsigned char* dst = (unsigned char*) fData;
    1.42 +    const unsigned char* dstStart = (const unsigned char*) fData;
    1.43 +    const unsigned char* src = (const unsigned char*) srcPtr;
    1.44 +    bool padTwo = false;
    1.45 +    bool padThree = false;
    1.46 +    const unsigned char* end = src + size;
    1.47 +    while (src < end) {
    1.48 +        unsigned char bytes[4];
    1.49 +        int byte = 0;
    1.50 +        do {
    1.51 +            unsigned char srcByte = *src++;
    1.52 +            if (srcByte == 0)
    1.53 +                goto goHome;
    1.54 +            if (srcByte <= ' ')
    1.55 +                continue; // treat as white space
    1.56 +            if (srcByte < '+' || srcByte > 'z')
    1.57 +                return kBadCharError;
    1.58 +            signed char decoded = decodeData[srcByte - '+'];
    1.59 +            bytes[byte] = decoded;
    1.60 +            if (decoded < 0) {
    1.61 +                if (decoded == DecodePad)
    1.62 +                    goto handlePad;
    1.63 +                return kBadCharError;
    1.64 +            } else
    1.65 +                byte++;
    1.66 +            if (*src)
    1.67 +                continue;
    1.68 +            if (byte == 0)
    1.69 +                goto goHome;
    1.70 +            if (byte == 4)
    1.71 +                break;
    1.72 +handlePad:
    1.73 +            if (byte < 2)
    1.74 +                return kPadError;
    1.75 +            padThree = true;
    1.76 +            if (byte == 2)
    1.77 +                padTwo = true;
    1.78 +            break;
    1.79 +        } while (byte < 4);
    1.80 +        int two = 0;
    1.81 +        int three = 0;
    1.82 +        if (writeDestination) {
    1.83 +            int one = (uint8_t) (bytes[0] << 2);
    1.84 +            two = bytes[1];
    1.85 +            one |= two >> 4;
    1.86 +            two = (uint8_t) (two << 4);
    1.87 +            three = bytes[2];
    1.88 +            two |= three >> 2;
    1.89 +            three = (uint8_t) (three << 6);
    1.90 +            three |= bytes[3];
    1.91 +            SkASSERT(one < 256 && two < 256 && three < 256);
    1.92 +            *dst = (unsigned char) one;
    1.93 +        }
    1.94 +        dst++;
    1.95 +        if (padTwo)
    1.96 +            break;
    1.97 +        if (writeDestination)
    1.98 +            *dst = (unsigned char) two;
    1.99 +        dst++;
   1.100 +        if (padThree)
   1.101 +            break;
   1.102 +        if (writeDestination)
   1.103 +            *dst = (unsigned char) three;
   1.104 +        dst++;
   1.105 +    }
   1.106 +goHome:
   1.107 +    fLength = dst - dstStart;
   1.108 +    return kNoError;
   1.109 +}
   1.110 +
   1.111 +#if defined _WIN32 && _MSC_VER >= 1300
   1.112 +#pragma warning ( pop )
   1.113 +#endif
   1.114 +
   1.115 +size_t SkBase64::Encode(const void* srcPtr, size_t length, void* dstPtr, const char* encodeMap) {
   1.116 +    const char* encode;
   1.117 +    if (NULL == encodeMap) {
   1.118 +        encode = default_encode;
   1.119 +    } else {
   1.120 +        encode = encodeMap;
   1.121 +    }
   1.122 +    const unsigned char* src = (const unsigned char*) srcPtr;
   1.123 +    unsigned char* dst = (unsigned char*) dstPtr;
   1.124 +    if (dst) {
   1.125 +        size_t remainder = length % 3;
   1.126 +        const unsigned char* end = &src[length - remainder];
   1.127 +        while (src < end) {
   1.128 +            unsigned a = *src++;
   1.129 +            unsigned b = *src++;
   1.130 +            unsigned c = *src++;
   1.131 +            int      d = c & 0x3F;
   1.132 +            c = (c >> 6 | b << 2) & 0x3F;
   1.133 +            b = (b >> 4 | a << 4) & 0x3F;
   1.134 +            a = a >> 2;
   1.135 +            *dst++ = encode[a];
   1.136 +            *dst++ = encode[b];
   1.137 +            *dst++ = encode[c];
   1.138 +            *dst++ = encode[d];
   1.139 +        }
   1.140 +        if (remainder > 0) {
   1.141 +            int k1 = 0;
   1.142 +            int k2 = EncodePad;
   1.143 +            int a = (uint8_t) *src++;
   1.144 +            if (remainder == 2)
   1.145 +            {
   1.146 +                int b = *src++;
   1.147 +                k1 = b >> 4;
   1.148 +                k2 = (b << 2) & 0x3F;
   1.149 +            }
   1.150 +            *dst++ = encode[a >> 2];
   1.151 +            *dst++ = encode[(k1 | a << 4) & 0x3F];
   1.152 +            *dst++ = encode[k2];
   1.153 +            *dst++ = encode[EncodePad];
   1.154 +        }
   1.155 +    }
   1.156 +    return (length + 2) / 3 * 4;
   1.157 +}
   1.158 +
   1.159 +SkBase64::Error SkBase64::decode(const char* src, size_t len) {
   1.160 +    Error err = decode(src, len, false);
   1.161 +    SkASSERT(err == kNoError);
   1.162 +    if (err != kNoError)
   1.163 +        return err;
   1.164 +    fData = new char[fLength];  // should use sk_malloc/sk_free
   1.165 +    decode(src, len, true);
   1.166 +    return kNoError;
   1.167 +}

mercurial