IBR-DTNSuite  0.12
MutableSerializer.cpp
Go to the documentation of this file.
1 /*
2  * MutableSerializer.cpp
3  *
4  * Copyright (C) 2011 IBR, TU Braunschweig
5  *
6  * Written-by: Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 
22 #include "ibrdtn/config.h"
24 #include "ibrdtn/data/Bundle.h"
25 #include "ibrdtn/data/Block.h"
26 #include "ibrdtn/data/EID.h"
28 #include <ibrcommon/Logger.h>
29 
30 #ifdef __DEVELOPMENT_ASSERTIONS__
31 #include <cassert>
32 #endif
33 
34 // include code for platform-independent endianess conversion
35 #include "ibrdtn/data/Endianess.h"
36 
37 namespace dtn
38 {
39  namespace security
40  {
41  MutableSerializer::MutableSerializer(std::ostream& stream, const dtn::data::Block *ignore)
42  : dtn::data::DefaultSerializer(stream), _ignore(ignore), _ignore_previous_bundles(ignore != NULL)
43  {
44  }
45 
47  {
48  }
49 
51  {
52  // we want to ignore all block before "ignore"
53  if (_ignore != NULL) _ignore_previous_bundles = true;
54 
55  // write unpacked primary block
56  // bundle version
57  _stream << dtn::data::BUNDLE_VERSION;
58 
59  // processing flags
60  (*this) << (obj.procflags & 0x0000000007C1BE);
61 
62  // length of header
63  (*this) << (uint32_t)getLength(obj);
64 
65  // dest, source, report to id
66  (*this) << obj.destination;
67  (*this) << obj.source;
68  (*this) << obj.reportto;
69 
70  // timestamp
71  (*this) << obj.timestamp;
72  (*this) << obj.sequencenumber;
73 
74  // lifetime
75  (*this) << obj.lifetime;
76 
77  return *this;
78  }
79 
81  {
82  // do we ignore the current block?
83  if (_ignore_previous_bundles && (&obj != _ignore))
84  {
85  return *this;
86  }
87  else
88  {
89  // process all following bundles
90  _ignore_previous_bundles = false;
91  }
92 
93  // only take payload related blocks
97  {
98  return *this;
99  }
100 
101  _stream << obj.getType();
102  (*this) << (obj.getProcessingFlags() & 0x0000000000000077);
103 
104  const dtn::data::Block::eid_list &eids = obj.getEIDList();
105 
106 #ifdef __DEVELOPMENT_ASSERTIONS__
107  // test: BLOCK_CONTAINS_EIDS => (_eids.size() > 0)
108  assert(!obj.get(dtn::data::Block::BLOCK_CONTAINS_EIDS) || (eids.size() > 0));
109 #endif
110 
112  for (dtn::data::Block::eid_list::const_iterator it = eids.begin(); it != eids.end(); ++it)
113  (*this) << (*it);
114 
115  try {
116  const dtn::security::SecurityBlock &sb = dynamic_cast<const dtn::security::SecurityBlock&>(obj);
117 
119  {
120  // write size of the payload in the block
121  (*this) << dtn::data::Number(sb.getLength_mutable());
122 
123  sb.serialize_mutable(*this, false);
124  }
125  } catch (const std::bad_cast&) {
126  // write size of the payload in the block
127  (*this) << dtn::data::Number(obj.getLength());
128 
129  // write the payload of the block
130  dtn::data::Length slength = 0;
131  obj.serialize(_stream, slength);
132  };
133 
134  return (*this);
135  }
136 
138  {
139 #ifdef __DEVELOPMENT_ASSERTIONS__
140  assert(false);
141 #endif
142  return 0;
143  }
144 
146  {
147  // predict the block length
148  // length in bytes
149  // starting with the fields after the length field
150 
151  // dest id length
152  uint32_t length = 4;
153  // dest id
154  length += static_cast<uint32_t>(obj.destination.getString().size());
155  // source id length
156  length += 4;
157  // source id
158  length += static_cast<uint32_t>(obj.source.getString().size());
159  // report to id length
160  length += 4;
161  // report to id
162  length += static_cast<uint32_t>(obj.reportto.getString().size());
163  // creation time: 2*SDNV
164  length += static_cast<uint32_t>(2 * sdnv_size);
165  // lifetime: SDNV
166  length += static_cast<uint32_t>(sdnv_size);
167 
169 
170  return length;
171  }
172 
174  {
175  dtn::data::Length len = 0;
176 
177  len += sizeof(obj.getType());
178  // proc flags
179  len += sdnv_size;
180 
181  const dtn::data::Block::eid_list &eids = obj.getEIDList();
182 
183 #ifdef __DEVELOPMENT_ASSERTIONS__
184  // test: BLOCK_CONTAINS_EIDS => (_eids.size() > 0)
185  assert(!obj.get(dtn::data::Block::BLOCK_CONTAINS_EIDS) || (eids.size() > 0));
186 #endif
187 
189  for (dtn::data::Block::eid_list::const_iterator it = eids.begin(); it != eids.end(); ++it)
190  len += it->getString().size();
191 
192  // size-field of the size of the payload in the block
193  len += sdnv_size;
194 
195  try {
196  const dtn::security::SecurityBlock &sb = dynamic_cast<const dtn::security::SecurityBlock&>(obj);
197 
198  // add size of the payload in the block
199  len += sb.getLength_mutable();
200  } catch (const std::bad_cast&) {
201  // add size of the payload in the block
202  len += obj.getLength();
203  };
204 
205  return len;
206  }
207 
208 
210  {
211  uint32_t be = GUINT32_TO_BE(value);
212  _stream.write(reinterpret_cast<char*>(&be), sizeof(uint32_t));
213  return *this;
214  }
215 
217  {
218  uint32_t length = static_cast<uint32_t>(value.getString().length());
219  (*this) << length;
220  _stream << value.getString();
221 
222  return *this;
223  }
224 
226  {
227  // convert to big endian if necessary
228  uint64_t be = GUINT64_TO_BE(value.get<uint64_t>());
229  _stream.write(reinterpret_cast<char*>(&be), sizeof(uint64_t));
230  return *this;
231  }
232 
234  {
235  (*this) << dtn::data::Number(list.getLength());
236  _stream << list.toString();
237  return *this;
238  }
239  }
240 }