--------------------------------
bitstring module version history
--------------------------------
-------------------------------------------------------
October 9th 2009: version 1.0.0 for Python 2.x released
-------------------------------------------------------
Version 1 is here!

This is the first release not to carry the 'beta' tag. It contains a couple of
minor new features but is principally a release to fix the API. If you've been
using an older version then you almost certainly will have to recode a bit. If
you're not ready to do that then you may wish to delay updating.

So the bad news is that there are lots of small changes to the API. The good
news is that all the changes are pretty trivial, the new API is cleaner and
more 'Pythonic', and that by making it version 1.0 I'm promising not to
tweak it again for some time.

** API Changes **

* New read / peek functions for returning multiple items.

The functions read, readbits, readbytes, peek, peekbits and peekbytes now only
ever return a single item, never a list.

The new functions readlist, readbitlist, readbytelist, peeklist, peekbitlist
and peekbytelist can be used to read multiple items and will always return a
list.

So a line like:

>>> a, b = s.read('uint:12, hex:32')

becomes

>>> a, b = s.readlist('uint:12, hex:32')

* Renaming / removing functions.

Functions have been renamed as follows:

seekbit -> seek
tellbit -> tell
reversebits -> reverse
deletebits -> delete
tostring -> tobytes

and a couple have been removed altogether:

deletebytes - use delete instead.
empty - use 'not s' rather than 's.empty()'.

* Renaming parameters.

The parameters 'startbit' and 'endbit' have been renamed 'start' and 'end'.
This affects the functions slice, find, findall, rfind, reverse, cut and split.

The parameter 'bitpos' has been renamed to 'pos'. The affects the functions
seek, tell, insert, overwrite and delete.

* Mutating methods return None rather than self.

This means that you can't chain functions together so

>>> s.append('0x00').prepend('0xff')
>>> t = s.reverse()

Needs to be rewritten

