Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
base64b.cpp
00001 /* 00002 * Copyright (c) 2018 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "base64b.h" 00018 00019 using namespace std; 00020 00021 static char IntToBase64Char(uint8_t intVal) 00022 { 00023 const char *base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 00024 return base64Digits[intVal & 0x3F]; 00025 } 00026 00027 #define BASE_64_PAD 0xFF 00028 static base64_result_e Base64CharToInt(char base64, uint8_t *intVal) 00029 { 00030 if (NULL == intVal) { 00031 return BASE64_INVALID_PARAMETER; 00032 } 00033 00034 if ((base64 >= 'A') && (base64 <= 'Z')) { 00035 *intVal = base64 - 'A' ; 00036 } else if ((base64 >= 'a') && (base64 <= 'z')) { 00037 *intVal = base64 - 'a' + 26; 00038 } else if ((base64 >= '0') && (base64 <= '9')) { 00039 *intVal = base64 - '0' + 52; 00040 } else if (base64 == '+') { 00041 *intVal = 62; 00042 } else if (base64 == '/') { 00043 *intVal = 63; 00044 } else if (base64 == '=') { 00045 *intVal = BASE_64_PAD; 00046 } else { 00047 return BASE64_ERROR; 00048 } 00049 00050 return BASE64_SUCCESS; 00051 } 00052 00053 base64_result_e trng_DecodeNBase64(const char *string, 00054 uint32_t stringMaxSize, 00055 void *buffer, 00056 uint32_t bufferSize, 00057 uint32_t *lengthWritten, 00058 uint32_t *charsProcessed) 00059 { 00060 base64_result_e result = BASE64_SUCCESS; 00061 uint32_t bitOffset = 0; 00062 uint8_t *writePtr = (uint8_t *)buffer; 00063 uint8_t *bufferEnd = (uint8_t *)buffer + bufferSize; 00064 uint8_t tempVal = 0; 00065 uint32_t currPos = 0; 00066 uint32_t localBytesWritten = 0; 00067 uint32_t localCharsProcessed = 0; 00068 bool isEndOfString = false; 00069 00070 if ((NULL == string) || (NULL == buffer) || (bufferSize == 0)) { 00071 return BASE64_INVALID_PARAMETER; 00072 } 00073 00074 *writePtr = 0; 00075 while (( currPos < stringMaxSize ) && 00076 ( string[currPos] != 0 ) && 00077 ( writePtr < bufferEnd ) && 00078 ( !isEndOfString )) { 00079 uint8_t val; 00080 00081 if (string[currPos] == 0) { 00082 break; 00083 } 00084 00085 result = Base64CharToInt(string[currPos++], &val); 00086 if (result != BASE64_SUCCESS) { 00087 break; 00088 } 00089 00090 if (val != BASE_64_PAD) { 00091 if (bitOffset <= 2) { 00092 tempVal |= val << (2 - bitOffset); 00093 if (bitOffset == 2) { 00094 *writePtr++ = tempVal; 00095 tempVal = 0; 00096 } 00097 } else { 00098 *writePtr++ = (uint8_t)(tempVal | (val >> (bitOffset - 2))); 00099 tempVal = (uint8_t)(val << (10 - bitOffset)); 00100 } 00101 } else { // found BASE_64_PAD 00102 // At most two pad characters may occur at the end of the encoded stream 00103 if (bitOffset == 2) { 00104 isEndOfString = true; // The last padding byte has been processed. 00105 } else if (bitOffset != 4) { 00106 return BASE64_ERROR; // Incorrect padding 00107 } 00108 } 00109 00110 bitOffset = (bitOffset + 6) & 0x7; 00111 if (bitOffset == 0) { 00112 localBytesWritten = (uint32_t)(writePtr - (uint8_t *)buffer); 00113 localCharsProcessed = currPos; 00114 } 00115 } 00116 if (charsProcessed == NULL) { 00117 localBytesWritten = (uint32_t)(writePtr - (uint8_t *)buffer); 00118 } else { 00119 *charsProcessed = localCharsProcessed; 00120 } 00121 if (lengthWritten != NULL) { 00122 *lengthWritten = localBytesWritten; 00123 } else if (bufferSize != localBytesWritten) { 00124 return BASE64_BUFFER_TOO_SMALL; 00125 } 00126 00127 // Check if additional bytes should have been processed but buffer isn't sufficient. 00128 if (( result == BASE64_SUCCESS ) && 00129 ( !isEndOfString ) && 00130 ( currPos < stringMaxSize ) && 00131 ( string[currPos] != 0 ) && 00132 ( string[currPos] != '=' ) ) { 00133 return BASE64_BUFFER_TOO_SMALL; 00134 } 00135 00136 if (result != BASE64_SUCCESS) { 00137 return result; 00138 } 00139 00140 return BASE64_SUCCESS; 00141 } 00142 00143 base64_result_e trng_EncodeBase64(const void *buffer, uint32_t bufferSize, char *string, uint32_t stringSize) 00144 { 00145 uint32_t bitOffset = 0; 00146 00147 const uint8_t *readPtr = (const uint8_t *)buffer; 00148 const uint8_t *bufferEnd = (const uint8_t *)buffer + bufferSize; 00149 00150 char *writePtr = string; 00151 char *stringEnd = string + stringSize - 1; 00152 00153 if ((NULL == string) || (NULL == buffer) || (stringSize == 0)) { 00154 return BASE64_INVALID_PARAMETER; 00155 } 00156 00157 stringSize--; 00158 while (readPtr < bufferEnd && writePtr < stringEnd) { 00159 uint8_t tempVal = 0; 00160 switch (bitOffset) { 00161 case 0: 00162 *writePtr++ = IntToBase64Char(*readPtr >> 2); // take upper 6 bits 00163 break; 00164 case 6: 00165 tempVal = *readPtr++ << 4; 00166 if (readPtr < bufferEnd) { 00167 tempVal |= *readPtr >> 4; 00168 } 00169 *writePtr++ = IntToBase64Char(tempVal); 00170 break; 00171 case 4: 00172 tempVal = *readPtr++ << 2; 00173 if (readPtr < bufferEnd) { 00174 tempVal |= *readPtr >> 6; 00175 } 00176 *writePtr++ = IntToBase64Char(tempVal); 00177 break; 00178 case 2: 00179 *writePtr++ = IntToBase64Char(*readPtr++); 00180 break; 00181 default: 00182 return BASE64_ERROR; // we should never reach this code. 00183 } 00184 bitOffset = (bitOffset + 6) & 0x7; 00185 } 00186 while (bitOffset > 0 && writePtr < stringEnd) { 00187 *writePtr++ = '='; 00188 bitOffset = (bitOffset + 6) & 0x7; 00189 } 00190 *writePtr = 0; 00191 00192 if ((readPtr < bufferEnd) || (bitOffset != 0)) { 00193 return (BASE64_BUFFER_TOO_SMALL); 00194 } 00195 00196 return (BASE64_SUCCESS); 00197 }
Generated on Tue Aug 9 2022 00:37:03 by
1.7.2