# Path: bdec/constraints.py
# class Equals(Constraint):
#     type = '!='
# 
#     def check(self, entry, value, context):
#         expected = self.limit.evaluate(context)
#         if isinstance(expected, int):
#             if int(value) !=  expected:
#                 raise ConstraintError(entry, int(value), '==', expected)
#         elif isinstance(expected, Data):
#             # We aren't checking the length here, only the value (for example,
#             # the expected value for a variable length binary field will have
#             # a different length than the actual). Only compare the bits that
#             # are valid.
#             length_diff = len(value) - len(expected)
#             if length_diff > 0:
#                 # The expected value is shorter than the actual, so grow it.
#                 expected = Data('\x00' * (length_diff / 8 + 1), 0, length_diff) + expected
#             elif length_diff < 0:
#                 # The expected value is longer than the actual, so shrink it.
#                 shorter = expected.copy()
#                 leading = shorter.pop(-length_diff)
#                 if not int(leading):
#                     # We can safely pop the leading bits.
#                     expected = shorter
#             if value !=  expected:
#                 raise ConstraintError(entry, value, '==', expected)
#         else:
#             if value !=  expected:
#                 raise ConstraintError(entry, value, '==', expected)
# 
#     def range(self):
#         limit = _limit(self.limit)
#         return Range(limit, limit)
# 
# Path: bdec/encode/sequenceof.py
# class InvalidSequenceOfCount(DecodeError):
#     """Raised during encoding when an invalid length is found."""
#     def __init__(self, seq, expected, actual):
#         DecodeError.__init__(self, seq)
#         self.sequenceof = seq
#         self.expected = expected
#         self.actual = actual
# 
#     def __str__(self):
#         return "%s expected count of %s, got %s" % (self.sequenceof, self.expected, self.actual)
# 
# Path: bdec/output/instance.py
# def encode(protocol, value):
#     """
#     Encode a python instance to binary data.
# 
#     Returns a bdec.data.Data instance.
#     """
#     return reduce(operator.add, protocol.encode(_get_value, {protocol.name: value}), Data())


import unittest
import bdec.choice as chc
import bdec.expression as expr
import bdec.data as dt
import bdec.field as fld
import bdec.sequence as seq
import bdec.sequenceof as sof
from bdec.constraints import Equals
from bdec.encode.sequenceof import InvalidSequenceOfCount
from bdec.output.instance import encode
        items = [value for is_starting, name, entry, data, value in sequenceof.decode(rawdata) if isinstance(entry, fld.Field) and not is_starting]
        self.assertEqual(4, len(items))
        self.assertEqual('date', ''.join(items))
        self.assertEqual('', rawdata.bytes())

    def test_encoding_greedy_sequenceof(self):
        sequenceof = sof.SequenceOf("blah", fld.Field("cat", 8, format=fld.Field.INTEGER), None)
        data = [5, 9, 0xf6]
        data = encode(sequenceof, data)
        self.assertEqual("\x05\x09\xf6", data.bytes())

    def test_negative_count(self):
        sequenceof = sof.SequenceOf("blah", fld.Field("cat", 8, format=fld.Field.INTEGER), -1)
        self.assertRaises(sof.NegativeSequenceofLoop, list, sequenceof.decode(dt.Data("")))

    def test_end_entries(self):
        null = fld.Field("null", 8, constraints=[Equals(dt.Data('\x00'))])
        char = fld.Field("char", 8)
        sequenceof = sof.SequenceOf("null terminated string", chc.Choice('entry', [null, char]), None, end_entries=[null])
        actual = []
        data = dt.Data("hello\x00bob")
        result = ""
        for is_starting, name, entry, entry_data, value in sequenceof.decode(data):
            if not is_starting and entry.name == "char":
                result += entry_data.bytes()

        self.assertEqual("hello", result)
        self.assertEqual("bob", data.bytes())

    def test_sequenceof_ended_early(self):

