public void CreateTest() { Type t = typeof(int); SuperStream ms = new SuperStream(Endianess.Little); var expected = new StreamDataTestData { A = -15, B = "Test one!", C = "Test two!", D = new List <int>(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }), E = ByteEnum.Hello, F = LongEnum.Max }; ms.WriteInt32(expected.A); ms.WriteString(expected.B); ms.WriteCString(expected.C); ms.WriteUInt32((uint)expected.D.Count); foreach (var i in expected.D) { ms.WriteInt32(i); } ms.WriteByte((byte)ByteEnum.Hello); ms.WriteInt64((Int64)LongEnum.Max); ms.Position = 0; StreamDataTestData actual; actual = StreamData.Create <StreamDataTestData>(ms); Assert.AreEqual(expected, actual); }
internal StreamDataParserTask(SuperStream stream, Type readType, Type dataType, Attribute[] attributes) { this.Stream = stream; this.StreamType = readType; this.Attributes = attributes; this.DataType = dataType; }
public void SerializeTest() { SuperStream expectedStream = new SuperStream(Endianess.Little); var expectedObject = new StreamDataTestData { A = -15, B = "Test one!", C = "Test two!", D = new List <int>(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }), E = ByteEnum.Hello, F = LongEnum.Max }; expectedStream.WriteInt32(expectedObject.A); expectedStream.WriteString(expectedObject.B); expectedStream.WriteCString(expectedObject.C); expectedStream.WriteUInt32((uint)expectedObject.D.Count); foreach (var i in expectedObject.D) { expectedStream.WriteInt32(i); } expectedStream.WriteByte((byte)ByteEnum.Hello); expectedStream.WriteInt64((Int64)LongEnum.Max); var expected = ((MemoryStream)expectedStream.BaseStream).ToArray(); var actualStream = new SuperStream(Endianess.Little); StreamData.Serialize(expectedObject, actualStream); var actual = ((MemoryStream)actualStream.BaseStream).ToArray(); Assert.IsTrue(actual.SequenceEqual(expected)); }
internal ulong WriteContentLength(SuperStream stream, ulong length) { var countType = this.Attributes.FirstOrDefault(a => a is StreamDataCollectionLengthAttribute) as StreamDataCollectionLengthAttribute; if (countType == null) { return(this.Entries); } switch (countType.Type) { case LengthType.Byte: stream.WriteByte((byte)length); break; case LengthType.UInt16: stream.WriteUInt16((ushort)length); break; default: case LengthType.UInt32: stream.WriteUInt32((uint)length); break; } return(length); }
public void ReadUInt64Test() { UInt64 expected = UInt64.MaxValue - 64; SuperStream target = new SuperStream(Endianess.Little); target.WriteSingle(expected); target.Position = 0; var actual = target.ReadSingle(); Assert.AreEqual(expected, actual); }
public void StringTest() { string expected = "Hello there!\0Yo!"; SuperStream target = new SuperStream(Endianess.Little); target.WriteString(expected); target.Position = 0; var actual = target.ReadString(); Assert.AreEqual(expected, actual); }
public void SingleTest() { Single expected = Single.MaxValue - 32.32f; SuperStream target = new SuperStream(Endianess.Little); target.WriteSingle(expected); target.Position = 0; var actual = target.ReadSingle(); Assert.AreEqual(expected, actual); }
public void LolTeger32TestA() { Int32 expected = 30; SuperStream target = new SuperStream(Endianess.Little); target.WriteLolTeger32(expected); target.Position = 0; var actual = target.ReadLolTeger32(); Assert.AreEqual(expected, actual); }
public void Int32Test() { Int32 expected = Int32.MaxValue - 32; SuperStream target = new SuperStream(Endianess.Little); target.WriteInt32(expected); target.Position = 0; var actual = target.ReadInt32(); Assert.AreEqual(expected, actual); }
public void CStringTestB() { var expected = "Hello there! This is a\0 test."; SuperStream target = new SuperStream(Endianess.Little); target.WriteCString(expected); target.Position = 0; var actual = target.ReadCString(); Assert.Equals(expected, actual); }
public void BytesTest() { var expected = new byte[] { 0, 15, 35, 255, 46, 80, 0 }; SuperStream target = new SuperStream(Endianess.Little); target.WriteBytes(expected); target.Position = 0; var actual = target.ReadBytes((uint)expected.Length); Assert.IsTrue(expected.SequenceEqual(actual)); }
private bool IsStale(FileInfo file) { // Create a read stream using (var stream = new SuperStream(file.OpenRead(), Endianess.Little) { DisposeBaseStream = true }) { // Find out of this entry should be removed // by reading a DateTime object (first parameter) // from the file. var dt = Misc.Unixtime(stream.ReadInt64()); return(dt < DateTime.Now); } }
/// <summary> /// /// </summary> /// <param name="ms"></param> /// <returns></returns> internal ulong ReadContentLength(SuperStream stream) { switch (this.Type) { case LengthType.Byte: return((byte)stream.ReadByte()); case LengthType.UInt16: return(stream.ReadUInt16()); default: case LengthType.UInt32: return(stream.ReadUInt32()); } }
public CacheEntry Retrieve(params object[] identifiers) { lock (this.CacheDirectory) { var file = this.GetCacheEntryFile(identifiers); if (!file.Exists) { return(CacheEntry.Empty); } using (var stream = new SuperStream(file.OpenRead(), Endianess.Little) { DisposeBaseStream = true }) { return(StreamData.Create <CacheEntry>(stream)); } } }
internal void WriteContentLength(SuperStream stream, ulong length) { switch (this.Type) { case LengthType.Byte: stream.WriteByte((byte)length); break; case LengthType.UInt16: stream.WriteUInt16((ushort)length); break; default: case LengthType.UInt32: stream.WriteUInt32((uint)length); break; } }
public override int GetHashCode() { // Handle special cases if (this.Bytes == null) { return(0); } if (this.Bytes.Length == 0) { return(0); } if (this.Bytes.Length == 1) { return(this.Bytes[0]); } if (this.Bytes.Length == 2) { return(BitConverter.ToInt16(this.Bytes, 0)); } if (this.Bytes.Length == 3) { return(BitConverter.ToInt16(this.Bytes, 0) + this.Bytes[2]); } if (this.Bytes.Length == 4) { return(BitConverter.ToInt32(this.Bytes, 0)); } // Handle normal cases. int[] integers = new int[this.Bytes.Length / 4]; var ms = new SuperStream(new MemoryStream(this.Bytes), BitConverter.IsLittleEndian ? Endianess.Little : Endianess.Big); for (int i = 0; i < integers.Length; i++) { integers[i] = ms.ReadInt32(); } int hash = integers[0]; for (int i = 1; i < integers.Length; i++) { hash ^= integers[i]; } return(hash); }
public void LolTeger32TestB() { for (int expectedAdd = 0; expectedAdd < 1009; expectedAdd++) { Int32 expected = 30; SuperStream target = new SuperStream(Endianess.Little); target.WriteLolTeger32( expected, additionalData: expectedAdd); target.Position = 0; int actualAdd; var actual = target.ReadLolTeger32(out actualAdd); Assert.AreEqual(expected, actual, "LolTeger value; i=" + expectedAdd.ToString()); Assert.AreEqual(expectedAdd, actualAdd, "LolTeger additional value; i=" + expectedAdd.ToString()); } }
public void Store(CacheEntry cacheEntry, params object[] identifiers) { lock (this.CacheDirectory) { var file = this.GetCacheEntryFile(identifiers); if (!file.Directory.Exists) { file.Directory.Create(); } using (var stream = new SuperStream( new FileStream(file.FullName, FileMode.Create, FileAccess.Write, FileShare.None), Endianess.Little) { DisposeBaseStream = true }) { StreamData.Serialize(cacheEntry, stream); } } }
/// <summary> /// /// </summary> /// <param name="ms"></param> /// <returns></returns> internal ulong ReadContentLength(SuperStream stream) { var countType = this.Attributes.FirstOrDefault(a => a is StreamDataCollectionLengthAttribute) as StreamDataCollectionLengthAttribute; if (countType == null) { return(this.Entries); } switch (countType.Type) { case LengthType.Byte: return((byte)stream.ReadByte()); case LengthType.UInt16: return(stream.ReadUInt16()); default: case LengthType.UInt32: return(stream.ReadUInt32()); } }
private bool WriteValue(Type dataType, SuperStream stream, object value) { if (dataType == typeof(Byte)) { stream.WriteByte((byte)value); return(true); } if (dataType == typeof(Int64)) { stream.WriteInt64((Int64)value); return(true); } if (dataType == typeof(UInt64)) { stream.WriteUInt64((UInt64)value); return(true); } if (dataType == typeof(Int32)) { stream.WriteInt32((Int32)value); return(true); } if (dataType == typeof(UInt32)) { stream.WriteUInt32((UInt32)value); return(true); } if (dataType == typeof(Int16)) { stream.WriteInt16((Int16)value); return(true); } if (dataType == typeof(UInt16)) { stream.WriteUInt16((UInt16)value); return(true); } if (dataType == typeof(Single)) { stream.WriteSingle((Single)value); return(true); } if (dataType == typeof(Double)) { stream.WriteDouble((Double)value); return(true); } if (dataType == typeof(bool)) { // If bool is true, write 1. Otherwise, write 0. int val = ((bool)value) ? 1 : 0; stream.WriteInt32(val); } if (dataType.IsEnum) { dynamic storeValue = Convert.ChangeType(value, Enum.GetUnderlyingType(dataType)); return(this.WriteValue(storeValue.GetType(), stream, storeValue)); } // Test if type has StreamDataAttribute on properties. // This allows nesting of StreamData-aware task.DataTypes var props = StreamDataInfo.GetProperties(dataType); if (props.Length == 0) { return(false); } StreamData.Serialize(value, stream); // Need to add error condition here. return(true); }
private bool GetValue(Type dataType, SuperStream stream, out object value) { if (dataType == typeof(Byte)) { value = (byte)stream.ReadByte(); return(true); } if (dataType == typeof(Int64)) { value = stream.ReadInt64(); return(true); } if (dataType == typeof(UInt64)) { value = stream.ReadUInt64(); return(true); } if (dataType == typeof(Int32)) { value = stream.ReadInt32(); return(true); } if (dataType == typeof(UInt32)) { value = stream.ReadUInt32(); return(true); } if (dataType == typeof(Int16)) { value = stream.ReadInt16(); return(true); } if (dataType == typeof(UInt16)) { value = stream.ReadUInt16(); return(true); } if (dataType == typeof(Single)) { value = stream.ReadSingle(); return(true); } if (dataType == typeof(Double)) { value = stream.ReadDouble(); return(true); } if (dataType == typeof(bool)) { var val = stream.ReadUInt32(); if (val == 0) { value = false; return(true); } else if (val == 1) { value = true; return(true); } else { throw new Exception("Parsing type bool: Expected value to be either 0 or 1, but it was " + val.ToString()); } } if (dataType.IsEnum) { object readValue; // Read the enums underlying type if (!this.GetValue(Enum.GetUnderlyingType(dataType), stream, out readValue)) { value = null; return(false); } // Parse enum using the read value. value = Enum.ToObject(dataType, readValue); return(true); } // Test if type has StreamDataAttribute on properties. // This allows nesting of StreamData-aware task.DataTypes var props = StreamDataInfo.GetProperties(dataType); if (props.Length == 0) { value = null; return(false); } value = StreamData.Create(dataType, stream); if (value == null) { return(false); } return(true); }
/// <summary> /// Populates an existing object with data from stream. /// </summary> /// <param name="obj"></param> /// <param name="ms"></param> /// <returns></returns> public static object Populate(object obj, SuperStream ms) { var properties = StreamDataInfo.GetProperties(obj.GetType()); bool gracefulStopAtEOF = obj.GetType().GetAttribute <StreamDataGracefulEofAttribute>() != null; dynamic value; // Parse spell arguments foreach (var pi in properties) { if (gracefulStopAtEOF && ms.EOF) { break; } StreamDataParserTask task = new StreamDataParserTask(ms, pi.ReadType, pi.DataType, pi.Attributes); if (pi.IsCollection) { var entries = pi.ReadContentLength(ms); if (pi.IsArray) { var arr = new ArrayList((int)Math.Min(int.MaxValue, entries)); for (ulong i = 0; i < entries; i++) { if (!GetParserData(task, out value)) { throw new Exception(); } arr.Add(value); } var arr2 = arr.ToArray(pi.ReadType); pi.PropertyInfo.SafeSetValue(obj, arr2, null); continue; } else if (pi.IsList) { dynamic list = Activator.CreateInstance( typeof(List <>).MakeGenericType(pi.DataType), (int)Math.Min(int.MaxValue, entries)); for (ulong i = 0; i < entries; i++) { if (!GetParserData(task, out value)) { throw new Exception(); } list.Add(value); } pi.PropertyInfo.SafeSetValue(obj, (object)list, null); } } else { if (!GetParserData(task, out value)) { throw new Exception(); } pi.PropertyInfo.SafeSetValue(obj, (object)value, null); continue; } } if (typeof(IStreamDataFinalizer).IsAssignableFrom(obj.GetType())) { IStreamDataFinalizer fin = (IStreamDataFinalizer)obj; fin.OnDeserialize(); } return(obj); }
/// <summary> /// Write a given object to stream /// </summary> /// <param name="obj">Object to write</param> /// <param name="ms">Stream to write to</param> public static void Serialize(object obj, SuperStream ms) { if (typeof(IStreamDataFinalizer).IsAssignableFrom(obj.GetType())) { IStreamDataFinalizer fin = (IStreamDataFinalizer)obj; fin.OnSerialize(); } var properties = StreamDataInfo.GetProperties(obj.GetType()); // Parse spell arguments foreach (var pi in properties) { dynamic value = pi.PropertyInfo.SafeGetValue(obj, null); StreamDataParserTask task = new StreamDataParserTask(ms, pi.ReadType, pi.DataType, pi.Attributes); if (pi.IsCollection) { // Find actual length of collection. ulong length; if (pi.IsArray) { length = (ulong)value.Length; } else if (pi.IsList) { length = (ulong)value.Count; } else { throw new Exception("Property is collection, but not array nor list."); } // Write length, and return written length. (Entries= will override length of collection if set) length = pi.WriteContentLength(ms, length); dynamic enumerable = pi.PropertyInfo.SafeGetValue(obj, null); ulong count = 0; foreach (var entry in enumerable) { // Make sure we do not write more entries than we've declared count++; if (count > length) { throw new Exception("Collection contains more items than "); } // Write enry. if (!WriteParserData(task, entry)) { throw new Exception(); } } continue; } else { if (!WriteParserData(task, value)) { throw new Exception(); } } } }
/// <summary> /// Creates a new object and populates it with data from the provided stream. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="ms"></param> /// <returns></returns> public static T Create <T>(SuperStream ms) { var obj = Activator.CreateInstance <T>(); return((T)Populate(obj, ms)); }
/// <summary> /// Creates a new object and populates it with data from the provided stream. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="ms"></param> /// <returns></returns> public static dynamic Create(Type t, SuperStream ms) { var obj = Activator.CreateInstance(t); return(Populate(obj, ms)); }