/// <summary> /// Shallow copies the base fields from the source message to this instance. /// </summary> /// <param name="source">The source message.</param> /// <param name="regenMsgID"> /// Pass as <c>true</c> to renegerate the <see cref="_MsgID" /> property if the /// source message ID property is not empty. /// </param> /// <remarks> /// Use this in overriden <see cref="Clone" /> method implementations /// to ensure that the base message fields are copied properly. /// </remarks> protected virtual void CopyBaseFields(Msg source, bool regenMsgID) { this.version = source.version; this.flags = source.flags; this.ttl = source.ttl; this.toEP = source.toEP; this.fromEP = source.fromEP; this.receiptEP = source.receiptEP; this.sessionID = source.sessionID; this.token = source.token; if (source.msgID == Guid.Empty) { this.msgID = Guid.Empty; } else if (regenMsgID) { this.msgID = Helper.NewGuid(); } else { this.msgID = source.msgID; } if (source.extHeaders != null) { this.extHeaders = source.extHeaders.Clone(); } }
private bool inUse; // True if the message is considered to be // owned by the messaging library. #endif /// <summary> /// Constructor. /// </summary> public Msg() { this.version = 0; this.flags = 0; this.ttl = 0; this.toEP = null; this.fromEP = null; this.receiptEP = null; this.msgID = Guid.Empty; this.sessionID = Guid.Empty; #if WINFULL this.session = null; #endif this.token = null; this.extHeaders = null; #if WINFULL this.recvChannel = null; #endif this.msgFrame = null; #if DEBUG this.inUse = false; #endif }
/// <summary> /// Loads the message payload of the base classes from the memory /// stream passed. /// </summary> /// <param name="es">The enhanced stream holding the payload data.</param> /// <remarks> /// Classes that are designed to be derived from should implement /// this method to serialize their content. Note that the base.ReadFrom() /// method should be called before doing this to ensure that any /// ancestor classes will be unserialized properly. /// </remarks> protected virtual void ReadFrom(EnhancedStream es) { #if DEBUG this.readBase = true; #endif this.version = es.ReadByte(); this.ttl = es.ReadByte(); this.flags = (MsgFlag)es.ReadInt32(); this.toEP = MsgEP.Parse(es.ReadString16()); this.fromEP = MsgEP.Parse(es.ReadString16()); this.receiptEP = MsgEP.Parse(es.ReadString16()); if ((flags & MsgFlag.MsgID) != 0) { msgID = new Guid(es.ReadBytes(16)); } else { msgID = Guid.Empty; } if ((flags & MsgFlag.SessionID) != 0) { sessionID = new Guid(es.ReadBytes(16)); } else { sessionID = Guid.Empty; } if ((flags & MsgFlag.SecurityToken) != 0) { token = es.ReadBytes16(); } else { token = null; } // Read the extended headers if ((flags & MsgFlag.ExtensionHeaders) != 0) { int cHeaders; MsgHeaderID headerID; byte[] contents; cHeaders = es.ReadByte(); if (cHeaders > 0) { extHeaders = new MsgHeaderCollection(cHeaders); for (int i = 0; i < cHeaders; i++) { headerID = (MsgHeaderID)es.ReadByte(); contents = es.ReadBytes16(); extHeaders.Set(new MsgHeader(headerID, contents)); } } } }
/// <summary> /// Serializes the payload of the base classes into the memory /// stream. /// </summary> /// <param name="es">The stream where the output is to be written.</param> /// <remarks> /// Classes that are designed to be derived from should implement /// this method to serialize their content. Note that the base.WriteBase() /// method should be called before doing this to ensure that any /// ancestor classes will be serialized properly. /// </remarks> protected virtual void WriteBase(EnhancedStream es) { #if DEBUG this.writeBase = true; #endif if (extHeaders != null && extHeaders.Count > 0) { flags |= MsgFlag.ExtensionHeaders; } #if DEBUG // Verify the consistency of the MsgID and SessionID flags and fields. if (msgID == Guid.Empty) { if ((flags & MsgFlag.MsgID) != 0) { SysLog.LogWarning("Message [{0}] has [MsgFlag.MsgID] set but has no [MsgID]. [MsgFlag.MsgID] flag will be cleared."); flags &= ~MsgFlag.MsgID; } } else { if ((flags & MsgFlag.MsgID) == 0) { SysLog.LogWarning("Message [{0}] has [MsgFlag.MsgID] cleared but has a [MsgID]. [MsgFlag.MsgID] will be set."); flags |= MsgFlag.MsgID; } } if (sessionID == Guid.Empty) { if ((flags & MsgFlag.SessionID) != 0) { SysLog.LogWarning("Message [{0}] has [MsgFlag.SessionID] set but has no [SessionID]. [MsgFlag.SessionID] flag will be cleared."); flags &= ~MsgFlag.SessionID; } } else { if ((flags & MsgFlag.SessionID) == 0) { SysLog.LogWarning("Message [{0}] has [MsgFlag.SessionID] cleared but has a [SessionID]. [MsgFlag.SessionID] will be set."); flags |= MsgFlag.SessionID; } } if (token == null) { if ((flags & MsgFlag.SecurityToken) != 0) { SysLog.LogWarning("Message [{0}] has [MsgFlag.SecurityToken] set but has no [SecurityToken]. [MsgFlag.SecurityToken] flag will be cleared."); flags &= ~MsgFlag.SessionID; } } else { if ((flags & MsgFlag.SecurityToken) == 0) { SysLog.LogWarning("Message [{0}] has [MsgFlag.SecurityToken] cleared but has a [SecurityToken]. [MsgFlag.SecurityToken] will be set."); flags |= MsgFlag.SecurityToken; } } #endif es.WriteByte((byte)version); es.WriteByte((byte)ttl); es.WriteInt32((int)flags); es.WriteString16(toEP != null ? toEP.ToString() : null); es.WriteString16(fromEP != null ? fromEP.ToString() : null); es.WriteString16(receiptEP != null ? receiptEP.ToString() : null); if ((flags & MsgFlag.MsgID) != 0) { es.WriteBytesNoLen(msgID.ToByteArray()); } if ((flags & MsgFlag.SessionID) != 0) { es.WriteBytesNoLen(sessionID.ToByteArray()); } if ((flags & MsgFlag.SecurityToken) != 0) { es.WriteBytes16(token); } // Write the extended headers if ((flags & MsgFlag.ExtensionHeaders) != 0) { es.WriteByte((byte)extHeaders.Count); for (int i = 0; i < extHeaders.Count; i++) { var header = extHeaders[i]; es.WriteByte((byte)header.HeaderID); es.WriteBytes16(header.Contents); } } }