|
IBR-DTNSuite 0.6
|
00001 /* 00002 * Dictionary.cpp 00003 * 00004 * Created on: 29.05.2009 00005 * Author: morgenro 00006 */ 00007 00008 #include "ibrdtn/data/Dictionary.h" 00009 #include "ibrdtn/data/SDNV.h" 00010 #include "ibrdtn/data/Exceptions.h" 00011 #include "ibrdtn/data/Bundle.h" 00012 #include <map> 00013 #include <stdexcept> 00014 #include <string.h> 00015 #include <iostream> 00016 00017 using namespace std; 00018 00019 namespace dtn 00020 { 00021 namespace data 00022 { 00023 Dictionary::Dictionary() 00024 { 00025 } 00026 00030 Dictionary::Dictionary(const dtn::data::Bundle &bundle) 00031 { 00032 // rebuild the dictionary 00033 add(bundle._destination); 00034 add(bundle._source); 00035 add(bundle._reportto); 00036 add(bundle._custodian); 00037 00038 // add EID of all secondary blocks 00039 const std::list<const dtn::data::Block*> list = bundle.getBlocks(); 00040 00041 for (std::list<const dtn::data::Block*>::const_iterator iter = list.begin(); iter != list.end(); iter++) 00042 { 00043 const Block &b = (*(*iter)); 00044 add( b.getEIDList() ); 00045 } 00046 } 00047 00048 Dictionary::Dictionary(const Dictionary &d) 00049 { 00050 this->operator=(d); 00051 } 00052 00056 Dictionary& Dictionary::operator=(const Dictionary &d) 00057 { 00058 _bytestream.str(""); 00059 _bytestream << d._bytestream.rdbuf(); 00060 return (*this); 00061 } 00062 00063 Dictionary::~Dictionary() 00064 { 00065 } 00066 00067 size_t Dictionary::get(const std::string value) const 00068 { 00069 std::string bytes = _bytestream.str(); 00070 const char *bytebegin = bytes.c_str(); 00071 const char *bytepos = bytebegin; 00072 const char *byteend = bytebegin + bytes.length() + 1; 00073 00074 if (bytes.length() <= 0) return std::string::npos; 00075 00076 while (bytepos < byteend) 00077 { 00078 std::string dictstr(bytepos); 00079 00080 if (dictstr == value) 00081 { 00082 return bytepos - bytebegin; 00083 } 00084 00085 bytepos += dictstr.length() + 1; 00086 } 00087 00088 return std::string::npos; 00089 } 00090 00091 bool Dictionary::exists(const std::string value) const 00092 { 00093 std::string bytes = _bytestream.str(); 00094 const char *bytepos = bytes.c_str(); 00095 const char *byteend = bytepos + bytes.length(); 00096 00097 if (bytes.length() <= 0) return false; 00098 00099 while (bytepos < byteend) 00100 { 00101 std::string dictstr(bytepos); 00102 00103 if (dictstr == value) 00104 { 00105 return true; 00106 } 00107 00108 bytepos += dictstr.length() + 1; 00109 } 00110 00111 return false; 00112 } 00113 00114 void Dictionary::add(const std::string value) 00115 { 00116 if (!exists(value)) 00117 { 00118 _bytestream << value << '\0'; 00119 } 00120 } 00121 00122 void Dictionary::add(const EID &eid) 00123 { 00124 add(eid.getScheme()); 00125 add(eid.getHost() + eid.getApplication()); 00126 } 00127 00128 void Dictionary::add(const list<EID> &eids) 00129 { 00130 list<EID>::const_iterator iter = eids.begin(); 00131 00132 while (iter != eids.end()) 00133 { 00134 add(*iter); 00135 iter++; 00136 } 00137 } 00138 00139 EID Dictionary::get(size_t scheme, size_t ssp) 00140 { 00141 char buffer[1024]; 00142 00143 _bytestream.seekg(scheme); 00144 _bytestream.get(buffer, 1024, '\0'); 00145 string scheme_str(buffer); 00146 00147 _bytestream.seekg(ssp); 00148 _bytestream.get(buffer, 1024, '\0'); 00149 string ssp_str(buffer); 00150 00151 return EID(scheme_str, ssp_str); 00152 } 00153 00154 void Dictionary::clear() 00155 { 00156 _bytestream.str(""); 00157 } 00158 00159 size_t Dictionary::getSize() const 00160 { 00161 return _bytestream.str().length(); 00162 } 00163 00164 pair<size_t, size_t> Dictionary::getRef(const EID &eid) const 00165 { 00166 const string scheme = eid.getScheme(); 00167 const string ssp = eid.getHost() + eid.getApplication(); 00168 return make_pair(get(scheme), get(ssp)); 00169 } 00170 00171 std::ostream &operator<<(std::ostream &stream, const dtn::data::Dictionary &obj) 00172 { 00173 dtn::data::SDNV length(obj.getSize()); 00174 stream << length; 00175 stream << obj._bytestream.rdbuf(); 00176 00177 return stream; 00178 } 00179 00180 std::istream &operator>>(std::istream &stream, dtn::data::Dictionary &obj) 00181 { 00182 dtn::data::SDNV length; 00183 stream >> length; 00184 00185 // if the dictionary size if zero throw a exception 00186 if (length.getValue() <= 0) 00187 throw dtn::InvalidDataException("Dictionary size is zero!"); 00188 00189 obj._bytestream.str(""); 00190 char data[length.getValue()]; 00191 stream.read(data, length.getValue()); 00192 obj._bytestream.write(data, length.getValue()); 00193 00194 return stream; 00195 } 00196 } 00197 }