IBR-DTNSuite 0.6

ibrcommon/ibrcommon/data/Base64Reader.cpp

Go to the documentation of this file.
00001 /*
00002  * Base64Reader.cpp
00003  *
00004  *  Created on: 21.06.2011
00005  *      Author: morgenro
00006  */
00007 
00008 #include "ibrcommon/data/Base64Reader.h"
00009 
00010 namespace ibrcommon
00011 {
00012         const char Base64Reader::decodeCharacterTable[256] = {
00013         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
00014         ,-1,62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21
00015         ,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,
00016         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
00017         -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
00018         ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
00019         -1,-1,-1};
00020 
00021         Base64Reader::Base64Reader(std::istream &stream, const size_t limit, const size_t buffer)
00022          : std::istream(this), _stream(stream), data_buf_(new char[buffer]), data_size_(buffer), _base64_state(0), _char_counter(0), _base64_padding(0), _byte_read(0), _byte_limit(limit)
00023         {
00024                 setg(0, 0, 0);
00025                 _base64_buf[0] = '\0';
00026                 _base64_buf[1] = '\0';
00027                 _base64_buf[2] = '\0';
00028                 _base64_buf[3] = '\0';
00029         }
00030 
00031         Base64Reader::~Base64Reader()
00032         {
00033                 delete[] data_buf_;
00034         }
00035 
00036         int Base64Reader::underflow()
00037         {
00038                 // signal EOF if end of stream is reached
00039                 if (_stream.eof())
00040                         return std::char_traits<char>::eof();
00041 
00042                 if ((_byte_limit > 0) && (_byte_read >= _byte_limit))
00043                 {
00044                         return std::char_traits<char>::eof();
00045                 }
00046 
00047                 // read some data
00048                 char buffer[data_size_];
00049 
00050                 if (_byte_limit > 0)
00051                 {
00052                         // get the remaining bytes
00053                         size_t bytes_to_read = _byte_limit - _byte_read;
00054 
00055                         if (bytes_to_read > data_size_) bytes_to_read = data_size_;
00056 
00057                         // read at least one byte
00058                         if (bytes_to_read == 0) bytes_to_read = 1;
00059 
00060                         _stream.read((char*)&buffer, bytes_to_read);
00061                 }
00062                 else
00063                 {
00064                         _stream.read((char*)&buffer, data_size_);
00065                 }
00066 
00067                 size_t len = _stream.gcount();
00068 
00069                 // position in array
00070                 size_t decoded_bytes = 0;
00071 
00072                 for (size_t i = 0; i < len; i++)
00073                 {
00074                         // skip newline chars
00075                         if (buffer[i] == '\n') continue;
00076 
00077                         // put char into the decode buffer
00078                         if (buffer[i] == '=')
00079                         {
00080                                 _base64_buf[_base64_state] = decodeCharacterTable[ (int)'\0' ];
00081                                 _base64_padding++;
00082                         }
00083                         else
00084                         {
00085                                 _base64_buf[_base64_state] = decodeCharacterTable[ (int)buffer[i] ];
00086                         }
00087 
00088                         if (_base64_state == 3)
00089                         {
00090                                 _base64_buf[0] = (char)((_base64_buf[0] << 2) + ((_base64_buf[1] & 0x30) >> 4));
00091                                 _base64_buf[1] = (char)(((_base64_buf[1] & 0xf) << 4) + ((_base64_buf[2] & 0x3c) >> 2));
00092                                 _base64_buf[2] = (char)(((_base64_buf[2] & 0x3) << 6) + _base64_buf[3]);
00093 
00094                                 for (int j = 0; j < (3 - _base64_padding); j++)
00095                                 {
00096                                         data_buf_[decoded_bytes] = _base64_buf[j];
00097                                         decoded_bytes++;
00098                                 }
00099 
00100                                 _base64_state = 0;
00101                                 _base64_padding = 0;
00102                         }
00103                         else
00104                         {
00105                                 _base64_state++;
00106                         }
00107                 }
00108 
00109                 // Since the input buffer content is now valid (or is new)
00110                 // the get pointer should be initialized (or reset).
00111                 setg(data_buf_, data_buf_, data_buf_ + decoded_bytes);
00112 
00113                 if (_byte_limit > 0)
00114                 {
00115                         _byte_read += decoded_bytes;
00116                 }
00117 
00118                 return std::char_traits<char>::not_eof(data_buf_[0]);
00119         }
00120 }