Switch to unified view

a/src/utils/base64.cpp b/src/utils/base64.cpp
...
...
21
21
22
#ifndef NO_NAMESPACES
22
#ifndef NO_NAMESPACES
23
using std::string;
23
using std::string;
24
#endif /* NO_NAMESPACES */
24
#endif /* NO_NAMESPACES */
25
25
26
//#define DEBUG_BASE64 
26
#undef DEBUG_BASE64 
27
#ifdef DEBUG_BASE64
27
#ifdef DEBUG_BASE64
28
#define DPRINT(X) fprintf X
28
#define DPRINT(X) fprintf X
29
#else
29
#else
30
#define DPRINT(X)
30
#define DPRINT(X)
31
#endif
31
#endif
32
32
33
// This is adapted from FreeBSD's code.
33
// This is adapted from FreeBSD's code, quite modified for performance.
34
// Tests on a Mac pro 2.1G with a 166MB base64 file
35
//
36
// The original version used strchr to lookup the base64 value from
37
// the input code:
38
//   real    0m13.053s user  0m12.574s sys   0m0.471s
39
// Using a direct access, 256 entries table:
40
//   real    0m3.073s user   0m2.600s sys    0m0.439s
41
// Using a variable to hold the array length (instead of in.length()):
42
//   real    0m2.972s user   0m2.527s sys    0m0.433s
43
// Using values from the table instead of isspace() (final)
44
//   real    0m2.513s user   0m2.059s sys    0m0.439s
45
//
46
// The table has one entry per char value (0-256). Invalid base64
47
// chars take value 256, whitespace 255, Pad ('=') 254. 
48
// Valid char points contain their base64 value (0-63) 
49
static const int b64values[] = {
50
/* 0 */ 256,/* 1 */ 256,/* 2 */ 256,/* 3 */ 256,/* 4 */ 256,
51
/* 5 */ 256,/* 6 */ 256,/* 7 */ 256,/* 8 */ 256,
52
/*9 ht */ 255,/* 10 nl */ 255,/* 11 vt */ 255,/* 12 np/ff*/ 255,/* 13 cr */ 255,
53
/* 14 */ 256,/* 15 */ 256,/* 16 */ 256,/* 17 */ 256,/* 18 */ 256,/* 19 */ 256,
54
/* 20 */ 256,/* 21 */ 256,/* 22 */ 256,/* 23 */ 256,/* 24 */ 256,/* 25 */ 256,
55
/* 26 */ 256,/* 27 */ 256,/* 28 */ 256,/* 29 */ 256,/* 30 */ 256,/* 31 */ 256,
56
/* 32 sp  */ 255,
57
/* ! */ 256,/* " */ 256,/* # */ 256,/* $ */ 256,/* % */ 256,
58
/* & */ 256,/* ' */ 256,/* ( */ 256,/* ) */ 256,/* * */ 256,
59
/* + */ 62,
60
/* , */ 256,/* - */ 256,/* . */ 256,
61
/* / */ 63,
62
/* 0 */ 52,/* 1 */ 53,/* 2 */ 54,/* 3 */ 55,/* 4 */ 56,/* 5 */ 57,/* 6 */ 58,
63
/* 7 */ 59,/* 8 */ 60,/* 9 */ 61,
64
/* : */ 256,/* ; */ 256,/* < */ 256,
65
/* = */ 254,
66
/* > */ 256,/* ? */ 256,/* @ */ 256,
67
/* A */ 0,/* B */ 1,/* C */ 2,/* D */ 3,/* E */ 4,/* F */ 5,/* G */ 6,/* H */ 7,
68
/* I */ 8,/* J */ 9,/* K */ 10,/* L */ 11,/* M */ 12,/* N */ 13,/* O */ 14,
69
/* P */ 15,/* Q */ 16,/* R */ 17,/* S */ 18,/* T */ 19,/* U */ 20,/* V */ 21,
70
/* W */ 22,/* X */ 23,/* Y */ 24,/* Z */ 25,
71
/* [ */ 256,/* \ */ 256,/* ] */ 256,/* ^ */ 256,/* _ */ 256,/* ` */ 256,
72
/* a */ 26,/* b */ 27,/* c */ 28,/* d */ 29,/* e */ 30,/* f */ 31,/* g */ 32,
73
/* h */ 33,/* i */ 34,/* j */ 35,/* k */ 36,/* l */ 37,/* m */ 38,/* n */ 39,
74
/* o */ 40,/* p */ 41,/* q */ 42,/* r */ 43,/* s */ 44,/* t */ 45,/* u */ 46,
75
/* v */ 47,/* w */ 48,/* x */ 49,/* y */ 50,/* z */ 51,
76
/* { */ 256,/* | */ 256,/* } */ 256,/* ~ */ 256,
77
256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,
78
256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,
79
256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,
80
256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,
81
256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,
82
256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,256,
83
256,256,256,256,256,256,256,256,
84
};
34
static const char Base64[] =
85
static const char Base64[] =
35
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
86
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
36
static const char Pad64 = '=';
87
static const char Pad64 = '=';
88
37
bool base64_decode(const string& in, string& out)
89
bool base64_decode(const string& in, string& out)
38
{
90
{
39
    int io = 0, state = 0, ch = 0;
91
    int io = 0, state = 0, ch = 0;
40
    const char *pos;
41
    unsigned int ii = 0;
92
    unsigned int ii = 0;
42
    out.erase();
93
    out.erase();
94
    size_t ilen = in.length();
43
    out.reserve(in.length());
95
    out.reserve(ilen);
44
96
45
    for (ii = 0; ii < in.length(); ii++) {
97
    for (ii = 0; ii < ilen; ii++) {
46
  ch = in[ii];
98
  ch = (unsigned char)in[ii];
47
  if (isspace((unsigned char)ch))        /* Skip whitespace anywhere. */
99
  int value = b64values[ch];
100
101
  if (value == 255)        /* Skip whitespace anywhere. */
48
        continue;
102
        continue;
49
50
    if (ch == Pad64)
103
    if (ch == Pad64)
51
        break;
104
        break;
52
105
  if (value == 256) {
53
  pos = strchr(Base64, ch);
54
  if (pos == 0) {
55
        /* A non-base64 character. */
106
        /* A non-base64 character. */
56
        DPRINT((stderr, "base64_dec: non-base64 char at pos %d\n", ii));
107
        DPRINT((stderr, "base64_dec: non-base64 char at pos %d\n", ii));
57
        return false;
108
        return false;
58
    }
109
    }
59
110
60
61
    switch (state) {
111
    switch (state) {
62
    case 0:
112
    case 0:
63
      out += (pos - Base64) << 2;
113
      out += value << 2;
64
        state = 1;
114
        state = 1;
65
        break;
115
        break;
66
    case 1:
116
    case 1:
67
        out[io]   |=  (pos - Base64) >> 4;
117
        out[io]   |=  value >> 4;
68
        out += ((pos - Base64) & 0x0f) << 4 ;
118
        out += (value & 0x0f) << 4 ;
69
        io++;
119
        io++;
70
        state = 2;
120
        state = 2;
71
        break;
121
        break;
72
    case 2:
122
    case 2:
73
        out[io]   |=  (pos - Base64) >> 2;
123
        out[io]   |=  value >> 2;
74
        out += ((pos - Base64) & 0x03) << 6;
124
        out += (value & 0x03) << 6;
75
        io++;
125
        io++;
76
        state = 3;
126
        state = 3;
77
        break;
127
        break;
78
    case 3:
128
    case 3:
79
      out[io] |= (pos - Base64);
129
      out[io] |= value;
80
        io++;
130
        io++;
81
        state = 0;
131
        state = 0;
82
        break;
132
        break;
83
    default:
133
    default:
84
        DPRINT((stderr, "base64_dec: internal!bad state!\n"));
134
        fprintf(stderr, "base64_dec: internal!bad state!\n");
85
        return false;
135
        return false;
86
    }
136
    }
87
    }
137
    }
88
138
89
    /*
139
    /*
...
...
152
        return false;
202
        return false;
153
    }
203
    }
154
    }
204
    }
155
205
156
    DPRINT((stderr, "base64_dec: ret ok, io %d sz %d len %d value [%s]\n", 
206
    DPRINT((stderr, "base64_dec: ret ok, io %d sz %d len %d value [%s]\n", 
157
        io, out.size(), out.length(), out.c_str()));
207
        io, (int)out.size(), (int)out.length(), out.c_str()));
158
    return true;
208
    return true;
159
}
209
}
160
210
161
#undef Assert
211
#undef Assert
162
#define Assert(X)
212
#define Assert(X)