|
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) 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 }