diff options
Diffstat (limited to 'src/modules/json/JSON_Base64.cpp')
-rw-r--r-- | src/modules/json/JSON_Base64.cpp | 272 |
1 files changed, 136 insertions, 136 deletions
diff --git a/src/modules/json/JSON_Base64.cpp b/src/modules/json/JSON_Base64.cpp index 07147afadc..66f2002b6b 100644 --- a/src/modules/json/JSON_Base64.cpp +++ b/src/modules/json/JSON_Base64.cpp @@ -1,136 +1,136 @@ -/* - -Miranda IM: the free IM client for Microsoft* Windows* - -Copyright 2000-2009 Miranda ICQ/IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" - -#include "JSON_Base64.h" -#include "JSONDefs.h" - -#ifdef JSON_BINARY //if this is not needed, don't waste space compiling it - -static const json_char * chars64 = JSON_TEXT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"); -#ifdef JSON_UNICODE - static std::string BASE64_EMPTY_STRING; -#else - #define BASE64_EMPTY_STRING EMPTY_STRING -#endif - -json_string JSONBase64::json_encode64(const unsigned char * binary, size_t bytes){ - size_t misaligned = bytes % 3; - size_t aligned = (bytes - misaligned) / 3; //divide by three once and inc is faster than add 3 each time - json_string result; - result.reserve((size_t)(((float)bytes) * 1.37f) + 4); - - //do all of the ones that are 3 byte aligned - for (size_t i=0; i < aligned; ++i){ - result += chars64[(binary[0] & 0xFC) >> 2]; - result += chars64[((binary[0] & 0x03) << 4) + ((binary[1] & 0xF0) >> 4)]; - result += chars64[((binary[1] & 0x0F) << 2) + ((binary[2] & 0xC0) >> 6)]; - result += chars64[binary[2] & 0x3F]; - binary += 3; - } - - if (misaligned){ - //copy the rest into a temporary buffer - unsigned char temp[3]; - for (unsigned int i=0; i < misaligned; ++i){ - temp[i] = *binary++; - } - for (unsigned int i = (unsigned int)misaligned; i < 3; ++i){ - temp[i] = '\0'; - } - - //now do the final three bytes - result += chars64[(temp[0] & 0xFC) >> 2]; - result += chars64[((temp[0] & 0x03) << 4) + ((temp[1] & 0xF0) >> 4)]; - if (misaligned == 2){ - result += chars64[((temp[1] & 0x0F) << 2) + ((temp[2] & 0xC0) >> 6)]; - result += JSON_TEXT('='); - } else { - result += JSON_TEXT(" = = "); - } - } - JSON_ASSERT((size_t)(((float)bytes) * 1.37f) + 4 >= result.length(), JSON_TEXT("Didn't reserve enough space for a one-time go")); - return result; -} - -inline json_char toBinary(json_char c){ - if (c == JSON_TEXT('+')) { - return JSON_TEXT('>'); - } else if (c == JSON_TEXT('/')) { - return JSON_TEXT('?'); - } else if (c < JSON_TEXT(':')) { - return c + JSON_TEXT('\x04'); - } else if (c < JSON_TEXT('[')) { - return c - JSON_TEXT('\x41'); - } - return c - 71; -} - -/* - Must be a std::string because it's binary, and chars must be 1 byte - */ -std::string JSONBase64::json_decode64(const json_string & encoded){ - const size_t length = encoded.length(); - #if defined JSON_DEBUG || defined JSON_SAFE - size_t pos = encoded.find_first_not_of(chars64); - if (pos != json_string::npos){ - JSON_ASSERT_SAFE(encoded[pos] == JSON_TEXT('='), JSON_TEXT("Not Base64"), return BASE64_EMPTY_STRING;); - if (pos != length - 1){ - JSON_ASSERT_SAFE(pos == length - 2, JSON_TEXT("Not Base64"), return BASE64_EMPTY_STRING;); - JSON_ASSERT_SAFE(encoded[pos + 1] == JSON_TEXT('='), JSON_TEXT("Not Base64"), return BASE64_EMPTY_STRING;); - } - } - #endif - const json_char * runner = encoded.c_str(); - size_t aligned = length / 4; //don't do the last ones as they might be = padding - std::string result; - if (aligned){ - --aligned; - result.reserve((size_t)((float)length / 1.37) + 1); - - //first do the ones that can not have any padding - for (unsigned int i=0; i < aligned; ++i){ - const json_char second = toBinary(runner[1]); - const json_char third = toBinary(runner[2]); - result += (toBinary(runner[0]) << 2) + ((second & 0x30) >> 4); - result += ((second & 0xf) << 4) + ((third & 0x3c) >> 2); - result += ((third & 0x3) << 6) + toBinary(runner[3]); - runner += 4; - } - - //now do the ones that might have padding, the first two characters can not be padding, so do them quickly - const char second = toBinary(runner[1]); - result += (toBinary(runner[0]) << 2) + ((second & 0x30) >> 4); - if (runner[2] != '=') { //not two = pads - const char third = toBinary(runner[2]); - result += ((second & 0xf) << 4) + ((third & 0x3c) >> 2); - if (runner[3] != '=') { //no padding - result += ((third & 0x3) << 6) + toBinary(runner[3]); - } - } - } - return result; -} - -#endif +/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright 2000-2009 Miranda ICQ/IM project,
+all portions of this codebase are copyrighted to the people
+listed in contributors.txt.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "..\..\core\commonheaders.h"
+
+#include "JSON_Base64.h"
+#include "JSONDefs.h"
+
+#ifdef JSON_BINARY //if this is not needed, don't waste space compiling it
+
+static const json_char * chars64 = JSON_TEXT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
+#ifdef JSON_UNICODE
+ static std::string BASE64_EMPTY_STRING;
+#else
+ #define BASE64_EMPTY_STRING EMPTY_STRING
+#endif
+
+json_string JSONBase64::json_encode64(const unsigned char * binary, size_t bytes){
+ size_t misaligned = bytes % 3;
+ size_t aligned = (bytes - misaligned) / 3; //divide by three once and inc is faster than add 3 each time
+ json_string result;
+ result.reserve((size_t)(((float)bytes) * 1.37f) + 4);
+
+ //do all of the ones that are 3 byte aligned
+ for (size_t i=0; i < aligned; ++i){
+ result += chars64[(binary[0] & 0xFC) >> 2];
+ result += chars64[((binary[0] & 0x03) << 4) + ((binary[1] & 0xF0) >> 4)];
+ result += chars64[((binary[1] & 0x0F) << 2) + ((binary[2] & 0xC0) >> 6)];
+ result += chars64[binary[2] & 0x3F];
+ binary += 3;
+ }
+
+ if (misaligned){
+ //copy the rest into a temporary buffer
+ unsigned char temp[3];
+ for (unsigned int i=0; i < misaligned; ++i){
+ temp[i] = *binary++;
+ }
+ for (unsigned int i = (unsigned int)misaligned; i < 3; ++i){
+ temp[i] = '\0';
+ }
+
+ //now do the final three bytes
+ result += chars64[(temp[0] & 0xFC) >> 2];
+ result += chars64[((temp[0] & 0x03) << 4) + ((temp[1] & 0xF0) >> 4)];
+ if (misaligned == 2){
+ result += chars64[((temp[1] & 0x0F) << 2) + ((temp[2] & 0xC0) >> 6)];
+ result += JSON_TEXT('=');
+ } else {
+ result += JSON_TEXT(" = = ");
+ }
+ }
+ JSON_ASSERT((size_t)(((float)bytes) * 1.37f) + 4 >= result.length(), JSON_TEXT("Didn't reserve enough space for a one-time go"));
+ return result;
+}
+
+inline json_char toBinary(json_char c){
+ if (c == JSON_TEXT('+')) {
+ return JSON_TEXT('>');
+ } else if (c == JSON_TEXT('/')) {
+ return JSON_TEXT('?');
+ } else if (c < JSON_TEXT(':')) {
+ return c + JSON_TEXT('\x04');
+ } else if (c < JSON_TEXT('[')) {
+ return c - JSON_TEXT('\x41');
+ }
+ return c - 71;
+}
+
+/*
+ Must be a std::string because it's binary, and chars must be 1 byte
+ */
+std::string JSONBase64::json_decode64(const json_string & encoded){
+ const size_t length = encoded.length();
+ #if defined JSON_DEBUG || defined JSON_SAFE
+ size_t pos = encoded.find_first_not_of(chars64);
+ if (pos != json_string::npos){
+ JSON_ASSERT_SAFE(encoded[pos] == JSON_TEXT('='), JSON_TEXT("Not Base64"), return BASE64_EMPTY_STRING;);
+ if (pos != length - 1){
+ JSON_ASSERT_SAFE(pos == length - 2, JSON_TEXT("Not Base64"), return BASE64_EMPTY_STRING;);
+ JSON_ASSERT_SAFE(encoded[pos + 1] == JSON_TEXT('='), JSON_TEXT("Not Base64"), return BASE64_EMPTY_STRING;);
+ }
+ }
+ #endif
+ const json_char * runner = encoded.c_str();
+ size_t aligned = length / 4; //don't do the last ones as they might be = padding
+ std::string result;
+ if (aligned){
+ --aligned;
+ result.reserve((size_t)((float)length / 1.37) + 1);
+
+ //first do the ones that can not have any padding
+ for (unsigned int i=0; i < aligned; ++i){
+ const json_char second = toBinary(runner[1]);
+ const json_char third = toBinary(runner[2]);
+ result += (toBinary(runner[0]) << 2) + ((second & 0x30) >> 4);
+ result += ((second & 0xf) << 4) + ((third & 0x3c) >> 2);
+ result += ((third & 0x3) << 6) + toBinary(runner[3]);
+ runner += 4;
+ }
+
+ //now do the ones that might have padding, the first two characters can not be padding, so do them quickly
+ const char second = toBinary(runner[1]);
+ result += (toBinary(runner[0]) << 2) + ((second & 0x30) >> 4);
+ if (runner[2] != '=') { //not two = pads
+ const char third = toBinary(runner[2]);
+ result += ((second & 0xf) << 4) + ((third & 0x3c) >> 2);
+ if (runner[3] != '=') { //no padding
+ result += ((third & 0x3) << 6) + toBinary(runner[3]);
+ }
+ }
+ }
+ return result;
+}
+
+#endif
|