//We now write and read in the abstract because we allow implementers
        //to only provide the serialization aspect.
        /// <inheritdoc />
        public override TType Read([NotNull] IWireStreamReaderStrategy source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            return(DeserializeFromBuffer(source.ReadBytes(ByteRepresentationSize)));
        }
        /// <inheritdoc />
        public override TEnumType Read(IWireStreamReaderStrategy source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //TODO: Should be handle exceptions?
            return(GenericMath.Convert <TBaseType, TEnumType>(serializerStrategy.Read(source)));
        }
Пример #3
0
        /// <inheritdoc />
        public void SetMember(TContainingType obj, IWireStreamReaderStrategy source)
        {
            //Check if we should read
            if (!(bool)isReadWriteEnabledGetter.Getter(obj))
            {
                return;
            }

            DecoratedMediator.SetMember(obj, source);
        }
Пример #4
0
        /// <inheritdoc />
        public int Size(IWireStreamReaderStrategy reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            //It's always a fixed size. Just reutnr the size.
            return(FixedSize);
        }
        /// <summary>
        /// Perform the steps necessary to deserialize a string.
        /// </summary>
        /// <param name="source">The reader providing the input data.</param>
        /// <returns>A string value from the reader.</returns>
        public override string Read(IWireStreamReaderStrategy source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //Review the source for Trinitycore's string reading for their ByteBuffer (payload/packet) Type.
            //(ctr+f >> for std::string): http://www.trinitycore.net/d1/d17/ByteBuffer_8h_source.html
            //They use 0 byte to terminate the string in the stream

            //TODO: We can likely do some fancy pointer stuff to make this much cheaper.
            //Read a byte from the stream; Stop when we find a 0
            List <byte> stringBytes = new List <byte>();

            //This is used to track larger than 1 char null terminators
            int zeroByteCountFound = 0;

            //How many characters have been counted
            int currentCharCount = 0;

            do
            {
                byte currentByte = source.ReadByte();
                currentCharCount++;

                stringBytes.Add(currentByte);

                //If we find a 0 byte we need to track it
                //char could be 1 byte or even 4 so we need to reset
                //if we encounter an actual character before we find all
                //null terminator bytes
                if (currentByte == 0)
                {
                    zeroByteCountFound++;
                }
                else
                {
                    zeroByteCountFound = 0;
                }

                //if we found 4 0 bytes in arow but we didn't find a full char set of CharacterSize
                //then we should reset. This can happen if you have {5 0 0 0} {0 0 0 0} it will stop after the first 4
                //But with this is will read the whole {0 0 0 0}.
                if (currentCharCount % CharacterSize == 0 && zeroByteCountFound < CharacterSize)
                {
                    zeroByteCountFound = 0;
                }
            } while(zeroByteCountFound < CharacterSize);

            //TODO: Invesitgate expected WoW/TC behavior for strings of length 0. Currently violates contract for return type.
            //I have decided to support empty strings instead of null
            return(stringBytes.Count - CharacterSize <= 0 ? "" : EncodingStrategy.GetString(stringBytes.ToArray(), 0, Math.Max(0, stringBytes.Count - CharacterSize)));
        }
Пример #6
0
        /// <inheritdoc />
        public override string Read(IWireStreamReaderStrategy source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            string value = decoratedSerializer.Read(source);

            return(new string(value.Reverse().ToArray()));
        }
        /// <inheritdoc />
        public override DateTime Read(IWireStreamReaderStrategy source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //Based on ByteBuffer.h from the Trinitycore Project, Jackpoz's 3.3.5 packet bot and WoWPacketParser
            //reads the packed int value from the stream
            return(ConvertIntegerToDateTimeRepresentation(decoratedSerializer.Read(source)));
        }
Пример #8
0
        /// <summary>
        /// Determines the size of the collection from the stream.
        /// </summary>
        public int Size(IWireStreamReaderStrategy reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            //Read the byte size from the stream.
            //Readd the addedsize so that we know how many items are really there.
            return(GenericMath.Convert <TSizeType, int>(SizeTypeSerializerStrategy.Read(reader)) + AddedSize);
        }
        /// <inheritdoc />
        public override string Read(IWireStreamReaderStrategy source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //This is akward. If to terminator was sent we cannot really fall back to the default string reader.
            //Someone must decorate this and override the read. Otherwise this will almost assuredly fail.
            return(decoratedSerializer.Read(source));
        }
