Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions src/FastSerialization/FastSerialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
using System.Diagnostics;
using System.IO;
using System.Text; // For StringBuilder.

using System.Runtime.InteropServices;
using System.Buffers.Binary;
// see #Introduction and #SerializerIntroduction
namespace FastSerialization
{
Expand Down Expand Up @@ -184,6 +185,10 @@ interface IStreamWriter : IDisposable
/// </summary>
void Write(int value);
/// <summary>
/// Write an blob to a stream
/// </summary>
void WriteBlobAsInt(int value);
/// <summary>
/// Write a long to a stream
/// </summary>
void Write(long value);
Expand Down Expand Up @@ -590,7 +595,6 @@ public Serializer(IStreamWriter writer, IFastSerializable entryObject)
Log("<Serializer>");
// Write the header.
Write("!FastSerialization.1");

// Write the main object. This is recursive and does most of the work.
Write(entryObject);

Expand Down Expand Up @@ -675,6 +679,14 @@ public void Write(int value)
writer.Write(value);
}
/// <summary>
/// Write an blob to a stream
/// </summary>
public void WriteBlobAsInt(int value)
{
Log("<Write Type=\"int\" Value=\"" + value + "\" StreamLabel=\"0x" + writer.GetLabel().ToString("x") + "\"/>");
writer.WriteBlobAsInt(value);
}
/// <summary>
/// Write a long to a stream
/// </summary>
public void Write(long value)
Expand All @@ -688,7 +700,15 @@ public void Write(long value)
public void Write(Guid value)
{
Log("<Write Type=\"Guid\" Value=\"" + value + "\" StreamLabel=\"0x" + writer.GetLabel().ToString("x") + "\"/>");
byte[] bytes = value.ToByteArray();
Span<byte> bytes = value.ToByteArray();

if (!BitConverter.IsLittleEndian)
{
BinaryPrimitives.WriteInt32LittleEndian(bytes.Slice(0), (MemoryMarshal.Read<int>(bytes.Slice(0,4))));
BinaryPrimitives.WriteInt16LittleEndian(bytes.Slice(4), (MemoryMarshal.Read<short>(bytes.Slice(4,6))));
BinaryPrimitives.WriteInt16LittleEndian(bytes.Slice(6), (MemoryMarshal.Read<short>(bytes.Slice(6,8))));
}

for (int i = 0; i < bytes.Length; i++)
{
writer.Write(bytes[i]);
Expand Down Expand Up @@ -1591,7 +1611,7 @@ public StreamLabel ResolveForwardReference(ForwardReference reference, bool pres
reader.GotoSuffixLabel();
Log("<Trailer StreamLabel=\"0x" + reader.Current.ToString("x") + "\"/>");
StreamLabel forwardRefsLabel = reader.ReadLabel();

Goto(forwardRefsLabel);
int fowardRefCount = reader.ReadInt32();
Log("<ForwardReferenceDefinitons StreamLabel=\"0x" + forwardRefsLabel.ToString("x") +
Expand Down
4 changes: 4 additions & 0 deletions src/FastSerialization/FastSerialization.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.Memory"/>
</ItemGroup>

<!-- ******************* Signing Support *********************** -->
<ItemGroup>
<FilesToSign Include="$(TargetPath)">
Expand Down
21 changes: 21 additions & 0 deletions src/FastSerialization/StreamReaderWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Diagnostics;
using System.IO;
using System.Text; // For StringBuilder.
using System.Buffers.Binary;

namespace FastSerialization
{
Expand Down Expand Up @@ -328,6 +329,7 @@ public void Write(byte value)
/// </summary>
public unsafe void Write(short value)
{
value = BinaryPrimitives.ReadInt16LittleEndian(BitConverter.GetBytes(value));
if (endPosition + sizeof(short) > bytes.Length)
{
MakeSpace();
Expand All @@ -344,6 +346,24 @@ public unsafe void Write(short value)
/// Implementation of IStreamWriter
/// </summary>
public unsafe void Write(int value)
{
value = BinaryPrimitives.ReadInt32LittleEndian(BitConverter.GetBytes(value));
if (endPosition + sizeof(int) > bytes.Length)
{
MakeSpace();
}

fixed (byte* data = bytes)
{
*(int*)(data + endPosition) = value;
}

endPosition += sizeof(int);
}
/// <summary>
/// Write an blob to a stream
/// </summary>
public unsafe void WriteBlobAsInt(int value)
{
if (endPosition + sizeof(int) > bytes.Length)
{
Expand All @@ -362,6 +382,7 @@ public unsafe void Write(int value)
/// </summary>
public unsafe void Write(long value)
{
value = BinaryPrimitives.ReadInt64LittleEndian(BitConverter.GetBytes(value));
if (endPosition + sizeof(long) > bytes.Length)
{
MakeSpace();
Expand Down
36 changes: 35 additions & 1 deletion src/TraceEvent/EventPipe/RewindableStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

using System.Buffers.Binary;
namespace Microsoft.Diagnostics.Tracing.EventPipe
{

Expand Down Expand Up @@ -60,6 +60,40 @@ public T Read<T>() where T : struct
{
Span<byte> buffer = stackalloc byte[Unsafe.SizeOf<T>()];
Read(buffer);
if (!BitConverter.IsLittleEndian)
{
if(typeof(T) == typeof(short))
{
short val = BinaryPrimitives.ReadInt16LittleEndian(buffer);
return (T)(object)val;
}
else if(typeof(T) == typeof(int))
{
int val = BinaryPrimitives.ReadInt32LittleEndian(buffer);
return (T)(object)val;
}
else if(typeof(T) == typeof(long))
{
long val = BinaryPrimitives.ReadInt64LittleEndian(buffer);
return (T)(object)val;
}
else if(typeof(T) == typeof(ushort))
{
ushort val = BinaryPrimitives.ReadUInt16LittleEndian(buffer);
return (T)(object)val;
}
else if(typeof(T) == typeof(uint))
{
uint val = BinaryPrimitives.ReadUInt32LittleEndian(buffer);
return (T)(object)val;
}
else if(typeof(T) == typeof(ulong))
{
ulong val = BinaryPrimitives.ReadUInt64LittleEndian(buffer);
return (T)(object)val;
}

}
return MemoryMarshal.Read<T>(buffer);
}

Expand Down
104 changes: 96 additions & 8 deletions src/TraceEvent/EventPipe/SpanReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;

using System.Buffers.Binary;
namespace Microsoft.Diagnostics.Tracing.EventPipe
{
ref struct SpanReader
Expand All @@ -21,12 +21,90 @@ public SpanReader(ReadOnlySpan<byte> buffer, long spanStartStreamOffset)

public sbyte ReadInt8() => Read<sbyte>();
public byte ReadUInt8() => Read<byte>();
public short ReadInt16() => Read<short>();
public ushort ReadUInt16() => Read<ushort>();
public int ReadInt32() => Read<int>();
public uint ReadUInt32() => Read<uint>();
public long ReadInt64() => Read<long>();
public ulong ReadUInt64() => Read<ulong>();

public short ReadInt16()
{
short val;
if (BinaryPrimitives.TryReadInt16LittleEndian(_buffer, out val))
{
_buffer = _buffer.Slice(sizeof(short));
}
else
{
ThrowFormatException<short>();
}
return val;
}

public ushort ReadUInt16()
{
ushort val;
if (BinaryPrimitives.TryReadUInt16LittleEndian(_buffer, out val))
{
_buffer = _buffer.Slice(sizeof(ushort));
}
else
{
ThrowFormatException<ushort>();
}
return val;
}

public int ReadInt32()
{
int val;
if (BinaryPrimitives.TryReadInt32LittleEndian(_buffer, out val))
{
_buffer = _buffer.Slice(sizeof(int));
}
else
{
ThrowFormatException<int>();
}
return val;
}

public uint ReadUInt32()
{
uint val;
if (BinaryPrimitives.TryReadUInt32LittleEndian(_buffer, out val))
{
_buffer = _buffer.Slice(sizeof(uint));
}
else
{
ThrowFormatException<uint>();
}
return val;
}

public long ReadInt64()
{
long val;
if (BinaryPrimitives.TryReadInt64LittleEndian(_buffer, out val))
{
_buffer = _buffer.Slice(sizeof(long));
}
else
{
ThrowFormatException<long>();
}
return val;
}

public ulong ReadUInt64()
{
ulong val;
if (BinaryPrimitives.TryReadUInt64LittleEndian(_buffer, out val))
{
_buffer = _buffer.Slice(sizeof(ulong));
}
else
{
ThrowFormatException<ulong>();
}
return val;
}

public T Read<T>() where T : struct
{
Expand Down Expand Up @@ -156,7 +234,17 @@ public string ReadVarUIntUTF8String()

public string ReadNullTerminatedUTF16String()
{
ReadOnlySpan<char> charBuffer = MemoryMarshal.Cast<byte, char>(_buffer);

ReadOnlySpan<char> Buffer = MemoryMarshal.Cast<byte, char>(_buffer);
Span<char> charBuffer = stackalloc char [Buffer.Length];
Buffer.CopyTo(charBuffer);
if (!BitConverter.IsLittleEndian)
{
for(int ii = 0; ii < charBuffer.Length; ii++)
{
charBuffer[ii] = (char)BinaryPrimitives.ReverseEndianness((ushort)charBuffer[ii]);
}
}
for(int i = 0; i < charBuffer.Length; i++)
{
if (charBuffer[i] == 0)
Expand Down
18 changes: 18 additions & 0 deletions src/TraceEvent/Parsers/ClrTraceEventParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Buffers.Binary;
using Address = System.UInt64;

// This file was generated with the following command:
Expand Down Expand Up @@ -4788,11 +4789,28 @@ public sealed class GCBulkNodeTraceData : TraceEvent
buffer->TypeID = value->TypeID;
buffer->EdgeCount = value->EdgeCount;
ret = buffer;

if (!BitConverter.IsLittleEndian)
{
ret->Address = BinaryPrimitives.ReadUInt32LittleEndian(BitConverter.GetBytes(ret->Address));
ret->Size = BinaryPrimitives.ReadUInt64LittleEndian(BitConverter.GetBytes(ret->Size));
ret->TypeID = BinaryPrimitives.ReadUInt64LittleEndian(BitConverter.GetBytes(ret->TypeID));
ret->EdgeCount = BinaryPrimitives.ReadInt64LittleEndian(BitConverter.GetBytes(ret->EdgeCount));
}

}
else
{
GCBulkNodeUnsafeNodes* basePtr = (GCBulkNodeUnsafeNodes*)(((byte*)DataStart) + 10);
ret = basePtr + arrayIdx;

if (!BitConverter.IsLittleEndian)
{
ret->Address = BinaryPrimitives.ReadUInt64LittleEndian(BitConverter.GetBytes(ret->Address));
ret->Size = BinaryPrimitives.ReadUInt64LittleEndian(BitConverter.GetBytes(ret->Size));
ret->TypeID = BinaryPrimitives.ReadUInt64LittleEndian(BitConverter.GetBytes(ret->TypeID));
ret->EdgeCount = BinaryPrimitives.ReadInt64LittleEndian(BitConverter.GetBytes(ret->EdgeCount));
}
}
Debug.Assert((ret->Address & 0xFF00000000000003L) == 0);
Debug.Assert((ret->TypeID & 0xFF00000000000001L) == 0);
Expand Down
Loading