OpenDDS  Snapshot(2023/04/28-20:55)
DataSampleHeader.h
Go to the documentation of this file.
1 /*
2  *
3  *
4  * Distributed under the OpenDDS License.
5  * See: http://www.opendds.org/license.html
6  */
7 
8 #ifndef OPENDDS_DCPS_DATASAMPLEHEADER_H
9 #define OPENDDS_DCPS_DATASAMPLEHEADER_H
10 
12 #include "Definitions.h"
13 #include "GuidUtils.h"
14 #include "Message_Block_Ptr.h"
15 #include "PoolAllocationBase.h"
16 #include "SequenceNumber.h"
17 
18 #include <ace/Guard_T.h>
19 #include <ace/Lock.h>
20 
21 #include <iosfwd>
22 
23 #if !defined (ACE_LACKS_PRAGMA_ONCE)
24 #pragma once
25 #endif /* ACE_LACKS_PRAGMA_ONCE */
26 
28 
29 namespace OpenDDS {
30 namespace DCPS {
31 
32 class ReceivedDataSample;
33 
34 /// One byte message id (<256)
35 enum MessageId {
48  MESSAGE_ID_MAX // must be the last enumerator
49 };
50 
57  SUBMESSAGE_ID_MAX // must be the last enumerator
58 };
59 
69 };
70 
74 };
75 
76 /// The header message of a data sample.
77 /// This header and the data sample are in different
78 /// message block and will be chained together.
80  enum {
81  MESSAGE_ID_OFFSET = 0,
82  SUBMESSAGE_ID_OFFSET = 1,
83  FLAGS_OFFSET = 2 // message_id_ + submessage_id_
84  };
85 
86  /// The enum MessageId.
88 
89  /// Implementation-specific sub-message Ids.
91 
92  /// 0 - Message encoded using big-endian byte order. (see ace/CDR_Base.h)
93  /// 1 - Message encoded using little-endian byte order.
94  bool byte_order_ : 1;
95 
96  /// The flag indicates the sample belongs to a coherent
97  /// change set (i.e. PRESENTATION coherent_access == true).
98  bool coherent_change_ : 1;
99 
100  /// This flag indicates a sample has been resent from a
101  /// non-VOLATILE DataWriter.
103 
104  /// This flag indicates the sample header contains non-default
105  /// LIFESPAN duration fields.
107 
108  bool group_coherent_ : 1;
109 
110  /// The publishing side has applied content filtering, and the optional
111  /// content_filter_entries_ field is present in the marshaled header.
112  bool content_filter_ : 1;
113 
114  /// Due to content filtering, a gap in the sequence numbers may be an
115  /// expected condition. If this bit is set, assume prior sequence numbers
116  /// were filtered-out and are not missing.
118 
119  /// The current "Data Sample" needs reassembly before further processing.
120  bool more_fragments_ : 1;
121 
122  // bools above this line are in the first flags byte, below this line are
123  // in the second flags byte. To avoid complicating the implementation of
124  // partial(), flags that impact the size of serialized DataSampleHeader
125  // should go in the first flags byte.
126 
127  /// The data payload uses CDR encapsulation and alignment rules, as defined
128  /// by the RTPS specification formal/2010-11-01.
130 
131  /// Only the key fields of the data sample are present in the payload.
133 
134  bool reserved_1 : 1;
135  bool reserved_2 : 1;
136  bool reserved_3 : 1;
137  bool reserved_4 : 1;
138  bool reserved_5 : 1;
139  bool reserved_6 : 1;
140 
141  /// The size of the data sample (without header). After this header is
142  /// demarshaled, the transport expects to see this many bytes in the stream
143  /// before the start of the next header (or end of the Transport PDU).
144  ACE_UINT32 message_length_;
145 
146  /// The sequence number is obtained from the Publisher
147  /// associated with the DataWriter based on the PRESENTATION
148  /// requirement for the sequence value (access_scope == GROUP).
150 
151  //{@
152  /// The SOURCE_TIMESTAMP field is generated from the DataWriter
153  /// or supplied by the application at the time of the write.
154  /// This value is derived from the local hosts system clock,
155  /// which is assumed to be synchronized with the clocks on other
156  /// hosts within the domain. This field is required for
157  /// DESTINATION_ORDER and LIFESPAN policy behaviors of subscriptions.
158  /// It is also required to be present for all data in the
159  /// SampleInfo structure supplied along with each data sample.
161  ACE_UINT32 source_timestamp_nanosec_; // Corresponding IDL is unsigned.
162  //@}
163 
164  //{@
165  /// The LIFESPAN duration field is generated from the DataWriter
166  /// or supplied by the application at the time of the write. This
167  /// field is used to determine if a given sample is considered
168  /// 'stale' and should be discarded by associated DataReader.
169  /// These fields are optional and are controlled by the
170  /// lifespan_duration_ flag.
172  ACE_UINT32 lifespan_duration_nanosec_; // Corresponding IDL is unsigned.
173  //@}
174 
175  /// Identify the DataWriter that produced the sample data being
176  /// sent.
178 
179  /// Id representing the coherent group. Optional field that's only present if
180  /// the flag for group_coherent_ is set.
182 
183  /// Optional field present if the content_filter_ flag bit is set.
184  /// Indicates which readers should not receive the data.
186 
187  static ACE_UINT8 mask_flag(DataSampleHeaderFlag flag) { return 1 << flag; }
188  static ACE_UINT8 mask_flag(DataSampleHeaderFlag2 flag) { return 1 << flag; }
189 
190  static void clear_flag(DataSampleHeaderFlag flag,
191  ACE_Message_Block* buffer);
192 
193  static void set_flag(DataSampleHeaderFlag flag,
194  ACE_Message_Block* buffer);
195 
196  static bool test_flag(DataSampleHeaderFlag flag,
197  const ACE_Message_Block* buffer);
198 
199  /// Does the data in this mb constitute a partial Sample Header?
200  static bool partial(const ACE_Message_Block& mb);
201 
202  /// Marshal the "guids" as an optional header chained as to the continuation
203  /// of "mb" (which must already be a valid DataSampleHeader serialization).
204  /// Any existing payload of "mb" (its continuation) will be chained after the
205  /// new optional header part. "guids" may be null, same serialization as 0.
206  static void add_cfentries(const GUIDSeq* guids, ACE_Message_Block* mb);
207 
208  /// Create two new serialized headers (owned by caller), the "head" having at
209  /// most "size" bytes (header + data) and the "tail" having the rest.
210  static void split(const ACE_Message_Block& orig, size_t size,
211  Message_Block_Ptr& head, Message_Block_Ptr& tail);
212 
213  /// If "first" and "second" are two fragments of the same original message
214  /// (as created by split()), return true and set up the "result" header to
215  /// match the original header. Joining the data payload is the
216  /// responsibility of the caller (manipulate the continuation chain).
217  static bool join(const DataSampleHeader& first,
218  const DataSampleHeader& second, DataSampleHeader& result);
219 
221 
222  /// Construct with values extracted from a buffer.
223  explicit DataSampleHeader(ACE_Message_Block& buffer);
224 
225  /// Assignment from an ACE_Message_Block.
226  DataSampleHeader& operator=(ACE_Message_Block& buffer);
227 
228  /// Amount of data read when initializing from a buffer.
229  size_t get_serialized_size() const;
230 
231  /// Similar to IDL compiler generated methods.
232  static size_t get_max_serialized_size();
233 
234  /// Implement load from buffer.
235  void init(ACE_Message_Block* buffer);
236 
237  bool into_received_data_sample(ReceivedDataSample& rds);
238 
239  ACE_UINT32 message_length() const { return this->message_length_; }
240 
241  bool more_fragments() const { return this->more_fragments_; }
242 
243  void pdu_remaining(size_t) { /* ignored, only RTPS uses this */ }
244 
245  static ACE_Message_Block* alloc_msgblock(const ACE_Message_Block& mb,
246  size_t size, bool use_data_alloc);
247 
248  static void split_payload(const ACE_Message_Block& orig, size_t size,
249  Message_Block_Ptr& head, Message_Block_Ptr& tail);
250 
251  /// Returns true if the sample has a complete serialized payload.
252  bool valid_data() const;
253 
255  {
256  switch (message_id_) {
257  case UNREGISTER_INSTANCE:
259  case DISPOSE_INSTANCE:
262  default:
264  }
265  }
266 
267 private:
268  /// Keep track of the amount of data read from a buffer.
270 
271  // If the constructor argument is null this object does nothing.
272  // Otherwise it is an ACE_Guard for the lock constructor argument.
273  struct MaybeGuard {
274  explicit MaybeGuard(ACE_Lock* a) : guard_(a ? *a : non_lock) {}
275 
277 
278  struct NoOpLock : ACE_Lock {
279  int remove() { return 0; }
280  int acquire() { return 0; }
281  int tryacquire() { return 0; }
282  int release() { return 0; }
283  int acquire_read() { return 0; }
284  int acquire_write() { return 0; }
285  int tryacquire_read() { return 0; }
286  int tryacquire_write() { return 0; }
287  int tryacquire_write_upgrade() { return 0; }
288  };
290  };
291 };
292 
294 
296 const char* to_string(MessageId value);
298 const char* to_string(SubMessageId value);
301 
302 /// Marshal/Insertion into a buffer.
305 
306 #ifndef OPENDDS_SAFETY_PROFILE
307 /// Message Id enumeration insertion onto an ostream.
309 std::ostream& operator<<(std::ostream& os, MessageId value);
310 
311 /// Sub-Message Id enumeration insertion onto an ostream.
313 std::ostream& operator<<(std::ostream& os, SubMessageId value);
314 
315 /// Message header insertion onto an ostream.
317 std::ostream& operator<<(std::ostream& str, const DataSampleHeader& value);
318 #endif //OPENDDS_SAFETY_PROFILE
319 
320 } // namespace DCPS
321 } // namespace OpenDDS
322 
324 
325 #if defined(__ACE_INLINE__)
326 #include "DataSampleHeader.inl"
327 #endif /* __ACE_INLINE__ */
328 
329 #endif /* OPENDDS_DCPS_DATASAMPLEHEADER_H */
const LogLevel::Value value
Definition: debug.cpp:61
char message_id_
The enum MessageId.
bool key_fields_only_
Only the key fields of the data sample are present in the payload.
#define OpenDDS_Dcps_Export
Definition: dcps_export.h:24
Cached_Allocator_With_Overflow< DataSampleHeader, ACE_Null_Mutex > DataSampleHeaderAllocator
DDS::InstanceStateKind instance_state() const
MessageId
One byte message id (<256)
#define OPENDDS_STRING
ACE_CDR::Boolean operator<<(Serializer &serializer, CoherentChangeControl &value)
Marshal/Insertion into a buffer.
Holds a data sample received by the transport.
unsigned long InstanceStateKind
A fixed-size allocator that caches items for quicker access but if the pool is exhausted it will use ...
size_t serialized_size_
Keep track of the amount of data read from a buffer.
int init(void)
bool more_fragments_
The current "Data Sample" needs reassembly before further processing.
char submessage_id_
Implementation-specific sub-message Ids.
static ACE_UINT8 mask_flag(DataSampleHeaderFlag2 flag)
sequence< GUID_t > GUIDSeq
Definition: DdsDcpsGuid.idl:62
Sequence number abstraction. Only allows positive 64 bit values.
const InstanceStateKind NOT_ALIVE_DISPOSED_INSTANCE_STATE
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
const char * to_string(MessageId value)
unsigned char ACE_UINT8
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
const InstanceStateKind NOT_ALIVE_NO_WRITERS_INSTANCE_STATE
static ACE_UINT8 mask_flag(DataSampleHeaderFlag flag)
const InstanceStateKind ALIVE_INSTANCE_STATE