Пример #10
0
        //Trinitycore Bytebuffer implementation

        /*ByteBuffer &operator>>(bool &value)
         * {
         *      value = read<char>() > 0 ? true : false;
         *      return *this;
         * }*/

        /// <inheritdoc />
        public override bool Read(IWireStreamReaderStrategy source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //Trinitycore could potentially send non-one bytes for a bool
            //See above
            return(source.ReadByte() > 0);
        }
        /// <inheritdoc />
        public int Size(IWireStreamReaderStrategy reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            TSizeType size = sizeSerializer.Read(reader);

            //Using JonSkeets MiscUtils we can convert objects efficently
            return(GenericMath <TSizeType, int> .Convert(size) + AddedSize);
        }
Пример #12
0
        /// <inheritdoc />
        public override TObjectType[] Read(IWireStreamReaderStrategy source)
        {
            TObjectType[] objectArray = new TObjectType[sizeStrategyService.Size(source)];

            //TODO: Error handling
            //read as many objects as in the message (this is safe for clients. Not so safe if the client sent a message of this type)
            for (int i = 0; i < objectArray.Length; i++)
            {
                objectArray[i] = decoratedSerializer.Read(source);
            }

            return(objectArray);
        }
Пример #13
0
        /// <inheritdoc />
        public override TEnumType Read(IWireStreamReaderStrategy source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //Read the string serialized version of the enum value
            string readString = decoratedSerializer.Read(source);

            //TODO: What should we do if it's empty or null?
            return((TEnumType)Enum.Parse(typeof(TEnumType), readString));
        }
        /// <inheritdoc />
        public int Read(IWireStreamReaderStrategy source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //Read the key from the stream.
            TKeyType key = KeyTypeSerializerStrategy
                           .Read(typeHandlingFlags.HasFlag(InformationHandlingFlags.DontConsumeRead) ? source.WithOnlyPeeking() : source);

            return(GenericMath.Convert <TKeyType, int>(key));
        }
Пример #15
0
        public static void Test_That_Prepended_Reader_Contains_Bytes(byte[] bytes)
        {
            //arrange
            DefaultStreamReaderStrategy reader = new DefaultStreamReaderStrategy(new byte[0]);

            //act
            IWireStreamReaderStrategy bufferedReader = reader.PreprendWithBytes(bytes);

            //assert
            for (int i = 0; i < bytes.Length; i++)
            {
                Assert.AreEqual(bufferedReader.ReadByte(), bytes[i]);
            }
        }
        //TODO: Error handling
        /// <inheritdoc />
        public override TComplexType Read(IWireStreamReaderStrategy source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //We need to do this oddity for structs
            TComplexType obj = Read(prototypeGeneratorService.Create(), source);

            //invoke after deserialization if it's available
            (obj as ISerializationEventListener)?.OnAfterDeserialization();

            return(obj);
        }
        /// <inheritdoc />
        public override LinearPathMoveInfo Read(IWireStreamReaderStrategy source)
        {
            int lastIndex = source.ReadBytes(4).Reinterpret <int>();

            byte[] lastPointBytes = source.ReadBytes(sizeof(float) * 3);

            Vector3 <float> lastPoint = new Vector3 <float>(lastPointBytes.Reinterpret <float>(),
                                                            lastPointBytes.Reinterpret <float>(sizeof(float)), lastPointBytes.Reinterpret <float>(sizeof(float) * 2));

            //TODO: Deserialize to vectors
            //Then there are a bunch of packed points here
            byte[] packedDataBytes = lastIndex > 1 ? source.ReadBytes((lastIndex - 1) * sizeof(int)) : Array.Empty <byte>();

            return(new LinearPathMoveInfo(lastIndex, lastPoint, packedDataBytes));
        }
        /// <inheritdoc />
        public override byte[] Read([NotNull] IWireStreamReaderStrategy source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //Must read size first before reverseing
            int size = SizeStrategy.Size(source);

            //Then reverse the stream with 1 time reverse/read semantics
            return(source.WithOneTimeReading()
                   .WithByteReversal()
                   .ReadBytes(size));
        }
        public override void SetMember(TContainingType obj, [NotNull] IWireStreamReaderStrategy source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            try
            {
                MemberSetter.Setter(obj, (TMemberType)TypeSerializer.Read(source));
            }
            catch (Exception e)
            {
                throw new InvalidOperationException($"Failed to set member {MemberInformation.Name} on Type: {MemberInformation.DeclaringType} for Type: {obj.GetType().Name} Exception: {e.Message}.", e);
            }
        }
        /// <inheritdoc />
        public override TType ReadIntoObject(TType obj, IWireStreamReaderStrategy source)
        {
            if (obj == null)
            {
                throw new ArgumentNullException(nameof(obj));
            }
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //Basically if someone calls this method they want us to set the members from the reader
            SetMembersFromReaderData(obj, source);

            return(obj);
        }
