IBR-DTNSuite
0.8
|
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(d._bytestream.str()); 00059 return (*this); 00060 } 00061 00062 Dictionary::~Dictionary() 00063 { 00064 } 00065 00066 size_t Dictionary::get(const std::string value) const 00067 { 00068 std::string bytes = _bytestream.str(); 00069 const char *bytebegin = bytes.c_str(); 00070 const char *bytepos = bytebegin; 00071 const char *byteend = bytebegin + bytes.length() + 1; 00072 00073 if (bytes.length() <= 0) return std::string::npos; 00074 00075 while (bytepos < byteend) 00076 { 00077 std::string dictstr(bytepos); 00078 00079 if (dictstr == value) 00080 { 00081 return bytepos - bytebegin; 00082 } 00083 00084 bytepos += dictstr.length() + 1; 00085 } 00086 00087 return std::string::npos; 00088 } 00089 00090 bool Dictionary::exists(const std::string value) const 00091 { 00092 std::string bytes = _bytestream.str(); 00093 const char *bytepos = bytes.c_str(); 00094 const char *byteend = bytepos + bytes.length(); 00095 00096 if (bytes.length() <= 0) return false; 00097 00098 while (bytepos < byteend) 00099 { 00100 std::string dictstr(bytepos); 00101 00102 if (dictstr == value) 00103 { 00104 return true; 00105 } 00106 00107 bytepos += dictstr.length() + 1; 00108 } 00109 00110 return false; 00111 } 00112 00113 void Dictionary::add(const std::string value) 00114 { 00115 if (!exists(value)) 00116 { 00117 _bytestream << value << '\0'; 00118 } 00119 } 00120 00121 void Dictionary::add(const EID &eid) 00122 { 00123 add(eid.getScheme()); 00124 add(eid.getSSP()); 00125 } 00126 00127 void Dictionary::add(const list<EID> &eids) 00128 { 00129 list<EID>::const_iterator iter = eids.begin(); 00130 00131 while (iter != eids.end()) 00132 { 00133 add(*iter); 00134 iter++; 00135 } 00136 } 00137 00138 EID Dictionary::get(size_t scheme, size_t ssp) 00139 { 00140 char buffer[1024]; 00141 00142 _bytestream.seekg(scheme); 00143 _bytestream.get(buffer, 1024, '\0'); 00144 string scheme_str(buffer); 00145 00146 _bytestream.seekg(ssp); 00147 _bytestream.get(buffer, 1024, '\0'); 00148 string ssp_str(buffer); 00149 00150 return EID(scheme_str, ssp_str); 00151 } 00152 00153 void Dictionary::clear() 00154 { 00155 _bytestream.str(""); 00156 } 00157 00158 size_t Dictionary::getSize() const 00159 { 00160 return _bytestream.str().length(); 00161 } 00162 00163 pair<size_t, size_t> Dictionary::getRef(const EID &eid) const 00164 { 00165 const string scheme = eid.getScheme(); 00166 const string ssp = eid.getSSP(); 00167 return make_pair(get(scheme), get(ssp)); 00168 } 00169 00170 std::ostream &operator<<(std::ostream &stream, const dtn::data::Dictionary &obj) 00171 { 00172 dtn::data::SDNV length(obj.getSize()); 00173 stream << length; 00174 stream << obj._bytestream.str(); 00175 00176 return stream; 00177 } 00178 00179 std::istream &operator>>(std::istream &stream, dtn::data::Dictionary &obj) 00180 { 00181 dtn::data::SDNV length; 00182 stream >> length; 00183 00184 // if the dictionary size if zero throw a exception 00185 if (length.getValue() <= 0) 00186 throw dtn::InvalidDataException("Dictionary size is zero!"); 00187 00188 obj._bytestream.str(""); 00189 char data[length.getValue()]; 00190 stream.read(data, length.getValue()); 00191 obj._bytestream.write(data, length.getValue()); 00192 00193 return stream; 00194 } 00195 } 00196 }