/// <summary> /// Serializes the message passed into a byte array. /// </summary> /// <param name="msg">The message to be serialized.</param> /// <param name="es">The enhanced stream where the output is to be written.</param> /// <returns>The size of the message written in bytes.</returns> /// <remarks> /// The buffer returned includes the preamble, the message type, /// and the payload. /// </remarks> public static int Save(EnhancedStream es, Msg msg) { string typeID; int cbMsg; MsgInfo msgInfo; EnvelopeMsg envelopeMsg; int startPos; // Write the type and payload first to determine the message // size and then go back and write the preamble. Note that // for envelope messages, we're going to get the typeID from the // message instance, rather than looking it up in the type map. envelopeMsg = msg as EnvelopeMsg; if (envelopeMsg != null) { typeID = envelopeMsg.TypeID; } else { lock (syncLock) typeMap.TryGetValue(msg.GetType(), out msgInfo); if (msgInfo == null) { throw new MsgException("Unregistered message class [{0}].", msg.GetType().FullName); } typeID = msgInfo.TypeID; } startPos = (int)es.Position; es.Write(preamble, 0, preamble.Length); // Leave room for the preamble es.WriteString16(typeID); #if DEBUG msg.writeBase = false; // $hack(jeff.lill): Strictly speaking, this isn't threadsafe #endif msg.WriteBase(es); #if DEBUG Assertion.Test(msg.writeBase, "Derived [Msg] classes must call [base.WriteBase()]."); #endif msg.WritePayload(es); cbMsg = (int)es.Position; es.Position = startPos; es.WriteByte(magic); // Magic number es.WriteByte(0); // Message format es.WriteInt32(cbMsg); // Total message length es.Position = startPos + cbMsg; return(cbMsg); }