Esempio n. 1
0
        /// <summary>
        /// Read and return the next IPacket from the stream
        /// </summary>
        public IPacket Read()
        {
#if ADD_GUARD_BYTES
            byte[] preamble = new byte[4];
            m_Stream.Read(preamble, 0, 4);

            //now compare it against the preamble.
            CompareArrays(preamble, PacketWriter.s_PreambleGuardPattern);
#endif

            int packetSize = (int)m_Reader.ReadUInt64();

            //if the packet size is less than one, that's obviously wrong
            if (packetSize < 1)
            {
                throw new GibraltarSerializationException("The size of the next packet is smaller than 1 byte or negative, which can't be correct.  The packet stream is corrupted.", true);
            }

            // TODO: There's got to be a more efficient way to get this done
            byte[] buffer = new byte[packetSize];
            m_Stream.Read(buffer, 0, packetSize);
            IFieldReader bufferReader = new FieldReader(new MemoryStream(buffer), m_Reader.Strings, m_MajorVersion, m_MinorVersion);

            PacketDefinition definition;
            int typeIndex = (int)bufferReader.ReadUInt32();
            if (typeIndex >= m_cachedTypes.Count)
            {
                definition = PacketDefinition.ReadPacketDefinition(bufferReader);
                if (string.IsNullOrEmpty(definition.TypeName))
                {
                    //we're hosed...  we won't be able to parse this packet.
                    throw new GibraltarSerializationException("The type name of the definition is null, which can't be correct.  The packet stream is corrupted.", true);
                }

                m_cachedTypes.Add(definition);
                m_cachedTypes.Commit();
            }
            else
            {
                definition = m_cachedTypes[typeIndex];
            }

            IPacketFactory factory = m_PacketFactory.GetPacketFactory(definition.TypeName);
            IPacket        packet  = factory.CreatePacket(definition, bufferReader);

            //we used to populate a packet cache here, but a cached packet should be read just once - it shouldn't be in the stream
            //(and I changed PacketWriter to enforce that)

#if ADD_GUARD_BYTES
            byte[] postamble = new byte[4];
            m_Stream.Read(postamble, 0, 4);

            //now compare it against the preamble.
            CompareArrays(postamble, PacketWriter.s_PostambleGuardPattern);
#endif

            return(packet);
        }
Esempio n. 2
0
        /// <summary>
        /// Initialize a PacketReader to read the specified stream using
        /// the provided encoding for strings.
        /// </summary>
        /// <param name="stream">Data to be read</param>
        /// <param name="inputIsReadOnly">Indicates if the input can be assumed fixed in length</param>
        /// <param name="majorVersion">Major version of the serialization protocol</param>
        /// <param name="minorVersion">Minor version of the serialization protocol</param>
        public PacketReader(Stream stream, bool inputIsReadOnly, int majorVersion, int minorVersion)
        {
            m_Stream          = stream;
            m_InputIsReadOnly = inputIsReadOnly;
            m_MajorVersion    = majorVersion;
            m_MinorVersion    = minorVersion;

            // m_ReleaseStream = false; // m_Stream was passed in to us, don't release it upon Dispose()!
            // (false by default) If we were invoked from another constructor, they will overwrite m_ReleaseStream correctly
            m_Reader        = new FieldReader(stream, new UniqueStringList(), majorVersion, minorVersion);
            m_cachedTypes   = new PacketDefinitionList();
            m_PacketFactory = new PacketFactory();

            if ((inputIsReadOnly) && (m_Stream != null))
            {
                m_StreamLength = m_Stream.Length;
            }
        }