DataSampleHeader.h

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * Distributed under the OpenDDS License.
00005  * See: http://www.opendds.org/license.html
00006  */
00007 
00008 #ifndef OPENDDS_DCPS_DATASAMPLEHEADER_H
00009 #define OPENDDS_DCPS_DATASAMPLEHEADER_H
00010 
00011 #include "Definitions.h"
00012 #include "GuidUtils.h"
00013 #include "PoolAllocationBase.h"
00014 #include "SequenceNumber.h"
00015 #include "RepoIdTypes.h"
00016 #include "Message_Block_Ptr.h"
00017 #include <iosfwd>
00018 
00019 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00020 #pragma once
00021 #endif /* ACE_LACKS_PRAGMA_ONCE */
00022 
00023 OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL
00024 
00025 namespace OpenDDS {
00026 namespace DCPS {
00027 
00028 class ReceivedDataSample;
00029 
00030 /// One byte message id (<256)
00031 enum MessageId {
00032   SAMPLE_DATA,
00033   DATAWRITER_LIVELINESS,
00034   INSTANCE_REGISTRATION,
00035   UNREGISTER_INSTANCE,
00036   DISPOSE_INSTANCE,
00037   GRACEFUL_DISCONNECT,
00038   REQUEST_ACK,
00039   SAMPLE_ACK,
00040   END_COHERENT_CHANGES,
00041   TRANSPORT_CONTROL,
00042   DISPOSE_UNREGISTER_INSTANCE,
00043   END_HISTORIC_SAMPLES,
00044   MESSAGE_ID_MAX // must be the last enumerator
00045 };
00046 
00047 enum SubMessageId {
00048   SUBMESSAGE_NONE,
00049   MULTICAST_SYN,
00050   MULTICAST_SYNACK,
00051   MULTICAST_NAK,
00052   MULTICAST_NAKACK,
00053   SUBMESSAGE_ID_MAX // must be the last enumerator
00054 };
00055 
00056 enum DataSampleHeaderFlag {
00057   BYTE_ORDER_FLAG,
00058   COHERENT_CHANGE_FLAG,
00059   HISTORIC_SAMPLE_FLAG,
00060   LIFESPAN_DURATION_FLAG,
00061   GROUP_COHERENT_FLAG,
00062   CONTENT_FILTER_FLAG,
00063   SEQUENCE_REPAIR_FLAG,
00064   MORE_FRAGMENTS_FLAG
00065 };
00066 
00067 enum DataSampleHeaderFlag2 {
00068   CDR_ENCAP_FLAG,
00069   KEY_ONLY_FLAG
00070 };
00071 
00072 /// The header message of a data sample.
00073 /// This header and the data sample are in different
00074 /// message block and will be chained together.
00075 struct OpenDDS_Dcps_Export DataSampleHeader : public PoolAllocationBase {
00076   enum {
00077     MESSAGE_ID_OFFSET = 0,
00078     SUBMESSAGE_ID_OFFSET = 1,
00079     FLAGS_OFFSET = 2 // message_id_ + submessage_id_
00080   };
00081 
00082   /// The enum MessageId.
00083   char message_id_;
00084 
00085   /// Implementation-specific sub-message Ids.
00086   char submessage_id_;
00087 
00088   /// 0 -  Message encoded using big-endian byte order. (see ace/CDR_Base.h)
00089   /// 1 -  Message encoded using little-endian byte order.
00090   bool byte_order_ : 1;
00091 
00092   /// The flag indicates the sample belongs to a coherent
00093   /// change set (i.e. PRESENTATION coherent_access == true).
00094   bool coherent_change_ : 1;
00095 
00096   /// This flag indicates a sample has been resent from a
00097   /// non-VOLATILE DataWriter.
00098   bool historic_sample_ : 1;
00099 
00100   /// This flag indicates the sample header contains non-default
00101   /// LIFESPAN duration fields.
00102   bool lifespan_duration_ : 1;
00103 
00104   bool group_coherent_ : 1;
00105 
00106   /// The publishing side has applied content filtering, and the optional
00107   /// content_filter_entries_ field is present in the marshaled header.
00108   bool content_filter_ : 1;
00109 
00110   /// Due to content filtering, a gap in the sequence numbers may be an
00111   /// expected condition.  If this bit is set, assume prior sequence numbers
00112   /// were filtered-out and are not missing.
00113   bool sequence_repair_ : 1;
00114 
00115   /// The current "Data Sample" needs reassembly before further processing.
00116   bool more_fragments_ : 1;
00117 
00118   // bools above this line are in the first flags byte, below this line are
00119   // in the second flags byte.  To avoid complicating the implementation of
00120   // partial(), flags that impact the size of serialized DataSampleHeader
00121   // should go in the first flags byte.
00122 
00123   /// The data payload uses CDR encapsulation and alignment rules, as defined
00124   /// by the RTPS specification formal/2010-11-01.
00125   bool cdr_encapsulation_ : 1;
00126 
00127   /// Only the key fields of the data sample are present in the payload.
00128   bool key_fields_only_ : 1;
00129 
00130   bool reserved_1 : 1;
00131   bool reserved_2 : 1;
00132   bool reserved_3 : 1;
00133   bool reserved_4 : 1;
00134   bool reserved_5 : 1;
00135   bool reserved_6 : 1;
00136 
00137   /// The size of the data sample (without header).  After this header is
00138   /// demarshaled, the transport expects to see this many bytes in the stream
00139   /// before the start of the next header (or end of the Transport PDU).
00140   ACE_UINT32 message_length_;
00141 
00142   /// The sequence number is obtained from the Publisher
00143   /// associated with the DataWriter based on the PRESENTATION
00144   /// requirement for the sequence value (access_scope == GROUP).
00145   SequenceNumber sequence_;
00146 
00147   //{@
00148   /// The SOURCE_TIMESTAMP field is generated from the DataWriter
00149   /// or supplied by the application at the time of the write.
00150   /// This value is derived from the local hosts system clock,
00151   /// which is assumed to be synchronized with the clocks on other
00152   /// hosts within the domain.  This field is required for
00153   /// DESTINATION_ORDER and LIFESPAN policy behaviors of subscriptions.
00154   /// It is also required to be present for all data in the
00155   /// SampleInfo structure supplied along with each data sample.
00156   ACE_INT32 source_timestamp_sec_;
00157   ACE_UINT32 source_timestamp_nanosec_; // Corresponding IDL is unsigned.
00158   //@}
00159 
00160   //{@
00161   /// The LIFESPAN duration field is generated from the DataWriter
00162   /// or supplied by the application at the time of the write. This
00163   /// field is used to determine if a given sample is considered
00164   /// 'stale' and should be discarded by associated DataReader.
00165   /// These fields are optional and are controlled by the
00166   /// lifespan_duration_ flag.
00167   ACE_INT32 lifespan_duration_sec_;
00168   ACE_UINT32 lifespan_duration_nanosec_;  // Corresponding IDL is unsigned.
00169   //@}
00170 
00171   /// Identify the DataWriter that produced the sample data being
00172   /// sent.
00173   PublicationId publication_id_;
00174 
00175   /// Id representing the coherent group.  Optional field that's only present if
00176   /// the flag for group_coherent_ is set.
00177   RepoId publisher_id_;
00178 
00179   /// Optional field present if the content_filter_ flag bit is set.
00180   /// Indicates which readers should not receive the data.
00181   GUIDSeq content_filter_entries_;
00182 
00183   static ACE_UINT8 mask_flag(DataSampleHeaderFlag  flag) { return 1 << flag; }
00184   static ACE_UINT8 mask_flag(DataSampleHeaderFlag2 flag) { return 1 << flag; }
00185 
00186   static void clear_flag(DataSampleHeaderFlag flag,
00187                          ACE_Message_Block* buffer);
00188 
00189   static void set_flag(DataSampleHeaderFlag flag,
00190                        ACE_Message_Block* buffer);
00191 
00192   static bool test_flag(DataSampleHeaderFlag flag,
00193                         const ACE_Message_Block* buffer);
00194 
00195   /// Does the data in this mb constitute a partial Sample Header?
00196   static bool partial(const ACE_Message_Block& mb);
00197 
00198   /// Marshal the "guids" as an optional header chained as to the continuation
00199   /// of "mb" (which must already be a valid DataSampleHeader serialization).
00200   /// Any existing payload of "mb" (its continuation) will be chained after the
00201   /// new optional header part.  "guids" may be null, same serialization as 0.
00202   static void add_cfentries(const GUIDSeq* guids, ACE_Message_Block* mb);
00203 
00204   /// Create two new serialized headers (owned by caller), the "head" having at
00205   /// most "size" bytes (header + data) and the "tail" having the rest.
00206   static void split(const ACE_Message_Block& orig, size_t size,
00207                     Message_Block_Ptr& head, Message_Block_Ptr& tail);
00208 
00209   /// If "first" and "second" are two fragments of the same original message
00210   /// (as created by split()), return true and set up the "result" header to
00211   /// match the original header.  Joining the data payload is the
00212   /// responsibility of the caller (manipulate the continuation chain).
00213   static bool join(const DataSampleHeader& first,
00214                    const DataSampleHeader& second, DataSampleHeader& result);
00215 
00216   DataSampleHeader();
00217 
00218   /// Construct with values extracted from a buffer.
00219   explicit DataSampleHeader(ACE_Message_Block& buffer);
00220 
00221   /// Assignment from an ACE_Message_Block.
00222   DataSampleHeader& operator=(ACE_Message_Block& buffer);
00223 
00224   /// Amount of data read when initializing from a buffer.
00225   size_t marshaled_size() const;
00226 
00227   /// Similar to IDL compiler generated methods.
00228   static size_t max_marshaled_size();
00229 
00230   /// Implement load from buffer.
00231   void init(ACE_Message_Block* buffer);
00232 
00233   bool into_received_data_sample(ReceivedDataSample& rds);
00234 
00235   ACE_UINT32 message_length() const { return this->message_length_; }
00236 
00237   bool more_fragments() const { return this->more_fragments_; }
00238 
00239   void pdu_remaining(size_t) { /* ignored, only RTPS uses this */ }
00240 
00241   static ACE_Message_Block* alloc_msgblock(const ACE_Message_Block& mb,
00242                                            size_t size, bool use_data_alloc);
00243 
00244   static void split_payload(const ACE_Message_Block& orig, size_t size,
00245                             Message_Block_Ptr& head, Message_Block_Ptr& tail);
00246 
00247 private:
00248   /// Keep track of the amount of data read from a buffer.
00249   size_t marshaled_size_;
00250 };
00251 
00252 const char* to_string(const MessageId value);
00253 const char* to_string(const SubMessageId value);
00254 OPENDDS_STRING to_string(const DataSampleHeader& value);
00255 
00256 /// Marshal/Insertion into a buffer.
00257 OpenDDS_Dcps_Export
00258 bool operator<<(ACE_Message_Block&, const DataSampleHeader& value);
00259 
00260 #ifndef OPENDDS_SAFETY_PROFILE
00261 /// Message Id enumeration insertion onto an ostream.
00262 OpenDDS_Dcps_Export
00263 std::ostream& operator<<(std::ostream& str, const MessageId value);
00264 
00265 /// Sub-Message Id enumeration insertion onto an ostream.
00266 OpenDDS_Dcps_Export
00267 std::ostream& operator<<(std::ostream& os, const SubMessageId rhs);
00268 
00269 /// Message header insertion onto an ostream.
00270 OpenDDS_Dcps_Export
00271 std::ostream& operator<<(std::ostream& str, const DataSampleHeader& value);
00272 #endif //OPENDDS_SAFETY_PROFILE
00273 
00274 } // namespace DCPS
00275 } // namespace OpenDDS
00276 
00277 OPENDDS_END_VERSIONED_NAMESPACE_DECL
00278 
00279 #if defined(__ACE_INLINE__)
00280 #include "DataSampleHeader.inl"
00281 #endif /* __ACE_INLINE__ */
00282 
00283 #endif  /* OPENDDS_DCPS_DATASAMPLEHEADER_H */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1