Bug Summary

File:external/xstream/src/base64.cpp
Location:line 56, column 17
Description:Value stored to 'ret' is never read

Annotated Source Code

1#include <xstream/config.h>
2#include <xstream/base64.h>
3#include <xstream/except/base64.h>
4
5#include "debug.h"
6
7namespace xstream
8{
9 namespace base64
10 {
11
12 static const char dictionary[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
13
14 static const int eof = std::streambuf::traits_type::eof();
15
16 ostreambuf::ostreambuf(std::streambuf* sb, unsigned int w, char c)
17 : _sb(sb), delim(c), delim_w(w), col(0) {
18 LOG("base64::ostreambuf (streambuf*)");
19 reset();
20 }
21
22 void ostreambuf::reset() {
23 LOG("base64::ostreambuf::reset");
24 setp(buf,buf+sizeof(buf)/sizeof(char));
25 }
26
27 //no flush of base64 data, just flushes the streambuf it writes to
28 int ostreambuf::sync() {
29 LOG("base64::ostreambuf::sync");
30 return _sb->pubsync();
31 }
32
33 static inline void encode(const char* in, char* out) {
34 LOG("base64::encode");
35 static const unsigned int hi6 = ((1 << 6) -1 ) << 2;
36 static const unsigned int lo2 = (1 << 2) - 1;
37 static const unsigned int hi4 = ((1 << 4) - 1) << 4;
38 static const unsigned int lo4 = (1 << 4) - 1;
39 static const unsigned int hi2 = ((1 << 2) - 1) << 6;
40 static const unsigned int lo6 = (1 << 6) - 1;
41
42 out[0] = dictionary[(hi6 & in[0]) >> 2];
43 out[1] = dictionary[(lo2 & in[0]) << 4 | (hi4 & in[1]) >> 4];
44 out[2] = dictionary[(lo4 & in[1]) << 2 | (hi2 & in[2]) >> 6];
45 out[3] = dictionary[lo6 & in[2]];
46 }
47
48 int ostreambuf::write(const char* buf, size_t len) {
49 unsigned int rcol = delim_w - col;
50 int ret = 0;
51
52 //XXX all these sputn calls need to be checked
53 if (delim_w > 0 && rcol <= len) {
54 LOG("\t" << rcol << " columns to padding");
55 ret = _sb->sputn(buf, rcol);
56 ret = _sb->sputc(delim);
Value stored to 'ret' is never read
57 ret = _sb->sputn(buf + rcol, len - rcol);
58 col = len - rcol;
59 LOG("\tcol = " << col);
60 }
61 else {
62 ret = _sb->sputn(buf,len);
63 col += len;
64 }
65
66 reset();
67
68 return ret;
69 }
70
71 int ostreambuf::overflow(int c) {
72 LOG("base64::ostreambuf::overflow (" << c << ")\n\t[" << *buf << *(buf+1) << *(buf+2) << "]");
73
74 char enc[4]; //encoded buffer
75 encode(buf, enc);
76
77 write(enc, 4);
78
79 *pptr() = static_cast < char >(c);
80 pbump(1);
81
82 return c;
83 }
84
85 ostreambuf::~ostreambuf() {
86 LOG("base64::~ostreambuf");
87 int av = available();
88
89 if (3 == av) {
90 //no need to do anything
91 }
92 else {
93 char enc[4];
94 for(int i=0; i < av; ++i) {
95 //pad to zero
96 buf[2-i] = '\0';
97 }
98 encode(buf,enc);
99
100 if (1 <= av) {
101 enc[3] = '=';
102 }
103 if (2 <= av) {
104 enc[2] = '=';
105 }
106
107 //XXX need to check return code
108 write(enc,4);
109 }
110
111 _sb->pubsync();
112 }
113
114 //should search in constant time
115 static inline char index(char c) {
116 static const int window = 'Z'- 'A' + 1 ;
117
118 //if c is not in dict throw exception
119 //could be a lot cleaner if no debugging was needed
120
121 int d = c - 'A';
122 int ret = -1;
123
124 if (d >= 0 && d < window) {
125 ret = d;
126 }
127 else {
128 d = c - 'a';
129 if (d >= 0 && d < window) {
130 ret = d + window;
131 }
132 else {
133 d = c - '0';
134 if (d >= 0 && d < 10) {
135 ret = d + 2 * window;
136 }
137 else {
138 if ('+' == c) {
139 ret = 62;
140 }
141 else {
142 if ('/' == c) {
143 ret = 63;
144 }
145 }
146 }
147 }
148 }
149
150 if (-1 == ret) {
151 LOG("base64::index (" << c << ") [unknown]");
152 throw(decode_error(std::string("character '") + c + "' not part of base64 alphabet"));
153 }
154 else {
155 return ret;
156 }
157 }
158
159 static inline void decode(const char* in, char* out) {
160 LOG("base64::decode");
161 static const unsigned char hi2 = ((1 << 2) - 1) << 4;
162 static const unsigned char lo4 = ((1 << 4) - 1);
163 static const unsigned char hi4 = ((1 << 4) - 1) << 2;
164 static const unsigned char lo2 = ((1 << 2) - 1);
165
166 char _in[4];
167
168 for (int i=0; i < 4; ++i) {
169 _in[i] = index(in[i]);
170 }
171
172 char c;
173 c = _in[0] << 2;
174 c |= (_in[1] & hi2) >> 4;
175 out[0] = c;
176
177 c = (_in[1] & lo4) << 4;
178 c |= (_in[2] & hi4) >> 2;
179 out[1] = c;
180
181 c = (_in[2] & lo2) << 6;
182 c |= _in[3];
183 out[2] = c;
184 }
185
186 istreambuf::istreambuf(std::streambuf* sb, unsigned int d_w, char d)
187 : _sb(sb), end(false), delim(d), delim_w(d_w), col(0) {
188 LOG("base64::istreambuf (streambuf*)");
189 setg(buf, buf, buf);
190 }
191
192 int istreambuf::underflow() {
193 LOG("base64::istreambuf::underflow");
194
195 if (end) {
196 LOG("\tattempt to read from an ended stream");
197 return eof;
198 }
199 else {
200 char enc[4 + 1];
201 int av = (delim_w - col);
202 if (delim_w > 0 && av <= 4) {
203 LOG("\texpecting delimiter at " << av);
204 int ret = _sb->sgetn(enc, 5);
205 LOG("\tenc=" << enc);
206 if (5 != ret) {
207 LOG("\tread " << ret << " but wanted " << 5);
208 //XXX throw exception?
209 end = true;
210 return eof;
211 }
212 if (delim != enc[av]) {
213 LOG("\texpected delimiter " << delim << " but got " << enc[av]);
214 end = true;
215 throw decode_error("expected delimiter missing");
216 return eof;
217 }
218 else {
219 col = 4 - av;
220 for (int i=av; i < 4; ++i) {
221 enc[i] = enc[i + 1];
222 }
223 }
224 }
225 else {
226 int ret = _sb->sgetn(enc, 4);
227 col += 4;
228
229 if (4 != ret) {
230 //XXX maybe I should throw an exception
231 end = true;
232 return eof;
233 }
234 }
235 int len=3;
236 if ('=' == enc[3]) {
237 enc[3] = 'A'; //guard
238 if ('=' == enc[2]) {
239 len = 1;
240 enc[2] = 'A'; //guard
241 } else {
242 len = 2;
243 }
244 }
245 if (3 != len) {
246 end = true;
247 }
248
249 decode(enc, buf);
250 setg(buf, buf, buf + len);
251 return 0;
252 }
253 }
254
255 istreambuf::~istreambuf() {
256 LOG("base64::~istreambuf");
257 }
258
259 }//namespace base64
260}//namespace xstream