Пример #21
0
        /// <inheritdoc />
        public override TObjectType[] Read(IWireStreamReaderStrategy source)
        {
            byte[] bytes = source.ReadAllBytes();
            FixedBufferWireReaderStrategy fixedStrategy = new FixedBufferWireReaderStrategy(bytes, 0, bytes.Length);

            QuickList <TObjectType> objects = new QuickList <TObjectType>(4);

            //Read until the fixed buffer is empty. This iwll give us all objects without read exceptions when end is reached.
            while (!fixedStrategy.isFinished)
            {
                objects.Add(ElementSerializer.Read(fixedStrategy));
            }

            //We can avoid some copies like this
            return(objects.Count == objects._items.Length ? objects._items : objects.ToArray());
        }
        /// <inheritdoc />
        public override BitArray Read(IWireStreamReaderStrategy source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //TODO: We should handle multiple types of sizes
            //WoW sends a byte for the block count and an int array. We use a surrogate to deserialize it
            byte size = source.ReadByte();

            //Load the data for the bitmask
            //WoW sends the size as an int array but we can more efficiently read a byte array so we pretend
            //It is the same
            return(new BitArray(source.ReadBytes(size * sizeof(int))));
        }
Пример #23
0
        public static void Test_Buffered_Peeking_Can_Peek_Byte(byte b)
        {
            //arrange
            DefaultStreamReaderStrategy reader = new DefaultStreamReaderStrategy(new byte[] { b });

            //act
            IWireStreamReaderStrategy peekedBufferReader = reader.PeekWithBuffering();

            //assert
            for (int i = 0; i < 5; i++)
            {
                Assert.AreEqual(b, peekedBufferReader.PeekByte());
            }

            Assert.AreEqual(b, peekedBufferReader.ReadByte());

            Assert.Throws <InvalidOperationException>(() => peekedBufferReader.ReadByte());
        }
        protected void SetMembersFromReaderData(TType obj, [NotNull] IWireStreamReaderStrategy source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //replaced for perf

            /*foreach (IMemberSerializationMediator<TType> serializerInfo in orderedMemberInfos)
             * {
             *      serializerInfo.SetMember(obj, source);
             * }*/
            for (int i = 0; i < orderedMemberInfos.Length; i++)
            {
                orderedMemberInfos[i].SetMember(obj, source);
            }
        }
        private TComplexType Read(TComplexType obj, IWireStreamReaderStrategy source)
        {
            //read all base type members first
            //WARNING: This caused HUGE perf probleems. Several orders of magnitude slower than Protobuf
            //We MUST not check if the serializer exists and we must precache the gets.
            if (reversedInheritanceHierarchy.Count() != 0)
            {
                foreach (Type t in reversedInheritanceHierarchy)
                {
                    if (serializerProviderService.HasSerializerFor(t))
                    {
                        serializerProviderService.Get(t).ReadIntoObject(obj, source);
                    }
                }
            }

            SetMembersFromReaderData(obj, source);

            return(obj);
        }
        /// <inheritdoc />
        public override string Read(IWireStreamReaderStrategy source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //The size must come from the strategy provided
            //TODO: Should we expect char size or byte size?
            int size = CharacterSize * sizeProvider.Size(source);

            byte[] bytes = source.ReadBytes(size);

            //TODO: Pointer hack for preformance
            //This is the only way to remove padding that I know of
            //There may be a more efficient way of removing the padding
            //There is actually an unsafe pointer hack to improve preformance here too.
            //profile and add later.
            return(EncodingStrategy.GetString(bytes).TrimEnd(NullTermincatorCharacterArray));
        }
Пример #27
0
        /// <inheritdoc />
        public override TBaseType Read(IWireStreamReaderStrategy source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //Incoming should be a byte that indicates the child type to use
            //Read it to lookup in the map to determine which type we should create
            int childIndexRequested = keyStrategy.Read(source);             //defer to key reader (could be int, byte or something else)

            ITypeSerializerStrategy strategy = GetReadStrategy(childIndexRequested);

            //Once we know which child this particular object should be
            //we need to dispatch the read request to that child's serializer handler
            //and if it happens to map to another child, which should be rare, it'll dispatch until it reaches a ComplexType serializer which is where
            //the end of the inheritance graph tree should end up. The complextype serializer, which is the true type serializer, should handle deserialization
            //include going up the base heriachiry.
            return((TBaseType)strategy.Read(source));
        }
 public abstract void SetMember(TContainingType obj, IWireStreamReaderStrategy source);
 public TType Read([NotNull] IWireStreamReaderStrategy source)
 {
     return(DecoratedSerializer.Read(source));
 }
 object ITypeSerializerStrategy.Read(IWireStreamReaderStrategy source)
 {
     return(DecoratedSerializer.Read(source));
 }