summaryrefslogtreecommitdiff
path: root/ndb/src/common/util/Base64.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ndb/src/common/util/Base64.cpp')
-rw-r--r--ndb/src/common/util/Base64.cpp161
1 files changed, 129 insertions, 32 deletions
diff --git a/ndb/src/common/util/Base64.cpp b/ndb/src/common/util/Base64.cpp
index 482d0b10ad2..f7a490d427d 100644
--- a/ndb/src/common/util/Base64.cpp
+++ b/ndb/src/common/util/Base64.cpp
@@ -22,89 +22,186 @@ static char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789+/";
int
-base64_encode(UtilBuffer &src, BaseString &dst) {
- char *s = (char *)src.get_data();
- int i = 0;
+base64_encode(const UtilBuffer &src, BaseString &dst) {
+ const unsigned char *s = (const unsigned char *)src.get_data();
+ size_t i = 0;
+ size_t len = 0;
+ size_t src_len = src.length();
+ while(i < src_len) {
+ if(len == 76){
+ len = 0;
+ dst.append('\n');
+ }
- while(i < src.length()) {
- int c;
+ unsigned c;
c = s[i++];
c <<= 8;
- if(i < src.length())
+ if(i < src_len)
c += s[i];
c <<= 8;
i++;
- if(i < src.length())
+ if(i < src_len)
c += s[i];
i++;
-
+
dst.append(base64_table[(c >> 18) & 0x3f]);
dst.append(base64_table[(c >> 12) & 0x3f]);
- if(i > (src.length() + 1))
+ if(i > (src_len + 1))
dst.append('=');
else
dst.append(base64_table[(c >> 6) & 0x3f]);
- if(i > src.length())
+ if(i > src_len)
dst.append('=');
else
dst.append(base64_table[(c >> 0) & 0x3f]);
+
+ len += 4;
}
return 0;
}
-static inline int
-pos(char c) {
+static inline unsigned
+pos(unsigned char c) {
return strchr(base64_table, c) - base64_table;
}
int
-base64_decode(BaseString &src, UtilBuffer &dst) {
- size_t size;
- size = (src.length() * 3) / 4;
+base64_decode(const BaseString &src, UtilBuffer &dst) {
+ return base64_decode(src.c_str(), src.length(), dst);
+}
+
+#define SKIP_SPACE(src, i, size){ \
+ while(i < size && isspace(* src)){ \
+ i++; \
+ src++; \
+ } \
+ if(i == size){ \
+ i = size + 1; \
+ break; \
+ } \
+}
+
+int
+base64_decode(const char * src, size_t size, UtilBuffer &dst) {
size_t i = 0;
- const char *s = src.c_str();
- while(i < size) {
- int c = 0;
+ while(i < size){
+ unsigned c = 0;
int mark = 0;
- c += pos(*s++);
+
+ SKIP_SPACE(src, i, size);
+
+ c += pos(*src++);
c <<= 6;
i++;
- c += pos(*s++);
+ SKIP_SPACE(src, i, size);
+
+ c += pos(*src++);
c <<= 6;
i++;
- if(*s != '=')
- c += pos(*s++);
+ SKIP_SPACE(src, i, size);
+
+ if(* src != '=')
+ c += pos(*src++);
else {
- size--;
- mark++;
+ i = size;
+ mark = 2;
+ c <<= 6;
+ goto end;
}
c <<= 6;
i++;
- if(*s != '=')
- c += pos(*s++);
+ SKIP_SPACE(src, i, size);
+
+ if(*src != '=')
+ c += pos(*src++);
else {
- size--;
- mark++;
+ i = size;
+ mark = 1;
+ goto end;
}
- /* c <<= 6; */
i++;
+ end:
char b[3];
-
-
b[0] = (c >> 16) & 0xff;
b[1] = (c >> 8) & 0xff;
b[2] = (c >> 0) & 0xff;
-
+
dst.append((void *)b, 3-mark);
}
+
+ if(i != size){
+ abort();
+ return -1;
+ }
return 0;
}
+
+#ifdef __TEST__B64
+/**
+ * USER_FLAGS="-D__TEST__B64" make Base64.o && g++ Base64.o BaseString.o
+ */
+inline
+void
+require(bool b){
+ if(!b)
+ abort();
+}
+
+int
+main(void){
+ for(int i = 0; i < 500; i++){
+ const size_t len = rand() % 10000 + 1;
+ UtilBuffer src;
+ for(size_t j = 0; j<len; j++){
+ char c = rand();
+ src.append(&c, 1);
+ }
+ require(src.length() == len);
+
+ BaseString str;
+ require(base64_encode(src, str) == 0);
+
+ if(str.length() == 3850){
+ printf(">%s<\n", str.c_str());
+ }
+
+ UtilBuffer dst;
+ require(base64_decode(str, dst) == 0);
+ require(dst.length() == src.length());
+
+ const char * c_src = (char*)src.get_data();
+ const char * c_dst = (char*)dst.get_data();
+ if(memcmp(src.get_data(), dst.get_data(), src.length()) != 0){
+ printf("-- src --\n");
+ for(int i2 = 0; i2<len; i2++){
+ unsigned char c = c_src[i2];
+ printf("%.2x ", (unsigned)c);
+ if((i2 % 8) == 7)
+ printf("\n");
+ }
+ printf("\n");
+
+ printf("-- dst --\n");
+ for(int i2 = 0; i2<len; i2++){
+ unsigned char c = c_dst[i2];
+ printf("%.2x ", (unsigned)c);
+ if((i2 % 8) == 7)
+ printf("\n");
+ }
+ printf("\n");
+ abort();
+ }
+ }
+ return 0;
+}
+
+#endif