/// <summary> /// Reads a binary-encoded <b>IMessage</b> from the passed /// <see cref="DataReader"/> object. /// </summary> /// <remarks> /// Using the passed <see cref="IChannel"/>, the Codec has access to /// both the <see cref="IMessageFactory"/> for the <b>IChannel</b> /// and the underlying <see cref="IConnection"/>. /// </remarks> /// <param name="channel"> /// The <b>IChannel</b> object through which the binary-encoded /// <b>IMessage</b> was passed. /// </param> /// <param name="reader"> /// The <b>DataReader</b> containing the binary-encoded /// <b>IMessage</b>. /// </param> /// <returns> /// The <b>IMessage</b> object encoded in the given /// <b>DataReader</b>. /// </returns> /// <exception cref="IOException"> /// If an error occurs reading or decoding the <b>IMessage</b>. /// </exception> public virtual IMessage Decode(IChannel channel, DataReader reader) { Debug.Assert(channel is IPofContext); IPofContext context = (IPofContext)channel; int typeId = reader.ReadPackedInt32(); int versionId = reader.ReadPackedInt32(); IPofReader pofreader = new PofStreamReader.UserTypeReader(reader, context, typeId, versionId); IMessage message = channel.MessageFactory.CreateMessage(typeId); Debug.Assert(message is IPortableObject); // set the version identifier bool isEvolvable = message is IEvolvable; IEvolvable evolvable = null; if (isEvolvable) { evolvable = (IEvolvable)message; evolvable.DataVersion = versionId; } // read the Message properties ((IPortableObject)message).ReadExternal(pofreader); // read the future properties Binary binFuture = pofreader.ReadRemainder(); if (isEvolvable) { evolvable.FutureData = binFuture; } return(message); }
/// <summary> /// Deserialize a user type instance from a POF stream by reading its /// state using the specified <see cref="IPofReader"/> object. /// </summary> /// <remarks> /// An implementation of <b>IPofSerializer</b> is required to follow /// the following steps in sequence for reading in an object of a /// user type: /// <list type="number"> /// <item> /// <description> /// If the object is evolvable, the implementation must get the /// version by calling <see cref="IPofWriter.VersionId"/>. /// </description> /// </item> /// <item> /// <description> /// The implementation may read any combination of the /// properties of the user type by using "read" methods of the /// <b>IPofReader</b>, but it must do so in the order of the property /// indexes. /// </description> /// </item> /// <item> /// <description> /// After all desired properties of the user type have been read, /// the implementation must terminate the reading of the user type by /// calling <see cref="IPofReader.ReadRemainder"/>. /// </description> /// </item> /// </list> /// </remarks> /// <param name="reader"> /// The <b>IPofReader</b> with which to read the object's state. /// </param> /// <returns> /// The deserialized user type instance. /// </returns> /// <exception cref="IOException"> /// If an I/O error occurs. /// </exception> public Object Deserialize(IPofReader reader) { String typeName = reader.ReadString(0); Binary bin = reader.ReadBinary(1); reader.ReadRemainder(); ConfigurablePofContext ctx = m_pofContext; IPortableObject po; try { po = (IPortableObject)ObjectUtils.CreateInstance(TypeResolver.Resolve(typeName)); } catch (Exception e) { throw new Exception("Unable to instantiate PortableObject class: " + typeName, e); } DataReader dataReader = bin.GetReader(); int nType = dataReader.ReadPackedInt32(); if (nType != TYPE_PORTABLE) { throw new IOException("Invalid POF type: " + nType + " (" + TYPE_PORTABLE + " expected)"); } int iVersion = dataReader.ReadPackedInt32(); IPofReader pofReader = new PofStreamReader.UserTypeReader( dataReader, ctx, TYPE_PORTABLE, iVersion); m_serializer.Initialize(po, pofReader); Register(typeName); return(po); }