| /* ------------------------------------------------------------------ |
| * Copyright (C) 2008 PacketVideo |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
| * express or implied. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * ------------------------------------------------------------------- |
| */ |
| #ifndef BASE64_CODEC_H_INCLUDED |
| #include "base64_codec.h" |
| #endif |
| |
| |
| OSCL_EXPORT_REF PVBase64Codec::PVBase64Codec() |
| { |
| int32 i; |
| //encoder table |
| { |
| for (i = 0;i < 9;i++) |
| { |
| etable[i] = OSCL_STATIC_CAST(uint8, 'A' + i); |
| etable[i+9] = OSCL_STATIC_CAST(uint8, 'J' + i); |
| etable[26+i] = OSCL_STATIC_CAST(uint8, 'a' + i); |
| etable[26+i+9] = OSCL_STATIC_CAST(uint8, 'j' + i); |
| } |
| for (i = 0;i < 8;i++) |
| { |
| etable[i+18] = OSCL_STATIC_CAST(uint8, 'S' + i); |
| etable[26+i+18] = OSCL_STATIC_CAST(uint8, 's' + i); |
| } |
| for (i = 0;i < 10;i++) |
| { |
| etable[52+i] = OSCL_STATIC_CAST(uint8, '0' + i); |
| } |
| etable[62] = '+'; |
| etable[63] = '/'; |
| } |
| |
| //deocder table |
| for (i = 0;i < 255;i++) |
| { |
| dtable[i] = 0x80; |
| } |
| for (i = 'A';i <= 'I';i++) |
| { |
| dtable[i] = OSCL_STATIC_CAST(uint8, 0 + (i - 'A')); |
| } |
| for (i = 'J';i <= 'R';i++) |
| { |
| dtable[i] = OSCL_STATIC_CAST(uint8, 9 + (i - 'J')); |
| } |
| for (i = 'S';i <= 'Z';i++) |
| { |
| dtable[i] = OSCL_STATIC_CAST(uint8, 18 + (i - 'S')); |
| } |
| for (i = 'a';i <= 'i';i++) |
| { |
| dtable[i] = OSCL_STATIC_CAST(uint8, 26 + (i - 'a')); |
| } |
| for (i = 'j';i <= 'r';i++) |
| { |
| dtable[i] = OSCL_STATIC_CAST(uint8, 35 + (i - 'j')); |
| } |
| for (i = 's';i <= 'z';i++) |
| { |
| dtable[i] = OSCL_STATIC_CAST(uint8, 44 + (i - 's')); |
| } |
| for (i = '0';i <= '9';i++) |
| { |
| dtable[i] = OSCL_STATIC_CAST(uint8, 52 + (i - '0')); |
| } |
| dtable[(uint16)'+'] = 62; |
| dtable[(uint16)'/'] = 63; |
| dtable[(uint16)'='] = 0; |
| } |
| |
| bool PVBase64Codec::Decode(uint8* aInBuf, uint32 aInBufLen, |
| uint8* aOutBuf, uint32& aOutBufLen, uint32 aMaxOutBufLen) |
| { |
| oscl_memset(aOutBuf, 0, aMaxOutBufLen); |
| aOutBufLen = 0; |
| |
| uint32 read_count = 0; |
| uint32 write_count = 0; |
| while (read_count < aInBufLen) |
| { |
| uint8 a[4], b[4], o[3]; |
| |
| int i; |
| for (i = 0;i < 4;i++) |
| { |
| uint8 c = *(aInBuf++); |
| read_count++; |
| |
| if (read_count > aInBufLen) |
| { |
| //Input incomplete |
| return false; |
| } |
| if (dtable[(uint16)c]&0x80) |
| { |
| //Illegal character in |
| //return false; |
| i--; |
| continue; |
| } |
| a[i] = (uint8)c; |
| b[i] = (uint8)dtable[(uint16)c]; |
| } |
| o[0] = OSCL_STATIC_CAST(uint8, (b[0] << 2) | (b[1] >> 4)); |
| o[1] = OSCL_STATIC_CAST(uint8, (b[1] << 4) | (b[2] >> 2)); |
| o[2] = OSCL_STATIC_CAST(uint8, (b[2] << 6) | b[3]); |
| i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3); |
| oscl_memcpy(aOutBuf, o, i); |
| aOutBuf += i; |
| write_count += i; |
| if (write_count > aMaxOutBufLen) |
| { |
| return false; |
| } |
| if (i < 3) |
| { |
| break; |
| } |
| } |
| aOutBufLen = write_count; |
| return true; |
| } |
| |
| OSCL_EXPORT_REF bool PVBase64Codec::Encode(uint8* aInBuf, uint32 aInBufLen, |
| uint8* aOutBuf, uint32& aOutBufLen, uint32 aMaxOutBufLen) |
| { |
| int i; |
| uint32 read_count = 0; |
| uint32 write_count = 0; |
| while (read_count < aInBufLen) |
| { |
| uint8 igroup[3], ogroup[4]; |
| igroup[0] = igroup[1] = igroup[2] = 0; |
| int n; |
| for (n = 0; n < 3; n++) |
| { |
| uint8 c = *(aInBuf++); |
| read_count++; |
| if (read_count > aInBufLen) |
| { |
| //Input incomplete |
| //return false; |
| break; |
| } |
| igroup[n] = (uint8) c; |
| } |
| if (n > 0) |
| { |
| ogroup[0] = etable [igroup[0] >> 2]; |
| ogroup[1] = etable [((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; |
| ogroup[2] = etable [((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; |
| ogroup[3] = etable [igroup[2] & 0x3F]; |
| /* Replace characters in output stream with = pad |
| characters if fewer than three characters were read from |
| the end of the input stream. */ |
| if (n < 3) |
| { |
| ogroup[3] = '='; |
| if (n < 2) |
| { |
| ogroup[2] = '='; |
| } |
| } |
| for (i = 0; i < 4; i++) |
| { |
| aOutBuf[write_count] = ogroup[i]; |
| write_count++; |
| if (write_count > aMaxOutBufLen) |
| { |
| return false; |
| } |
| } |
| } |
| } |
| aOutBufLen = write_count; |
| return true; |
| } |
| |
| |