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) && (_byte_limit < data_size_))
00051                 {
00052                         _stream.read((char*)&buffer, _byte_limit);
00053                 }
00054                 else
00055                 {
00056                         _stream.read((char*)&buffer, data_size_);
00057                 }
00058 
00059                 size_t len = _stream.gcount();
00060 
00061                 // position in array
00062                 size_t decoded_bytes = 0;
00063 
00064                 for (size_t i = 0; i < len; i++)
00065                 {
00066                         // skip newline chars
00067                         if (buffer[i] == '\n') continue;
00068 
00069                         // put char into the decode buffer
00070                         if (buffer[i] == '=')
00071                         {
00072                                 _base64_buf[_base64_state] = decodeCharacterTable[ (int)'\0' ];
00073                                 _base64_padding++;
00074                         }
00075                         else
00076                         {
00077                                 _base64_buf[_base64_state] = decodeCharacterTable[ (int)buffer[i] ];
00078                         }
00079 
00080                         if (_base64_state == 3)
00081                         {
00082                                 _base64_buf[0] = (char)((_base64_buf[0] << 2) + ((_base64_buf[1] & 0x30) >> 4));
00083                                 _base64_buf[1] = (char)(((_base64_buf[1] & 0xf) << 4) + ((_base64_buf[2] & 0x3c) >> 2));
00084                                 _base64_buf[2] = (char)(((_base64_buf[2] & 0x3) << 6) + _base64_buf[3]);
00085 
00086                                 for (int j = 0; j < (3 - _base64_padding); j++)
00087                                 {
00088                                         data_buf_[decoded_bytes] = _base64_buf[j];
00089                                         decoded_bytes++;
00090                                 }
00091 
00092                                 _base64_state = 0;
00093                                 _base64_padding = 0;
00094                         }
00095                         else
00096                         {
00097                                 _base64_state++;
00098                         }
00099                 }
00100 
00101                 // Since the input buffer content is now valid (or is new)
00102                 // the get pointer should be initialized (or reset).
00103                 setg(data_buf_, data_buf_, data_buf_ + decoded_bytes);
00104 
00105                 if (_byte_limit > 0)
00106                 {
00107                         _byte_read += decoded_bytes;
00108                 }
00109 
00110                 return std::char_traits<char>::not_eof(data_buf_[0]);
00111         }
00112 }