Guest User

C# Stream sloužící k zápisu jednotlivých bitů

a guest
Aug 8th, 2012
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.08 KB | None | 0 0
  1. using System;
  2. using System.IO;
  3. using System.Text;
  4.  
  5. namespace AlexClarai
  6. {
  7.   class Program
  8.   {
  9.     static void Main(string[] args)
  10.     {
  11.       using (var binaryStream = new BinaryStream())
  12.       {
  13.         binaryStream.Write(true, true, true);
  14.         binaryStream.Write(false, false, false);
  15.         binaryStream.Write(true, true, true);
  16.         binaryStream.Write(false, false, false);
  17.         binaryStream.Write(true, false, true);
  18.         binaryStream.Write(true, true, false);
  19.         binaryStream.Write(true, true, true);
  20.         binaryStream.Write(false, false, false);
  21.         binaryStream.Write(true, true, true);
  22.         binaryStream.Write(false, false, false);
  23.         binaryStream.Write(true, false, true);
  24.         binaryStream.Write(true, true, false);
  25.         binaryStream.Write(true, true);
  26.         binaryStream.Flush();
  27.         Console.WriteLine(binaryStream.ToBitString(true));
  28.         using (var fileStream = new FileStream("C:/bits.bit", FileMode.Create))
  29.         {
  30.           binaryStream.WriteTo(fileStream);
  31.         }
  32.       }
  33.       Console.ReadLine();
  34.     }
  35.   }
  36.  
  37.   /// <summary>
  38.   /// Stream umožňující zápis jednotlivých bitů.
  39.   /// </summary>
  40.   public class BinaryStream : MemoryStream
  41.   {
  42.     // Pole celých bajtů, které se při naplněné zapíše
  43.     // a ukazatel na aktuální pozici v něm.
  44.     private byte[] byteBuffer = new byte[32];
  45.     private int byteIndex = 0;
  46.  
  47.     // Pole bitů (poslední, neúplný bajt), které se při
  48.     // naplnění zapíše do pole bajtů a ukazatel na
  49.     // aktuální pozici v něm.
  50.     private byte bitBuffer = 0x00;
  51.     private int bitIndex = 0;
  52.  
  53.     /// <summary>
  54.     /// Meotda pro zápis jednoho či více samostatných bitů.
  55.     /// </summary>
  56.     /// <param name="bits">Pole bitů pro zápis.</param>
  57.     public void Write(params bool[] bits)
  58.     {
  59.       foreach (var bit in bits)
  60.       {
  61.         // Posuneme bit buffer
  62.         bitBuffer <<= 1;
  63.         if (bit) bitBuffer |= 1;
  64.         else bitBuffer |= 0;
  65.         // Naplněno, zapíšeme bit buffer
  66.         if (bitIndex++ == 7)
  67.         {
  68.           bitIndex = 0;
  69.           // Posuneme byte buffer
  70.           byteBuffer[byteIndex] = bitBuffer;
  71.           // Naplněno, zapíšeme byte buffer
  72.           if (byteIndex++ == byteBuffer.Length - 1)
  73.           {
  74.             byteIndex = 0;
  75.             base.Write(byteBuffer, 0, byteBuffer.Length);
  76.           }
  77.         }
  78.       }
  79.     }
  80.     /// <summary>
  81.     /// Metoda, která zapíše do streamu obsah bufferu bajtů
  82.     /// do aktuální pozice a odsadí do bajtu a zapíše buffer
  83.     /// bitů.
  84.     /// </summary>
  85.     public override void Flush()
  86.     {
  87.       // Zapsat aktuální bajty
  88.       base.Write(byteBuffer, 0, byteIndex);
  89.       // Odsadit a zapsat bity
  90.       base.Write(new byte[] { (byte)(bitBuffer << (8 - bitIndex)) }, 0, 1);
  91.     }
  92.  
  93.   }
  94.  
  95.   public static class ExtensionMethods
  96.   {
  97.     /// <summary>
  98.     /// Metoda vypisující v textové podobě binární podobu jednoho
  99.     /// bajtu.
  100.     /// </summary>
  101.     /// <param name="buffer">Bajt k převedení na string.</param>
  102.     /// <returns>Textová reprezentace bajtu.</returns>
  103.     public static string ToBitString(this byte buffer)
  104.     {
  105.       var builder = new StringBuilder();
  106.       for (var i = 128; i > 0; i /= 2)
  107.       {
  108.         builder.Append((buffer & i) == 0 ? '0' : '1');
  109.       }
  110.       return builder.ToString();
  111.     }
  112.     /// <summary>
  113.     /// Metoda vypisující celé pole bajtů v jejich textové podobě,
  114.     /// volitelně oddělené mezerou.
  115.     /// </summary>
  116.     /// <param name="buffer">Pole bajtů k převedení na string.</param>
  117.     /// <param name="delimit">Pravidvostní hodnota určující, zda rozdělit bajty mezerou.</param>
  118.     /// <returns>Textová reprezentace pole bajtů.</returns>
  119.     public static string ToBitString(this byte[] buffer, bool delimit = false)
  120.     {
  121.       var builder = new StringBuilder();
  122.       foreach (var individualBuffer in buffer)
  123.       {
  124.         builder.Append(individualBuffer.ToBitString());
  125.         if (delimit) builder.Append(' ');
  126.       }
  127.       return builder.ToString();
  128.     }
  129.     /// <summary>
  130.     /// Metoda vypisující binární obsah streamu v textové podobě,
  131.     /// volitelně oddělený mezerami po jednom bajtu.
  132.     /// </summary>
  133.     /// <param name="stream">Stream k převedení na string.</param>
  134.     /// <param name="delimit">Pravidvostní hodnota určující, zda rozdělit bajty mezerou.</param>
  135.     /// <returns>Textová reprezentace streamu.</returns>
  136.     /// <remarks>
  137.     /// Určeno k ladění, nepoužívat na dlouhé streamy - čte celý stream najednou!
  138.     /// </remarks>
  139.     public static string ToBitString(this Stream stream, bool delimit = false)
  140.     {
  141.       if (!stream.CanSeek) throw new InvalidOperationException("Stream neumožňuje posouvání, nelze začít číst od počátku streamu.");
  142.       stream.Seek(0, SeekOrigin.Begin);
  143.       var buffer = new byte[stream.Length];
  144.       stream.Read(buffer, 0, buffer.Length);
  145.       stream.Seek(0, SeekOrigin.End);
  146.       return buffer.ToBitString(delimit);
  147.     }
  148.   }
  149. }
Add Comment
Please, Sign In to add comment