# Path: ripyl/util/enum.py
# class Enum(object):
#     '''Base class for enumeration classes
#     
#     This provides a name() class method that will return the string
#     attribute name for an encoded enumeration value.
#     
#     e.g.
#     
#     >>> class Colors(Enum):
#     ...     blue = 1
#     ...     red = 2
#     ...     green = 3
#         
#     >>> Colors.name(Colors.red)
#     'red'
#     
#     >>> Colors.name(1, full_name=True)
#     'Colors.blue'
# 
#     "Instantiating" the Enum sub-class calls the name() method as well:
#     
#     >>> Colors(3, full_name=False)
#     'green'
#     
#     If necesssary you can use non-integers as the values as long as they are hashable:
#     
#     >>> class MathConst(Enum):
#     ...     pi = 3.2     # in certain US states :)
#     ...     e = 2.71828
#         
#     >>> MathConst.pi
#     3.2
#     
#     '''
# 
#     @classmethod
#     def name(cls, value, full_name=False):
#         '''Lookup the enumeration name with the provided value
# 
#         value (hashable)
#             A hashable Enum value (typically int) to find a name for.
# 
#         full_name (bool)
#             Include full name of Enum object in result
# 
#         Returns a string for the Enum attribute associated with value.
#         '''
#         
#         try:
#             enum_lookup = cls._enum_lookup
#         except AttributeError:
#             # Build inverse dict of class attributes with their values as key
#             enum_lookup = dict((v, k) for k, v in cls.__dict__.items() if k[0] != '_')
#             cls._enum_lookup = enum_lookup
#         
#         try:
#             aname = enum_lookup[value]
#             prefix = cls.__name__ + '.' if full_name else ''
#             return prefix + aname
# 
#         except KeyError:
#             return 'unknown'
# 
#     def __new__(cls, value, full_name=False):
#         '''Override class instantitation to perform name lookup instead'''
#         return cls.name(value, full_name)
# 
# Path: ripyl/util/bitops.py
# def split_bits(n, num_bits):
#     '''Convert integer to a list of bits (MSB-first)
# 
#     n (int)
#         The number to convert to bits.
# 
#     num_bits (int)
#         The number of bits in the result.
# 
#     Returns a list of ints representing each bit in n.
#     '''
#     bits = [0] * num_bits
#     for i in xrange(num_bits-1, -1, -1):
#         bits[i] = n & 0x01
#         n >>= 1
#         
#     return bits
# 
# def join_bits(bits):
#     '''Convert an array of bits (MSB first) to an integer word
# 
#     bits (sequence of ints)
#         The bits to be merged into an integer
# 
#     Returns an int representing the bits contained in the bits parameter.
#     '''
#     word = 0
#     for b in bits:
#         word = (word << 1) | b
#         
#     return word


