# Path: bdec/encode/entry.py
# class MissingInstanceError(bdec.DecodeError):
#     """
#     Error raised during encoding when a parent object doesn't have a named child object.
#     """
#     def __init__(self, parent, child):
#         bdec.DecodeError.__init__(self, child)
#         self.parent = parent
#         self.child = child
# 
#     def __str__(self):
#         return "object '%s' doesn't have child object '%s'" % (self.parent, self.child.name)
# 
# Path: bdec/expression.py
# class ValueResult(ReferenceExpression):
#     """
#     Object returning the result of a entry when cast to an integer.
#     """
#     def param_name(self):
#         return self.name
# 
#     def __repr__(self):
#         return '${%s}' % self.name
# 
# 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)
# 
# class ConstraintError(DecodeError):
#     def __init__(self, entry, actual, comparison, limit):
#         DecodeError.__init__(self, entry)
#         self._comparision = comparison
#         self._expected = limit
#         self._actual = actual
# 
#     def __str__(self):
#         return 'Expected ${%s} %s %s; got %s' % (self.entry.name,
#                 self._comparision, self._expected, self._actual)


import operator
import unittest
import bdec.entry as ent
import bdec.choice as chc
import bdec.data as dt
import bdec.field as fld
import bdec.sequence as seq
import bdec.expression as expr
from bdec.encode.entry import MissingInstanceError
from bdec.expression import ValueResult
from bdec.constraints import Equals, ConstraintError
        byte = seq.Sequence('8 bit:', [
            fld.Field('id', 8, constraints=[Equals(dt.Data('\x00'))]),
            fld.Field('length', 8)],
            value=expr.compile('${length}'))
        word = seq.Sequence('16 bit:', [
            fld.Field('id', 8, constraints=[Equals(dt.Data('\x01'))]),
            fld.Field('length', 16)],
            value=expr.compile('${length}'))
        length = chc.Choice('variable integer', [byte, word])
        data = fld.Field('data', expr.compile('${variable integer}'), fld.Field.TEXT)
        spec = seq.Sequence('spec', [length, data])

        results = dict((entry, value)for is_starting, name, entry, entry_data, value in spec.decode(dt.Data('\x00\x20abcde')) if not is_starting)
        self.assertEqual('abcd', results[data])

        results = dict((entry, value)for is_starting, name, entry, entry_data, value in spec.decode(dt.Data('\x01\x00\x20abcde')) if not is_starting)
        self.assertEqual('abcd', results[data])

    def test_best_guess_number_of_entries(self):
        # A common pattern is to have a common type, then select on it using
        # sequences with an expected value. Even when a sequent field fails,
        # it should still report an error given the context of the failing
        # entry.
        a = seq.Sequence('a', [
            fld.Field('type:', length=8),
            chc.Choice('b', [
                seq.Sequence('c', [
                    seq.Sequence('c1', [], value=ValueResult('type:'), constraints=[Equals(0)]),
                    fld.Field('c2', length=8, constraints=[Equals(dt.Data('c'))])]),
                seq.Sequence('d', [

# Path: bdec/encode/entry.py
# class MissingInstanceError(bdec.DecodeError):
#     """
#     Error raised during encoding when a parent object doesn't have a named child object.
#     """
#     def __init__(self, parent, child):
#         bdec.DecodeError.__init__(self, child)
#         self.parent = parent
#         self.child = child
# 
#     def __str__(self):
#         return "object '%s' doesn't have child object '%s'" % (self.parent, self.child.name)
# 
# Path: bdec/expression.py
# class ValueResult(ReferenceExpression):
#     """
#     Object returning the result of a entry when cast to an integer.
#     """
#     def param_name(self):
#         return self.name
# 
#     def __repr__(self):
#         return '${%s}' % self.name
# 
# 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)
# 
# class ConstraintError(DecodeError):
#     def __init__(self, entry, actual, comparison, limit):
#         DecodeError.__init__(self, entry)
#         self._comparision = comparison
#         self._expected = limit
#         self._actual = actual
# 
#     def __str__(self):
#         return 'Expected ${%s} %s %s; got %s' % (self.entry.name,
#                 self._comparision, self._expected, self._actual)


# Path: bdec/test/testchoice.py
import operator
import unittest
import bdec.entry as ent
import bdec.choice as chc
import bdec.data as dt
import bdec.field as fld
import bdec.sequence as seq
import bdec.expression as expr
from bdec.encode.entry import MissingInstanceError
from bdec.expression import ValueResult
from bdec.constraints import Equals, ConstraintError

        byte = seq.Sequence('8 bit:', [
            fld.Field('id', 8, constraints=[Equals(dt.Data('\x00'))]),
            fld.Field('length', 8)],
            value=expr.compile('${length}'))
        word = seq.Sequence('16 bit:', [
            fld.Field('id', 8, constraints=[Equals(dt.Data('\x01'))]),
            fld.Field('length', 16)],
            value=expr.compile('${length}'))
        length = chc.Choice('variable integer', [byte, word])
        data = fld.Field('data', expr.compile('${variable integer}'), fld.Field.TEXT)
        spec = seq.Sequence('spec', [length, data])

        results = dict((entry, value)for is_starting, name, entry, entry_data, value in spec.decode(dt.Data('\x00\x20abcde')) if not is_starting)
        self.assertEqual('abcd', results[data])

        results = dict((entry, value)for is_starting, name, entry, entry_data, value in spec.decode(dt.Data('\x01\x00\x20abcde')) if not is_starting)
        self.assertEqual('abcd', results[data])

    def test_best_guess_number_of_entries(self):
        # A common pattern is to have a common type, then select on it using
        # sequences with an expected value. Even when a sequent field fails,
        # it should still report an error given the context of the failing
        # entry.
        a = seq.Sequence('a', [
            fld.Field('type:', length=8),
            chc.Choice('b', [
                seq.Sequence('c', [
                    seq.Sequence('c1', [], value=ValueResult('type:'), constraints=[Equals(0)]),
                    fld.Field('c2', length=8, constraints=[Equals(dt.Data('c'))])]),
                seq.Sequence('d', [

                    seq.Sequence('d1', [], value=ValueResult('type:'), constraints=[Equals(1)]),