Skip to content
Draft
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
2 changes: 1 addition & 1 deletion src/010 Templates/trees.bt
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ struct InstanceRef {
if (isDirt3 || isGridAutosport) {
int32 distant;
int32 maxInstances;
local int32 numInstances = 0;
local int32 numInstances <hidden=true> = 0;
}
else {
int32 maxInstances;
Expand Down
23 changes: 23 additions & 0 deletions src/EgoEngineLibrary/IO/EndianBinaryReaderExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Runtime.InteropServices;

namespace EgoEngineLibrary.IO;

public static class EndianBinaryReaderExtensions
{
extension(EndianBinaryReader reader)
{
public string ReadNullTerminatedString()
{
List<byte> bytes = [];
byte b = reader.ReadByte();

while (b != 0x00)
{
bytes.Add(b);
b = reader.ReadByte();
}

return reader.Encoding.GetString(CollectionsMarshal.AsSpan(bytes));
}
}
}
57 changes: 57 additions & 0 deletions src/EgoEngineLibrary/Text/EncodingExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System.Text;
using EgoEngineLibrary.IO;

namespace EgoEngineLibrary.Text;

public static class EncodingExtensions
{
extension(Encoding encoding)
{
public StringByteBuffer BuildStringByteBuffer(IEnumerable<string> strings)
{
return encoding.BuildStringByteBuffer([.. strings]);
}

public StringByteBuffer BuildStringByteBuffer(IReadOnlyCollection<string> strings)
{
int totalCharacters = 0;
int largestStringLength = 0;
foreach (var s in strings)
{
totalCharacters += s.Length;
largestStringLength = Math.Max(largestStringLength, s.Length);
}

int bufferSize = encoding.GetMaxByteCount(totalCharacters);
int singleBufferSize = encoding.GetMaxByteCount(largestStringLength);
int bufferIndex = 0;
byte[] buffer = new byte[bufferSize + strings.Count];
byte[] singleBuffer = new byte[singleBufferSize + 1];
var stringOffsetMap = new Dictionary<string, int>(strings.Count);
foreach (var s in strings)
{
if (stringOffsetMap.ContainsKey(s))
{
continue;
}

var bytesWritten = encoding.GetBytes(s, singleBuffer);
singleBuffer[bytesWritten] = 0;
var filenameSpan = singleBuffer.AsSpan(0, bytesWritten + 1);
var index = buffer.IndexOf(filenameSpan);
if (index >= 0)
{
stringOffsetMap.Add(s, index);
}
else
{
stringOffsetMap.Add(s, bufferIndex);
filenameSpan.CopyTo(buffer.AsSpan(bufferIndex));
bufferIndex += filenameSpan.Length;
}
}

return new StringByteBuffer(buffer, bufferIndex, stringOffsetMap);
}
}
}
3 changes: 3 additions & 0 deletions src/EgoEngineLibrary/Text/StringByteBuffer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace EgoEngineLibrary.Text;

public record StringByteBuffer(byte[] Buffer, int BufferSize, Dictionary<string, int> StringOffsetMap);
Loading