from copy import copy
from ripyl.util.enum import Enum
from ripyl.util.bitops import split_bits, join_bits
import itertools
import ripyl.streaming as stream
import ripyl.decode as decode
import ripyl.sigproc as sigp
        ifr_with_crc = False
        if 200.0e-6 < pulse_width <= 280.0e-6 and (msg_type & 0x08) == 0:
            # IFR is present
            # Check normalization bit width to determine if IFR CRC is present
            es.advance_to_edge() # Start of norm bit
            if es.next_states[0] > es.cur_time:
                pulse_width = es.next_states[0] - es.cur_time
            else:
                pulse_width = 500.0e-6

            if norm_bit == VPWNormBitStyle.SAE:
                ifr_with_crc = True if pulse_width > 96.0e-6 else False
            else: # GM
                ifr_with_crc = True if pulse_width <= 96.0e-6 else False

            es.advance_to_edge() # Move to first bit

            # Get the IFR bits
            ifr_bits, ifr_bit_starts, pulse_width = collect_bits(es)
            if pulse_width > 280.0e-6 and es.cur_state() == 1:
                brk = J1850Break()
                sf = stream.StreamSegment((es.cur_time, es.next_states[0]), brk, kind='break')
                sf.annotate('frame', {'value':'Break'}, stream.AnnotationFormat.String)
                yield sf
                continue

            # Validate IFR bits
            if len(ifr_bits) % 8 == 0 and len(ifr_bits) >= 8:
                # Convert IFR bits to bytes
                for i in xrange(len(ifr_bits) // 8):

# Path: ripyl/util/enum.py
# class Enum(object):
#     '''Base class for enumeration classes
#     
#     This provides a name() class method that will return the string
#     attribute name for an encoded enumeration value.
#     
#     e.g.
#     
#     >>> class Colors(Enum):
#     ...     blue = 1
#     ...     red = 2
#     ...     green = 3
#         
#     >>> Colors.name(Colors.red)
#     'red'
#     
#     >>> Colors.name(1, full_name=True)
#     'Colors.blue'
# 
#     "Instantiating" the Enum sub-class calls the name() method as well:
#     
#     >>> Colors(3, full_name=False)
#     'green'
#     
#     If necesssary you can use non-integers as the values as long as they are hashable:
#     
#     >>> class MathConst(Enum):
#     ...     pi = 3.2     # in certain US states :)
#     ...     e = 2.71828
#         
#     >>> MathConst.pi
#     3.2
#     
#     '''
# 
#     @classmethod
#     def name(cls, value, full_name=False):
#         '''Lookup the enumeration name with the provided value
# 
#         value (hashable)
#             A hashable Enum value (typically int) to find a name for.
# 
#         full_name (bool)
#             Include full name of Enum object in result
# 
#         Returns a string for the Enum attribute associated with value.
#         '''
#         
#         try:
#             enum_lookup = cls._enum_lookup
#         except AttributeError:
#             # Build inverse dict of class attributes with their values as key
#             enum_lookup = dict((v, k) for k, v in cls.__dict__.items() if k[0] != '_')
#             cls._enum_lookup = enum_lookup
#         
#         try:
#             aname = enum_lookup[value]
#             prefix = cls.__name__ + '.' if full_name else ''
#             return prefix + aname
# 
#         except KeyError:
#             return 'unknown'
# 
#     def __new__(cls, value, full_name=False):
#         '''Override class instantitation to perform name lookup instead'''
#         return cls.name(value, full_name)
# 
# Path: ripyl/util/bitops.py
# def split_bits(n, num_bits):
#     '''Convert integer to a list of bits (MSB-first)
# 
#     n (int)
#         The number to convert to bits.
# 
#     num_bits (int)
#         The number of bits in the result.
# 
#     Returns a list of ints representing each bit in n.
#     '''
#     bits = [0] * num_bits
#     for i in xrange(num_bits-1, -1, -1):
#         bits[i] = n & 0x01
#         n >>= 1
#         
#     return bits
# 
# def join_bits(bits):
#     '''Convert an array of bits (MSB first) to an integer word
# 
#     bits (sequence of ints)
#         The bits to be merged into an integer
# 
#     Returns an int representing the bits contained in the bits parameter.
#     '''
#     word = 0
#     for b in bits:
#         word = (word << 1) | b
#         
#     return word


# Path: ripyl/protocol/j1850.py
from copy import copy
from ripyl.util.enum import Enum
from ripyl.util.bitops import split_bits, join_bits
import itertools
import ripyl.streaming as stream
import ripyl.decode as decode
import ripyl.sigproc as sigp

        ifr_with_crc = False
        if 200.0e-6 < pulse_width <= 280.0e-6 and (msg_type & 0x08) == 0:
            # IFR is present
            # Check normalization bit width to determine if IFR CRC is present
            es.advance_to_edge() # Start of norm bit
            if es.next_states[0] > es.cur_time:
                pulse_width = es.next_states[0] - es.cur_time
            else:
                pulse_width = 500.0e-6

            if norm_bit == VPWNormBitStyle.SAE:
                ifr_with_crc = True if pulse_width > 96.0e-6 else False
            else: # GM
                ifr_with_crc = True if pulse_width <= 96.0e-6 else False

            es.advance_to_edge() # Move to first bit

            # Get the IFR bits
            ifr_bits, ifr_bit_starts, pulse_width = collect_bits(es)
            if pulse_width > 280.0e-6 and es.cur_state() == 1:
                brk = J1850Break()
                sf = stream.StreamSegment((es.cur_time, es.next_states[0]), brk, kind='break')
                sf.annotate('frame', {'value':'Break'}, stream.AnnotationFormat.String)
                yield sf
                continue

            # Validate IFR bits
            if len(ifr_bits) % 8 == 0 and len(ifr_bits) >= 8:
                # Convert IFR bits to bytes
                for i in xrange(len(ifr_bits) // 8):

                    ifr_bytes.append(join_bits(ifr_bits[i*8:i*8+8]))