<|start_filename|>docs/custom/index.html<|end_filename|>

<!doctype html>
<html lang="en" class="no-js">
  <head>
    
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1">
      
      
      
      
      <link rel="shortcut icon" href="../assets/images/favicon.png">
      <meta name="generator" content="mkdocs-1.1.2, mkdocs-material-6.1.7">
    
    
      
        <title>Custom Types - BitStream</title>
      
    
    
      <link rel="stylesheet" href="../assets/stylesheets/main.19753c6b.min.css">
      
        
        <link rel="stylesheet" href="../assets/stylesheets/palette.196e0c26.min.css">
        
      
    
    
    
      
        
        <link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700%7CRoboto+Mono&display=fallback">
        <style>body,input{font-family:"Roboto",-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono",SFMono-Regular,Consolas,Menlo,monospace}</style>
      
    
    
    
    
      
    
    
  </head>
  
  
    
    
    
    
    
    <body dir="ltr" data-md-color-scheme="" data-md-color-primary="none" data-md-color-accent="none">
      
  
    <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
    <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
    <label class="md-overlay" for="__drawer"></label>
    <div data-md-component="skip">
      
        
        <a href="#custom-types" class="md-skip">
          Skip to content
        </a>
      
    </div>
    <div data-md-component="announce">
      
    </div>
    
      

<header class="md-header" data-md-component="header">
  <nav class="md-header-nav md-grid" aria-label="Header">
    <a href=".." title="BitStream" class="md-header-nav__button md-logo" aria-label="BitStream">
      
  
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 003-3 3 3 0 00-3-3 3 3 0 00-3 3 3 3 0 003 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54z"/></svg>

    </a>
    <label class="md-header-nav__button md-icon" for="__drawer">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2z"/></svg>
    </label>
    <div class="md-header-nav__title" data-md-component="header-title">
      
        <div class="md-header-nav__ellipsis">
          <span class="md-header-nav__topic md-ellipsis">
            BitStream
          </span>
          <span class="md-header-nav__topic md-ellipsis">
            
              Custom Types
            
          </span>
        </div>
      
    </div>
    
      <label class="md-header-nav__button md-icon" for="__search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0116 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 019.5 16 6.5 6.5 0 013 9.5 6.5 6.5 0 019.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
      </label>
      
<div class="md-search" data-md-component="search" role="dialog">
  <label class="md-search__overlay" for="__search"></label>
  <div class="md-search__inner" role="search">
    <form class="md-search__form" name="search">
      <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" data-md-state="active" required>
      <label class="md-search__icon md-icon" for="__search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0116 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 019.5 16 6.5 6.5 0 013 9.5 6.5 6.5 0 019.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
      </label>
      <button type="reset" class="md-search__icon md-icon" aria-label="Clear" data-md-component="search-reset" tabindex="-1">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>
      </button>
    </form>
    <div class="md-search__output">
      <div class="md-search__scrollwrap" data-md-scrollfix>
        <div class="md-search-result" data-md-component="search-result">
          <div class="md-search-result__meta">
            Initializing search
          </div>
          <ol class="md-search-result__list"></ol>
        </div>
      </div>
    </div>
  </div>
</div>
    
    
      <div class="md-header-nav__source">
        
<a href="https://github.com/boisgera/bitstream/" title="Go to repository" class="md-source">
  <div class="md-source__icon md-icon">
    
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05L244 40.45a28.87 28.87 0 00-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 01-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 000 40.81l195.61 195.6a28.86 28.86 0 0040.8 0l194.69-194.69a28.86 28.86 0 000-40.81z"/></svg>
  </div>
  <div class="md-source__repository">
    bitstream
  </div>
</a>
      </div>
    
  </nav>
</header>
    
    <div class="md-container" data-md-component="container">
      
      
        
      
      <main class="md-main" data-md-component="main">
        <div class="md-main__inner md-grid">
          
            
              <div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    

<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
  <label class="md-nav__title" for="__drawer">
    <a href=".." title="BitStream" class="md-nav__button md-logo" aria-label="BitStream">
      
  
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 003-3 3 3 0 00-3-3 3 3 0 00-3 3 3 3 0 003 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54z"/></svg>

    </a>
    BitStream
  </label>
  
    <div class="md-nav__source">
      
<a href="https://github.com/boisgera/bitstream/" title="Go to repository" class="md-source">
  <div class="md-source__icon md-icon">
    
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05L244 40.45a28.87 28.87 0 00-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 01-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 000 40.81l195.61 195.6a28.86 28.86 0 0040.8 0l194.69-194.69a28.86 28.86 0 000-40.81z"/></svg>
  </div>
  <div class="md-source__repository">
    bitstream
  </div>
</a>
    </div>
  
  <ul class="md-nav__list" data-md-scrollfix>
    
      
      
      


  <li class="md-nav__item">
    <a href=".." class="md-nav__link">
      Overview
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../examples/" class="md-nav__link">
      Examples
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../installation/" class="md-nav__link">
      Installation
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../types/" class="md-nav__link">
      Built-in Types
    </a>
  </li>

    
      
      
      

  


  <li class="md-nav__item md-nav__item--active">
    
    <input class="md-nav__toggle md-toggle" data-md-toggle="toc" type="checkbox" id="__toc">
    
      
    
    
      <label class="md-nav__link md-nav__link--active" for="__toc">
        Custom Types
        <span class="md-nav__icon md-icon"></span>
      </label>
    
    <a href="./" class="md-nav__link md-nav__link--active">
      Custom Types
    </a>
    
      
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
  
  
    
  
  
    <label class="md-nav__title" for="__toc">
      <span class="md-nav__icon md-icon"></span>
      Table of contents
    </label>
    <ul class="md-nav__list" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#definition" class="md-nav__link">
    Definition
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#registration" class="md-nav__link">
    Registration
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#factories" class="md-nav__link">
    Factories
  </a>
  
</li>
      
    </ul>
  
</nav>
    
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../snapshots/" class="md-nav__link">
      Snapshots
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../API/" class="md-nav__link">
      API Reference
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../contributing/" class="md-nav__link">
      Contributing
    </a>
  </li>

    
  </ul>
</nav>
                  </div>
                </div>
              </div>
            
            
              <div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
  
  
    
  
  
    <label class="md-nav__title" for="__toc">
      <span class="md-nav__icon md-icon"></span>
      Table of contents
    </label>
    <ul class="md-nav__list" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#definition" class="md-nav__link">
    Definition
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#registration" class="md-nav__link">
    Registration
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#factories" class="md-nav__link">
    Factories
  </a>
  
</li>
      
    </ul>
  
</nav>
                  </div>
                </div>
              </div>
            
          
          <div class="md-content">
            <article class="md-content__inner md-typeset">
              
                
                  <a href="https://github.com/boisgera/bitstream/edit/master/mkdocs/custom.md" title="Edit this page" class="md-content__button md-icon">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z"/></svg>
                  </a>
                
                
                <h1 id="custom-types">Custom Types<a class="headerlink" href="#custom-types" title="Permanent link">&para;</a></h1>
<p>This section explains how to deal with a data type or a binary coding 
that bitstream does not support natively: how to define bitstream 
writer and reader functions and register them so that your custom
types behave like native ones.</p>
<pre><code>&gt;&gt;&gt; import sys
&gt;&gt;&gt; import bitstream
&gt;&gt;&gt; from bitstream import BitStream
</code></pre>
<p>We use the example of representation of unsigned integers 
as binary numbers;
out of the box, bitstream only supports unsigned integers of fixed size 
(refer to <a href="../types/#integers">Built-in Types / Integers</a> for details).</p>
<h2 id="definition">Definition<a class="headerlink" href="#definition" title="Permanent link">&para;</a></h2>
<p>For every type of data that we want bitstream to support, 
we need to specify at least one writer function that
encodes the data as a bitstream and one reader function
that decodes data out of bitstreams.</p>
<p>The signature of writers is</p>
<pre><code>def writer(stream, data)
</code></pre>
<p>where</p>
<ol>
<li>
<p><code>stream</code> is a <code>BitStream</code> instance,</p>
</li>
<li>
<p>the type of <code>data</code> is writer-dependent.</p>
</li>
</ol>
<p>A writer is totally free to specify what is a valid <code>data</code>,
but it is sensible to accept:</p>
<ul>
<li>
<p>instances of a reference data type (or some of these instances),</p>
</li>
<li>
<p>data that can be safely converted to the reference data type,</p>
</li>
<li>
<p>sequences (lists, arrays, etc.) of the reference type (or assimilated).</p>
</li>
</ul>
<p>A writer should raise an exception (<code>ValueError</code> or <code>TypeError</code>) 
when the data is invalid.</p>
<hr />
<p>To write unsigned integers as binary numbers for example,
we can consider as valid anything any non-negative integer-like
data (defined as anything that the constructor <code>int</code> accepts) 
as well as lists of such data.</p>
<pre><code>&gt;&gt;&gt; def write_uint(stream, data):
...     if isinstance(data, list):
...         for integer in data:
...             write_uint(stream, integer)
...     else:
...         integer = int(data)
...         if integer &lt; 0:
...             error = "negative integers cannot be encoded"
...             raise ValueError(error)
...         bools = []
...         while integer:
...             bools.append(integer &amp; 1)
...             integer = integer &gt;&gt; 1
...         bools.reverse()
...         stream.write(bools, bool)
</code></pre>
<p>This writer behaves as expected:</p>
<pre><code>&gt;&gt;&gt; stream = BitStream()
&gt;&gt;&gt; write_uint(stream, 42)
&gt;&gt;&gt; stream
101010
&gt;&gt;&gt; write_uint(stream, [1, 2, 3])
&gt;&gt;&gt; stream
10101011011
&gt;&gt;&gt; write_uint(stream, -1)
Traceback (most recent call last):
...
ValueError: negative integers cannot be encoded
&gt;&gt;&gt; write_uint(stream, {}) # doctest: +ELLIPSIS
Traceback (most recent call last):
...
TypeError: int() argument must be ..., not 'dict'
</code></pre>
<hr />
<p>The signature of readers is:</p>
<pre><code>def reader(stream, n=None)
</code></pre>
<p>where</p>
<ul>
<li>
<p><code>stream</code> is a <code>BitStream</code> instance,</p>
</li>
<li>
<p><code>n</code> is a non-negative integer (or <code>None</code>).</p>
</li>
</ul>
<p>The call <code>read(stream, n)</code> should read <code>n</code> data items 
out of <code>stream</code> when <code>n</code> is an integer. 
However, bitstream does not require a specific type of container 
(list, array, string, etc.), the choice is all yours;
for consistency however, you should pick a type of container
that your writer supports.</p>
<p>The semantics of call <code>read(stream)</code> (when <code>n=None</code>) is up to you; 
for most of built-in types, it returns a single (unboxed) datum of
the stream but there are sometimes good reasons to decide otherwise
(see for example <a href="../types/#strings">strings</a>).
The support for this default case is not mandatory.</p>
<p>Actually, readers may support only a subset of the possible values of <code>n</code>;
for example they may allow only <code>n=1</code> and <code>n=None</code>.
If a reader is called with an invalid value of <code>n</code>,
a <code>ValueError</code> or <code>TypeError</code> exception should be raised. 
If instead the <code>read</code> fails because there is not enough 
data in the stream or more generally if the binary data
cannot be decoded, a <code>ReadError</code> (from <code>bitstream</code>) should 
be raised.</p>
<hr />
<p>When we represent unsigned integers as binary numbers,
while we can write multiple integers in the same stream,
we cannot read unambiguously multiple integers from the 
stream: the code is not <em>self-delimiting</em>. 
For example <code>110</code> can be split as <code>1</code> then <code>10</code>
and code for the integers <code>1</code> and <code>2</code> but also 
as <code>11</code> and <code>0</code> which represent the integers <code>3</code> and <code>0</code>.</p>
<p>Thus, we design a reader that reads the whole stream as a single 
integer: we support only the cases <code>n=1</code> 
and for convenience the default <code>n=None</code> with the same result.</p>
<p>A possible implementation of this reader is:</p>
<pre><code>&gt;&gt;&gt; def read_uint(stream, n=None):
...     if n is not None and not n == 1:
...         error = "unsupported argument n = {0!r}".format(n)
...         raise ValueError(error)
...     else:
...         integer = 0
...         for _ in range(len(stream)):
...             integer = integer &lt;&lt; 1
...             if stream.read(bool):
...                 integer += 1
...     return integer
</code></pre>
<p>It behaves as expected:</p>
<pre><code>&gt;&gt;&gt; stream = BitStream()
&gt;&gt;&gt; write_uint(stream, 42)
&gt;&gt;&gt; read_uint(stream)
42
&gt;&gt;&gt; write_uint(stream, [1, 2, 3]) 
&gt;&gt;&gt; read_uint(stream)
27
&gt;&gt;&gt; len(stream)
0
&gt;&gt;&gt; write_uint(stream, 42)
&gt;&gt;&gt; read_uint(stream, 1)
42
&gt;&gt;&gt; write_uint(stream, 42)
&gt;&gt;&gt; read_uint(stream, 2)
Traceback (most recent call last):
...
ValueError: unsupported argument n = 2
</code></pre>
<h2 id="registration">Registration<a class="headerlink" href="#registration" title="Permanent link">&para;</a></h2>
<p>To fully integrate unsigned integers into bitstream, 
you need to associate a unique type identifier to 
the reader and/or writer, 
This type identifier is usually a type;
a user-defined type with an empty 
definition will do:</p>
<pre><code>&gt;&gt;&gt; class uint(object):
...     pass
</code></pre>
<p>Once the type <code>uint</code> has been associated to the unsigned integer writer</p>
<pre><code>&gt;&gt;&gt; bitstream.register(uint, writer=write_uint)
</code></pre>
<p>we can use the <code>write</code> method of <code>BitStream</code> to encode unsigned integers</p>
<pre><code>&gt;&gt;&gt; stream = BitStream()
&gt;&gt;&gt; stream.write(42, uint)
&gt;&gt;&gt; stream
101010

&gt;&gt;&gt; stream = BitStream()
&gt;&gt;&gt; stream.write([2, 2, 2], uint)
&gt;&gt;&gt; stream
101010
</code></pre>
<p>and also the shorter former using the <code>BitStream</code> constructor</p>
<pre><code>&gt;&gt;&gt; BitStream(42, uint)
101010
&gt;&gt;&gt; BitStream([2, 2, 2], uint)
101010
</code></pre>
<p>Once the reader is registered</p>
<pre><code>&gt;&gt;&gt; bitstream.register(uint, reader=read_uint)
</code></pre>
<p>we can also use the <code>read</code> method of <code>BitStream</code>:</p>
<pre><code>&gt;&gt;&gt; BitStream(42, uint).read(uint)
42
</code></pre>
<p>Here, the <code>uint</code> type was merely an identifier for our reader and writer,
but "real" types can be used too. If you write some data whose type is
the type identifier of a writer, you don't need to specify explicitly the
type identifier in writes.</p>
<p>For example, if we also associate our writer with Python integers:</p>
<pre><code>&gt;&gt;&gt; bitstream.register(int, writer=write_uint)
&gt;&gt;&gt; if sys.version_info[0] == 2: # Python 2 has a 'long integer' type
...     bitstream.register(long, writer=write_uint)
</code></pre>
<p>then every Python integer will be automatically encoded with 
the <code>write_uint</code> writer</p>
<pre><code>&gt;&gt;&gt; BitStream(42)
101010
&gt;&gt;&gt; BitStream([2, 2, 2])
101010
</code></pre>
<h2 id="factories">Factories<a class="headerlink" href="#factories" title="Permanent link">&para;</a></h2>
<p>The coding of arbitrary unsigned integers as binary numbers 
doesn't allow us to represent unambiguously multiple numbers in a stream. However, if there is a known bound on the integers we use, we can
assign a sufficient numbers of bits to each integer, pad the
binary numbers with enough zeros of the left to use the same
number of bits and this code is self-delimiting.</p>
<p>However, to do that, we would have to define and register a new writer 
for every possible number of bits. 
Instead, we may register a single but configurable writer, defined
by a writer factory.</p>
<p>Let's define a type identifier factory <code>uint</code> whose instances 
hold a number of bits:</p>
<pre><code>&gt;&gt;&gt; class uint(object):
...     def __init__(self, num_bits):
...         self.num_bits = num_bits
</code></pre>
<p>Then, we define a writer factory: given an instance of <code>uint</code>, 
it returns a stream writer:</p>
<pre><code>&gt;&gt;&gt; def write_uint_factory(instance):
...     num_bits = instance.num_bits
...     def write_uint(stream, data):
...         if isinstance(data, list):
...             for integer in data:
...                 write_uint(stream, integer)
...         else:
...             integer = int(data)
...             if integer &lt; 0:
...                 error = "negative integers cannot be encoded"
...                 raise ValueError(error)
...             bools = []
...             for _ in range(num_bits):
...                 bools.append(integer &amp; 1)
...                 integer = integer &gt;&gt; 1
...             bools.reverse()
...             stream.write(bools, bool)
...     return write_uint
</code></pre>
<p>Finally, we register this writer factory with <code>bitstream</code>:</p>
<pre><code>&gt;&gt;&gt; bitstream.register(uint, writer=write_uint_factory)
</code></pre>
<p>To select a writer, we use the appropriate type identifier:</p>
<pre><code>&gt;&gt;&gt; BitStream(255, uint(8))
11111111
&gt;&gt;&gt; BitStream(255, uint(16))
0000000011111111
&gt;&gt;&gt; BitStream(42, uint(8))
00101010
&gt;&gt;&gt; BitStream(0, uint(16))
0000000000000000
</code></pre>
<p>The definition of a reader factory is similar:</p>
<pre><code>&gt;&gt;&gt; def read_uint_factory(instance):
...     num_bits = instance.num_bits
...     def read_uint(stream, n=None):
...         if n is None:
...             integer = 0
...             for _ in range(num_bits):
...                 integer = integer &lt;&lt; 1
...                 if stream.read(bool):
...                     integer += 1
...             return integer
...         else:
...             integers = [read_uint(stream) for _ in range(n)]
...             return integers
...     return read_uint
</code></pre>
<p>Once the reader factory is registered</p>
<pre><code>&gt;&gt;&gt; bitstream.register(uint, reader=read_uint_factory)
</code></pre>
<p>we can use the family of type identifiers in reads too:</p>
<pre><code>&gt;&gt;&gt; stream = BitStream([0, 1, 2, 3, 4], uint(8))
&gt;&gt;&gt; stream.read(uint(8))
0
&gt;&gt;&gt; stream.read(uint(8), 1)
[1]
&gt;&gt;&gt; stream.read(uint(8), 3)
[2, 3, 4]
</code></pre>
                
              
              
                


              
            </article>
          </div>
        </div>
      </main>
      
        
<footer class="md-footer">
  
    <div class="md-footer-nav">
      <nav class="md-footer-nav__inner md-grid" aria-label="Footer">
        
          <a href="../types/" class="md-footer-nav__link md-footer-nav__link--prev" rel="prev">
            <div class="md-footer-nav__button md-icon">
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
            </div>
            <div class="md-footer-nav__title">
              <div class="md-ellipsis">
                <span class="md-footer-nav__direction">
                  Previous
                </span>
                Built-in Types
              </div>
            </div>
          </a>
        
        
          <a href="../snapshots/" class="md-footer-nav__link md-footer-nav__link--next" rel="next">
            <div class="md-footer-nav__title">
              <div class="md-ellipsis">
                <span class="md-footer-nav__direction">
                  Next
                </span>
                Snapshots
              </div>
            </div>
            <div class="md-footer-nav__button md-icon">
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11H4z"/></svg>
            </div>
          </a>
        
      </nav>
    </div>
  
  <div class="md-footer-meta md-typeset">
    <div class="md-footer-meta__inner md-grid">
      <div class="md-footer-copyright">
        
        Made with
        <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
          Material for MkDocs
        </a>
      </div>
      
    </div>
  </div>
</footer>
      
    </div>
    
      <script src="../assets/javascripts/vendor.0ac82a11.min.js"></script>
      <script src="../assets/javascripts/bundle.f81dfb4d.min.js"></script><script id="__lang" type="application/json">{"clipboard.copy": "Copy to clipboard", "clipboard.copied": "Copied to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.placeholder": "Type to start searching", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.term.missing": "Missing"}</script>
      
      <script>
        app = initialize({
          base: "..",
          features: [],
          search: Object.assign({
            worker: "../assets/javascripts/worker/search.4ac00218.min.js"
          }, typeof search !== "undefined" && search)
        })
      </script>
      
    
  </body>
</html>

<|start_filename|>docs/snapshots/index.html<|end_filename|>

<!doctype html>
<html lang="en" class="no-js">
  <head>
    
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1">
      
      
      
      
      <link rel="shortcut icon" href="../assets/images/favicon.png">
      <meta name="generator" content="mkdocs-1.1.2, mkdocs-material-6.1.7">
    
    
      
        <title>Snapshots - BitStream</title>
      
    
    
      <link rel="stylesheet" href="../assets/stylesheets/main.19753c6b.min.css">
      
        
        <link rel="stylesheet" href="../assets/stylesheets/palette.196e0c26.min.css">
        
      
    
    
    
      
        
        <link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700%7CRoboto+Mono&display=fallback">
        <style>body,input{font-family:"Roboto",-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono",SFMono-Regular,Consolas,Menlo,monospace}</style>
      
    
    
    
    
      
    
    
  </head>
  
  
    
    
    
    
    
    <body dir="ltr" data-md-color-scheme="" data-md-color-primary="none" data-md-color-accent="none">
      
  
    <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
    <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
    <label class="md-overlay" for="__drawer"></label>
    <div data-md-component="skip">
      
        
        <a href="#snapshots" class="md-skip">
          Skip to content
        </a>
      
    </div>
    <div data-md-component="announce">
      
    </div>
    
      

<header class="md-header" data-md-component="header">
  <nav class="md-header-nav md-grid" aria-label="Header">
    <a href=".." title="BitStream" class="md-header-nav__button md-logo" aria-label="BitStream">
      
  
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 003-3 3 3 0 00-3-3 3 3 0 00-3 3 3 3 0 003 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54z"/></svg>

    </a>
    <label class="md-header-nav__button md-icon" for="__drawer">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2z"/></svg>
    </label>
    <div class="md-header-nav__title" data-md-component="header-title">
      
        <div class="md-header-nav__ellipsis">
          <span class="md-header-nav__topic md-ellipsis">
            BitStream
          </span>
          <span class="md-header-nav__topic md-ellipsis">
            
              Snapshots
            
          </span>
        </div>
      
    </div>
    
      <label class="md-header-nav__button md-icon" for="__search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0116 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 019.5 16 6.5 6.5 0 013 9.5 6.5 6.5 0 019.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
      </label>
      
<div class="md-search" data-md-component="search" role="dialog">
  <label class="md-search__overlay" for="__search"></label>
  <div class="md-search__inner" role="search">
    <form class="md-search__form" name="search">
      <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" data-md-state="active" required>
      <label class="md-search__icon md-icon" for="__search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0116 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 019.5 16 6.5 6.5 0 013 9.5 6.5 6.5 0 019.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
      </label>
      <button type="reset" class="md-search__icon md-icon" aria-label="Clear" data-md-component="search-reset" tabindex="-1">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>
      </button>
    </form>
    <div class="md-search__output">
      <div class="md-search__scrollwrap" data-md-scrollfix>
        <div class="md-search-result" data-md-component="search-result">
          <div class="md-search-result__meta">
            Initializing search
          </div>
          <ol class="md-search-result__list"></ol>
        </div>
      </div>
    </div>
  </div>
</div>
    
    
      <div class="md-header-nav__source">
        
<a href="https://github.com/boisgera/bitstream/" title="Go to repository" class="md-source">
  <div class="md-source__icon md-icon">
    
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05L244 40.45a28.87 28.87 0 00-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 01-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 000 40.81l195.61 195.6a28.86 28.86 0 0040.8 0l194.69-194.69a28.86 28.86 0 000-40.81z"/></svg>
  </div>
  <div class="md-source__repository">
    bitstream
  </div>
</a>
      </div>
    
  </nav>
</header>
    
    <div class="md-container" data-md-component="container">
      
      
        
      
      <main class="md-main" data-md-component="main">
        <div class="md-main__inner md-grid">
          
            
              <div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    

<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
  <label class="md-nav__title" for="__drawer">
    <a href=".." title="BitStream" class="md-nav__button md-logo" aria-label="BitStream">
      
  
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 003-3 3 3 0 00-3-3 3 3 0 00-3 3 3 3 0 003 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54z"/></svg>

    </a>
    BitStream
  </label>
  
    <div class="md-nav__source">
      
<a href="https://github.com/boisgera/bitstream/" title="Go to repository" class="md-source">
  <div class="md-source__icon md-icon">
    
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05L244 40.45a28.87 28.87 0 00-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 01-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 000 40.81l195.61 195.6a28.86 28.86 0 0040.8 0l194.69-194.69a28.86 28.86 0 000-40.81z"/></svg>
  </div>
  <div class="md-source__repository">
    bitstream
  </div>
</a>
    </div>
  
  <ul class="md-nav__list" data-md-scrollfix>
    
      
      
      


  <li class="md-nav__item">
    <a href=".." class="md-nav__link">
      Overview
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../examples/" class="md-nav__link">
      Examples
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../installation/" class="md-nav__link">
      Installation
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../types/" class="md-nav__link">
      Built-in Types
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../custom/" class="md-nav__link">
      Custom Types
    </a>
  </li>

    
      
      
      

  


  <li class="md-nav__item md-nav__item--active">
    
    <input class="md-nav__toggle md-toggle" data-md-toggle="toc" type="checkbox" id="__toc">
    
      
    
    
      <label class="md-nav__link md-nav__link--active" for="__toc">
        Snapshots
        <span class="md-nav__icon md-icon"></span>
      </label>
    
    <a href="./" class="md-nav__link md-nav__link--active">
      Snapshots
    </a>
    
      
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
  
  
    
  
  
    <label class="md-nav__title" for="__toc">
      <span class="md-nav__icon md-icon"></span>
      Table of contents
    </label>
    <ul class="md-nav__list" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#lookahead" class="md-nav__link">
    Lookahead
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#exception-safety" class="md-nav__link">
    Exception Safety
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#multiple-snapshots" class="md-nav__link">
    Multiple Snapshots
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#how-does-it-work" class="md-nav__link">
    How does it Work?
  </a>
  
</li>
      
    </ul>
  
</nav>
    
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../API/" class="md-nav__link">
      API Reference
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../contributing/" class="md-nav__link">
      Contributing
    </a>
  </li>

    
  </ul>
</nav>
                  </div>
                </div>
              </div>
            
            
              <div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
  
  
    
  
  
    <label class="md-nav__title" for="__toc">
      <span class="md-nav__icon md-icon"></span>
      Table of contents
    </label>
    <ul class="md-nav__list" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#lookahead" class="md-nav__link">
    Lookahead
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#exception-safety" class="md-nav__link">
    Exception Safety
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#multiple-snapshots" class="md-nav__link">
    Multiple Snapshots
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#how-does-it-work" class="md-nav__link">
    How does it Work?
  </a>
  
</li>
      
    </ul>
  
</nav>
                  </div>
                </div>
              </div>
            
          
          <div class="md-content">
            <article class="md-content__inner md-typeset">
              
                
                  <a href="https://github.com/boisgera/bitstream/edit/master/mkdocs/snapshots.md" title="Edit this page" class="md-content__button md-icon">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z"/></svg>
                  </a>
                
                
                <h1 id="snapshots">Snapshots<a class="headerlink" href="#snapshots" title="Permanent link">&para;</a></h1>
<p>A stream is a simple model to deal with binary data,
but sometimes you need more: you want to perform some lookahead without 
changing the stream or you want to try some read/write operations 
but go back to the initial state if they fail. 
At this stage, you probably have copies of streams 
everywhere and the stream interface seems very cumbersome.</p>
<p>Therefore, we provide snapshots, a simple solution for these
use cases that doesn't require copies of streams:
you can save the state of a stream at any 
stage in a sequence of read/write operations and restore 
any such state later if you need it.</p>
<h2 id="lookahead">Lookahead<a class="headerlink" href="#lookahead" title="Permanent link">&para;</a></h2>
<p>The type of binary data can usually be identified by a specific header
coded in its first few bytes.
For example, <a href="https://en.wikipedia.org/wiki/WAV">WAVE</a> audio can be detected with the function:</p>
<pre><code>&gt;&gt;&gt; from bitstream import BitStream, ReadError

&gt;&gt;&gt; def is_wave(stream):
...    try:
...        riff = stream.read(bytes, 4)
...        _ = stream.read(bytes, 4)
...        wave = stream.read(bytes, 4)
...        return (riff == b"RIFF") and (wave == b"WAVE")
...    except ReadError:
...        return False
</code></pre>
<p>The contents of an empty single-channel 44.1 kHz WAVE audio file are for example</p>
<pre><code>&gt;&gt;&gt; wave = b'RIFF$\x00\x00\x00WAVEfmt \x10\x00\x00\x00\x01\x00\x01\x00D\xac\x00\x00\x88X\x01\x00\x02\x00\x10\x00data\x00\x00\x00\x00'
</code></pre>
<p>The function <code>is_wave</code> above works as expected at first</p>
<pre><code>&gt;&gt;&gt; stream = BitStream(wave)
&gt;&gt;&gt; is_wave(stream)
True
</code></pre>
<p>but another attempt gives an incorrect answer:</p>
<pre><code>&gt;&gt;&gt; is_wave(stream)
False
</code></pre>
<p>The explanation is simple: to identify the header of a WAVE file,
we need to consume the first 12 bytes in the stream. 
Since this header is missing from the stream afterwards, 
the new attempt fails.</p>
<p>To solve this issue, 
it's possible to make <code>is_wave</code> perform a (partial) copy of the stream 
and perform the check on the copy, leaving the initial 
stream unchanged. 
However in general this approach may be cumbersome;
copies should also be avoided when possible for performance reasons.</p>
<p>Bitstream also supports snapshots, 
a better way to deal with lookaheads.
With them you can:</p>
<ul>
<li>
<p>save the state of a stream at any time, </p>
</li>
<li>
<p>perform arbitrary operations on it and then </p>
</li>
<li>
<p>restore its initial state.</p>
</li>
</ul>
<p>The implementation of <code>is_wave</code> that does this is plain;
we just make sure that whatever happens 
(even an error in the processing) 
the original state of the stream is restored at the end. </p>
<pre><code>&gt;&gt;&gt; def is_wave(stream):
...     snapshot = stream.save()
...     try:
...         riff = stream.read(bytes, 4)
...         _ = stream.read(bytes, 4)
...         wave = stream.read(bytes, 4)
...         return (riff == b"RIFF") and (wave == b"WAVE")
...     except ReadError:
...         return False
...     finally:
...         stream.restore(snapshot)
</code></pre>
<p>This version works as expected:</p>
<pre><code>&gt;&gt;&gt; wave = b'RIFF$\x00\x00\x00WAVEfmt \x10\x00\x00\x00\x01\x00\x01\x00D\xac\x00\x00\x88X\x01\x00\x02\x00\x10\x00data\x00\x00\x00\x00'
&gt;&gt;&gt; stream = BitStream(wave)
&gt;&gt;&gt; copy = stream.copy()
&gt;&gt;&gt; is_wave(stream)
True
&gt;&gt;&gt; stream == copy
True
&gt;&gt;&gt; is_wave(stream)
True
</code></pre>
<h2 id="exception-safety">Exception Safety<a class="headerlink" href="#exception-safety" title="Permanent link">&para;</a></h2>
<p>Consider the toy DNA reader below:</p>
<pre><code>&gt;&gt;&gt; def DNA_read(stream, n=1):
...     DNA_bases = b"ACGT"
...     bases = []
...     for i in range(n):
...         base = stream.read(bytes, 1)
...         if base not in DNA_bases:
...             error = "invalid base {0!r}".format(base)
...             raise ReadError(error)
...         else:
...             bases.append(base)
...     return b"".join(bases)
</code></pre>
<p>It reads DNA sequences represented as bytes, either 
<code>b'A'</code>, <code>b'C'</code>, <code>b'G'</code> or <code>b'T'</code>:</p>
<pre><code>&gt;&gt;&gt; dna = BitStream(b"GATA")
&gt;&gt;&gt; DNA_read(dna, 4) # doctest: +BYTES
b'GATA'
</code></pre>
<p>If there is a <code>'U'</code> in the sequence, this is an error since
the <a href="https://en.wikipedia.org/wiki/Nucleobase">uracil base</a> 
is only found in RNA.</p>
<pre><code>&gt;&gt;&gt; stream = BitStream(b"GAUTA") # invalid DNA sequence
</code></pre>
<p>The DNA reader correctly rejects the code</p>
<pre><code>&gt;&gt;&gt; try:
...     DNA_read(stream, 4)
... except ReadError:
...     print("Read error")
Read error
</code></pre>
<p>but the initial stream is partially consumed in the process:</p>
<pre><code>&gt;&gt;&gt; stream.read(bytes) # doctest: +BYTES
b'TA'
</code></pre>
<p>This implementation therefore only provides some basic exception safety.
A reader that preserves the original value of the stream when an error
occurs would provide <a href="https://en.wikipedia.org/wiki/Exception_safety">strong exception safety</a> instead.
With snapshots, the modifications required to support this 
are plain: we simply restore the original stream whenever an
error occurs</p>
<pre><code>&gt;&gt;&gt; def DNA_read(stream, n=1):
...     DNA_bases = b"ACGT"
...     snapshot = stream.save()
...     try:
...         bases = []
...         for i in range(n):
...             base = stream.read(bytes, 1)
...             if base not in DNA_bases:
...                 error = "invalid base {0!r}".format(base)
...                 raise ReadError(error)
...             else:
...                 bases.append(base)
...         return "".join(bases)
...     except:
...         stream.restore(snapshot)
...         raise
</code></pre>
<p>With this new version, reading an invalid DNA code still 
raises an exception</p>
<pre><code>&gt;&gt;&gt; stream = BitStream(b"GAUTA") # invalid DNA sequence
&gt;&gt;&gt; try:
...     DNA_read(stream, 4)
... except ReadError:
...     print("Read error")
Read error
</code></pre>
<p>but now the original stream is intact</p>
<pre><code>&gt;&gt;&gt; stream.read(bytes) # doctest: +BYTES
b'GAUTA'
</code></pre>
<h2 id="multiple-snapshots">Multiple Snapshots<a class="headerlink" href="#multiple-snapshots" title="Permanent link">&para;</a></h2>
<p>You can create snapshots of a stream at any stage between read/write operations.
Multiple snapshots enable for example the implemention a hierarchy of readers 
or writers that provide strong exception safety at every level.</p>
<p>However arbitrary sequences of save and restore are not allowed:
when a given snapshot is restored, the snapshots that were created 
between the snapshot creation and before its restoration are forgotten.
In other words, saves and restores can only be applied in reverse order.
Of course it is perfectly valid to skip some of the restores in the process:
you can always create additional snapshots and never use them.</p>
<p>For example, you can take two snapshots <code>s0</code> then <code>s1</code> of a stream
between write operations</p>
<pre><code>&gt;&gt;&gt; stream = BitStream()
&gt;&gt;&gt; s0 = stream.save()
&gt;&gt;&gt; stream.write(b"A")
&gt;&gt;&gt; s1 = stream.save()
&gt;&gt;&gt; stream.write(b"B")
&gt;&gt;&gt; stream == BitStream(b"AB")
True
</code></pre>
<p>restore <code>s1</code></p>
<pre><code>&gt;&gt;&gt; stream.restore(s1)
&gt;&gt;&gt; stream == BitStream(b"A")
True
</code></pre>
<p>and then <code>s0</code></p>
<pre><code>&gt;&gt;&gt; stream.restore(s0)
&gt;&gt;&gt; stream == BitStream(b"")
True
</code></pre>
<p>You can also make the same snapshots </p>
<pre><code>&gt;&gt;&gt; stream = BitStream()
&gt;&gt;&gt; s0 = stream.save()
&gt;&gt;&gt; stream.write(b"A")
&gt;&gt;&gt; s1 = stream.save()
&gt;&gt;&gt; stream.write(b"B")
&gt;&gt;&gt; stream == BitStream(b"AB")
True
</code></pre>
<p>and directly restore <code>s0</code></p>
<pre><code>&gt;&gt;&gt; stream.restore(s0)
&gt;&gt;&gt; stream == BitStream(b"")
True
</code></pre>
<p>but then <code>s1</code> cannot be used anymore</p>
<pre><code>&gt;&gt;&gt; stream.restore(s1) # doctest: +ELLIPSIS
Traceback (most recent call last):
...
ValueError: ...
</code></pre>
<h2 id="how-does-it-work">How does it Work?<a class="headerlink" href="#how-does-it-work" title="Permanent link">&para;</a></h2>
<p>The main (private) attributes of a <code>BitStream</code> structure are:</p>
<ul>
<li>
<p>an array of bytes: the raw data</p>
</li>
<li>
<p>read and write cursors: they locate the beginning and the end 
    of the stream in the bytes array.</p>
</li>
</ul>
<p>When you read data from a stream, 
you shift the read cursor but the 
corresponding data is <em>not</em> deleted<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup> -- its is merely not accessible.
The <code>State</code> structure stores values 
of the read and write cursors; the call <code>state = stream.save()</code> produces 
a snapshot of the current cursor locations and
<code>stream.restore(state)</code> restores them.</p>
<div class="footnote">
<hr />
<ol>
<li id="fn:1">
<p>This is why the memory consumption increases if you write a lot
of data into a stream, <em>even if you read it!</em> The solution in this case is to
copy the stream and discard the original since the copy method discards 
write history.&#160;<a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text">&#8617;</a></p>
</li>
</ol>
</div>
                
              
              
                


              
            </article>
          </div>
        </div>
      </main>
      
        
<footer class="md-footer">
  
    <div class="md-footer-nav">
      <nav class="md-footer-nav__inner md-grid" aria-label="Footer">
        
          <a href="../custom/" class="md-footer-nav__link md-footer-nav__link--prev" rel="prev">
            <div class="md-footer-nav__button md-icon">
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
            </div>
            <div class="md-footer-nav__title">
              <div class="md-ellipsis">
                <span class="md-footer-nav__direction">
                  Previous
                </span>
                Custom Types
              </div>
            </div>
          </a>
        
        
          <a href="../API/" class="md-footer-nav__link md-footer-nav__link--next" rel="next">
            <div class="md-footer-nav__title">
              <div class="md-ellipsis">
                <span class="md-footer-nav__direction">
                  Next
                </span>
                API Reference
              </div>
            </div>
            <div class="md-footer-nav__button md-icon">
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11H4z"/></svg>
            </div>
          </a>
        
      </nav>
    </div>
  
  <div class="md-footer-meta md-typeset">
    <div class="md-footer-meta__inner md-grid">
      <div class="md-footer-copyright">
        
        Made with
        <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
          Material for MkDocs
        </a>
      </div>
      
    </div>
  </div>
</footer>
      
    </div>
    
      <script src="../assets/javascripts/vendor.0ac82a11.min.js"></script>
      <script src="../assets/javascripts/bundle.f81dfb4d.min.js"></script><script id="__lang" type="application/json">{"clipboard.copy": "Copy to clipboard", "clipboard.copied": "Copied to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.placeholder": "Type to start searching", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.term.missing": "Missing"}</script>
      
      <script>
        app = initialize({
          base: "..",
          features: [],
          search: Object.assign({
            worker: "../assets/javascripts/worker/search.4ac00218.min.js"
          }, typeof search !== "undefined" && search)
        })
      </script>
      
    
  </body>
</html>

<|start_filename|>docs/index.html<|end_filename|>

<!doctype html>
<html lang="en" class="no-js">
  <head>
    
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1">
      
      
      
      
      <link rel="shortcut icon" href="assets/images/favicon.png">
      <meta name="generator" content="mkdocs-1.1.2, mkdocs-material-6.1.7">
    
    
      
        <title>BitStream</title>
      
    
    
      <link rel="stylesheet" href="assets/stylesheets/main.19753c6b.min.css">
      
        
        <link rel="stylesheet" href="assets/stylesheets/palette.196e0c26.min.css">
        
      
    
    
    
      
        
        <link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700%7CRoboto+Mono&display=fallback">
        <style>body,input{font-family:"Roboto",-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono",SFMono-Regular,Consolas,Menlo,monospace}</style>
      
    
    
    
    
      
    
    
  </head>
  
  
    
    
    
    
    
    <body dir="ltr" data-md-color-scheme="" data-md-color-primary="none" data-md-color-accent="none">
      
  
    <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
    <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
    <label class="md-overlay" for="__drawer"></label>
    <div data-md-component="skip">
      
        
        <a href="#overview" class="md-skip">
          Skip to content
        </a>
      
    </div>
    <div data-md-component="announce">
      
    </div>
    
      

<header class="md-header" data-md-component="header">
  <nav class="md-header-nav md-grid" aria-label="Header">
    <a href="." title="BitStream" class="md-header-nav__button md-logo" aria-label="BitStream">
      
  
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 003-3 3 3 0 00-3-3 3 3 0 00-3 3 3 3 0 003 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54z"/></svg>

    </a>
    <label class="md-header-nav__button md-icon" for="__drawer">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2z"/></svg>
    </label>
    <div class="md-header-nav__title" data-md-component="header-title">
      
        <div class="md-header-nav__ellipsis">
          <span class="md-header-nav__topic md-ellipsis">
            BitStream
          </span>
          <span class="md-header-nav__topic md-ellipsis">
            
              Overview
            
          </span>
        </div>
      
    </div>
    
      <label class="md-header-nav__button md-icon" for="__search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0116 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 019.5 16 6.5 6.5 0 013 9.5 6.5 6.5 0 019.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
      </label>
      
<div class="md-search" data-md-component="search" role="dialog">
  <label class="md-search__overlay" for="__search"></label>
  <div class="md-search__inner" role="search">
    <form class="md-search__form" name="search">
      <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" data-md-state="active" required>
      <label class="md-search__icon md-icon" for="__search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0116 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 019.5 16 6.5 6.5 0 013 9.5 6.5 6.5 0 019.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
      </label>
      <button type="reset" class="md-search__icon md-icon" aria-label="Clear" data-md-component="search-reset" tabindex="-1">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>
      </button>
    </form>
    <div class="md-search__output">
      <div class="md-search__scrollwrap" data-md-scrollfix>
        <div class="md-search-result" data-md-component="search-result">
          <div class="md-search-result__meta">
            Initializing search
          </div>
          <ol class="md-search-result__list"></ol>
        </div>
      </div>
    </div>
  </div>
</div>
    
    
      <div class="md-header-nav__source">
        
<a href="https://github.com/boisgera/bitstream/" title="Go to repository" class="md-source">
  <div class="md-source__icon md-icon">
    
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05L244 40.45a28.87 28.87 0 00-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 01-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 000 40.81l195.61 195.6a28.86 28.86 0 0040.8 0l194.69-194.69a28.86 28.86 0 000-40.81z"/></svg>
  </div>
  <div class="md-source__repository">
    bitstream
  </div>
</a>
      </div>
    
  </nav>
</header>
    
    <div class="md-container" data-md-component="container">
      
      
        
      
      <main class="md-main" data-md-component="main">
        <div class="md-main__inner md-grid">
          
            
              <div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    

<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
  <label class="md-nav__title" for="__drawer">
    <a href="." title="BitStream" class="md-nav__button md-logo" aria-label="BitStream">
      
  
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 003-3 3 3 0 00-3-3 3 3 0 00-3 3 3 3 0 003 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54z"/></svg>

    </a>
    BitStream
  </label>
  
    <div class="md-nav__source">
      
<a href="https://github.com/boisgera/bitstream/" title="Go to repository" class="md-source">
  <div class="md-source__icon md-icon">
    
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05L244 40.45a28.87 28.87 0 00-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 01-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 000 40.81l195.61 195.6a28.86 28.86 0 0040.8 0l194.69-194.69a28.86 28.86 0 000-40.81z"/></svg>
  </div>
  <div class="md-source__repository">
    bitstream
  </div>
</a>
    </div>
  
  <ul class="md-nav__list" data-md-scrollfix>
    
      
      
      

  


  <li class="md-nav__item md-nav__item--active">
    
    <input class="md-nav__toggle md-toggle" data-md-toggle="toc" type="checkbox" id="__toc">
    
      
    
    
    <a href="." class="md-nav__link md-nav__link--active">
      Overview
    </a>
    
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="examples/" class="md-nav__link">
      Examples
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="installation/" class="md-nav__link">
      Installation
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="types/" class="md-nav__link">
      Built-in Types
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="custom/" class="md-nav__link">
      Custom Types
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="snapshots/" class="md-nav__link">
      Snapshots
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="API/" class="md-nav__link">
      API Reference
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="contributing/" class="md-nav__link">
      Contributing
    </a>
  </li>

    
  </ul>
</nav>
                  </div>
                </div>
              </div>
            
            
              <div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
  
  
    
  
  
</nav>
                  </div>
                </div>
              </div>
            
          
          <div class="md-content">
            <article class="md-content__inner md-typeset">
              
                
                  <a href="https://github.com/boisgera/bitstream/edit/master/mkdocs/index.md" title="Edit this page" class="md-content__button md-icon">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z"/></svg>
                  </a>
                
                
                <h1 id="overview">Overview<a class="headerlink" href="#overview" title="Permanent link">&para;</a></h1>
<p>Bitstream is a <a href="http://www.python.org/">Python</a> library to manage binary data as bitstreams:</p>
<pre><code>&gt;&gt;&gt; from bitstream import BitStream
&gt;&gt;&gt; BitStream(b"Hello World!")
010010000110010101101100011011000110111100100000010101110110111101110010011011000110010000100001
</code></pre>
<p>If you need to deal with existing binary file formats,
or design your own binary formats or
experiment with data compression algorithms, etc. 
and if the Python standard library doesn't work for you,
you may be interested in bitstream.
Read this section and have a look at the <a href="examples">example applications</a> 
to see if it is what you need.</p>
<p>The main features are:</p>
<div class="admonition note">
<p class="admonition-title">Easy to use</p>
<p><a href="https://en.wikipedia.org/wiki/Bitstream">Bitstreams</a> are a simple abstraction.
They behave like communication channels: 
you can only write data at one end of it 
and read data at the other end, in the same order.
So you only need to know how to create a stream, write into it
and read it to use this library:</p>
<pre><code>&gt;&gt;&gt; stream = BitStream()
&gt;&gt;&gt; stream.write(b"Hello")
&gt;&gt;&gt; stream.write(b" World!")
&gt;&gt;&gt; stream.read(bytes, 5) # doctest: +BYTES
b'Hello'
&gt;&gt;&gt; stream.read(bytes, 7) # doctest: +BYTES
b' World!'
</code></pre>
<p>This simple way to manage binary data is good enough for a surprisingly
large number of use cases. 
It should be much easier to use than
<a href="https://docs.python.org/2/library/struct.html">struct</a> and 
<a href="https://docs.python.org/2/library/array.html">array</a>, 
the modules that the standard Python library provides for this task. </p>
</div>
<div class="admonition note">
<p class="admonition-title">Works at the bit and byte level.</p>
<p>Compact codes (for example <a href="https://en.wikipedia.org/wiki/Huffman_coding">Huffman codes</a>)
do not always represent data with an entire number of bytes.
Since bitstream supports bits and not merely bytes, such codes
are implemented with the same API.
For example, the <a href="https://en.wikipedia.org/wiki/Unary_coding">unary coding</a> 
of a sequence natural numbers requires only a few lines:</p>
<pre><code>&gt;&gt;&gt; data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
&gt;&gt;&gt; stream = BitStream()
&gt;&gt;&gt; for number in data:
...     stream.write(number * [True] + [False])
... 
&gt;&gt;&gt; stream
0101101110111101111101111110111111101111111101111111110
</code></pre>
</div>
<div class="admonition note">
<p class="admonition-title">Supports Python &amp; NumPy types</p>
<p>BitStream has built-in support for the common data types 
with a standard binary layout: bools, bytes, 
fixed-size integers and floating-point integers. </p>
<pre><code>&gt;&gt;&gt; stream = BitStream()
&gt;&gt;&gt; stream.write(True, bool)
&gt;&gt;&gt; stream.write(False, bool)
&gt;&gt;&gt; from numpy import int8
&gt;&gt;&gt; stream.write(-128, int8)
&gt;&gt;&gt; stream.write(b"AB", bytes)
&gt;&gt;&gt; stream
10100000000100000101000010
&gt;&gt;&gt; stream.read(bool, 2)
[True, False]
&gt;&gt;&gt; stream.read(int8, 1)
array([-128], dtype=int8)
&gt;&gt;&gt; stream.read(bytes, 2) # doctest: +BYTES
b'AB'
</code></pre>
<p>NumPy arrays are a convenient way to deal with sequences of homogeneous data:</p>
<pre><code>&gt;&gt;&gt; from numpy import *
&gt;&gt;&gt; dt = 1.0 / 44100.0
&gt;&gt;&gt; t = r_[0.0:1.0:dt]
&gt;&gt;&gt; data = cos(2*pi*440.0*t)       
&gt;&gt;&gt; stream = BitStream(data)
</code></pre>
<p>Refer to the <a href="types">Built-in types</a> section for more details.</p>
</div>
<div class="admonition note">
<p class="admonition-title">Advanced features</p>
<ul>
<li>
<p><strong>Performance.</strong> Bitstream is a Python C-extension module that has been
    optimized for the common use cases. Hopefully, it will be fast enough 
    for your needs! 
    Under the hood, the <a href="http://www.cython.org">Cython</a> language and compiler are used to generate 
    this extension module.</p>
</li>
<li>
<p><strong>Custom types.</strong>
    The list of supported types and binary 
    representation may be enlarged at will: new readers and writers 
    can be implemented and associated to specific data types.</p>
<p>See also: <a href="custom">Custom types</a>.</p>
</li>
<li>
<p><strong>Snapshots.</strong> At times, the stream abstraction is too simple,
    for example when you need to lookahead into the stream without
    consuming its content. Snapshots are an extension of the stream
    model that solve this kind of issue
    since they provide a "time machine" to restore a stream 
    to an earlier state.</p>
<p>See also: <a href="snapshots">Snapshots</a>.</p>
</li>
</ul>
</div>
<div class="admonition note">
<p class="admonition-title">Open Source</p>
<p>Bitstream  is distributed under a <a href="https://github.com/boisgera/bitstream/blob/master/LICENSE.txt">MIT license</a>. 
The development takes place on <a href="https://github.com/boisgera/bitstream">GitHub</a> and 
releases are distributed on <a href="https://pypi.python.org/pypi/bitstream/">PyPI</a>.</p>
</div>
                
              
              
                


              
            </article>
          </div>
        </div>
      </main>
      
        
<footer class="md-footer">
  
    <div class="md-footer-nav">
      <nav class="md-footer-nav__inner md-grid" aria-label="Footer">
        
        
          <a href="examples/" class="md-footer-nav__link md-footer-nav__link--next" rel="next">
            <div class="md-footer-nav__title">
              <div class="md-ellipsis">
                <span class="md-footer-nav__direction">
                  Next
                </span>
                Examples
              </div>
            </div>
            <div class="md-footer-nav__button md-icon">
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11H4z"/></svg>
            </div>
          </a>
        
      </nav>
    </div>
  
  <div class="md-footer-meta md-typeset">
    <div class="md-footer-meta__inner md-grid">
      <div class="md-footer-copyright">
        
        Made with
        <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
          Material for MkDocs
        </a>
      </div>
      
    </div>
  </div>
</footer>
      
    </div>
    
      <script src="assets/javascripts/vendor.0ac82a11.min.js"></script>
      <script src="assets/javascripts/bundle.f81dfb4d.min.js"></script><script id="__lang" type="application/json">{"clipboard.copy": "Copy to clipboard", "clipboard.copied": "Copied to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.placeholder": "Type to start searching", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.term.missing": "Missing"}</script>
      
      <script>
        app = initialize({
          base: ".",
          features: [],
          search: Object.assign({
            worker: "assets/javascripts/worker/search.4ac00218.min.js"
          }, typeof search !== "undefined" && search)
        })
      </script>
      
    
  </body>
</html>

<|start_filename|>docs/examples/index.html<|end_filename|>

<!doctype html>
<html lang="en" class="no-js">
  <head>
    
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1">
      
      
      
      
      <link rel="shortcut icon" href="../assets/images/favicon.png">
      <meta name="generator" content="mkdocs-1.1.2, mkdocs-material-6.1.7">
    
    
      
        <title>Examples - BitStream</title>
      
    
    
      <link rel="stylesheet" href="../assets/stylesheets/main.19753c6b.min.css">
      
        
        <link rel="stylesheet" href="../assets/stylesheets/palette.196e0c26.min.css">
        
      
    
    
    
      
        
        <link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700%7CRoboto+Mono&display=fallback">
        <style>body,input{font-family:"Roboto",-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono",SFMono-Regular,Consolas,Menlo,monospace}</style>
      
    
    
    
    
      
    
    
  </head>
  
  
    
    
    
    
    
    <body dir="ltr" data-md-color-scheme="" data-md-color-primary="none" data-md-color-accent="none">
      
  
    <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
    <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
    <label class="md-overlay" for="__drawer"></label>
    <div data-md-component="skip">
      
        
        <a href="#examples" class="md-skip">
          Skip to content
        </a>
      
    </div>
    <div data-md-component="announce">
      
    </div>
    
      

<header class="md-header" data-md-component="header">
  <nav class="md-header-nav md-grid" aria-label="Header">
    <a href=".." title="BitStream" class="md-header-nav__button md-logo" aria-label="BitStream">
      
  
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 003-3 3 3 0 00-3-3 3 3 0 00-3 3 3 3 0 003 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54z"/></svg>

    </a>
    <label class="md-header-nav__button md-icon" for="__drawer">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2z"/></svg>
    </label>
    <div class="md-header-nav__title" data-md-component="header-title">
      
        <div class="md-header-nav__ellipsis">
          <span class="md-header-nav__topic md-ellipsis">
            BitStream
          </span>
          <span class="md-header-nav__topic md-ellipsis">
            
              Examples
            
          </span>
        </div>
      
    </div>
    
      <label class="md-header-nav__button md-icon" for="__search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0116 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 019.5 16 6.5 6.5 0 013 9.5 6.5 6.5 0 019.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
      </label>
      
<div class="md-search" data-md-component="search" role="dialog">
  <label class="md-search__overlay" for="__search"></label>
  <div class="md-search__inner" role="search">
    <form class="md-search__form" name="search">
      <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" data-md-state="active" required>
      <label class="md-search__icon md-icon" for="__search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0116 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 019.5 16 6.5 6.5 0 013 9.5 6.5 6.5 0 019.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
      </label>
      <button type="reset" class="md-search__icon md-icon" aria-label="Clear" data-md-component="search-reset" tabindex="-1">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>
      </button>
    </form>
    <div class="md-search__output">
      <div class="md-search__scrollwrap" data-md-scrollfix>
        <div class="md-search-result" data-md-component="search-result">
          <div class="md-search-result__meta">
            Initializing search
          </div>
          <ol class="md-search-result__list"></ol>
        </div>
      </div>
    </div>
  </div>
</div>
    
    
      <div class="md-header-nav__source">
        
<a href="https://github.com/boisgera/bitstream/" title="Go to repository" class="md-source">
  <div class="md-source__icon md-icon">
    
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05L244 40.45a28.87 28.87 0 00-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 01-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 000 40.81l195.61 195.6a28.86 28.86 0 0040.8 0l194.69-194.69a28.86 28.86 0 000-40.81z"/></svg>
  </div>
  <div class="md-source__repository">
    bitstream
  </div>
</a>
      </div>
    
  </nav>
</header>
    
    <div class="md-container" data-md-component="container">
      
      
        
      
      <main class="md-main" data-md-component="main">
        <div class="md-main__inner md-grid">
          
            
              <div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    

<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
  <label class="md-nav__title" for="__drawer">
    <a href=".." title="BitStream" class="md-nav__button md-logo" aria-label="BitStream">
      
  
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 003-3 3 3 0 00-3-3 3 3 0 00-3 3 3 3 0 003 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54z"/></svg>

    </a>
    BitStream
  </label>
  
    <div class="md-nav__source">
      
<a href="https://github.com/boisgera/bitstream/" title="Go to repository" class="md-source">
  <div class="md-source__icon md-icon">
    
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05L244 40.45a28.87 28.87 0 00-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 01-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 000 40.81l195.61 195.6a28.86 28.86 0 0040.8 0l194.69-194.69a28.86 28.86 0 000-40.81z"/></svg>
  </div>
  <div class="md-source__repository">
    bitstream
  </div>
</a>
    </div>
  
  <ul class="md-nav__list" data-md-scrollfix>
    
      
      
      


  <li class="md-nav__item">
    <a href=".." class="md-nav__link">
      Overview
    </a>
  </li>

    
      
      
      

  


  <li class="md-nav__item md-nav__item--active">
    
    <input class="md-nav__toggle md-toggle" data-md-toggle="toc" type="checkbox" id="__toc">
    
      
    
    
      <label class="md-nav__link md-nav__link--active" for="__toc">
        Examples
        <span class="md-nav__icon md-icon"></span>
      </label>
    
    <a href="./" class="md-nav__link md-nav__link--active">
      Examples
    </a>
    
      
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
  
  
    
  
  
    <label class="md-nav__title" for="__toc">
      <span class="md-nav__icon md-icon"></span>
      Table of contents
    </label>
    <ul class="md-nav__list" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#spoon" class="md-nav__link">
    Spoon
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#wave" class="md-nav__link">
    Wave
  </a>
  
</li>
      
    </ul>
  
</nav>
    
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../installation/" class="md-nav__link">
      Installation
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../types/" class="md-nav__link">
      Built-in Types
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../custom/" class="md-nav__link">
      Custom Types
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../snapshots/" class="md-nav__link">
      Snapshots
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../API/" class="md-nav__link">
      API Reference
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../contributing/" class="md-nav__link">
      Contributing
    </a>
  </li>

    
  </ul>
</nav>
                  </div>
                </div>
              </div>
            
            
              <div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
  
  
    
  
  
    <label class="md-nav__title" for="__toc">
      <span class="md-nav__icon md-icon"></span>
      Table of contents
    </label>
    <ul class="md-nav__list" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#spoon" class="md-nav__link">
    Spoon
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#wave" class="md-nav__link">
    Wave
  </a>
  
</li>
      
    </ul>
  
</nav>
                  </div>
                </div>
              </div>
            
          
          <div class="md-content">
            <article class="md-content__inner md-typeset">
              
                
                  <a href="https://github.com/boisgera/bitstream/edit/master/mkdocs/examples.md" title="Edit this page" class="md-content__button md-icon">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z"/></svg>
                  </a>
                
                
                <h1 id="examples">Examples<a class="headerlink" href="#examples" title="Permanent link">&para;</a></h1>
<p>We provide the following examples of bitstream usage:</p>
<ul>
<li>
<p><a href="#spoon">Spoon</a>: build a translator between Brainfuck programs and Spoon
    programs.</p>
</li>
<li>
<p><a href="#wave">Wave</a>: synthesize a pure tone and generate the corresponding
    WAVE audio file.</p>
</li>
</ul>
<p>But first, as usual, let's start with</p>
<pre><code>&gt;&gt;&gt; from bitstream import BitStream
</code></pre>
<h2 id="spoon">Spoon<a class="headerlink" href="#spoon" title="Permanent link">&para;</a></h2>
<p><a href="https://esolangs.org/wiki/Spoon">Spoon</a> is a derivative of the <a href="https://en.wikipedia.org/wiki/Brainfuck">Brainfuck</a> programming language.
Instead of the 8 ASCII symbols used by Brainfuck, it relies on
binary sequences to represent each instruction. </p>
<p>The source of the "Hello World!" program in Brainfuck is<sup id="fnref:dtm"><a class="footnote-ref" href="#fn:dtm">1</a></sup>:</p>
<pre><code>&gt;&gt;&gt; hello_world = "++++++++++[&gt;+++++++&gt;++++++++++&gt;+++&gt;+&lt;&lt;&lt;&lt;-]&gt;++.&gt;+.+++++++..+++.&gt;++.&lt;&lt;+++++++++++++++.&gt;.+++.------.--------.&gt;+.&gt;."
</code></pre>
<p>The conversion between Brainfuck and Spoon is given by the table:</p>
<pre><code>&gt;&gt;&gt; spoon = {
...   "+": "1",
...   "-": "000",
...   "&gt;": "010",
...   "&lt;": "011",
...   "[": "00100",
...   "]": "0011",
...   ".": "001010",
...   ",": "0010110",
... }
</code></pre>
<p>You may notice that the binary codes that correspond to symbols that frequently
appear in the <code>hello_world</code> program (such as <code>+</code>) are shorter than the others,
a nice property since it generates a compact representation of Spoon programs<sup id="fnref:nac"><a class="footnote-ref" href="#fn:nac">2</a></sup>.</p>
<p>To create a bitstream that contains the Spoon translation of <code>hello_world</code>,
we may for each symbol in this program find the corresponding binary code 
in the <code>spoon</code> table, transform it into a list of bools and append this data 
to the stream.</p>
<pre><code>&gt;&gt;&gt; stream = BitStream()
&gt;&gt;&gt; for symbol in hello_world:
...     code = spoon[symbol]
...     code_as_bools = [bool(int(char)) for char in code]
...     stream.write(code_as_bools)
</code></pre>
<p>Here is the result:</p>
<pre><code>&gt;&gt;&gt; stream
11111111110010001011111110101111111111010111010101101101101100000110101100101001010010101111111001010001010111001010010110010100110111111111111111110010100100010101110010100000000000000000000010100000000000000000000000000010100101001010010001010
&gt;&gt;&gt; len(hello_world) * 8
888
&gt;&gt;&gt; len(stream)
245
</code></pre>
<p>We now have of program of 245 bits instead of the 888 bits 
(111 bytes) of the original ASCII program. Not bad ...</p>
<hr />
<p>It's also pretty easy to perform the opposite operation, to translate Spoon into
Brainfuck. First, we can compute <code>noops</code>, the inverse of the <code>spoon</code> dictionary.</p>
<pre><code>&gt;&gt;&gt; noops = {}
&gt;&gt;&gt; for symbol, code in spoon.items():
...     noops[code] = symbol
&gt;&gt;&gt; n = max(len(code) for code in noops)
</code></pre>
<p>Then we read bits one by one from the stream into a buffer and look at each 
stage if the buffer corresponds to a key in <code>noops</code>, translate this code,
empty the buffer and start again<sup id="fnref:pfc"><a class="footnote-ref" href="#fn:pfc">3</a></sup>.</p>
<pre><code>&gt;&gt;&gt; src = ""
&gt;&gt;&gt; buffer = BitStream()
&gt;&gt;&gt; while len(stream) &gt; 0:
...     if len(buffer) &gt; n:
...         raise ValueError("invalid Spoon bitstream")
...     else:
...         buffer.write(stream.read(bool))
...         try:
...             src += noops[str(buffer)]
...             buffer = BitStream()
...         except KeyError:
...             pass
&gt;&gt;&gt; if len(buffer) &gt; 0: # should be empty by now
...     raise ValueError("invalid Spoon bitstream")
</code></pre>
<p>We can then check that <code>src</code> and <code>hello_world</code> are the same program:</p>
<pre><code>&gt;&gt;&gt; src == hello_world
True
</code></pre>
<h2 id="wave">Wave<a class="headerlink" href="#wave" title="Permanent link">&para;</a></h2>
<p>What does it take to play a pure tone?
The synthesis of the data is quite easy: in the realm of digital audio,
sounds are just numbers and NumPy is up to the task.
The painful, low-level part of the process is to actually generate an
audio file in a format that your computer does understand. 
Fortunately, this is where bitstream can help<sup id="fnref:r"><a class="footnote-ref" href="#fn:r">4</a></sup>.</p>
<p>Most of the audio file formats that you may know (MP3, AAC, FLAC, ALAC, etc.)
use compression to reduce file size; unfortunately
this feature leads to rather complex formats. 
Therefore, we are going to output <a href="https://en.wikipedia.org/wiki/WAV">WAVE</a> 
files instead, which are typically uncompressed.</p>
<p>The <a href="http://soundfile.sapp.org/doc/WaveFormat/">WAVE PCM soundfile format</a> webpage<sup id="fnref:cs"><a class="footnote-ref" href="#fn:cs">5</a></sup> is a great source of information
about the format. We will use it to design our code; please have a look at it!
Here is its high-level description:</p>
<blockquote>
<p>The WAVE file format is a subset of Microsoft's RIFF specification for the 
storage of multimedia files. 
A RIFF file starts out with a file header followed by a sequence of data 
chunks. 
A WAVE file is often just a RIFF file with a single "WAVE" chunk which 
consists of two sub-chunks -- a "fmt " chunk specifying the data format 
and a "data" chunk containing the actual sample data. </p>
</blockquote>
<p>First, we import NumPy (and globally the integer types that we need).</p>
<pre><code>&gt;&gt;&gt; import numpy as np
&gt;&gt;&gt; from numpy import uint8, uint16, uint32, int16
</code></pre>
<p>We use NumPy to produce 3 seconds of a pure tone with frequency 440 Hz
(A4) at a sampling rate of 44.1 kHz 
(the audio CD standard).</p>
<pre><code>&gt;&gt;&gt; # Generate a waveform (pure tone)
&gt;&gt;&gt; df = 44100
&gt;&gt;&gt; dt = 1.0 / df
&gt;&gt;&gt; T = 3.0
&gt;&gt;&gt; t = np.r_[0.0:T:dt]
&gt;&gt;&gt; f = 440.0
&gt;&gt;&gt; data = np.sin(2 * np.pi * f * t)
</code></pre>
<p>In this description, every sample is a floating-point number that requires 
64 bits. The typical WAVE file requires 16-bit integer data instead, so we
perform the (lossy) conversion:</p>
<pre><code>&gt;&gt;&gt; # Quantize the floating-point data
&gt;&gt;&gt; ones_ = np.ones_like(data)
&gt;&gt;&gt; low  = (-2**15    ) * ones_
&gt;&gt;&gt; high = ( 2**15 - 1) * ones_
&gt;&gt;&gt; data = np.clip(2**15 * data, low, high)
&gt;&gt;&gt; data = np.round(data).astype(np.int16)
</code></pre>
<p>Since WAVE files use a <a href="https://en.wikipedia.org/wiki/Endianness">little-endian</a>
representation every numeric value
and since bitstream is <a href="https://en.wikipedia.org/wiki/Endianness">big-endian</a>
by default, we define a small function to
help us perform the change automatically, using the <code>newbyteorder</code> 
method of NumPy.</p>
<pre><code>&gt;&gt;&gt; # Stream endianness helper 
&gt;&gt;&gt; stream = BitStream()
&gt;&gt;&gt; def write(datum, type=None):
...     if type and issubclass(type, np.integer):
...         datum = type(datum).newbyteorder()
...     stream.write(datum, type)
</code></pre>
<p>The rest of the work is a straightforward translation of the 
<a href="http://soundfile.sapp.org/doc/WaveFormat/">specification</a>: first we write the main chunk</p>
<pre><code>&gt;&gt;&gt; # "RIFF" Chunk Descriptor
&gt;&gt;&gt; chunk_size = 36 + 2 * len(data)  # size of the chunk after "RIFF"
&gt;&gt;&gt; 
&gt;&gt;&gt; write(b"RIFF"           )
&gt;&gt;&gt; write(chunk_size, uint32)
&gt;&gt;&gt; write(b"WAVE"           )
</code></pre>
<p>then the format subchunk</p>
<pre><code>&gt;&gt;&gt; # "fmt" SubChunk
&gt;&gt;&gt; subchunk1_size  = 16      # size in bytes of the subchunk after "fmt " 
&gt;&gt;&gt; audio_format    = 1       # PCM data
&gt;&gt;&gt; num_channels    = 1       # mono
&gt;&gt;&gt; byte_rate       = 2 * df
&gt;&gt;&gt; block_align     = 2       # number of bytes for one sample (all channels)
&gt;&gt;&gt; bits_per_sample = 16
&gt;&gt;&gt; 
&gt;&gt;&gt; write(b"fmt "                )
&gt;&gt;&gt; write(subchunk1_size , uint32)
&gt;&gt;&gt; write(audio_format   , uint16)
&gt;&gt;&gt; write(num_channels   , uint16)
&gt;&gt;&gt; write(df             , uint32)
&gt;&gt;&gt; write(byte_rate      , uint32)
&gt;&gt;&gt; write(block_align    , uint16)
&gt;&gt;&gt; write(bits_per_sample, uint16)
</code></pre>
<p>and finally the data subchunk</p>
<pre><code>&gt;&gt;&gt; # "data" SubChunk
&gt;&gt;&gt; subchunk2_size = 2 * len(data)  # size in bytes of the subchunk after "data"
&gt;&gt;&gt;  
&gt;&gt;&gt; write(b"data"               )
&gt;&gt;&gt; write(subchunk2_size, uint32)
&gt;&gt;&gt; write(data          ,  int16)
</code></pre>
<p>and that's it! <code>stream</code> holds the content of our WAVE file;
all we have to do is to read it as a string that we write into an 
actual file.</p>
<pre><code>&gt;&gt;&gt; # Generate the WAVE file
&gt;&gt;&gt; wave_bytes = stream.read(bytes)
&gt;&gt;&gt; wave_file = open("output.wav", "wb")
&gt;&gt;&gt; _ = wave_file.write(wave_bytes)
</code></pre>
<p>You can now listen to the sound in <code>output.wav</code> with your favorite music player.</p>
<p>For the sake of consistency, let's make sure that you and I have the same 
contents:</p>
<pre><code>&gt;&gt;&gt; import hashlib
&gt;&gt;&gt; m = hashlib.md5()
&gt;&gt;&gt; m.update(wave_bytes)
&gt;&gt;&gt; m.digest() # doctest: +BYTES
b'\xb0\xcf\x0e8\x150\x1fV \x86\x9e2\xdf\xfb\x1d\xec'
</code></pre>
<div class="footnote">
<hr />
<ol>
<li id="fn:dtm">
<p>You don't have to trust me on this, you may try this code online at <a href="https://copy.sh/brainfuck/">https://copy.sh/brainfuck/</a>.&#160;<a class="footnote-backref" href="#fnref:dtm" title="Jump back to footnote 1 in the text">&#8617;</a></p>
</li>
<li id="fn:nac">
<p>This is not a coincidence: Spoon has been designed as 
a <a href="https://en.wikipedia.org/wiki/Huffman_coding">Huffman code</a>
based on the analysis of a representative collection of Brainfuck programs.&#160;<a class="footnote-backref" href="#fnref:nac" title="Jump back to footnote 2 in the text">&#8617;</a></p>
</li>
<li id="fn:pfc">
<p>This approach -- without any lookahead -- is safe here because 
    this code is <a href="https://en.wikipedia.org/wiki/Prefix_code">prefix-free</a>.&#160;<a class="footnote-backref" href="#fnref:pfc" title="Jump back to footnote 3 in the text">&#8617;</a></p>
</li>
<li id="fn:r">
<p>Of course, there is a module in the Python standard library to
<a href="https://docs.python.org/2/library/wave.html">read and write WAV files</a>.
We just pretend that we're in the mood to reinvent this wheel and learn
something in the process.&#160;<a class="footnote-backref" href="#fnref:r" title="Jump back to footnote 4 in the text">&#8617;</a></p>
</li>
<li id="fn:cs">
<p>by <a href="mailto:<EMAIL>"><NAME></a> from the
   <a href="https://ccrma.stanford.edu/">Center for Computer Research in Music and Acoustics</a>:&#160;<a class="footnote-backref" href="#fnref:cs" title="Jump back to footnote 5 in the text">&#8617;</a></p>
</li>
</ol>
</div>
                
              
              
                


              
            </article>
          </div>
        </div>
      </main>
      
        
<footer class="md-footer">
  
    <div class="md-footer-nav">
      <nav class="md-footer-nav__inner md-grid" aria-label="Footer">
        
          <a href=".." class="md-footer-nav__link md-footer-nav__link--prev" rel="prev">
            <div class="md-footer-nav__button md-icon">
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
            </div>
            <div class="md-footer-nav__title">
              <div class="md-ellipsis">
                <span class="md-footer-nav__direction">
                  Previous
                </span>
                Overview
              </div>
            </div>
          </a>
        
        
          <a href="../installation/" class="md-footer-nav__link md-footer-nav__link--next" rel="next">
            <div class="md-footer-nav__title">
              <div class="md-ellipsis">
                <span class="md-footer-nav__direction">
                  Next
                </span>
                Installation
              </div>
            </div>
            <div class="md-footer-nav__button md-icon">
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11H4z"/></svg>
            </div>
          </a>
        
      </nav>
    </div>
  
  <div class="md-footer-meta md-typeset">
    <div class="md-footer-meta__inner md-grid">
      <div class="md-footer-copyright">
        
        Made with
        <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
          Material for MkDocs
        </a>
      </div>
      
    </div>
  </div>
</footer>
      
    </div>
    
      <script src="../assets/javascripts/vendor.0ac82a11.min.js"></script>
      <script src="../assets/javascripts/bundle.f81dfb4d.min.js"></script><script id="__lang" type="application/json">{"clipboard.copy": "Copy to clipboard", "clipboard.copied": "Copied to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.placeholder": "Type to start searching", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.term.missing": "Missing"}</script>
      
      <script>
        app = initialize({
          base: "..",
          features: [],
          search: Object.assign({
            worker: "../assets/javascripts/worker/search.4ac00218.min.js"
          }, typeof search !== "undefined" && search)
        })
      </script>
      
    
  </body>
</html>

<|start_filename|>docs/API/index.html<|end_filename|>

<!doctype html>
<html lang="en" class="no-js">
  <head>
    
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width,initial-scale=1">
      
      
      
      
      <link rel="shortcut icon" href="../assets/images/favicon.png">
      <meta name="generator" content="mkdocs-1.1.2, mkdocs-material-6.1.7">
    
    
      
        <title>API Reference - BitStream</title>
      
    
    
      <link rel="stylesheet" href="../assets/stylesheets/main.19753c6b.min.css">
      
        
        <link rel="stylesheet" href="../assets/stylesheets/palette.196e0c26.min.css">
        
      
    
    
    
      
        
        <link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700%7CRoboto+Mono&display=fallback">
        <style>body,input{font-family:"Roboto",-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono",SFMono-Regular,Consolas,Menlo,monospace}</style>
      
    
    
    
    
      
    
    
  </head>
  
  
    
    
    
    
    
    <body dir="ltr" data-md-color-scheme="" data-md-color-primary="none" data-md-color-accent="none">
      
  
    <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
    <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
    <label class="md-overlay" for="__drawer"></label>
    <div data-md-component="skip">
      
        
        <a href="#api-reference" class="md-skip">
          Skip to content
        </a>
      
    </div>
    <div data-md-component="announce">
      
    </div>
    
      

<header class="md-header" data-md-component="header">
  <nav class="md-header-nav md-grid" aria-label="Header">
    <a href=".." title="BitStream" class="md-header-nav__button md-logo" aria-label="BitStream">
      
  
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 003-3 3 3 0 00-3-3 3 3 0 00-3 3 3 3 0 003 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54z"/></svg>

    </a>
    <label class="md-header-nav__button md-icon" for="__drawer">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2z"/></svg>
    </label>
    <div class="md-header-nav__title" data-md-component="header-title">
      
        <div class="md-header-nav__ellipsis">
          <span class="md-header-nav__topic md-ellipsis">
            BitStream
          </span>
          <span class="md-header-nav__topic md-ellipsis">
            
              API Reference
            
          </span>
        </div>
      
    </div>
    
      <label class="md-header-nav__button md-icon" for="__search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0116 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 019.5 16 6.5 6.5 0 013 9.5 6.5 6.5 0 019.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
      </label>
      
<div class="md-search" data-md-component="search" role="dialog">
  <label class="md-search__overlay" for="__search"></label>
  <div class="md-search__inner" role="search">
    <form class="md-search__form" name="search">
      <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" data-md-state="active" required>
      <label class="md-search__icon md-icon" for="__search">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0116 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 019.5 16 6.5 6.5 0 013 9.5 6.5 6.5 0 019.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
      </label>
      <button type="reset" class="md-search__icon md-icon" aria-label="Clear" data-md-component="search-reset" tabindex="-1">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>
      </button>
    </form>
    <div class="md-search__output">
      <div class="md-search__scrollwrap" data-md-scrollfix>
        <div class="md-search-result" data-md-component="search-result">
          <div class="md-search-result__meta">
            Initializing search
          </div>
          <ol class="md-search-result__list"></ol>
        </div>
      </div>
    </div>
  </div>
</div>
    
    
      <div class="md-header-nav__source">
        
<a href="https://github.com/boisgera/bitstream/" title="Go to repository" class="md-source">
  <div class="md-source__icon md-icon">
    
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05L244 40.45a28.87 28.87 0 00-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 01-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 000 40.81l195.61 195.6a28.86 28.86 0 0040.8 0l194.69-194.69a28.86 28.86 0 000-40.81z"/></svg>
  </div>
  <div class="md-source__repository">
    bitstream
  </div>
</a>
      </div>
    
  </nav>
</header>
    
    <div class="md-container" data-md-component="container">
      
      
        
      
      <main class="md-main" data-md-component="main">
        <div class="md-main__inner md-grid">
          
            
              <div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    

<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
  <label class="md-nav__title" for="__drawer">
    <a href=".." title="BitStream" class="md-nav__button md-logo" aria-label="BitStream">
      
  
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 003-3 3 3 0 00-3-3 3 3 0 00-3 3 3 3 0 003 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54z"/></svg>

    </a>
    BitStream
  </label>
  
    <div class="md-nav__source">
      
<a href="https://github.com/boisgera/bitstream/" title="Go to repository" class="md-source">
  <div class="md-source__icon md-icon">
    
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05L244 40.45a28.87 28.87 0 00-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 01-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 000 40.81l195.61 195.6a28.86 28.86 0 0040.8 0l194.69-194.69a28.86 28.86 0 000-40.81z"/></svg>
  </div>
  <div class="md-source__repository">
    bitstream
  </div>
</a>
    </div>
  
  <ul class="md-nav__list" data-md-scrollfix>
    
      
      
      


  <li class="md-nav__item">
    <a href=".." class="md-nav__link">
      Overview
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../examples/" class="md-nav__link">
      Examples
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../installation/" class="md-nav__link">
      Installation
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../types/" class="md-nav__link">
      Built-in Types
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../custom/" class="md-nav__link">
      Custom Types
    </a>
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../snapshots/" class="md-nav__link">
      Snapshots
    </a>
  </li>

    
      
      
      

  


  <li class="md-nav__item md-nav__item--active">
    
    <input class="md-nav__toggle md-toggle" data-md-toggle="toc" type="checkbox" id="__toc">
    
      
    
    
      <label class="md-nav__link md-nav__link--active" for="__toc">
        API Reference
        <span class="md-nav__icon md-icon"></span>
      </label>
    
    <a href="./" class="md-nav__link md-nav__link--active">
      API Reference
    </a>
    
      
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
  
  
    
  
  
    <label class="md-nav__title" for="__toc">
      <span class="md-nav__icon md-icon"></span>
      Table of contents
    </label>
    <ul class="md-nav__list" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#constructor" class="md-nav__link">
    Constructor
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#read-write" class="md-nav__link">
    Read / Write
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#string-representation" class="md-nav__link">
    String Representation
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#copy" class="md-nav__link">
    Copy
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#length-and-comparison" class="md-nav__link">
    Length and Comparison
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#custom-types" class="md-nav__link">
    Custom Types
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#exceptions" class="md-nav__link">
    Exceptions
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#snapshots" class="md-nav__link">
    Snapshots
  </a>
  
</li>
      
    </ul>
  
</nav>
    
  </li>

    
      
      
      


  <li class="md-nav__item">
    <a href="../contributing/" class="md-nav__link">
      Contributing
    </a>
  </li>

    
  </ul>
</nav>
                  </div>
                </div>
              </div>
            
            
              <div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
                <div class="md-sidebar__scrollwrap">
                  <div class="md-sidebar__inner">
                    
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
  
  
    
  
  
    <label class="md-nav__title" for="__toc">
      <span class="md-nav__icon md-icon"></span>
      Table of contents
    </label>
    <ul class="md-nav__list" data-md-scrollfix>
      
        <li class="md-nav__item">
  <a href="#constructor" class="md-nav__link">
    Constructor
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#read-write" class="md-nav__link">
    Read / Write
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#string-representation" class="md-nav__link">
    String Representation
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#copy" class="md-nav__link">
    Copy
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#length-and-comparison" class="md-nav__link">
    Length and Comparison
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#custom-types" class="md-nav__link">
    Custom Types
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#exceptions" class="md-nav__link">
    Exceptions
  </a>
  
</li>
      
        <li class="md-nav__item">
  <a href="#snapshots" class="md-nav__link">
    Snapshots
  </a>
  
</li>
      
    </ul>
  
</nav>
                  </div>
                </div>
              </div>
            
          
          <div class="md-content">
            <article class="md-content__inner md-typeset">
              
                
                  <a href="https://github.com/boisgera/bitstream/edit/master/mkdocs/API.md" title="Edit this page" class="md-content__button md-icon">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z"/></svg>
                  </a>
                
                
                <h1 id="api-reference">API Reference<a class="headerlink" href="#api-reference" title="Permanent link">&para;</a></h1>
<p>We assume in the sequel that all symbols of NumPy and BitStream are available:</p>
<pre><code>&gt;&gt;&gt; from numpy import *
&gt;&gt;&gt; from bitstream import *
</code></pre>
<h2 id="constructor">Constructor<a class="headerlink" href="#constructor" title="Permanent link">&para;</a></h2>
<p>Most of the library features are available through the <code>BitStream</code> class:</p>
<details class="note"><summary><code>BitStream()</code></summary><p>Create an empty bitstream.</p>
<p><h5>Usage</h5></p>
<pre><code>&gt;&gt;&gt; stream = BitStream()
</code></pre>
</details>
<details class="note"><summary><code>BitStream(data, type=None)</code></summary><p>Create an empty bitstream,
then call the <code>write</code> method.</p>
<p><h5>Arguments</h5></p>
<ul>
<li>
<p><code>data</code> is the data to be encoded.</p>
<p>The data type should be consistent with the <code>type</code> argument.</p>
</li>
<li>
<p><code>type</code> is a type identifier (such as <code>bool</code>, <code>bytes</code>, <code>int8</code>, etc.).</p>
<p><code>type</code> can be omitted if <code>data</code> is an instance
    of a registered type or a
    list or 1d NumPy array of such 
    instances.</p>
</li>
</ul>
<p><h5>Usage</h5></p>
<pre><code>&gt;&gt;&gt; stream = BitStream([False, True])
&gt;&gt;&gt; stream = BitStream(b"Hello", bytes)
&gt;&gt;&gt; stream = BitStream(42, uint8)
</code></pre>
<p><h5>See also</h5></p>
<ul>
<li><a href="#read-write">Read / Write</a></li>
</ul>
</details>
<h2 id="read-write">Read / Write<a class="headerlink" href="#read-write" title="Permanent link">&para;</a></h2>
<details class="note"><summary><code>BitStream.write(self, data, type=None)</code></summary><p>Encode <code>data</code> and append it to the stream.</p>
<p><h5>Arguments</h5></p>
<ul>
<li>
<p><code>data</code> is the data to be encoded.</p>
<p>Its type should be consistent with the <code>type</code> argument.</p>
</li>
<li>
<p><code>type</code> is a type identifier (such as <code>bool</code>, <code>str</code>, <code>int8</code>, etc.).</p>
<p><code>type</code> can be omitted if <code>data</code>
    is an instance
    of a registered type or a
    list or 1d NumPy array of such 
    instances.</p>
</li>
</ul>
<p><h5>Usage</h5></p>
<pre><code>&gt;&gt;&gt; stream = BitStream()
&gt;&gt;&gt; stream.write(True, bool)       # explicit bool type
&gt;&gt;&gt; stream.write(False)            # implicit bool type
&gt;&gt;&gt; stream.write(3*[False], bool)  # list (explicit type)
&gt;&gt;&gt; stream.write(3*[True])         # list (implicit type)
&gt;&gt;&gt; stream.write(b"AB", bytes)     # bytes
&gt;&gt;&gt; stream.write(-128, int8)       # signed 8 bit integer
</code></pre>
<p><h5>See also</h5></p>
<ul>
<li>
<p><a href="../types">Builtin Types</a></p>
</li>
<li>
<p><a href="../custom">Custom Types</a></p>
</li>
</ul>
</details>
<details class="note"><summary><code>BitStream.read(self, type=None, n=None)</code></summary><p>Decode and consume <code>n</code> items of <code>data</code> from the start of the stream.</p>
<p><h5>Arguments</h5></p>
<ul>
<li>
<p><code>type</code>: type identifier (such as <code>bool</code>, <code>bytes</code>, <code>int8</code>, etc.)</p>
<p>If <code>type</code> is <code>None</code> a bitstream is returned.</p>
</li>
<li>
<p><code>n</code>: number of items to read</p>
<p>For most types, <code>n=None</code> reads one item, 
    but some types use a different convention.</p>
</li>
</ul>
<p><h5>Returns</h5></p>
<ul>
<li>
<p><code>data</code>: <code>n</code> items of data</p>
<p>The type of <code>data</code> depends on <code>type</code> and <code>n</code>. For built-in types:</p>
<table>
<thead>
<tr>
<th><code>type</code></th>
<th><code>n = None</code></th>
<th><code>n = 0, 1, 2, ...</code></th>
</tr>
</thead>
<tbody>
<tr>
<td><code>bool</code></td>
<td><code>bool</code></td>
<td><code>list</code> of bools</td>
</tr>
<tr>
<td><code>BitStream</code></td>
<td><code>BitStream</code></td>
<td><code>BitStream</code></td>
</tr>
<tr>
<td><code>bytes</code></td>
<td><code>bytes</code></td>
<td><code>bytes</code></td>
</tr>
<tr>
<td><code>numpy.uint8</code></td>
<td><code>numpy.uint8</code></td>
<td><code>numpy.array</code></td>
</tr>
<tr>
<td><code>numpy.int8</code></td>
<td><code>numpy.int8</code></td>
<td><code>numpy.array</code></td>
</tr>
<tr>
<td><code>numpy.uint16</code></td>
<td><code>numpy.int16</code></td>
<td><code>numpy.array</code></td>
</tr>
<tr>
<td>...</td>
<td>...</td>
<td>...</td>
</tr>
<tr>
<td><code>float</code></td>
<td><code>float</code></td>
<td><code>numpy.array</code></td>
</tr>
</tbody>
</table>
</li>
</ul>
<p><h5>Usage</h5></p>
<pre><code>&gt;&gt;&gt; stream = BitStream(b"Hello World!")
&gt;&gt;&gt; stream.read(bytes, 2) # doctest: +BYTES
b'He'
&gt;&gt;&gt; stream.read(bool)
False
&gt;&gt;&gt; stream.read(bool, 7)
[True, True, False, True, True, False, False]
&gt;&gt;&gt; stream.read(uint8, 2)
array([108, 111], dtype=uint8)
&gt;&gt;&gt; stream.read(uint8)
32
&gt;&gt;&gt; stream.read(bytes) # doctest: +BYTES
b'World!'
</code></pre>
<p><h5>See also</h5></p>
<ul>
<li>
<p><a href="../types">Builtin Types</a></p>
</li>
<li>
<p><a href="../custom">Custom Types</a></p>
</li>
</ul>
</details>
<h2 id="string-representation">String Representation<a class="headerlink" href="#string-representation" title="Permanent link">&para;</a></h2>
<details class="note"><summary><code>BitStream.__str__(self)</code></summary><p>Represent the stream as a string of <code>'0'</code> and <code>'1'</code>.</p>
<p><h5>Usage</h5></p>
<pre><code>&gt;&gt;&gt; print(BitStream(b"ABC"))
010000010100001001000011
</code></pre>
</details>
<details class="note"><summary><code>BitStream.__repr__(self)</code></summary><p>Represent the stream as a string of <code>'0'</code> and <code>'1'</code>.</p>
<p><h5>Usage</h5></p>
<pre><code>&gt;&gt;&gt; BitStream(b"ABC")
010000010100001001000011
</code></pre>
</details>
<h2 id="copy">Copy<a class="headerlink" href="#copy" title="Permanent link">&para;</a></h2>
<p>Bitstreams can be copied non-destructively with <code>BitStream.copy</code>. 
They also support the interface required by the standard library <code>copy</code> module.</p>
<details class="note"><summary><code>BitStream.copy(self, n=None)</code></summary><p>Copy (partially or totally) the stream.</p>
<p>Copies do not consume the stream they read.</p>
<p><h5>Arguments</h5></p>
<ul>
<li>
<p><code>n</code>: unsigned integer of <code>None</code>.</p>
<p>The number of bits to copy from the start of the stream. 
    The full stream is copied if <code>n</code> is None.</p>
</li>
</ul>
<p><h5>Returns</h5></p>
<ul>
<li><code>stream</code>: a bitstream.</li>
</ul>
<p><h5>Raises</h5></p>
<ul>
<li><code>ReadError</code> if <code>n</code> is larger than the length of the stream.</li>
</ul>
<p><h5>Usage</h5></p>
<pre><code>&gt;&gt;&gt; stream = BitStream(b"A")
&gt;&gt;&gt; stream
01000001
&gt;&gt;&gt; copy = stream.copy()
&gt;&gt;&gt; copy
01000001
&gt;&gt;&gt; stream
01000001
&gt;&gt;&gt; stream.copy(4)
0100
&gt;&gt;&gt; stream
01000001
&gt;&gt;&gt; stream.read(BitStream, 4)
0100
&gt;&gt;&gt; stream
0001
</code></pre>
</details>
<details class="note"><summary><code>BitStream.__copy__(self)</code></summary><p>Bitstream shallow copy.</p>
<p><h5>Usage</h5></p>
<pre><code>&gt;&gt;&gt; from copy import copy
&gt;&gt;&gt; stream = BitStream(b"A")
&gt;&gt;&gt; stream
01000001
&gt;&gt;&gt; copy(stream)
01000001
&gt;&gt;&gt; stream
01000001
</code></pre>
</details>
<details class="note"><summary><code>BitStream.__deepcopy__(self, memo)</code></summary><p>Bitstream deep copy.</p>
<p><h5>Usage</h5></p>
<pre><code>&gt;&gt;&gt; from copy import deepcopy
&gt;&gt;&gt; stream = BitStream(b"A")
&gt;&gt;&gt; stream
01000001
&gt;&gt;&gt; deepcopy(stream)
01000001
&gt;&gt;&gt; stream
01000001
</code></pre>
</details>
<h2 id="length-and-comparison">Length and Comparison<a class="headerlink" href="#length-and-comparison" title="Permanent link">&para;</a></h2>
<details class="note"><summary><code>BitStream.__len__(self, other)</code></summary><p>Return the bitstream length in bits.</p>
<p><h5>Usage</h5></p>
<pre><code>&gt;&gt;&gt; stream = BitStream([True, False])
&gt;&gt;&gt; len(stream) 
2

&gt;&gt;&gt; stream = BitStream(b"ABC")
&gt;&gt;&gt; len(stream)
24
&gt;&gt;&gt; len(stream) // 8
3
&gt;&gt;&gt; len(stream) % 8
0
</code></pre>
</details>
<details class="note"><summary><code>BitStream.__eq__(self, other)</code></summary><p>Equality operator</p>
<p><h5>Usage</h5></p>
<pre><code>&gt;&gt;&gt; BitStream(True) == BitStream(True)
True
&gt;&gt;&gt; BitStream(True) == BitStream([True])
True
&gt;&gt;&gt; BitStream(True) == BitStream(False)
False
&gt;&gt;&gt; BitStream(True) == BitStream([True, False])
False

&gt;&gt;&gt; ord(b"A")
65
&gt;&gt;&gt; BitStream(b"A") == BitStream(65, uint8)
True
&gt;&gt;&gt; BitStream(b"A") == BitStream(66, uint8)
False
</code></pre>
</details>
<details class="note"><summary><code>BitStream.__ne__(self, other)</code></summary><p>Inequality operator</p>
<p><h5>Usage</h5></p>
<pre><code>&gt;&gt;&gt; BitStream(True) != BitStream(True)
False
&gt;&gt;&gt; BitStream(True) != BitStream([True])
False
&gt;&gt;&gt; BitStream(True) != BitStream(False)
True
&gt;&gt;&gt; BitStream(True) != BitStream([True, False])
True

&gt;&gt;&gt; ord(b"A")
65
&gt;&gt;&gt; BitStream(b"A") != BitStream(65, uint8)
False
&gt;&gt;&gt; BitStream(b"A") != BitStream(66, uint8)
True
</code></pre>
</details>
<details class="note"><summary><code>BitStream.__hash__(self)</code></summary><p>Compute a bitstream hash </p>
<p>The computed hash is consistent with the equality operator.</p>
</details>
<h2 id="custom-types">Custom Types<a class="headerlink" href="#custom-types" title="Permanent link">&para;</a></h2>
<p>User-defined binary codecs can be bound to type identifiers.
For details, refer to <a href="../custom">Custom Types</a>.</p>
<details class="note"><summary><code>register(type, reader=None, writer=None)</code></summary><p>Register a binary encoding (and/or) decoding.</p>
<ul>
<li>
<p><code>type</code> is a type identifier (type or "type tag").</p>
</li>
<li>
<p><code>reader</code> is a function with signature <code>reader(stream, n=None)</code>.</p>
</li>
<li>
<p><code>writer</code> is a function with signature <code>writer(stream, data)</code>.</p>
</li>
</ul>
</details>
<h2 id="exceptions">Exceptions<a class="headerlink" href="#exceptions" title="Permanent link">&para;</a></h2>
<details class="note"><summary><code>ReadError</code></summary><p>Exception raised when a binary decoding is impossible.</p>
</details>
<details class="note"><summary><code>WriteError</code></summary><p>Exception raised when a binary encoding is impossible.</p>
</details>
<h2 id="snapshots">Snapshots<a class="headerlink" href="#snapshots" title="Permanent link">&para;</a></h2>
<p>Save and restore stream states. 
For details, refer to <a href="snapshots">Snapshots</a>.</p>
<p>As a user, you should not rely on the implementation of <code>State</code> 
which is an internal detail: 
instances of <code>State</code> have no public attribute, no public method,
they can only be produced by <code>save</code> and consumed by <code>restore</code>.</p>
<details class="note"><summary><code>State</code></summary><p>The opaque type of stream state.</p>
</details>
<details class="note"><summary><code>BitStream.save(self)</code></summary><p>Return a <code>State</code> instance</p>
</details>
<details class="note"><summary><code>BitStream.restore(self, state)</code></summary><p>Restore a previous stream state.</p>
<p>Raise a <code>ValueError</code> if the state is invalid.</p>
</details>
                
              
              
                


              
            </article>
          </div>
        </div>
      </main>
      
        
<footer class="md-footer">
  
    <div class="md-footer-nav">
      <nav class="md-footer-nav__inner md-grid" aria-label="Footer">
        
          <a href="../snapshots/" class="md-footer-nav__link md-footer-nav__link--prev" rel="prev">
            <div class="md-footer-nav__button md-icon">
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
            </div>
            <div class="md-footer-nav__title">
              <div class="md-ellipsis">
                <span class="md-footer-nav__direction">
                  Previous
                </span>
                Snapshots
              </div>
            </div>
          </a>
        
        
          <a href="../contributing/" class="md-footer-nav__link md-footer-nav__link--next" rel="next">
            <div class="md-footer-nav__title">
              <div class="md-ellipsis">
                <span class="md-footer-nav__direction">
                  Next
                </span>
                Contributing
              </div>
            </div>
            <div class="md-footer-nav__button md-icon">
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11H4z"/></svg>
            </div>
          </a>
        
      </nav>
    </div>
  
  <div class="md-footer-meta md-typeset">
    <div class="md-footer-meta__inner md-grid">
      <div class="md-footer-copyright">
        
        Made with
        <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
          Material for MkDocs
        </a>
      </div>
      
    </div>
  </div>
</footer>
      
    </div>
    
      <script src="../assets/javascripts/vendor.0ac82a11.min.js"></script>
      <script src="../assets/javascripts/bundle.f81dfb4d.min.js"></script><script id="__lang" type="application/json">{"clipboard.copy": "Copy to clipboard", "clipboard.copied": "Copied to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.placeholder": "Type to start searching", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.term.missing": "Missing"}</script>
      
      <script>
        app = initialize({
          base: "..",
          features: [],
          search: Object.assign({
            worker: "../assets/javascripts/worker/search.4ac00218.min.js"
          }, typeof search !== "undefined" && search)
        })
      </script>
      
    
  </body>
</html>