Files

63 lines
1.8 KiB
C#
Raw Permalink Normal View History

2025-09-29 23:12:23 -04:00
using System.Collections.Generic;
2025-09-29 23:07:05 -04:00
namespace SabreTools.Data.Extensions
{
public static class XZExtensions
2025-09-29 23:07:05 -04:00
{
/// <summary>
/// Decode a value from a variable-length integer
/// </summary>
/// <param name="value">Value to decode</param>
/// <param name="maxSize">Maximum number of bytes to parse</param>
2025-09-30 09:47:19 -04:00
/// <param name="length">Number of bytes parsed</param>
2025-09-29 23:07:05 -04:00
/// <returns>UInt64 representing the decoded integer</returns>
/// <see href="https://tukaani.org/xz/xz-file-format.txt"/>
2025-09-30 09:47:19 -04:00
public static ulong DecodeVariableLength(this byte[] value, int maxSize, out int length)
2025-09-29 23:07:05 -04:00
{
2025-09-30 09:47:19 -04:00
length = 0;
2025-09-29 23:07:05 -04:00
if (maxSize <= 0)
return 0;
if (maxSize > 9)
maxSize = 9;
2025-09-29 23:12:23 -04:00
ulong output = (ulong)(value[0] & 0x7F);
2025-09-29 23:07:05 -04:00
int i = 0;
2025-09-29 23:12:23 -04:00
while ((value[i++] & 0x80) != 0)
2025-09-29 23:07:05 -04:00
{
if (i >= maxSize || value[i] == 0x00)
return 0;
2025-09-29 23:12:23 -04:00
output |= (ulong)(value[i] & 0x7F) << (i * 7);
2025-09-29 23:07:05 -04:00
}
2025-09-30 09:47:19 -04:00
length = i;
2025-09-29 23:07:05 -04:00
return output;
}
/// <summary>
/// Encode a value to a variable-length integer
/// </summary>
/// <param name="value">Value to encode</param>
/// <returns>Byte array representing the encoded integer</returns>
/// <see href="https://tukaani.org/xz/xz-file-format.txt"/>
public static byte[] EncodeVariableLength(this ulong value)
{
if (value > long.MaxValue / 2)
return [];
var output = new List<byte>();
while (value >= 0x80)
{
2025-09-29 23:12:23 -04:00
output.Add((byte)(value | 0x80));
2025-09-29 23:07:05 -04:00
value >>= 7;
}
output.Add((byte)value);
return [.. output];
}
}
2025-09-29 23:12:23 -04:00
}