using System; using System.IO; using System.Runtime.InteropServices; using System.Text; namespace Capnp { /// /// Supports the deserialization of Cap'n Proto messages from a stream (see https://capnproto.org/encoding.html#serialization-over-a-stream). /// Packing and compression cannot be handled yet. /// public static class Framing { /// /// Deserializes a message from given stream. /// /// The stream to read from /// The deserialized message /// is null. /// The stream does not support reading, is null, or is already closed. /// The end of the stream is reached. /// The stream is closed. /// An I/O error occurs. /// Encountered invalid framing data. /// Too many or too large segments, probably due to invalid framing data. public static WireFrame ReadSegments(Stream stream) { using (var reader = new BinaryReader(stream, Encoding.Default, true)) { uint scountm = reader.ReadUInt32(); uint scount = checked(scountm + 1); var buffers = new Memory[scount]; for (uint i = 0; i < scount; i++) { uint size = reader.ReadUInt32(); buffers[i] = new Memory(new ulong[size]); } if ((scount & 1) == 0) { // Padding reader.ReadUInt32(); } for (uint i = 0; i < scount; i++) { var buffer = MemoryMarshal.Cast(buffers[i].Span); if (reader.Read(buffer) != buffer.Length) { throw new EndOfStreamException("Expected more bytes according to framing header"); } } return new WireFrame(buffers); } } } }