// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0.
// See THIRD-PARTY-NOTICES.TXT in the project root for license information.
using System.Diagnostics;
namespace System.Net.Http.HPack
{
internal static class IntegerEncoder
{
///
/// Encodes an integer into one or more bytes.
///
/// The value to encode. Must not be negative.
/// The length of the prefix, in bits, to encode within. Must be between 1 and 8.
/// The destination span to encode to.
/// The number of bytes used to encode .
/// If had enough storage to encode , true. Otherwise, false.
public static bool Encode(int value, int numBits, Span destination, out int bytesWritten)
{
Debug.Assert(value >= 0);
Debug.Assert(numBits >= 1 && numBits <= 8);
if (destination.Length == 0)
{
bytesWritten = 0;
return false;
}
destination[0] &= MaskHigh(8 - numBits);
if (value < (1 << numBits) - 1)
{
destination[0] |= (byte)value;
bytesWritten = 1;
return true;
}
else
{
destination[0] |= (byte)((1 << numBits) - 1);
if (1 == destination.Length)
{
bytesWritten = 0;
return false;
}
value = value - ((1 << numBits) - 1);
int i = 1;
while (value >= 128)
{
destination[i++] = (byte)(value % 128 + 128);
if (i >= destination.Length)
{
bytesWritten = 0;
return false;
}
value = value / 128;
}
destination[i++] = (byte)value;
bytesWritten = i;
return true;
}
}
private static byte MaskHigh(int n) => (byte)(sbyte.MinValue >> (n - 1));
}
}