/// <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 }
/// <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); }
/// <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); }