# Path: bdec/constraints.py
# class Equals(Constraint):
#     type = '!='
# 
#     def check(self, entry, value, context):
#         expected = self.limit.evaluate(context)
#         if isinstance(expected, int):
#             if int(value) !=  expected:
#                 raise ConstraintError(entry, int(value), '==', expected)
#         elif isinstance(expected, Data):
#             # We aren't checking the length here, only the value (for example,
#             # the expected value for a variable length binary field will have
#             # a different length than the actual). Only compare the bits that
#             # are valid.
#             length_diff = len(value) - len(expected)
#             if length_diff > 0:
#                 # The expected value is shorter than the actual, so grow it.
#                 expected = Data('\x00' * (length_diff / 8 + 1), 0, length_diff) + expected
#             elif length_diff < 0:
#                 # The expected value is longer than the actual, so shrink it.
#                 shorter = expected.copy()
#                 leading = shorter.pop(-length_diff)
#                 if not int(leading):
#                     # We can safely pop the leading bits.
#                     expected = shorter
#             if value !=  expected:
#                 raise ConstraintError(entry, value, '==', expected)
#         else:
#             if value !=  expected:
#                 raise ConstraintError(entry, value, '==', expected)
# 
#     def range(self):
#         limit = _limit(self.limit)
#         return Range(limit, limit)
# 
# Path: bdec/encode/sequenceof.py
# class InvalidSequenceOfCount(DecodeError):
#     """Raised during encoding when an invalid length is found."""
#     def __init__(self, seq, expected, actual):
#         DecodeError.__init__(self, seq)
#         self.sequenceof = seq
#         self.expected = expected
#         self.actual = actual
# 
#     def __str__(self):
#         return "%s expected count of %s, got %s" % (self.sequenceof, self.expected, self.actual)
# 
# Path: bdec/output/instance.py
# def encode(protocol, value):
#     """
#     Encode a python instance to binary data.
# 
#     Returns a bdec.data.Data instance.
#     """
#     return reduce(operator.add, protocol.encode(_get_value, {protocol.name: value}), Data())


# Path: bdec/test/testsequenceof.py
import unittest
import bdec.choice as chc
import bdec.expression as expr
import bdec.data as dt
import bdec.field as fld
import bdec.sequence as seq
import bdec.sequenceof as sof
from bdec.constraints import Equals
from bdec.encode.sequenceof import InvalidSequenceOfCount
from bdec.output.instance import encode

        items = [value for is_starting, name, entry, data, value in sequenceof.decode(rawdata) if isinstance(entry, fld.Field) and not is_starting]
        self.assertEqual(4, len(items))
        self.assertEqual('date', ''.join(items))
        self.assertEqual('', rawdata.bytes())

    def test_encoding_greedy_sequenceof(self):
        sequenceof = sof.SequenceOf("blah", fld.Field("cat", 8, format=fld.Field.INTEGER), None)
        data = [5, 9, 0xf6]
        data = encode(sequenceof, data)
        self.assertEqual("\x05\x09\xf6", data.bytes())

    def test_negative_count(self):
        sequenceof = sof.SequenceOf("blah", fld.Field("cat", 8, format=fld.Field.INTEGER), -1)
        self.assertRaises(sof.NegativeSequenceofLoop, list, sequenceof.decode(dt.Data("")))

    def test_end_entries(self):
        null = fld.Field("null", 8, constraints=[Equals(dt.Data('\x00'))])
        char = fld.Field("char", 8)
        sequenceof = sof.SequenceOf("null terminated string", chc.Choice('entry', [null, char]), None, end_entries=[null])
        actual = []
        data = dt.Data("hello\x00bob")
        result = ""
        for is_starting, name, entry, entry_data, value in sequenceof.decode(data):
            if not is_starting and entry.name == "char":
                result += entry_data.bytes()

        self.assertEqual("hello", result)
        self.assertEqual("bob", data.bytes())

    def test_sequenceof_ended_early(self):

        null = fld.Field("null", 8, constraints=[Equals(dt.Data('\x00'))])