/// <inheritdoc /> public override async Task <PackedGuid> ReadAsync(IWireStreamReaderStrategyAsync source) { //See: https://github.com/jackpoz/BotFarm/blob/592dbc9dbb58c06175bffecfced56eba42107c9a/Client/World/Network/InPacket.cs#L24 var mask = await source.ReadByteAsync(); if (mask == 0) { return(PackedGuid.Empty); } ulong res = 0; var i = 0; while (i < 8) { if ((mask & 1 << i) != 0) { res += (ulong)(await source.ReadByteAsync()) << (i * 8); } i++; } return(new PackedGuid(res)); }
/// <inheritdoc /> public override async Task <TBaseType> ReadAsync(IWireStreamReaderStrategyAsync source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } //TODO: Handle 0 flags //Ask the key strategy for what flags are present int flags = await keyStrategy.ReadAsync(source) .ConfigureAwait(false); //defer to key reader (could be int, byte or something else) //TODO: Test perf foreach (ChildKeyPair childKey in serializers) { if ((childKey.Flags & flags) != 0) { return((TBaseType)await childKey.Serializer.ReadAsync(source) .ConfigureAwait(false)); } ; } //If we didn't find a flags for it then try the default if (DefaultSerializer != null) { return((TBaseType)await DefaultSerializer.ReadAsync(source) .ConfigureAwait(false)); } else { throw new InvalidOperationException($"{this.GetType()} attempted to deserialize to a child type with Flags: {flags} but no valid type matches and there is no default type."); } }
/// <inheritdoc /> public override async Task <UpdateFieldValueCollection> ReadAsync(IWireStreamReaderStrategyAsync source) { //Update fields are sent with an inital byte size byte size = await source.ReadByteAsync(); if (size == 0) { return(new UpdateFieldValueCollection(new WireReadyBitArray(0), Array.Empty <byte>())); } //TODO: Reduce allocation somehow. byte[] bytes = await source.ReadBytesAsync(size *sizeof(int)); WireReadyBitArray mask = new WireReadyBitArray(bytes); //We know how many bytes the bitarray is suppose to be //but to know how many values are read we need to compute the bit size int updateValueSize = GetCardinality(mask.InternalArray); AssertSizeIsCorrect(mask, updateValueSize); //Once we have the mask AND the bytes we can construct the update values byte[] updateValueBytes = await source.ReadBytesAsync(updateValueSize *sizeof(int)); return(new UpdateFieldValueCollection(mask, updateValueBytes)); }
public static async Task Test_Buffered_Peeking_Can_Peek_Counted_Bytes_Async() { //arrange DefaultStreamReaderStrategyAsync reader = new DefaultStreamReaderStrategyAsync(new byte[] { 5, 6, 7, 5 }); //act IWireStreamReaderStrategyAsync peekedBufferReader = reader.PeekWithBufferingAsync(); byte[] peekedBytes = await peekedBufferReader.PeekBytesAsync(4); byte[] peekedBytesAgain = await peekedBufferReader.PeekBytesAsync(2); byte[] readBytes = await peekedBufferReader.ReadBytesAsync(4); //assert Assert.AreEqual(4, readBytes.Length); for (int i = 0; i < peekedBytes.Length; i++) { Assert.AreEqual(peekedBytes[i], readBytes[i]); } for (int i = 0; i < peekedBytesAgain.Length; i++) { Assert.AreEqual(peekedBytes[i], peekedBytesAgain[i]); } Assert.Throws <InvalidOperationException>(() => peekedBufferReader.ReadByte()); }
public static async Task Test_Buffered_Peeking_Can_Peek_Bytes_Async() { //arrange DefaultStreamReaderStrategyAsync reader = new DefaultStreamReaderStrategyAsync(new byte[] { 5, 6, 7, 5 }); //act IWireStreamReaderStrategyAsync peekedBufferReader = reader.PeekWithBufferingAsync(); //assert for (int i = 0; i < 5; i++) { Assert.AreEqual(5, await peekedBufferReader.PeekByteAsync()); } Assert.AreEqual(5, await peekedBufferReader.ReadByteAsync()); Assert.AreEqual(6, await peekedBufferReader.ReadByteAsync()); byte[] readBytes = await peekedBufferReader.ReadAllBytesAsync(); Assert.AreEqual(7, readBytes[0]); Assert.AreEqual(5, readBytes[1]); Assert.Throws <AggregateException>(() => { byte b = peekedBufferReader.ReadByteAsync().Result; }); }
/// <inheritdoc /> public override Task SetMemberAsync(TContainingType obj, IWireStreamReaderStrategyAsync source) { //We need to reconvert the size back to bytes to reinsert into the stream //so that the collection can recieve it and then be able to deserialize the elements. byte[] bytes = ((TSizeType)SizeMemberGetter.Getter(obj)).Reinterpret(); //We don't need to modify how we set the size member return(DecoratedMediator.SetMemberAsync(obj, source.PreprendWithBytesAsync(bytes))); }
/// <inheritdoc /> public override async Task <TType> ReadAsync([NotNull] IWireStreamReaderStrategyAsync source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } return(DeserializeFromBuffer(await source.ReadBytesAsync(ByteRepresentationSize).ConfigureAwait(false))); }
/// <inheritdoc /> public async Task <int> ReadAsync(IWireStreamReaderStrategyAsync source) { //Read the key from the stream. TKeyType key = await KeyTypeSerializerStrategy .ReadAsync(typeHandlingFlags.HasFlag(InformationHandlingFlags.DontConsumeRead)?source.WithOnlyPeekingAsync() : source) .ConfigureAwait(false); return(GenericMath.Convert <TKeyType, int>(key)); }
/// <inheritdoc /> public override async Task <bool> ReadAsync([NotNull] IWireStreamReaderStrategyAsync source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } return(ConvertFromByte(await source.ReadByteAsync().ConfigureAwait(false))); }
/// <inheritdoc /> public override async Task SetMemberAsync(object obj, IWireStreamReaderStrategyAsync source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } await SetMemberAsync((TContainingType)obj, source) .ConfigureAwait(false); }
/// <inheritdoc /> public Task <int> SizeAsync(IWireStreamReaderStrategyAsync reader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } //It's always a fixed size. Just reutnr the size. return(Task.FromResult(FixedSize)); }
/// <inheritdoc /> public override Task <string> ReadAsync(IWireStreamReaderStrategyAsync 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.ReadAsync(source)); }
/// <inheritdoc /> public override async Task <TEnumType> ReadAsync(IWireStreamReaderStrategyAsync source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } //TODO: Should be handle exceptions? return(GenericMath.Convert <TBaseType, TEnumType>(await serializerStrategy.ReadAsync(source) .ConfigureAwait(false))); }
/// <inheritdoc /> public async Task SetMemberAsync(object obj, IWireStreamReaderStrategyAsync source) { //Check if we should read if (!(bool)isReadWriteEnabledGetter.Getter((TContainingType)obj)) { return; } await DecoratedMediator.SetMemberAsync(obj, source) .ConfigureAwait(false); }
/*private byte[] ConvertToByteArray(TType[] array) * { * Span<TType> span = new Span<TType>(array); * * return span.AsBytes(); * }*/ /// <inheritdoc /> public override async Task <TType[]> ReadAsync(IWireStreamReaderStrategyAsync source) { int size = await SizeStrategyService.SizeAsync(source) .ConfigureAwait(false); int byteCount = SizeOfType * size; byte[] bytes = await source.ReadBytesAsync(byteCount) .ConfigureAwait(false); return(bytes.ReinterpretToArray <TType>()); }
/// <inheritdoc /> public override async Task <string> ReadAsync(IWireStreamReaderStrategyAsync source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } string value = await decoratedSerializer.ReadAsync(source) .ConfigureAwait(false); return(new string(value.Reverse().ToArray())); }
//Async implementation /// <inheritdoc /> public virtual Task <TType> ReadIntoObjectAsync(TType obj, IWireStreamReaderStrategyAsync source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } //We can't really write or read into an object on a simple type. //Default implementation is to just read the object from the source. return(ReadAsync(source)); }
/// <inheritdoc /> public override async Task <string> ReadAsync(IWireStreamReaderStrategyAsync source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } //See sync method for doc //TODO: Find an average size for WoW strings 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 = await source.ReadByteAsync() .ConfigureAwait(false); 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))); }
/// <inheritdoc /> public async Task <int> SizeAsync(IWireStreamReaderStrategyAsync reader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } TSizeType size = await sizeSerializer.ReadAsync(reader) .ConfigureAwait(false); //Using JonSkeets MiscUtils we can convert objects efficently return(GenericMath <TSizeType, int> .Convert(size) + AddedSize); }
/// <inheritdoc /> public override async Task SetMemberAsync(TContainingType obj, IWireStreamReaderStrategyAsync source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } #if NET35 throw new NotImplementedException(); #else MemberSetter.Setter(obj, (TMemberType)await TypeSerializer.ReadAsync(source).ConfigureAwait(false)); #endif }
/// <inheritdoc /> public async Task <int> SizeAsync(IWireStreamReaderStrategyAsync reader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } //Read the byte size from the stream. TSizeType result = await SizeTypeSerializerStrategy.ReadAsync(reader) .ConfigureAwait(false); //Readd the addedsize so that we know how many items are really there. return(GenericMath.Convert <TSizeType, int>(result) + AddedSize); }
/// <inheritdoc /> public override async Task <TEnumType> ReadAsync(IWireStreamReaderStrategyAsync source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } //Read the string serialized version of the enum value string readString = await decoratedSerializer.ReadAsync(source) .ConfigureAwait(false); //TODO: What should we do if it's empty or null? return((TEnumType)Enum.Parse(typeof(TEnumType), readString)); }
public static async Task Test_That_Prepended_Reader_Contains_Bytes_Async(byte[] bytes) { //arrange DefaultStreamReaderStrategyAsync reader = new DefaultStreamReaderStrategyAsync(new byte[0]); //act IWireStreamReaderStrategyAsync bufferedReader = reader.PreprendWithBytesAsync(bytes); //assert for (int i = 0; i < bytes.Length; i++) { Assert.AreEqual(await bufferedReader.ReadByteAsync(), bytes[i]); } }
protected async Task SetMembersFromReaderDataAsync(TType obj, [NotNull] IWireStreamReaderStrategyAsync source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } // Tested, does not yield better perf // ReSharper disable once ForCanBeConvertedToForeach for (int i = 0; i < orderedMemberInfos.Length; i++) { await orderedMemberInfos[i].SetMemberAsync(obj, source) .ConfigureAwait(false); } }
/// <inheritdoc /> public override async Task <TComplexType> ReadAsync(IWireStreamReaderStrategyAsync source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } TComplexType obj = await ReadAsync(prototypeGeneratorService.Create(), source) .ConfigureAwait(false); //invoke after deserialization if it's available (obj as ISerializationEventListener)?.OnAfterDeserialization(); return(obj); }
/// <inheritdoc /> public override async Task <string> ReadAsync(IWireStreamReaderStrategyAsync source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } //The size must come from the strategy provided int size = CharacterSize * await sizeProvider.SizeAsync(source) .ConfigureAwait(false); byte[] bytes = await source.ReadBytesAsync(size) .ConfigureAwait(false); return(EncodingStrategy.GetString(bytes).TrimEnd(NullTermincatorCharacterArray)); }
/// <inheritdoc /> public override async Task <byte[]> ReadAsync([NotNull] IWireStreamReaderStrategyAsync source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } //Must read size first before reverseing int size = await SizeStrategy.SizeAsync(source) .ConfigureAwait(false); return(await source.WithOneTimeReadingAsync() .WithByteReversalAsync() .ReadBytesAsync(size) .ConfigureAwait(false)); }
/// <inheritdoc /> public override async Task <TObjectType[]> ReadAsync(IWireStreamReaderStrategyAsync source) { int size = await sizeStrategyService.SizeAsync(source).ConfigureAwait(false); TObjectType[] objectArray = new TObjectType[size]; //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] = await decoratedSerializer.ReadAsync(source) .ConfigureAwait(false); } return(objectArray); }
/// <inheritdoc /> public override async Task <TType> ReadIntoObjectAsync(TType obj, IWireStreamReaderStrategyAsync 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 await SetMembersFromReaderDataAsync(obj, source) .ConfigureAwait(false); return(obj); }
/// <inheritdoc /> public override async Task <BitArray> ReadAsync([NotNull] IWireStreamReaderStrategyAsync 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 = await source.ReadByteAsync() .ConfigureAwait(false); //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(await source.ReadBytesAsync(size * sizeof(int)).ConfigureAwait(false))); }