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

Generated on Fri Feb 12 20:05:20 2016 for OpenDDS by  doxygen 1.4.7