public static int PutSubMessage(this IoBuffer buffer, SubMessage msg) { // The PSM aligns each Submessage on a 32-bit boundary with respect to the start of the Message (page 159). buffer.Align(4); buffer.Order = (msg.Header.IsLittleEndian ? ByteOrder.LittleEndian : ByteOrder.BigEndian); // Set the endianess buffer.PutSubMessageHeader(msg.Header); int position = buffer.Position; switch (msg.Kind) { case SubMessageKind.PAD: buffer.PutPad((Pad)msg); break; case SubMessageKind.ACKNACK: buffer.PutAckNack((AckNack)msg); break; case SubMessageKind.HEARTBEAT: buffer.PutHeartbeat((Heartbeat)msg); break; case SubMessageKind.GAP: buffer.PutGap((Gap)msg); break; case SubMessageKind.INFO_TS: buffer.PutInfoTimestamp((InfoTimestamp)msg); break; case SubMessageKind.INFO_SRC: buffer.PutInfoSource((InfoSource)msg); break; case SubMessageKind.INFO_REPLY_IP4: buffer.PutInfoReplyIp4((InfoReplyIp4)msg); break; case SubMessageKind.INFO_DST: buffer.PutInfoDestination((InfoDestination)msg); break; case SubMessageKind.INFO_REPLY: buffer.PutInfoReply((InfoReply)msg); break; case SubMessageKind.NACK_FRAG: buffer.PutNackFrag((NackFrag)msg); break; case SubMessageKind.HEARTBEAT_FRAG: buffer.PutHeartbeatFrag((HeartbeatFrag)msg); break; case SubMessageKind.DATA: buffer.PutDataSubMessage((Data)msg); break; case SubMessageKind.DATA_FRAG: buffer.PutDataFrag((DataFrag)msg); break; default: break; } buffer.Align(4); int subMessageLength = buffer.Position - position; // Position to 'submessageLength' -2 is for short (2 bytes) // buffers current position is not changed buffer.PutInt16(position - 2, (short)subMessageLength); return position; }
public static int PutSubMessage(this IoBuffer buffer, SubMessage msg) { buffer.Align(4); buffer.Order = msg.Header.EndiannessFlag; // Set the endianess buffer.PutSubMessageHeader(msg.Header); int position = buffer.Position; switch (msg.Kind) { case SubMessageKind.PAD: buffer.PutPad((Pad)msg); break; case SubMessageKind.ACKNACK: buffer.PutAckNack((AckNack)msg); break; case SubMessageKind.HEARTBEAT: buffer.PutHeartbeat((Heartbeat)msg); break; case SubMessageKind.GAP: buffer.PutGap((Gap)msg); break; case SubMessageKind.INFO_TS: buffer.PutInfoTimestamp((InfoTimestamp)msg); break; case SubMessageKind.INFO_SRC: buffer.PutInfoSource((InfoSource)msg); break; case SubMessageKind.INFO_REPLY_IP4: buffer.PutInfoReplyIp4((InfoReplyIp4)msg); break; case SubMessageKind.INFO_DST: buffer.PutInfoDestination((InfoDestination)msg); break; case SubMessageKind.INFO_REPLY: buffer.PutInfoReply((InfoReply)msg); break; case SubMessageKind.NACK_FRAG: buffer.PutNackFrag((NackFrag)msg); break; case SubMessageKind.HEARTBEAT_FRAG: buffer.PutHeartbeatFrag((HeartbeatFrag)msg); break; case SubMessageKind.DATA: buffer.PutDataSubMessage((Data)msg); break; case SubMessageKind.DATA_FRAG: buffer.PutDataFrag((DataFrag)msg); break; default: break; } int subMessageLength = buffer.Position - position; // Position to 'submessageLength' -2 is for short (2 bytes) // buffers current position is not changed buffer.PutInt16(position - 2, (short)subMessageLength); return position; }
public static void PutParameterList(this IoBuffer buffer, ParameterList obj) { buffer.Align(4); // @see 9.4.2.11 obj.Value.Add(Sentinel.Instance); // Sentinel must be the last Parameter foreach (Parameter param in obj.Value) { buffer.PutParameter(param); } }
public static void PutParameterList(this IoBuffer buffer, ParameterList obj) { buffer.Align(4); // @see 9.4.2.11 obj.Add(new Sentinel()); // Sentinel must be the last Parameter foreach (Parameter param in obj) { buffer.PutInt16((short)param.ParameterId); buffer.PutInt16(0); // length will be calculated int pos = buffer.Position; buffer.PutParameter(param); buffer.Align(4); // Make sure length is multiple of 4 & align for // next param int paramLength = buffer.Position - pos; buffer.PutInt16(pos - 2, (short)paramLength); } // TODO: last Parameter must be PID_SENTINEL }
public static void PutParameter(this IoBuffer buffer, Parameter obj) { buffer.PutInt16((short)obj.ParameterId); buffer.PutInt16(0); // length will be calculated int pos = buffer.Position; buffer.Put(obj.Bytes); buffer.Align(4); // Make sure length is multiple of 4 & align for // next param int paramLength = buffer.Position - pos; buffer.PutInt16(pos - 2, (short)paramLength); }
/// <summary> /// Reads a <see cref="VersionInfo"/> object form the stream. /// </summary> /// <param name="reader"> /// The reader to read the data from. /// </param> /// <returns> /// A <see cref="VersionInfo"/> object. /// </returns> public static VersionInfo ReadVersionInfo(this BinaryReader reader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } var versionHeader = reader.ReadStruct<VersionHeader>(); var key = reader.ReadUnicodeString(); reader.Align(); return new VersionInfo { Header = versionHeader, Key = key }; }
public static void PutDataSubMessage(this IoBuffer buffer, Data obj) { buffer.PutInt16(obj.ExtraFlags.Value); short octetsToInlineQos = 0; if (obj.HasInlineQosFlag) { octetsToInlineQos = 4 + 4 + 8;// EntityId.LENGTH + EntityId.LENGTH + SequenceNumber.LENGTH; } buffer.PutInt16(octetsToInlineQos); buffer.PutEntityId(obj.ReaderId); buffer.PutEntityId(obj.WriterId); buffer.PutSequenceNumber(obj.WriterSN); if (obj.HasInlineQosFlag) { buffer.PutParameterList(obj.InlineQos); } if (obj.HasDataFlag || obj.HasKeyFlag) { buffer.Align(4); buffer.Put(obj.SerializedPayload.DataEncapsulation.SerializedPayload); } }
/// <summary> /// Aligns a string given a total character width and alignment style. Fills in the extra space with the space character. /// </summary> /// <param name="value">The current string.</param> /// <param name="alignment">The horizontal alignment.</param> /// <param name="totalWidth">The total width of the new string.</param> /// <returns>A new string instance.</returns> public static string Align(this string value, HorizontalAlignment alignment, int totalWidth) { return value.Align(alignment, totalWidth, ' '); }
public static void GetSubMessage(this IoBuffer buffer, ref SubMessage obj) { buffer.Align(4); int smhPosition = buffer.Position; SubMessageHeader header = buffer.GetSubMessageHeader(); int smStart = buffer.Position; switch (header.SubMessageKind) { // @see 9.4.5.1.1 case SubMessageKind.PAD: Pad smPad = new Pad(); smPad.Header = header; buffer.GetPad(ref smPad); obj = smPad; break; case SubMessageKind.ACKNACK: AckNack smAckNack = new AckNack(); smAckNack.Header = header; buffer.GetAckNack(ref smAckNack); obj = smAckNack; break; case SubMessageKind.HEARTBEAT: Heartbeat smHeartbeat = new Heartbeat(); smHeartbeat.Header = header; buffer.GetHeartbeat(ref smHeartbeat); obj = smHeartbeat; break; case SubMessageKind.GAP: Gap smgap = new Gap(); smgap.Header = header; buffer.GetGap(ref smgap); obj = smgap; break; case SubMessageKind.INFO_TS: InfoTimestamp sminfots = new InfoTimestamp(); sminfots.Header = header; buffer.GetInfoTimestamp(ref sminfots); obj = sminfots; break; case SubMessageKind.INFO_SRC: InfoSource smInfoSource = new InfoSource(); smInfoSource.Header = header; buffer.GetInfoSource(ref smInfoSource); obj = smInfoSource; break; case SubMessageKind.INFO_REPLY_IP4: InfoReplyIp4 smInfoReplyIp4 = new InfoReplyIp4(); smInfoReplyIp4.Header = header; buffer.GetInfoReplyIp4(ref smInfoReplyIp4); obj = smInfoReplyIp4; break; case SubMessageKind.INFO_DST: InfoDestination smInfoDestination = new InfoDestination(); smInfoDestination.Header = header; buffer.GetInfoDestination(ref smInfoDestination); obj = smInfoDestination; break; case SubMessageKind.INFO_REPLY: InfoReply smInfoReply = new InfoReply(); smInfoReply.Header = header; buffer.GetInfoReply(ref smInfoReply); obj = smInfoReply; break; case SubMessageKind.NACK_FRAG: NackFrag smNackFrag = new NackFrag(); smNackFrag.Header = header; buffer.GetNackFrag(ref smNackFrag); obj = smNackFrag; break; case SubMessageKind.HEARTBEAT_FRAG: HeartbeatFrag smHeartbeatFrag = new HeartbeatFrag(); smHeartbeatFrag.Header = header; buffer.GetHeartbeatFrag(ref smHeartbeatFrag); obj = smHeartbeatFrag; break; case SubMessageKind.DATA: Data smdata = new Data(); smdata.Header = header; buffer.GetDataSubMessage(ref smdata); obj = smdata; break; case SubMessageKind.DATA_FRAG: DataFrag smdDataFrag = new DataFrag(); smdDataFrag.Header = header; buffer.GetDataFrag(ref smdDataFrag); obj = smdDataFrag; break; default: throw new NotSupportedException(); break; } int smEnd = buffer.Position; int smLength = smEnd - smStart; if (smLength != header.SubMessageLength && header.SubMessageLength != 0) { log.WarnFormat("SubMessage length differs for {0} != {1} for {2}", smLength, header.SubMessageLength, obj); if (smLength < header.SubMessageLength) { byte[] unknownBytes = new byte[header.SubMessageLength - smLength]; log.DebugFormat("Trying to skip {0} bytes", unknownBytes.Length); buffer.Get(unknownBytes, 0, unknownBytes.Length); } } log.DebugFormat("SubMsg in: {0}", obj); }
public static void GetDataSubMessage(this IoBuffer buffer, ref Data obj) { if (obj.HasDataFlag && obj.HasKeyFlag) { // Should we just ignore this message instead throw new ApplicationException( "This version of protocol does not allow Data submessage to contain both serialized data and serialized key (9.4.5.3.1)"); } int start_count = buffer.Position; // start of bytes Read so far from the // beginning Flags flgs = new Flags(); flgs.Value = (byte)buffer.GetInt16(); obj.ExtraFlags = flgs; int octetsToInlineQos = buffer.GetInt16() & 0xffff; int currentCount = buffer.Position; // count bytes to inline qos obj.ReaderId = buffer.GetEntityId(); obj.WriterId = buffer.GetEntityId(); obj.WriterSN = buffer.GetSequenceNumber(); int bytesRead = buffer.Position - currentCount; int unknownOctets = octetsToInlineQos - bytesRead; for (int i = 0; i < unknownOctets; i++) { // TODO: Instead of looping, we should do just // newPos = bb.getBuffer.position() + unknownOctets or something // like that buffer.Get(); // Skip unknown octets, @see 9.4.5.3.3 // octetsToInlineQos } if (obj.HasInlineQosFlag) { obj.InlineQos = buffer.GetParameterList(); } if (obj.HasDataFlag || obj.HasKeyFlag) { buffer.Align(4); // Each submessage is aligned on 32-bit boundary, @see // 9.4.1 Overall Structure int end_count = buffer.Position; // end of bytes Read so far from the beginning int length; if (obj.Header.SubMessageLength != 0) { length = obj.Header.SubMessageLength - (end_count - start_count); } else { // SubMessage is the last one. Rest of the bytes are Read. // @see 8.3.3.2.3 length = buffer.Remaining; } obj.SerializedPayload = new SerializedPayload(); obj.SerializedPayload.DataEncapsulation = EncapsulationManager.Deserialize(buffer, length); } }