Home | History | Annotate | Download | only in objmng
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <objmng/drm_decoder.h>
     18 
     19 /* global variables */
     20 static const uint8_t * base64_alphabet = (const uint8_t *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     21 
     22 #define SKIP_CRLF(p) while('\r' == *(p) || '\n' == *(p)) \
     23                          p++
     24 
     25 static int8_t get_alphabet_index(int8_t ch)
     26 {
     27     uint8_t * tmp;
     28 
     29     if ('=' == ch)
     30         return 64;
     31 
     32     tmp = (uint8_t *)strchr((const char *)base64_alphabet, ch);
     33     if (NULL == tmp)
     34         return -1;
     35 
     36     return (int8_t)(tmp - base64_alphabet);
     37 }
     38 
     39 /* See drm_decoder.h */
     40 int32_t drm_decodeBase64(uint8_t * dest, int32_t destLen, uint8_t * src, int32_t * srcLen)
     41 {
     42     int32_t maxDestSize, i, maxGroup;
     43     uint8_t *pDest, *pSrc;
     44     int8_t tpChar;
     45 
     46     if (NULL == src || NULL == srcLen || *srcLen <= 0 || destLen < 0)
     47         return -1;
     48 
     49     maxDestSize = (*srcLen) * 3/4;
     50     if (NULL == dest || 0 == destLen)
     51         return maxDestSize;
     52 
     53     if (destLen < maxDestSize)
     54         maxDestSize = destLen;
     55     maxGroup = maxDestSize/3;
     56 
     57     pDest = dest;   /* start to decode src to dest */
     58     pSrc = src;
     59     for (i = 0; i < maxGroup && *srcLen - (pSrc - src) >= 4; i++) {
     60         SKIP_CRLF(pSrc);
     61         if (pSrc - src >= *srcLen)
     62             break;
     63         tpChar = get_alphabet_index(*pSrc);       /* to first byte */
     64         if (-1 == tpChar || 64 == tpChar)
     65             return -1;
     66         pDest[0] = tpChar << 2;
     67         pSrc++;
     68         SKIP_CRLF(pSrc);
     69         tpChar = get_alphabet_index(*pSrc);
     70         if (-1 == tpChar || 64 == tpChar)
     71             return -1;
     72         pDest[0] |= (tpChar >> 4);
     73         pDest[1] = tpChar << 4;                     /* to second byte */
     74         pSrc++;
     75         SKIP_CRLF(pSrc);
     76         tpChar = get_alphabet_index(*pSrc);
     77         if (-1 == tpChar)
     78             return -1;
     79         if (64 == tpChar)           /* end */
     80             return pDest - dest + 1;
     81         pDest[1] |= (tpChar >> 2);
     82         pDest[2] = tpChar << 6;                     /* to third byte */
     83         pSrc++;
     84         SKIP_CRLF(pSrc);
     85         tpChar = get_alphabet_index(*pSrc);
     86         if (-1 == tpChar)
     87             return -1;
     88         if (64 == tpChar)           /* end */
     89             return pDest - dest + 2;
     90         pDest[2] |= tpChar;
     91         pDest += 3;
     92         pSrc++;
     93     }
     94     *srcLen = pSrc - src;
     95     return pDest - dest;
     96 }
     97