|
IBR-DTNSuite 0.6
|
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 }