d3ullist

WrappedStream

Jul 13th, 2021
980
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.71 KB | None | 0 0
  1. using System;
  2. using System.IO;
  3.  
  4. namespace Shared.Util
  5. {
  6.     /// <summary>
  7.     /// A wrapper around another stream that adds a prefix and postfix
  8.     /// to the content of the stream.
  9.     /// </summary>
  10.     public class WrapperStream : Stream
  11.     {
  12.         /// <summary>
  13.         /// The prefix position.
  14.         /// </summary>
  15.         private int prefixPosition;
  16.  
  17.         /// <summary>
  18.         /// The prefix (readonly).
  19.         /// </summary>
  20.         private readonly string Prefix;
  21.  
  22.         /// <summary>
  23.         /// The wrapped stream (readonly).
  24.         /// </summary>
  25.         private readonly Stream WrappedStream;
  26.  
  27.         /// <summary>
  28.         /// The postfix position.
  29.         /// </summary>
  30.         private int postfixPosition;
  31.  
  32.         /// <summary>
  33.         /// The postfix (readonly).
  34.         /// </summary>
  35.         private readonly string Postfix;
  36.  
  37.         /// <summary>
  38.         /// Gets a value indicating whether
  39.         /// </summary>
  40.         public override bool CanRead => true;
  41.  
  42.         /// <summary>
  43.         /// Gets a value indicating whether
  44.         /// </summary>
  45.         public override bool CanSeek => false;
  46.  
  47.         /// <summary>
  48.         /// Gets a value indicating whether
  49.         /// </summary>
  50.         public override bool CanWrite => false;
  51.  
  52.         /// <summary>
  53.         /// Gets the length.
  54.         /// </summary>
  55.         public override long Length => throw new NotSupportedException();
  56.  
  57.         /// <summary>
  58.         /// Gets or sets the position.
  59.         /// </summary>
  60.         public override long Position { get => prefixPosition + WrappedStream.Position + postfixPosition; set => throw new NotSupportedException(); }
  61.  
  62.         /// <summary>
  63.         /// Initializes a new instance of the <see cref="WrapperStream"/> class.
  64.         /// </summary>
  65.         /// <param name="prefix">The prefix.</param>
  66.         /// <param name="wrappedStream">The wrappedStream.</param>
  67.         /// <param name="postfix">The postfix.</param>
  68.         /// <exception cref="ArgumentException">The wrappedstream, prefix or postfix cannot be null</exception>
  69.         /// <exception cref="ArgumentException">Must be able to read from the wrapped stream</exception>
  70.         public WrapperStream(string prefix, Stream wrappedStream, string postfix)
  71.         {
  72.             Prefix = prefix;
  73.             Postfix = postfix;
  74.             WrappedStream = wrappedStream;
  75.  
  76.             if (wrappedStream == null || prefix == null || postfix == null)
  77.             {
  78.                 throw new ArgumentException("The wrappedstream, prefix or postfix cannot be null");
  79.             }
  80.             if (!wrappedStream.CanRead)
  81.             {
  82.                 throw new ArgumentException("Must be able to read from the wrapped stream");
  83.             }
  84.         }
  85.  
  86.         /// <summary>
  87.         /// The flush.
  88.         /// </summary>
  89.         public override void Flush()
  90.         {
  91.             prefixPosition = 0;
  92.             postfixPosition = 0;
  93.             WrappedStream.Flush();
  94.         }
  95.  
  96.         /// <summary>
  97.         /// The seek.
  98.         /// </summary>
  99.         /// <param name="offset">The offset.</param>
  100.         /// <param name="origin">The origin.</param>
  101.         /// <returns>The <see cref="long"/>.</returns>
  102.         /// <exception cref="NotSupportedException"></exception>
  103.         public override long Seek(long offset, SeekOrigin origin)
  104.         {
  105.             throw new NotSupportedException();
  106.         }
  107.  
  108.         /// <summary>
  109.         /// Set the length.
  110.         /// </summary>
  111.         /// <param name="value">The value.</param>
  112.         /// <exception cref="NotSupportedException"></exception>
  113.         public override void SetLength(long value)
  114.         {
  115.             throw new NotSupportedException();
  116.         }
  117.  
  118.         /// <summary>
  119.         /// Read.
  120.         /// </summary>
  121.         /// <param name="buffer">The buffer.</param>
  122.         /// <param name="offset">The offset.</param>
  123.         /// <param name="count">The count.</param>
  124.         /// <returns>The <see cref="int"/>.</returns>
  125.         public override int Read(byte[] buffer, int offset, int count)
  126.         {
  127.             int readBytes = 0;
  128.             // If bytes need to be read from the prefix set those bytes in the buffer
  129.             for (; readBytes < count && prefixPosition < Prefix.Length; ++readBytes)
  130.             {
  131.                 buffer[offset + readBytes] = (byte)Prefix[prefixPosition++];
  132.             }
  133.  
  134.             // If bytes need to be read from the wrapped stream read them
  135.             if (readBytes < count)
  136.             {
  137.                 readBytes += WrappedStream.Read(buffer, offset + readBytes, count - readBytes);
  138.             }
  139.  
  140.             // If we still need to read bytes but can't read them from the wrapped
  141.             // stream object read them from the postfix. There is no real way to
  142.             // know when there are no bytes anymore in the WrappedStream object
  143.             // unless reading from it returns a 0.
  144.             if (readBytes == 0 && postfixPosition < Postfix.Length)
  145.             {
  146.                 for (; readBytes < count && postfixPosition < Postfix.Length; ++readBytes)
  147.                 {
  148.                     buffer[offset + readBytes] = (byte)Postfix[postfixPosition++];
  149.                 }
  150.             }
  151.  
  152.             return readBytes;
  153.         }
  154.  
  155.         /// <summary>
  156.         /// Write.
  157.         /// </summary>
  158.         /// <param name="buffer">The buffer.</param>
  159.         /// <param name="offset">The offset.</param>
  160.         /// <param name="count">The count.</param>
  161.         /// <exception cref="NotSupportedException"></exception>
  162.         public override void Write(byte[] buffer, int offset, int count)
  163.         {
  164.             throw new NotSupportedException();
  165.         }
  166.     }
  167. }
Advertisement
Add Comment
Please, Sign In to add comment