Operator Console
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Static Public Member Functions | List of all members
JSONBase64 Class Reference

#include <JSON_Base64.h>

Static Public Member Functions

static json_string json_encode64 (const unsigned char *binary, size_t bytes) json_nothrow json_cold
 
static std::string json_decode64 (const json_string &encoded) json_nothrow json_cold
 
static json_string json_encode64 (const unsigned char *binary, size_t bytes) json_nothrow json_cold
 
static std::string json_decode64 (const json_string &encoded) json_nothrow json_cold
 

Member Function Documentation

std::string JSONBase64::json_decode64 ( const json_string &  encoded)
static

References chars64(), HitScopeCoverage, JSON_ASSERT_SAFE, json_char, json_global, json_likely, JSON_TEXT, json_unlikely, and toBinary().

Referenced by JSONNode::as_binary(), and libjson::decode64().

64  {
65  const size_t length = encoded.length();
66  #if defined JSON_DEBUG || defined JSON_SAFE
67  size_t pos = encoded.find_first_not_of(chars64);
68  if (json_unlikely(pos != json_string::npos)){
69  HitScopeCoverage(json_decode64, pos_not_npos);
70  JSON_ASSERT_SAFE(encoded[pos] == JSON_TEXT('='), json_global(ERROR_NOT_BASE64), return json_global(EMPTY_STD_STRING););
71  if (pos != length - 1){
72  HitScopeCoverage(json_decode64, pos_not_lengthminusone);
73  JSON_ASSERT_SAFE(pos == length - 2, json_global(ERROR_NOT_BASE64), return json_global(EMPTY_STD_STRING););
74  JSON_ASSERT_SAFE(encoded[pos + 1] == JSON_TEXT('='), json_global(ERROR_NOT_BASE64), return json_global(EMPTY_STD_STRING););
75  } else {
76  HitScopeCoverage(json_decode64, pos_lengthminusone);
77  }
78  } else {
79  HitScopeCoverage(json_decode64, pos_is_npos);
80  }
81  #endif
82  const json_char * runner = encoded.c_str();
83  size_t aligned = length / 4; //don't do the last ones as they might be = padding
84  std::string result;
85  if (json_likely(aligned != 0)){
86  HitScopeCoverage(json_decode64, aligned_not_zero);
87  --aligned;
88  result.reserve((size_t)((float)length / 1.37) + 1);
89 
90  //first do the ones that can not have any padding
91  for (unsigned int i = 0; i < aligned; ++i){
93  const json_char second = toBinary(runner[1]);
94  const json_char third = toBinary(runner[2]);
95  result += (toBinary(runner[0]) << 2) + ((second & 0x30) >> 4);
96  result += ((second & 0xf) << 4) + ((third & 0x3c) >> 2);
97  result += ((third & 0x3) << 6) + toBinary(runner[3]);
98  runner += 4;
99  }
100 
101  //now do the ones that might have padding, the first two characters can not be padding, so do them quickly
102  const json_char second = toBinary(runner[1]);
103  result += (toBinary(runner[0]) << 2) + ((second & 0x30) >> 4);
104  if (runner[2] != '='){ //not two = pads
105  HitScopeCoverage(json_decode64, not_two_pads);
106  const json_char third = toBinary(runner[2]);
107  result += ((second & 0xf) << 4) + ((third & 0x3c) >> 2);
108  if (runner[3] != '='){ //no padding
109  HitScopeCoverage(json_decode64, no_padding);
110  result += ((third & 0x3) << 6) + toBinary(runner[3]);
111  } else {
112  HitScopeCoverage(json_decode64, padding_three);
113  }
114  } else {
115  HitScopeCoverage(json_decode64, padding_two);
116  }
117  } else {
118  HitScopeCoverage(json_decode64, aligned_zero);
119  }
120  return result;
121 }
static std::string json_decode64(const json_string &encoded) json_nothrow json_cold
Definition: JSON_Base64.cpp:64
#define JSON_TEXT(s)
Definition: Strings_Defs.h:30
json_uchar toBinary(json_uchar c) json_pure
Definition: JSON_Base64.cpp:57
#define json_unlikely(x)
Definition: Unknown_C.h:17
#define HitScopeCoverage(name, id)
Definition: JSONDebug.h:130
static const json_char * chars64(JSON_TEXT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"))
#define json_global(NAME)
Definition: JSONGlobals.h:26
#define json_char
Definition: Strings_Defs.h:21
#define JSON_ASSERT_SAFE(condition, msg, code)
Definition: JSONDebug.h:49
#define json_likely(x)
Definition: Unknown_C.h:16

Here is the call graph for this function:

Here is the caller graph for this function:

static std::string JSONBase64::json_decode64 ( const json_string &  encoded)
static
static json_string JSONBase64::json_encode64 ( const unsigned char *  binary,
size_t  bytes 
)
static
json_string JSONBase64::json_encode64 ( const unsigned char *  binary,
size_t  bytes 
)
static

References chars64(), HitScopeCoverage, JSON_ASSERT, json_likely, and JSON_TEXT.

Referenced by libjson::encode64(), and JSONNode::set_binary().

8  {
9  size_t misaligned = bytes % 3;
10  json_string result;
11  result.reserve((size_t)(((float)bytes) * 1.37f) + 4);
12 
13  //do all of the ones that are 3 byte aligned
14  for (size_t i = 0, aligned((bytes - misaligned) / 3); i < aligned; ++i){
16  result += chars64[(binary[0] & 0xFC) >> 2];
17  result += chars64[((binary[0] & 0x03) << 4) + ((binary[1] & 0xF0) >> 4)];
18  result += chars64[((binary[1] & 0x0F) << 2) + ((binary[2] & 0xC0) >> 6)];
19  result += chars64[binary[2] & 0x3F];
20  binary += 3;
21  }
22 
23  if (json_likely(misaligned != 0)){
24  HitScopeCoverage(json_encode64, misaligned);
25  //copy the rest into a temporary buffer
26  unsigned char temp[3];
27  for (unsigned int i = 0; i < misaligned; ++i){
28  HitScopeCoverage(json_encode64, misaligned_loop_1);
29  temp[i] = *binary++;
30  }
31  for (unsigned int i = (unsigned int)misaligned; i < 3; ++i){
32  HitScopeCoverage(json_encode64, misaligned_loop_2);
33  temp[i] = '\0';
34  }
35 
36  //now do the final three bytes
37  result += chars64[(temp[0] & 0xFC) >> 2];
38  result += chars64[((temp[0] & 0x03) << 4) + ((temp[1] & 0xF0) >> 4)];
39  if (misaligned == 2){
40  HitScopeCoverage(json_encode64, misaligned_equals_two);
41  result += chars64[((temp[1] & 0x0F) << 2) + ((temp[2] & 0xC0) >> 6)];
42  result += JSON_TEXT('=');
43  } else {
44  HitScopeCoverage(json_encode64, misaligned_not_two);
45  result += JSON_TEXT("==");
46  }
47  } else {
48  HitScopeCoverage(json_encode64, notmisaligned);
49  }
50  JSON_ASSERT((size_t)(((float)bytes) * 1.37f) + 4 >= result.length(), JSON_TEXT("Didn't reserve enough space for a one-time go"));
51  return result;
52 }
#define JSON_TEXT(s)
Definition: Strings_Defs.h:30
#define HitScopeCoverage(name, id)
Definition: JSONDebug.h:130
static const json_char * chars64(JSON_TEXT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"))
static json_string json_encode64(const unsigned char *binary, size_t bytes) json_nothrow json_cold
Definition: JSON_Base64.cpp:8
#define JSON_ASSERT(condition, msg)
Definition: JSONDebug.h:53
#define json_likely(x)
Definition: Unknown_C.h:16

Here is the call graph for this function:

Here is the caller graph for this function:


The documentation for this class was generated from the following files: