Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Monday, March 17, 2014

State behavioral pattern to the rescue.

The Creeping Problem

I recently found myself developing a request-response style system, where the lifetime of a request could be interrupted at any moment. For most same process execution, like your average desktop application, this is a concern, but arises more often when dealing with multiple coordinated processes. My case ended up being the latter.

One of the ways to ensure redundancy is to isolate the steps of the request-response workflow into isolated atomic units or states. This way, if it fails, it can always be re-executed without having to perform the work that came before it. It is especially helpful when the total resources required are large and there is a higher probability of failure. We can just divvy up the work into states that act like idempotent functions. Below is a great simplification of the actual project I worked on but I wanted to boil it down to its simplest form, eliminating excessive states that I have collapsed to the CreateResponse state.

In my original implementation, I modeled the requests as queued items (UserRequest) that I would dequeue and start work on.

foreach (var request in requests) // as IEnumerable
{
   switch (request.State)
   {
      case State.ReceiveRequest:
         if (TryReceiveRequest(request)) request.State = State.CreateResponse;
         break;
         
      case State.CreateResponse:
         if (TryCreateResponse(request)) request.State = State.SendResponse;
         break;

      case State.SendResponse:
         if (TrySendResponse(request)) request.State = State.ResponseSent;
         break;

      case State.ResponseSent:
         break;

      case State.Faulted:

      default:
         throw new ArgumentOutOfRangeException("request.State");
   }
   if (request.State != State.ResponseSent && request.State != State.Faulted)
      requests.Enqueue(request);
}

Seems simple enough, but in my case the CreateResponse state ended being fairly computationally intensive and could take anywhere from a few seconds to several minutes. These long delays could be due to the workload of remote processes it was waiting on, temporal failure points like the network or even the system the process was running on. Another added complexity was that these requests were being serviced in parallel, by multiple processes that could be on the same system or not. Lastly, actual production level code never ends up being this simple; you quickly find yourself adding a lot of instrumentation and covering of edge cases.

foreach (var request in requests)
{
   log.LogDebug("request.Id = {0}: Request dequeued in state {1}.", request.Id, request.State);
   switch (request.State)
   {
      case State.ReceiveRequest:
         logger.LogDebug("request.Id = {0}: Trying to receive request.", request.Id);
         if (TryReceiveRequest(request)) request.State = State.CreateResponsePart1;
         break;
         
      case State.CreateResponsePart1:
         logger.LogDebug("request.Id = {0}: Trying to create response for part 1.", request.Id);
         if (TryCreateResponsePart1(request)) request.State = State.CreateResponsePart2;
         break;

      case State.CreateResponsePart2:
         logger.LogDebug("request.Id = {0}: Trying to create response for part 2.", request.Id);
         if (TryCreateResponsePart2(request))
         {
            request.State = State.CreateResponsePart3;
         }
         else
         {
            request.State = State.CreateResponsePart1;
            ExecuteCreateResponsePart2Cleanup();
            logger.LogError("request.Id = {0}: Unexpected failure while evaluation create response part 2.", request.Id);
         }
         break;

      case State.CreateResponsePart3:
         logger.LogDebug("request.Id = {0}: Trying to create response for part 3.", request.Id);
         bool unrecoverable;
         if (TryCreateResponsePart3(request, out unrecoverable))
         {
            request.State = State.SendResponse;
         }
         else
         {
           if (unrecoverable)
           {
               logger.LogError("request.Id = {0}: Failure is unrecoverable, faulting request.", request.Id);
               request.State = State.Faulted;
           }
           else
           {
               request.State = State.CreateResponse2;
           }
         }
         break;

      case State.SendResponse:
         logger.LogDebug("request.Id = {0}: Trying to send response.", request.Id);
         if (TrySendResponse(request)) request.State = State.ResponseSent;
         break;

      case State.ResponseSent:
         break;

      case State.Faulted:
         logger.LogCritical("request.Id = {0}: Request faulted.", request.Id);
         break;

      default:
         throw new ArgumentOutOfRangeException("request.State");
   }
   log.LogDebug("request.Id = {0}: Request transitioned to state {1}.", request.Id, request.State);
   if (request.State != State.ResponseSent && request.State != State.Faulted)
   {
      logger.LogDebug("request.Id = {0}: Re-enqueuing request for further evaluation.", request.Id);
      requests.Enqueue(request);
   }
   else
   {
      logger.LogDebug("request.Id = {0}: Request evaluation is complete, not re-enqueuing.", request.Id);
   }
}

What a mess! This code quickly starts getting bloated. In addition, not every state evaluation will be successful and be considered exceptional. Maybe it is polling another process and can't transition until that process is ready. As the result of each state evaluation changes beyond a simple yes/no (true/false), we end up with a state machine that could have multiple transitions. This makes for ugly code and too much coupling. All the state evaluation logic is in the same class and you have this huge switch statement. We could get around the extensive logging by using dependency injection but what do we inject? There is no consistent call site signature to inject to. The ever growing case statements could be extracted into their own method, but then readability suffers. This sucks.

You may be saying, "Well you obviously could solve it by ..." and I would agree with you. This code ugliness could be solved many different ways, and is intentionally crap for the purpose of this post. The major problems I faced was:

  • A large state machine object and large code blocks.
  • Lack of symmetry in state handling.
  • Multiple method postconditions that couldn't be expressed by the boolean return result alone.
  • Coupling of state transition logic, business logic and diagnostics.

I knew something was wrong but I wasn't quite sure how to solve it without adding more complexity to the system and allowing readability to suffer. As someone who has had to spend hours reading other people's unreadable code, I didn't want to commit the same sin.

Looking For A Solution

In university, they teach you how to be a good Computer Scientist; you learn complexity analysis, synthetic languages and the theoretical underpinning of computation. Although, none of this really prepares you to be a software engineer. I could concoct my own system, by why do this when I can stand on the shoulders of giants.

I always read or heard references to the Gang of Four book, even listened to talks by the original authors and became familiar with some of the more famous patterns (Factory and Singleton come to mind). Maybe there was a solution in there. I can't be the first one to come across this simple design problem. So there I found it in the State design pattern.

The design is pretty simple. You have a context that is used by the end user, and the states themselves wrapped by the context. The context can have a range of methods that behave differently based on the concrete state type being used at that moment (eg. behavior of a cursor click in a graphics editor). I modified this design, using a single method to abstract workflow and act as a procedural agent for processing multiple state machines.

The Code

The first step was to construct a state object that will be the super type to all of my concrete states.

public abstract class StateBase   
{
   // Let the concrete type decide what the next transition state will be.
   protected abstract StateBase OnExecute();  

   public StateBase Execute()
   {
      // Can add diagnostic information here.
      return this.OnExecute();   
   }   
}

Next I need a context class that can create and run the state machine.

public abstract class StateContextBase
{
   private StateBase state;   

   protected abstract StateBase OnCreate();
   protected abstract StateBase OnExecuted(StateBase nextState);
   protected abstract bool OnIsRunning(StateBase state);

   public StateContextBase(StateBase state)
   {
      this.state = state;
   }

   public StateContextBase Execute()
   {
      // Need to create the state machine from something.
      if (this.state == null)
      {
         // We will get to this later.
         this.state = this.OnCreate();
      }
      // Let the concrete context decide what to do after a state transition.
      this.state = this.OnExecuted(state.Execute());
      return this;
   } 
 
   public bool IsRunning()
   {
      // Have the concrete type tell us when it is in the final state.
      return this.OnIsRunning(this.state);
   }
}

While glossing over the details, what will this look like at the application's entry point.

class Program
{
   static void Main(string[] args)
   {
      // Will need to get it from somewhere but won't worry about this for now.
      var requests = Enumerable.Empty<StateContextBase>();

      // Can be changed to false on an exit call.
      var running = true;
      while (running)
      {    
         requests = requests
            .Where(r => r.IsRunning())
            .Select(r => r.Execute());
      }
   }
}

That is beautiful! All I see is the state machine decider logic and I don't even need to be concerned with what type of state machines are running.

So let's dive into the details. First, there is the creation of the state into memory. We have to get this from somewhere, so let's add another abstraction on top of our StateBase super type. Something that can be persisted in case the process crashes and can be accessed across many systems (eg. database).

In my case, I used the Entity Framework ORM, which is based off of the unit of work and repository design patterns. There is a context (DataContext) that I will get my model object (UserRequest) from to figure out the current state. A unique key (UserRequest.Id : Guid) will be used to identify the persisted object. We won't concern ourselves as to why this is just unique and not an identity key (that could be in another post) but it basically comes down to the object's initial creation at runtime not relying on any persistence store for uniqueness.

public class DataContext
   : System.Data.Entity.DbContext
{
   public DbSet UserRequests { get; set; }

   public DataContext()
      : base("name=DataContext")
   {
   }
}
public abstract class PersistedStateBase<TEntity>
   : StateBase
   where TEntity : class
{
   private Guid id;

   protected abstract StateBase OnExecuteCommit(DataContext context, Guid id, TEntity entity);
   protected abstract TEntity OnExecuteCreate(DataContext context, Guid id);
   protected abstract StateBase OnExecuteRollback(DataContext context, Guid id, TEntity entity);

   public PersistedStateBase(Guid id)
   {
      this.id = id;
   }

   protected override StateBase OnExecute()
   {
      // Also consider exceptions thrown by DataContext.
      StateBase nextState = this;
      using (var context = new DataContext())
      {
         TEntity entity = null;
         try
         {
            entity = this.OnExecuteCreate(context, this.id);
            nextState = this.OnExecuteCommit(context, this.id, entity);
            context.SaveChanges();
         }
         catch (Exception ex)
         {
            // Handle exception.
            nextState = this.OnExecuteRollback(context, this.id, entity);
         }
      }
      return nextState;
   }
}

The model object (UserRequest, our entity type) will hold the state as an enumeration (UserRequest.State) and contain all the data needed for processing through the state machine.

public enum UserRequestState
{
   None = 0,  
   Receive = 1,  
   CreateResponse = 3,
   SendResponse = 4,
   ResponseSent = 5,
   Faulted = -1,  
}
[DataContract]
public class UserRequest
{
   [DataMember]
   public Guid Id { get; private set; }
   [DataMember]
   public UserRequestState State { get; private  set; }

   // Other properties here like the location of the user request and other metadata.

   private UserRequest()  // Required by EF to create the POCO proxy.
   {}

   public UserRequest(Guid id, UserRequestState state)
   {
      this.Id = id;
      this.State = state;
   }
}

Now let's implement our first state using the types we have created.

public class ReceiveState
   : PersistedStateBase<UserRequest>
{
   public ReceiveState(Guid id)
      : base(id)
   {}
  
   protected override StateBase OnExecuteCommit(DataContext context, Guid id, UserRequest entity)
   {      
      var successful = false;
      var faulted = false;
      // Receive user request and decide whether successful, unsuccessful with retry or
      // unrecoverable/faulted. 
      if (successful)
      {
         return new CreateResponseState(id);
      }
      else
      {
         return faulted ? new FaultedState(id) : this;
      }
   }

   protected override UserRequest OnExecuteCreate(DataContext context, Guid id)
   {
      // Get model object
      return context.UserRequests.Find(id);
   }

   protected override StateBase OnExecuteRollback(DataContext context, Guid id, UserRequest entity)
   {
      // Rollback any changes possibly made in the OnExecuteCommit method and attempt recovery,
      // if possible, in this method. For this example, we will just return the current state.
      return this;
   }
}

We need to also make our state context concrete with the type below. This tends to have more wiring since type per state doesn't really translate well in an ORM. This class could be greater simplified with attributes on the state types, designating the enumeration value they map to.

public class UserRequestContext
   : StateContextBase
{
   private static Dictionary<Type, UserRequestState> typeToDbState;
   private static bool databaseRead = false;

   public Guid Id { get; private set; }

   static UserRequestContext()
   {
      databaseRead = false;
      typeToDbState = new Dictionary<Type, UserRequestState>()
      {
         { typeof(ReceiveState), UserRequestState.Receive },
         { typeof(CreateResponseState), UserRequestState.CreateResponse},
         { typeof(SendResponse), UserRequestState.SendResponse},
         { typeof(ResponseSent), UserRequestState.ResponseSent},
         { typeof(FaultedState), UserRequestState.Faulted },
      };
   }

   public UserRequestContext(Guid id)
      : base(null)
   {
      this.Id = id;
   }

   public static IEnumerable<Guid> GetRunningIds()
   {
      if (UserRequestContext.databaseRead)
      {
         var ids = Enumerable.Empty<Guid>(); // Get from message queue.    
         return ids;
      }
      else
      {
         using (var dataContext = new DataContext())
         {
            var ids = dataContext.UserRequests
               .Where(u => 
                  u.State != UserRequestState.ResponseSent &&
                  u.State != UserRequestState.Faulted)
               .Select(u => u.Id)
               .ToArray(); // Force evaluation.

            UserRequestContext.databaseRead = true;

            return ids;
         }
      }
   }

   protected override bool OnIsRunning(StateBase state)
   {
      return !(state is CompleteState);
   }

   protected override StateBase OnCreate()
   {
      using (var dataContext = new DataContext())
      {
         // Maps persisted state enumeration to runtime types.
         var entity = dataContext.UserRequests.Find(this.Id);
         switch (entity.State)
         {
            case UserRequestState.Receive:
               return new ReceiveState(this.Id);

            case UserRequestState.CreateResponse:
               return new CreateResponseState(this.Id);

            case UserRequestState.SendResponse:
               return new SendResponseState(this.Id);

            case UserRequestState.ResponseSent:
               return new ResponseSentState(this.Id);

            case UserRequestState.Faulted:
               return new FaultedState(this.Id);

            default:
               throw new ArgumentOutOfRangeException();
         }
      }
   }

   protected override StateBase OnExecuted(StateBase nextState)
   {
      // Run any other deciding logic in here that is independent 
      // of the states themselves (eg. logging, perf counters).

      return nextState;      
   }
}

Finally, let's come full circle and show what the application entry point will look like once all is said and done.

class Program
{
   static void Main(string[] args)
   {
      var requests = Enumerable.Empty<StateContextBase>();

      var running = true;
      while (running)
      {         
         requests = requests
            .Where(r => r.IsRunning())
            // Append new user requests found.
            .Concat((IEnumerable)UserRequestContext
               .GetRunningIds()
               .Select(i => new UserRequestContext(i)));
            .Select(r => r.Execute());
      }
   }
}

Ahhhh Yeah...

After fleshing it all out, I really got that satisfying feeling you get as a software engineer when you know that you made the right design decisions. I isolated my business logic into their own types (eg. ReceiveRequestState), separated it from the state machine transition logic, added symmetrical handling of persistence logic by layering it on top of the state type (PersistedStateBase) and contained the persistence-runtime bridge (from UserRequest to PersistedStateBase subtypes) into its own type (UserRequestContext). If I want to add more states, I can simply add to the model's state enumeration (UserRequest.State) and update the state context (UserRequestContext). If I want to change the transition logic, all I need to do is go to the concrete state type itself (eg. ReceiveRequestState) and feel confident that my variables are all scoped correctly. No coupling, no excessive mutations and no excessive side effects.

Using The Right Tool

This design pattern isn't for every state machine problem. In simple cases, it can definitely be overkill; you can see a bit of starter code is needed. Although, if you find yourself designing a state machine with multiple outbound transitions and final states, this could be the right modified pattern for you.

More Reading & Resources

Wednesday, April 10, 2013

PCAP-NG reader for .NET.

Introduction & Scope

The PCAP-NG file format is used to store network captured data used by great programs like Wireshark. There are several API's available for both Linux and Windows but none that are ported to .NET. I decided to make one for my own use in building a network traffic replay agent.

This code demonstrates an approach to reading in PCAP-NG files. Most of the time I was concerned with the enhanced packet block type since it stored the TCP payloads I wanted to replay.

Design Considerations

All block types derive from a common abstract class (BlockBase). This is useful when you need a collection of blocks with different subtypes, as in the second code segments below. Internally, all classes populate themselves from the underlying binary reader.

The reader class can be used to iterate over a single block type.

var reader = new PcapngFile.Reader("test.pcapng");   
foreach (var packet in reader.EnhancedPackets)
{
   byte[] payload = packet.Data;
}

... or all of them, cast into their parent type.

var blocks = new List<PcapngFile.BlockBase>();
while (reader.PeekStoreType() != PcapngFile.BlockType.None)
{
   blocks.Add(reader.ReadBlock());
}

The Code and NuGet Package

Get access to the complete project here on my GitHub account. If you have any suggestions or comments, feel free to leave a comment. I also have the assembly available via NuGet here.

More Reading & Resources

Wednesday, October 3, 2012

Reading and writing large binary data in T-SQL and ADO.NET.

Introduction

In some cases, you may want to read/write binary data from/to your relational database. This can be a problem when the data set size exceeds the memory address size (eg. 32-bit processes) or the managed large object heap cannot load it all without throwing an OutOfMemoryException. In those cases, you will need to load the data into memory in chunks. Fortunately, the T-SQL syntax supports this operation.

Latest Standard

The old standard for reading and writing raw text data was by using the UPDATETEXT, READTEXT and TEXTPTR commands. Although, these are being obsoleted for the newer command SUBSTRING and the addition of the .WRITE argument to the UPDATE command. I found the newer syntax much easier to use and requiring less parameters. Below is an example schema and implementation.

Example Schema

For this example, we will use a very simple table setup with a primary key and binary data column.

CREATE TABLE [dbo].[DataTable] (
 [Id] [int] IDENTITY(1,1) NOT NULL,
 [Data] [varbinary](max) NOT NULL
)

Example Code

The Read method simply provides an offset into the data and the size of the chunk it wishes to read. The same applies for the Write method, except that a data argument is also supplied.

private const int ReadChunkSize = 1 << 21;   // 2MB Chunks
private const int WriteChunkSize = 1 << 21;  // 2MB Chunks

...

public static void Read(string connectionString, string readPath)
{
    using (var connection = new SqlConnection(connectionString))
    {
        int offsetIndex = 0;
        var buffer = new byte[1];
        var offset = new SqlParameter("@Offset", SqlDbType.Int, 32);
        var command = new SqlCommand(@"SELECT SUBSTRING([Data], @Offset, " + ReadChunkSize + ") FROM [dbo].[DataTable] WHERE [Id] = 1", connection);

        command.Parameters.Add(offset);

        connection.Open();

        using (var stream = File.Create(readPath))
        {
            using (var writer = new BinaryWriter(stream))
            {
                while (buffer.Length > 0)
                {
                    offset.Value = offsetIndex;
                    buffer = (byte[])command.ExecuteScalar();
                    if (buffer.Length > 0)
                    {
                        writer.Write(buffer);
                        offsetIndex += ReadChunkSize;
                    }
                }
            }
        }
    }
}

public static void Write(string connectionString, string writePath)
{
    using (var connection = new SqlConnection(connectionString))
    {
        int offsetIndex = 0;
        var buffer = new byte[1];
        var offset = new SqlParameter("@Offset", SqlDbType.Int, 32);
        var data = new SqlParameter("@Data", SqlDbType.Binary, WriteChunkSize);
        var command = new SqlCommand(@"UPDATE [dbo].[DataTable] SET [Data] .WRITE(@Data, @Offset, " + WriteChunkSize + ") WHERE [Id] = 1", connection);

        command.Parameters.Add(offset);
        command.Parameters.Add(data);

        connection.Open();

        using (var stream = File.OpenRead(writePath))
        {
            using (var reader = new BinaryReader(stream))
            {
                while (buffer.Length > 0)
                {
                    buffer = reader.ReadBytes(WriteChunkSize);
                    if (buffer.Length > 0)
                    {
                        offset.Value = offsetIndex;
                        data.Value = buffer;
                        command.ExecuteNonQuery();
                        offsetIndex += WriteChunkSize;
                    }
                }
            }
        }
    }
}

Performance Considerations

When benchmarking my code against the simple database schema, execution time was drastically different if the data was already read into memory. When a read was performed after a write, it took 2 seconds. A read without a write beforehand took about 10 seconds. This is also the same time that the write took before a read. The chunk size did not seems to have any significant impact when adjusted between 512K and 4MB sizes. Your results may vary though depending on your system's memory layout.

These time benchmarks are very informal and highly dependent on system architecture, network latency and hardware specifications. Although, the relative performance gain between the two benchmarks can be gleaned from these tests.

A further performance gain would be to front load the data into memory on a separate thread and process the loaded data into and out of the database on another. This would require some tweaking and knowledge of the system's memory constraints to ensure it doesn't become a performance bottleneck. If properly done, a lot can be gained from not having to block on I/O between every chunk read and write.

Tuesday, September 18, 2012

IMAPI version 2 managed wrapper.

Introduction

Microsoft introduced native image mastering support in Vista, going forward. The library itself is not too complex but the latest version of the image mastering API (IMAPI) has some quirks. This is well documented by Eric Haddan in his article describing how to build an interop file and use it from .NET.

Implementation

I wanted to take it a step further and provide a library wrapper that was CLI compliant. The end result is a class that provides 3 methods, called in order, to burn an image. The project can be found on my GitHub account.

Properties

  • Media: A read only property that populates after the LoadMedia call and reports what type of physical media is connected (eg. CD-R, DVD-R, DVD+RW, etc.).
  • MediaStates: A read only collection of states in which the media is under, that populates after the LoadMedia call (eg. is blank, overwriteable, unsupported).
  • MediaCapacity: A read only property that populates after the LoadMedia call and reports the size capacity of the media.
  • Nodes: A root list of file and directory nodes that are to be written to the media.
  • Recorders: A read only selectable collection. A recorder must be selected for the LoadRecorder call.
  • VolumeLabel: A property that sets the volume label of the media to be written to.

Methods

  • LoadRecorder: Verifies a recorder is selected, loads the recording drive resources and verifies that it is working.
  • LoadMedia: Loads the media resource and verifies that it is valid for the recorder. An exception will occur if the media isn't supported (eg. closed session disc, no disc present).
  • FormatMedia: Formats the media of any previous data.
  • WriteImage: The final step to write your files to disc. This is a blocking call.

Events

  • FormatEraseUpdate: Reports progress of FormatMedia call.
  • FormatWriteUpdate: Reports progress of files being written to the media.
  • ImageUpdate: Reports progress of files being added to the media image.

Caveats

I use this library for the simple single purpose of writing finalized images to a blank CD. It has not been fully tested to accomodate all media and recorder state scenarios; I haven't tried it yet with DVD's or multi-session discs. If you would like to extend the library, feel free to push some changes to the GitHub project and I will wrap them in.

I decided to leave the method calls as blocking (synchronous) since there could be many different synchronization models that may use this library. For my purposes, I used this in an WPF application that would call the WriteImage method from a Task and then post back the progress events of the write using the Dispatcher from my WPF window. Below is a code snippet demonstrating this.

private ImageMaster _burner;

...

private void _CreateCd()
{
 // files added to _burner and _burner.WriteImage called
}

private void _burner_FormatWriteUpdate(IMAPI2.ImageMaster sender, IMAPI2.FormatWriteUpdateEventArgs e)
{
 this.Dispatcher.Invoke(() => this.statusProgressBar.Value == (e.ElapsedTime / e.TotalTime) * 100);
}

private void CreateCdWindow_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
 System.Threading.Tasks.Task.Factory.StartNew(_CreateCd);
}

Wednesday, August 17, 2011

Writing a TEDS (IEEE 1451.4) parser.

I was tasked recently with writing a parser for TEDS bit stream data. There is an IEEE published paper with an overview of the standard but it doesn't give any examples for implementation. I was finally able to find a paper that gave examples but still had trouble parsing the data. I finally realized there is not only 2 selector bits after the basic TEDS block but selector bits inside the standard template (2 in the case of template 25). Here are my main findings:

  • It depends on the software interface to get the bit-stream, but bits usually start their indexing from left to right. If you are using a language that assumes right to left bit encoding, the stream indices will need to be reversed (eg. 010110002 translates to 00011010= 2610).
  • If you are using an little-endian architecture (eg. x86), then the byte order will need to be converted from big-endian (reverse the byte indices). It is big-endian since the standard is defined for networks and thus has a network byte order.
  • To calculate ConRelRes values, use the formula...
    <start_value> * [1 + 2 * <tolerance>] ^ <teds_value>
    In the published paper, you will see an entry like ConRelRes(5E-7 to 172, +- 0.15%) in the "Data Type (and Range)" field. 5E-7 is the start value, 0.15 is the tolerance and the TEDS value is whatever value gets parsed from the bit stream.

Here are some helper functions to parse TEDS correctly on the .NET platform (x86 systems).
int _streamOffset = 0;

private System.Collections.BitArray _GetBits(System.Collections.BitArray bits, int length)
{
 System.Collections.BitArray result = new System.Collections.BitArray(length);
 for (int index = 0; index <= length - 1; index++) {
  result[index] = bits[_streamOffset + index];
 }
 return result;
}
private byte[] _GetBytes(System.Collections.BitArray bits)
{
 int byteCount = Convert.ToInt32(Math.Ceiling(bits.Count / 8));
 int padCount = (byteCount * 8) - bits.Count;
 byte[] bytes = new byte[byteCount];
 int byteIndex = 0;
 int bitIndex = 0;
 System.Collections.BitArray reverseBits = new System.Collections.BitArray(bits.Count + padCount);

 //byte align new bit array
 for (int index = 0; index <= padCount - 1; index++) {
  reverseBits[index] = false;
 }
 //reverse bits to read from right to left
 for (int index = 0; index <= bits.Length - 1; index++) {
  reverseBits[padCount + index] = bits[bits.Length - 1 - index];
 }

 //create byte array from byte aligned right to left bits
 for (int index = 0; index <= reverseBits.Count - 1; index++) {
  if ((reverseBits[index])) {
   bytes[byteIndex] = bytes[byteIndex] | Convert.ToByte(1 << (7 - bitIndex));
  }

  bitIndex += 1;
  if ((bitIndex == 8)) {
   bitIndex = 0;
   byteIndex += 1;
  }
 }

 return bytes;
}

private bool _GetBoolean(System.Collections.BitArray bits)
{
 bool result = bits[_streamOffset];
 _streamOffset += 1;
 return result;
}
private char _GetChar(System.Collections.BitArray bits, int length)
{
 char result = BitConverter.ToChar(new byte[] {
  0,
  _GetBytes(_GetBits(bits, length))[0]
 }, 0);
 _streamOffset += length;
 return result;
}
private int _GetInteger(System.Collections.BitArray bits, int length)
{
 byte[] intBytes = new byte[] {
  0,
  0,
  0,
  0
 };
 byte[] bytes = _GetBytes(_GetBits(bits, length));
 int result = 0;
 //pad out rest of bytes so it is int32 aligned and convert endianess
 for (int index = 0; index <= bytes.Length - 1; index++) {
  intBytes[index] = bytes[bytes.Length - 1 - index];
 }
 result = Convert.ToInt32(BitConverter.ToUInt32(intBytes, 0));
 _streamOffset += length;
 return result;
}