/// <summary> /// Reads a <see cref="System.Decimal"/> value. /// </summary> /// <param name="stream">Stream to read the value from.</param> /// <returns>The read value.</returns> internal decimal ReadPrimitive_Decimal(Stream stream) { const int elementSize = sizeof(decimal); int bytesRead = stream.Read(TempBuffer_Buffer, 0, elementSize); if (bytesRead < elementSize) { throw new SerializationException("Unexpected end of stream."); } #if NETSTANDARD2_0 || NETSTANDARD2_1 || NET461 Buffer.BlockCopy(TempBuffer_Buffer, 0, TempBuffer_Int32, 0, elementSize); if (mDeserializingLittleEndian != BitConverter.IsLittleEndian) { EndiannessHelper.SwapBytes(ref TempBuffer_Int32[0]); EndiannessHelper.SwapBytes(ref TempBuffer_Int32[1]); EndiannessHelper.SwapBytes(ref TempBuffer_Int32[2]); EndiannessHelper.SwapBytes(ref TempBuffer_Int32[3]); } return(new decimal(TempBuffer_Int32)); #elif NET5_0_OR_GREATER var intBuffer = MemoryMarshal.Cast <byte, int>(TempBuffer_Buffer.AsSpan(0, elementSize)); if (mDeserializingLittleEndian != BitConverter.IsLittleEndian) { EndiannessHelper.SwapBytes(ref intBuffer[0]); EndiannessHelper.SwapBytes(ref intBuffer[1]); EndiannessHelper.SwapBytes(ref intBuffer[2]); EndiannessHelper.SwapBytes(ref intBuffer[3]); } return(new decimal(intBuffer)); #else #error Unhandled .NET framework #endif }
public override void Read(EndianBinaryReader reader, ISection section = null) { reader.PushBaseOffset(); int signature = reader.ReadInt32(); if (signature != 0x03505854) { reader.Endianness = Endianness = Endianness.Big; signature = EndiannessHelper.Swap(signature); } if (signature != 0x03505854) { throw new InvalidDataException("Invalid signature (expected TXP with type 3)"); } int textureCount = reader.ReadInt32(); int textureCountWithRubbish = reader.ReadInt32(); Textures.Capacity = textureCount; for (int i = 0; i < textureCount; i++) { reader.ReadOffset(() => { Textures.Add(new Texture(reader)); }); } reader.PopBaseOffset(); }
public override void Write(long value) { if (EndiannessHelper.Swap(value) != value) { SetBitArrayValue(Position - mBeginPosition, ( int )ValueType.Int64); } base.Write(value); }
public override void Write(long value) { if (EndiannessHelper.Swap(value) != value) { mPositionMap[Position] = sizeof(long); } base.Write(value); }
private void SwapHeader(ref BinaryHeader header) { EndiannessHelper.Swap(ref header.UserId); EndiannessHelper.Swap(ref header.FileSize); EndiannessHelper.Swap(ref header.Field0C); EndiannessHelper.Swap(ref header.RelocationTable.Offset); EndiannessHelper.Swap(ref header.RelocationTableSize); EndiannessHelper.Swap(ref header.DialogCount); EndiannessHelper.Swap(ref header.Field1E); }
public static T ToStruct <T>(this byte[] bytes) { EndiannessHelper.RespectEndianness(typeof(T), bytes); GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); try { return((T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T))); } finally { handle.Free(); } }
private int ReadSegmentLength() { int segmentLength = mReader.ReadInt32(); if (segmentLength > mReader.BaseStreamLength || segmentLength < 0) { mReader.Endianness = mReader.Endianness == Endianness.LittleEndian ? Endianness.BigEndian : Endianness.LittleEndian; segmentLength = EndiannessHelper.Swap(segmentLength); } return(segmentLength); }
/// <summary> /// Reads a <see cref="System.DateTime"/> object. /// </summary> /// <param name="stream">Stream to read the DateTime object from.</param> /// <returns>The read <see cref="System.DateTime"/> object.</returns> internal DateTime ReadPrimitive_DateTime(Stream stream) { const int elementSize = sizeof(long); // binary representation of a DateTime int bytesRead = stream.Read(TempBuffer_Buffer, 0, elementSize); if (bytesRead < elementSize) { throw new SerializationException("Unexpected end of stream."); } long value = MemoryMarshal.Read <long>(TempBuffer_Buffer); if (mDeserializingLittleEndian != BitConverter.IsLittleEndian) { EndiannessHelper.SwapBytes(ref value); } return(DateTime.FromBinary(value)); }
/// <summary> /// Reads a <see cref="System.Char"/> value (native encoding). /// </summary> /// <param name="stream">Stream to read the value from.</param> /// <returns>The read value.</returns> internal char ReadPrimitive_Char_Native(Stream stream) { const int bytesToRead = 2; int bytesRead = stream.Read(TempBuffer_Buffer, 0, bytesToRead); if (bytesRead < bytesToRead) { throw new SerializationException("Unexpected end of stream."); } char value = MemoryMarshal.Read <char>(TempBuffer_Buffer); if (mDeserializingLittleEndian != BitConverter.IsLittleEndian) { EndiannessHelper.SwapBytes(ref value); } return(value); }
/// <summary> /// Reads a <see cref="System.Double"/> value. /// </summary> /// <param name="stream">Stream to read the value from.</param> /// <returns>The read value.</returns> internal double ReadPrimitive_Double(Stream stream) { const int elementSize = sizeof(double); int bytesRead = stream.Read(TempBuffer_Buffer, 0, elementSize); if (bytesRead < elementSize) { throw new SerializationException("Unexpected end of stream."); } double value = MemoryMarshal.Read <double>(TempBuffer_Buffer); if (mDeserializingLittleEndian != BitConverter.IsLittleEndian) { EndiannessHelper.SwapBytes(ref value); } return(value); }
public static byte[] ToBytes <T>(this T data) { byte[] bytes = new byte[Marshal.SizeOf(data)]; GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); try { IntPtr rawDataPtr = handle.AddrOfPinnedObject(); Marshal.StructureToPtr(data, rawDataPtr, false); } finally { handle.Free(); } EndiannessHelper.RespectEndianness(typeof(T), bytes); return(bytes); }
/// <summary> /// Reads a <see cref="System.DateTimeOffset"/> object. /// </summary> /// <param name="stream">Stream to read the DateTimeOffset object from.</param> /// <returns>The read <see cref="System.DateTimeOffset"/> object.</returns> internal DateTimeOffset ReadPrimitive_DateTimeOffset(Stream stream) { const int elementSize = 2 * sizeof(long); int bytesRead = stream.Read(TempBuffer_Buffer, 0, elementSize); if (bytesRead < elementSize) { throw new SerializationException("Unexpected end of stream."); } long dateTimeTicks = MemoryMarshal.Read <long>(TempBuffer_Buffer); long timezoneOffsetTicks = MemoryMarshal.Read <long>(TempBuffer_Buffer.AsSpan().Slice(8)); if (mDeserializingLittleEndian != BitConverter.IsLittleEndian) { EndiannessHelper.SwapBytes(ref dateTimeTicks); EndiannessHelper.SwapBytes(ref timezoneOffsetTicks); } return(new DateTimeOffset(dateTimeTicks, new TimeSpan(timezoneOffsetTicks))); }
/// <summary> /// Reads a <see cref="System.String"/> object (UTF-16 encoding). /// </summary> /// <param name="stream">Stream to read the string object from.</param> /// <returns>The read string.</returns> internal unsafe string ReadPrimitive_String_UTF16(Stream stream) { // read the number of UTF-16 code units int codeUnitCount = Leb128EncodingHelper.ReadInt32(stream); int size = codeUnitCount * sizeof(char); // read encoded string EnsureTemporaryByteBufferSize(size); int bytesRead = stream.Read(TempBuffer_Buffer, 0, size); if (bytesRead < size) { throw new SerializationException("Unexpected end of stream."); } // swap bytes to fix endianness issues, if necessary var buffer = MemoryMarshal.Cast <byte, char>(TempBuffer_Buffer.AsSpan(0, bytesRead)); if (mDeserializingLittleEndian != BitConverter.IsLittleEndian) { for (int i = 0; i < buffer.Length; i++) { EndiannessHelper.SwapBytes(ref buffer[i]); } } // create a string from the buffer #if NETSTANDARD2_0 || NET461 string s; fixed(char *p = buffer) { s = new string(p, 0, buffer.Length); } #elif NETSTANDARD2_1_OR_GREATER || NET5_0_OR_GREATER string s = new string(buffer); #else #error Unhandled .NET framework #endif mDeserializedObjectIdTable.Add(mNextDeserializedObjectId++, s); return(s); }
public override void Read(EndianBinaryReader reader, ISection section = null) { if (section != null) { ReadModern(); } else { ReadClassic(); } void ReadClassic() { var offsets = new List <long>(); // Try to determine endianness (apparently DT uses big endian string arrays) uint stringOffset = reader.ReadUInt32(); if (stringOffset >= reader.Length) { reader.Endianness = Endianness.Big; stringOffset = EndiannessHelper.Swap(stringOffset); } Endianness = reader.Endianness; do { offsets.Add(stringOffset); stringOffset = reader.ReadUInt32(); } while (reader.Position < offsets[0] && stringOffset != 0); Strings.Capacity = offsets.Count; for (int i = 0; i < offsets.Count; i++) { long offset = offsets[i]; reader.SeekBegin(offset); string value = reader.ReadString(StringBinaryFormat.NullTerminated); if (!string.IsNullOrEmpty(value)) { Strings.Add(new StringEntry { Value = value, Id = ( uint )i }); } } } void ReadModern() { int count = reader.ReadInt32(); reader.ReadOffset(() => { Strings.Capacity = count; for (int i = 0; i < count; i++) { Strings.Add(new StringEntry { Value = reader.ReadStringOffset(StringBinaryFormat.NullTerminated), Id = reader.ReadUInt32() }); } }); } }
private static bool IsValidArchiveVersion2And3(Stream stream, int entrySize) { // check stream length if (stream.Length <= 4 + entrySize) { return(false); } byte[] testData = new byte[4 + entrySize]; stream.Read(testData, 0, 4 + entrySize); stream.Position = 0; int numOfFiles = BitConverter.ToInt32(testData, 0); // num of files sanity check if (numOfFiles > 1024 || numOfFiles < 1 || (numOfFiles * entrySize) > stream.Length) { numOfFiles = EndiannessHelper.Swap(numOfFiles); if (numOfFiles > 1024 || numOfFiles < 1 || (numOfFiles * entrySize) > stream.Length) { return(false); } } // check if the name field is correct bool nameTerminated = false; for (int i = 0; i < entrySize - 4; i++) { if (testData[4 + i] == 0x00) { if (i == 0) { return(false); } nameTerminated = true; } if (testData[4 + i] != 0x00 && nameTerminated) { return(false); } } // first entry length sanity check int length = BitConverter.ToInt32(testData, entrySize); if (length >= stream.Length || length < 0) { length = EndiannessHelper.Swap(length); if (length >= stream.Length || length < 0) { return(false); } } return(true); }