//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))); }
/// <inheritdoc /> public void SetMember(TContainingType obj, IWireStreamReaderStrategy source) { //Check if we should read if (!(bool)isReadWriteEnabledGetter.Getter(obj)) { return; } DecoratedMediator.SetMember(obj, source); }
/// <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))); }
/// <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))); }
/// <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)); }
//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); }
/// <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); }
/// <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)); }
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); }
/// <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)))); }
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)); }
/// <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)); }