>>> s.append('0x00')
>>> s.prepend('0xff)
>>> s.reverse()
>>> t = s

Affects truncatestart, truncateend, insert, overwrite, delete, append,
prepend, reverse and reversebytes.

* Properties renamed.

The 'data' property has been renamed to 'bytes'. Also if the BitString is not a
whole number of bytes then a ValueError exception will be raised when using
'bytes' as a 'getter'.

Properties 'len' and 'pos' have been added to replace 'length' and 'bitpos',
although the longer names have not been removed so you can continue to use them
if you prefer.

* Other changes.

The unpack function now always returns a list, never a single item.

BitStrings are now 'unhashable', so calling hash on one or making a set will
fail.

The colon separating the token name from its length is now mandatory. So for
example BitString('uint12=100') becomes BitString('uint:12=100').

Removed support for the 'bytes' token in format strings. Instead of
s.read('bytes:4') use s.read('bits:32'). 

** New features **

* Added endswith and startswith functions.

These do much as you'd expect; they return True or False depending on whether
the BitString starts or ends with the parameter.

>>> BitString('0xef342').startswith('0b11101')
True

----------------------------------------------------------
September 11th 2009: version 0.5.2 for Python 2.x released
----------------------------------------------------------
Finally some tools for dealing with endianness!

* New interpretations are now available for whole-byte BitStrings that treat
them as big, little, or native-endian.

>>> big = BitString(intbe=1, length=16) # or BitString('intbe:16=1') if you prefer.
>>> little = BitString(intle=1, length=16)
>>> print big.hex, little.hex
0x0001 0x0100
>>> print big.intbe, little.intle
1 1

* 'Struct'-like compact format codes

To save some typing when using pack, unpack, read and peek, compact format
codes based on those used in the struct and array modules have been added.
These must start with a character indicating the endianness (>, < or @ for
big, little and native-endian), followed by characters giving the format:

b 	1-byte signed int
B 	1-byte unsigned int
h 	2-byte signed int
H 	2-byte unsigned int
l 	4-byte signed int
L 	4-byte unsigned int
q 	8-byte signed int
Q 	8-byte unsigned int

For example:

>>> s = bitstring.pack('<4h', 0, 1, 2, 3)

creates a BitString with four little-endian 2-byte integers. While

>>> x, y, z = s.read('>hhl')

reads them back as two big-endian two-byte integers and one four-byte big
endian integer.

Of course you can combine this new format with the old ones however you like:

>>> s.unpack('<h, intle:24, uint:5, bin')
[0, 131073, 0, '0b0000000001100000000']

-------------------------------------------------------
August 26th 2009: version 0.5.1 for Python 2.x released
-------------------------------------------------------

This update introduces pack and unpack functions for creating and dissembling
BitStrings.

* New pack() and unpack() functions.

The module level pack function provides a flexible new method for creating
BitStrings. Tokens for BitString 'literals' can be used in the same way as in
the constructor.

>>> from bitstring import BitString, pack
>>> a = pack('0b11, 0xff, 0o77, int:5=-1, se=33')

You can also leave placeholders in the format, which will be filled in by
the values provided.

>>> b = pack('uint:10, hex:4', 33, 'f')

Finally you can use a dictionary or keywords.

>>> c = pack('bin=a, hex=b, bin=a', a='010', b='ef')

The unpack function is similar to the read function except that it always
unpacks from the start of the BitString.

>>> x, y = b.unpack('uint:10, hex')

If a token is given without a length (as above) then it will expand to fill the
remaining bits in the BitString. This also now works with read() and peek().

* New tostring() and tofile() functions.

The tostring() function just returns the data as a string, with up to seven
zero bits appended to byte align. The tofile() function does the same except
writes to a file object.

>>> f = open('myfile', 'wb')
>>> BitString('0x1234ff').tofile(f)

* Other changes.

The use of '=' is now mandatory in 'auto' initialisers. Tokens like 'uint12 100' will
no longer work. Also the use of a ':' before the length is encouraged, but not yet
mandated. So the previous example should be written as 'uint:12=100'.

The 'auto' initialiser will now take a file object.

>>> f = open('myfile', 'rb')
>>> s = BitString(f)

-----------------------------------------------------
July 19th 2009: version 0.5.0 for Python 2.x released
-----------------------------------------------------

This update breaks backward compatibility in a couple of areas. The only one
you probably need to be concerned about is the change to the default for
bytealigned in find, replace, split, etc.

See the user manual for more details on each of these items.

* Expanded abilities of 'auto' initialiser.

More types can be initialised through the 'auto' initialiser. For example
instead of

>>> a = BitString(uint=44, length=16)

you can write

>>> a = BitString('uint16=44')

Also, different comma-separated tokens will be joined together, e.g.

>>> b = BitString('0xff') + 'int8=-5'

can be written

>>> b = BitString('0xff, int8=-5')

* New formatted read() and peek() functions.

These takes a format string similar to that used in the auto initialiser.
If only one token is provided then a single value is returned, otherwise a
list of values is returned.

>>> start_code, width, height = s.read('hex32, uint12, uint12')

is equivalent to

>>> start_code = s.readbits(32).hex
>>> width = s.readbits(12).uint
>>> height = s.readbits(12).uint

The tokens are:

  int n   : n bits as an unsigned integer.
  uint n  : n bits as a signed integer.
  hex n   : n bits as a hexadecimal string.
  oct n   : n bits as an octal string.
  bin n   : n bits as a binary string.
  ue      : next bits as an unsigned exp-Golomb.
  se      : next bits as a signed exp-Golomb.
  bits n  : n bits as a new BitString.
  bytes n : n bytes as a new BitString.

See the user manual for more details.

* hex() and oct() functions removed.

The special functions for hex() and oct() have been removed. Please use the
hex and oct properties instead.

>>> hex(s)

becomes
 
>>> s.hex

* join made a member function.

The join function must now be called on a BitString object, which will be
used to join the list together. You may need to recode slightly:

>>> s = bitstring.join('0x34', '0b1001', '0b1')

becomes

>>> s = BitString().join('0x34', '0b1001', '0b1')

* More than one value allowed in readbits, readbytes, peekbits and peekbytes

If you specify more than one bit or byte length then a list of BitStrings will
be returned.

>>> a, b, c = s.readbits(10, 5, 5)

is equivalent to

>>> a = readbits(10)
>>> b = readbits(5)
>>> c = readbits(5)

* bytealigned defaults to False, and is at the end of the parameter list

Functions that have a bytealigned paramater have changed so that it now
defaults to False rather than True. Also its position in the parameter list
has changed to be at the end. You may need to recode slightly (sorry!)

* readue and readse functions have been removed

Instead you should use the new read function with a 'ue' or 'se' token:

>>> i = s.readue()

becomes

>>> i = s.read('ue')

This is more flexible as you can read multiple items in one go, plus you can
now also use the peek function with ue and se.

* Minor bugs fixed.

See the issue tracker for more details.

-----------------------------------------------------
June 15th 2009: version 0.4.3 for Python 2.x released
-----------------------------------------------------

This is a minor update. This release is the first to bundle the bitstring
manual. This is a PDF and you can find it in the docs directory.

Changes in version 0.4.3

* New 'cut' function

This function returns a generator for constant sized chunks of a BitString.

>>> for byte in s.cut(8):
...     do_something_with(byte)

You can also specify a startbit and endbit, as well as a count, which limits
the number of items generated:

>>> first100TSPackets = list(s.cut(188*8, count=100))

* 'slice' function now equivalent to __getitem__.

This means that a step can also be given to the slice function so that the
following are now the same thing, and it's just a personal preference which
to use:

>>> s1 = s[a:b:c]
>>> s2 = s.slice(a, b, c)

* findall gets a 'count' parameter.

So now

>>> list(a.findall(s, count=n))

is equivalent to

>>> list(a.findall(s))[:n]

except that it won't need to generate the whole list and so is much more
efficient.

* Changes to 'split'.

The split function now has a 'count' parameter rather than 'maxsplit'. This
makes the interface closer to that for cut, replace and findall. The final item
generated is now no longer the whole of the rest of the BitString.

* A couple of minor bugs were fixed. See the issue tracker for details.

----------------------------------------------------
May 25th 2009: version 0.4.2 for Python 2.x released
----------------------------------------------------

This is a minor update, and almost doesn't break compatibility with version
0.4.0, but with the slight exception of findall() returning a generator,
detailed below.

Changes in version 0.4.2

* Stepping in slices

The use of the step parameter (also known as the stride) in slices has been
added. Its use is a little non-standard as it effectively gives a multiplicative
factor to apply to the start and stop parameters, rather than skipping over
bits.

For example this makes it much more convenient if you want to give slices in
terms of bytes instead of bits. Instead of writing s[a*8:b*8] you can use
s[a:b:8].

When using a step the BitString is effectively truncated to a multiple of the
step, so s[::8] is equal to s if s is an integer number of bytes, otherwise it
is truncated by up to 7 bits. So the final seven complete 16-bit words could be
written as s[-7::16]

Negative slices are also allowed, and should do what you'd expect. So for
example s[::-1] returns a bit-reversed copy of s (which is similar to
s.reversebits(), which does the same operation on s in-place). As another
example, to get the first 10 bytes in reverse byte order you could use
s_bytereversed = s[0:10:-8].

* Removed restrictions on offset

You can now specify an offset of greater than 7 bits when creating a BitString,
and the use of offset is also now permitted when using the filename initialiser.
This is useful when you want to create a BitString from the middle of a file
without having to read the file into memory.

>>> f = BitString(filename='reallybigfile', offset=8000000, length=32)

* Integers can be assigned to slices

You can now assign an integer to a slice of a BitString. If the integer doesn't
fit in the size of slice given then a ValueError exception is raised. So this
is now allowed and works as expected:

>>> s[8:16] = 106

and is equivalent to

>>> s[8:16] = BitString(uint=106, length=8)

* Less exceptions raised

Some changes have been made to slicing so that less exceptions are raised,
bringing the interface closer to that for lists. So for example trying to delete
past the end of the BitString will now just delete to the end, rather than
raising a ValueError.

* Initialisation from lists and tuples

A new option for the auto initialiser is to pass it a list or tuple. The items
in the list or tuple are evaluated as booleans and the bits in the BitString are
set to 1 for True items and 0 for False items. This can be used anywhere the
auto initialiser can currently be used. For example:

>>> a = BitString([True, 7, False, 0, ()])     # 0b11000
>>> b = a + ['Yes', '']                        # Adds '0b10'
>>> (True, True, False) in a
True

* Miscellany

reversebits() now has optional startbit and endbit parameters.

As an optimisation findall() will return a generator, rather than a list. If you
still want the whole list then of course you can just call list() on the
generator.

Improved efficiency of rfind().

A couple of minor bugs were fixed. See the issue tracker for details. 

-----------------------------------------------------
April 23rd 2009: Python 3 only version 0.4.1 released
-----------------------------------------------------

This version is just a port of version 0.4.0 to Python 3. All the unit tests
pass, but beyond that only limited ad hoc testing has been done and so it
should be considered an experimental release. That said, the unit test
coverage is very good - I'm just not sure if anyone even wants a Python 3
version! 

---------------------------------------
April 11th 2009: version 0.4.0 released
---------------------------------------
Changes in version 0.4.0

* New functions

Added rfind(), findall(), replace(). These do pretty much what you'd expect -
see the docstrings or the wiki for more information.

* More special functions

Some missing functions were added: __repr__, __contains__, __rand__,
__ror__, _rxor__ and __delitem__.

* Miscellany

A couple of small bugs were fixed (see the issue tracker).

----

There are some small backward incompatibilities relative to version 0.3.2:

* Combined find() and findbytealigned()

findbytealigned() has been removed, and becomes part of find(). The default
start position has changed on both find() and split() to be the start of the
BitString. You may need to recode:

>>> s1.find(bs)
>>> s2.findbytealigned(bs)
>>> s2.split(bs)

becomes

>>> s1.find(bs, bytealigned=False, startbit=s1.bitpos)
>>> s2.find(bs, startbit=s1.bitpos)  # bytealigned defaults to True
>>> s2.split(bs, startbit=s2.bitpos)

* Reading off end of BitString no longer raises exception.

Previously a read or peek function that encountered the end of the BitString
would raise a ValueError. It will now instead return the remainder of the
BitString, which could be an empty BitString. This is closer to the file
object interface.

* Removed visibility of offset.

The offset property was previously read-only, and has now been removed from
public view altogether. As it is used internally for efficiency reasons you
shouldn't really have needed to use it. If you do then use the _offset parameter
instead (with caution).

---------------------------------------
March 11th 2009: version 0.3.2 released
---------------------------------------
Changes in version 0.3.2

* Better performance

A number of functions (especially find() and findbytealigned()) have been sped
up considerably.

* Bit-wise operations

Added support for bit-wise AND (&), OR (|) and XOR (^). For example:

>>> a = BitString('0b00111')
>>> print a & '0b10101'
0b00101

* Miscellany

Added seekbit() and seekbyte() functions. These complement the 'advance' and
'retreat' functions, although you can still just use bitpos and bytepos
properties directly.

>>> a.seekbit(100)                   # Equivalent to a.bitpos = 100

Allowed comparisons between BitString objects and strings. For example this
will now work:

>>> a = BitString('0b00001111')
>>> a == '0x0f'
True

------------------------------------------
February 26th 2009: version 0.3.1 released
------------------------------------------
Changes in version 0.3.1

This version only adds features and fixes bugs relative to 0.3.0, and doesn't
break backwards compatibility.

* Octal interpretation and initialisation

The oct property now joins bin and hex. Just prefix octal numbers with '0o'.

>>> a = BitString('0o755')
>>> print a.bin
0b111101101

* Simpler copying

Rather than using b = copy.copy(a) to create a copy of a BitString, now you
can just use b = BitString(a).

* More special methods

Lots of new special methods added, for example bit-shifting via << and >>,
equality testing via == and !=, bit inversion (~) and concatenation using *.

Also __setitem__ is now supported so BitString objects can be modified using
standard index notation.

* Proper installer

Finally got round to writing the distutils script. To install just
python setup.py install.

------------------------------------------
February 15th 2009: version 0.3.0 released
------------------------------------------
Changes in version 0.3.0

* Simpler initialisation from binary and hexadecimal

The first argument in the BitString constructor is now called auto and will
attempt to interpret the type of a string. Prefix binary numbers with '0b'
and hexadecimals with '0x'.

>>> a = BitString('0b0')         # single zero bit
>>> b = BitString('0xffff')      # two bytes

Previously the first argument was data, so if you relied on this then you
will need to recode:

>>> a = BitString('\x00\x00\x01\xb3')   # Don't do this any more!

becomes

>>> a = BitString(data='\x00\x00\x01\xb3')

or just

>>> a = BitString('0x000001b3')

This new notation can also be used in functions that take a BitString as an
argument. For example:

>>> a = BitString('0x0011') + '0xff'
>>> a.insert('0b001', 6)
>>> a.find('0b1111')

* BitString made more mutable

The functions append, deletebits, insert, overwrite, truncatestart and
truncateend now modify the BitString that they act upon. This allows for
cleaner and more efficient code, but you may need to rewrite slightly if you
depended upon the old behaviour:

>>> a = BitString(hex='0xffff')
>>> a = a.append(BitString(hex='0x00'))
>>> b = a.deletebits(10, 10)

becomes:

>>> a = BitString('0xffff')
>>> a.append('0x00')
>>> b = copy.copy(a)
>>> b.deletebits(10, 10)

Thanks to Frank Aune for suggestions in this and other areas.

* Changes to printing

The binary interpretation of a BitString is now prepended with '0b'. This is
in keeping with the Python 2.6 (and 3.0) bin function. The prefix is optional
when initialising using 'bin='.

Also, if you just print a BitString with no interpretation it will pick
something appropriate - hex if it is an integer number of bytes, otherwise
binary. If the BitString representation is very long it will be truncated
by '...' so it is only an approximate interpretation.

>>> a = BitString('0b0011111')
>>> print a
0b0011111
>>> a += '0b0'
>>> print a
0x3e

* More convenience functions

Some missing functions such as advancebit and deletebytes have been added. Also
a number of peek functions make an appearance as have prepend and reversebits.
See the Tutorial for more details.

-----------------------------------------
January 13th 2009: version 0.2.0 released
-----------------------------------------
Some fairly minor updates, not really deserving of a whole version point update.
------------------------------------------
December 29th 2008: version 0.1.0 released
------------------------------------------
First release!