Skip to content
Open
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
dotnet-version: [ '9.0.x' ]
dotnet-version: [ '10.0.x' ]
rid: ['win-x64', 'win-x86', 'linux-x64', 'linux-arm64', 'osx-x64', 'osx-arm64']

steps:
Expand Down
8 changes: 4 additions & 4 deletions LibXboxOne.Tests/LibXboxOne.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<IsTestProject>true</IsTestProject>
<IsPackable>false</IsPackable>
<IsPublishable>false</IsPublishable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="xunit" Version="2.9.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.5.1" />
</ItemGroup>

<ItemGroup>
Expand Down
11 changes: 6 additions & 5 deletions LibXboxOne/LibXboxOne.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Folder Include="NAND\" />
Expand All @@ -10,12 +11,12 @@
<Folder Include="ThirdParty\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.IO.Packaging" Version="9.0.1" />
<PackageReference Include="LTRData.DiscUtils.Ntfs" Version="1.0.80" />
<PackageReference Include="LTRData.DiscUtils.Vhd" Version="1.0.80" />
<PackageReference Include="System.Formats.Cbor" Version="10.0.7" />
<PackageReference Include="System.IO.Packaging" Version="10.0.7" />
<PackageReference Include="System.Data.DataSetExtensions" Version="4.6.0-preview3.19128.7" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Portable.BouncyCastle" Version="1.9.0" />
<PackageReference Include="DiscUtils.Ntfs" Version="0.16.13" />
<PackageReference Include="DiscUtils.Vhd" Version="0.16.13" />
</ItemGroup>
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
Expand Down
16 changes: 16 additions & 0 deletions LibXboxOne/XVC2/BoxIndex.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Formats.Cbor;
using LibXboxOne.XVC2.SerializedModel;

namespace LibXboxOne.XVC2;

public readonly record struct BoxIndex(int Value) : ISerialize
{
public override string ToString() => $"box:{Value}";

public void Serialize(CborWriter writer)
{
writer.WriteInt32(Value);
}

public static BoxIndex Deserialize(CborReader reader) => new(reader.ReadInt32());
}
157 changes: 157 additions & 0 deletions LibXboxOne/XVC2/CborExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Formats.Cbor;
using System.IO;
using LibXboxOne.XVC2.SerializedModel;

namespace LibXboxOne.XVC2;

public static class CborExtensions
{
extension(CborWriter writer)
{
public void WriteTagEx(CborTagEx tag)
=> writer.WriteTag((CborTag)tag);

public void WriteSelfDescribeTag(CborTagEx tag)
{
writer.WriteTag(CborTag.SelfDescribeCbor);
writer.WriteTagEx(tag);
}

public void WriteHash(PackagingHash hash)
{
var tag = hash.Algorithm switch
{
PackagingHashAlgorithm.SHA256 => CborTagEx.SHA256,
PackagingHashAlgorithm.SHA384 => CborTagEx.SHA384,
PackagingHashAlgorithm.SHA512 => CborTagEx.SHA512,
_ => throw new UnreachableException()
};

writer.WriteTagEx(tag);
writer.WriteByteString(hash.Hash);
}

public void WriteMap<TKey>(Dictionary<TKey, object> map)
{
writer.WriteStartMap(map.Count);

foreach (var (key, value) in map)
{
writer.WriteInt32((int)(object)key);

switch (value)
{
case string str:
writer.WriteTextString(str);
break;
case byte[] bytes:
writer.WriteByteString(bytes);
break;
case int i32:
writer.WriteInt32(i32);
break;
case long i64:
writer.WriteInt64(i64);
break;
case uint u32:
writer.WriteUInt32(u32);
break;
case ulong u64:
writer.WriteUInt64(u64);
break;
case bool boolean:
writer.WriteBoolean(boolean);
break;
default:
Debug.Assert(false);
break;
}
}

writer.WriteEndMap();
}

public void WriteGuid(Guid value)
=> writer.WriteTextString(value.ToString());

public void WriteEnum<T>(T value) where T : Enum
=> writer.WriteInt32((int)(object)value);

public void WriteLabel(SerializedLabel label)
=> writer.WriteInt32((int)label);
}

extension(CborReader reader)
{
public CborTagEx ReadTagEx()
=> (CborTagEx)reader.ReadTag();

public void ReadSelfDescribeTag(CborTagEx tag)
{
var tag0 = reader.ReadTag();
if (tag0 != CborTag.SelfDescribeCbor)
throw new InvalidDataException();

var tag1 = reader.ReadTagEx();
if (tag1 != tag)
throw new InvalidDataException();
}

public PackagingHash ReadHash()
{
var tagType = reader.ReadTagEx();
var type = tagType switch
{
CborTagEx.SHA256 => PackagingHashAlgorithm.SHA256,
CborTagEx.SHA384 => PackagingHashAlgorithm.SHA384,
CborTagEx.SHA512 => PackagingHashAlgorithm.SHA512,
_ => throw new UnreachableException()
};

var hash = reader.ReadByteString();
return new PackagingHash(type, hash);
}

public Dictionary<TKey, object> ReadMap<TKey>()
{
var count = reader.ReadStartMap();

var dict = new Dictionary<TKey, object>();
while (count-- != 0)
{
var key = (TKey)(object)reader.ReadInt32();
dict[key] = reader.PeekState() switch
{
CborReaderState.TextString => reader.ReadTextString(),
CborReaderState.ByteString => reader.ReadByteString(),
CborReaderState.UnsignedInteger => reader.ReadUInt64(),
CborReaderState.NegativeInteger => reader.ReadInt64(),
CborReaderState.Boolean => reader.ReadBoolean(),
_ => throw new UnreachableException()
};
}

reader.ReadEndMap();

return dict;
}

public Guid ReadGuid()
=> Guid.Parse(reader.ReadTextString());

public T ReadEnum<T>() where T : Enum
=> (T)(object)reader.ReadInt32();

public void AssertInvalidValue()
{
Debug.Assert(false);
reader.SkipValue();
}

public SerializedLabel ReadLabel()
=> (SerializedLabel)reader.ReadInt32();
}
}
28 changes: 28 additions & 0 deletions LibXboxOne/XVC2/CborTagEx.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace LibXboxOne.XVC2;

public enum CborTagEx
{
SHA512 = 18512,
SHA384 = 18513,
SHA256 = 18540,
Enum0 = 121,
Enum1 = 122,
Enum2 = 123,
Enum3 = 124,
Enum4 = 125,
Enum5 = 126,
Enum6 = 127,
LogicalNone = 32870,
LogicalAny = 32871,
LogicalAll = 32872,
XVC2 = 1482048306,
XVCB = 1482048322, // Box
XVCC = 1482048323, // Chunk
XVCD = 1482048324,
XVCE = 1482048325,
XVCF = 1482048326,
XVCI = 1482048329,
XVCP = 1482048336, // Package
XVCS = 1482048339,
XVCZ = 1482048346, // Seal
}
Loading