# -*- Mode: Python; py-indent-offset: 4 -*-
#
# Copyright (C) 2003,2004,2007  Ray Burr
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# See: <http://www.gnu.org/copyleft/gpl.html>
#

"""
Utilities for using Python iterators with bitstreams.

:authors: Ray Burr
:license: GPL
:contact: http://www.nightmare.com/~ryb/
"""

__version__ = "20070612"


import itertools as _it


def fileToCharIter(file):
    while 1:
        c = file.read(1)
        if not c:
            break
        yield c


def fileToByteIter(file):
    return iter(_it.imap(ord, fileToCharIter(file)))


def byteToBinaryIter(source):
    source = iter(source)
    for b in source:
        for i in range(7,-1,-1):
            yield (b >> i) & 1


def fileToBinaryIter(file):
    return iter(byteToBinaryIter(fileToByteIter(file)))


def binaryToByteIter(source):
    source = iter(source)
    while 1:
        x = 0
        for i in range(8):
            x <<= 1
            x |= (source.next() & 1)
        yield x


def binaryToCharIter(source):
    return iter(_it.imap(chr, binaryToByteIter(source)))


def binaryInvertIter(source):
    source = iter(source)
    for b in source:
        yield int(not b)


def binaryDifferentialIter(source):
    source = iter(source)
    bp = source.next()
    for b in source:
        yield int(bp != b)
        bp = b


def asciiToBinaryIter(source):
    source = iter(source)
    for c in source:
        yield "01".index(c)


def binaryToAsciiIter(source):
    source = iter(source)
    for b in source:
        if b not in (0, 1):
            raise ValueError("not binary %r" % b)
        yield b and "1" or "0"
