StreamUtilities
using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities.IO;
using System;
using System.IO;
namespace Org.BouncyCastle.Bcpg
{
internal static class StreamUtilities
{
[Flags]
internal enum StreamFlags
{
None = 0,
LongLength = 1,
Partial = 2,
Eof = 4
}
internal static uint ReadBodyLen(Stream s, out StreamFlags flags)
{
flags = StreamFlags.None;
int num = s.ReadByte();
if (num < 0) {
flags = StreamFlags.Eof;
return 0;
}
if (num < 192)
return (uint)num;
if (num < 224) {
int num2 = RequireByte(s);
return (uint)((num - 192 << 8) + num2 + 192);
}
if (num == 255) {
flags |= StreamFlags.LongLength;
return RequireUInt32BE(s);
}
flags |= StreamFlags.Partial;
return (uint)(1 << num);
}
internal static uint RequireBodyLen(Stream s, out StreamFlags streamFlags)
{
uint result = ReadBodyLen(s, out streamFlags);
if (streamFlags.HasFlag(StreamFlags.Eof))
throw new EndOfStreamException();
return result;
}
internal static byte RequireByte(Stream s)
{
int num = s.ReadByte();
if (num < 0)
throw new EndOfStreamException();
return (byte)num;
}
internal static byte[] RequireBytes(Stream s, int count)
{
byte[] array = new byte[count];
RequireBytes(s, array);
return array;
}
internal static void RequireBytes(Stream s, byte[] buffer)
{
RequireBytes(s, buffer, 0, buffer.Length);
}
internal static void RequireBytes(Stream s, byte[] buffer, int offset, int count)
{
if (Streams.ReadFully(s, buffer, offset, count) < count)
throw new EndOfStreamException();
}
internal static void RequireBytes(Stream s, Span<byte> buffer)
{
if (Streams.ReadFully(s, buffer) != buffer.Length)
throw new EndOfStreamException();
}
internal unsafe static ushort RequireUInt16BE(Stream s)
{
Span<byte> span = new Span<byte>(stackalloc byte[2], 2);
RequireBytes(s, span);
return Pack.BE_To_UInt16(span);
}
internal unsafe static uint RequireUInt32BE(Stream s)
{
Span<byte> span = new Span<byte>(stackalloc byte[4], 4);
RequireBytes(s, span);
return Pack.BE_To_UInt32(span);
}
internal unsafe static ulong RequireUInt64BE(Stream s)
{
Span<byte> span = new Span<byte>(stackalloc byte[8], 8);
RequireBytes(s, span);
return Pack.BE_To_UInt64(span);
}
internal unsafe static void WriteNewPacketLength(Stream s, long bodyLen, bool longLength = false)
{
if (longLength || bodyLen > 8383) {
Span<byte> span = new Span<byte>(stackalloc byte[5], 5);
span[0] = byte.MaxValue;
Pack.UInt32_To_BE((uint)bodyLen, span, 1);
s.Write(span);
} else if (bodyLen < 192) {
s.WriteByte((byte)bodyLen);
} else {
bodyLen -= 192;
Span<byte> span2 = new Span<byte>(stackalloc byte[2], 2);
span2[0] = (byte)(((bodyLen >> 8) & 255) + 192);
span2[1] = (byte)bodyLen;
s.Write(span2);
}
}
internal unsafe static void WriteUInt16BE(Stream s, ushort n)
{
Span<byte> span = new Span<byte>(stackalloc byte[2], 2);
Pack.UInt16_To_BE(n, span);
s.Write(span);
}
internal unsafe static void WriteUInt32BE(Stream s, uint n)
{
Span<byte> span = new Span<byte>(stackalloc byte[4], 4);
Pack.UInt32_To_BE(n, span);
s.Write(span);
}
internal unsafe static void WriteUInt64BE(Stream s, ulong n)
{
Span<byte> span = new Span<byte>(stackalloc byte[8], 8);
Pack.UInt64_To_BE(n, span);
s.Write(span);
}
}
}