# 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/sigproc.py
# def remove_excess_edges(edges):
#     '''Remove incorrect edge transitions from an edge stream
#     
#     This is a generator function.
#     
#     This function is most useful for conditioning the outputs of the protocol
#     synthesizers. For those protocols with multiple signals, the synthesizers
#     myst yield a new output set for *all* signals when any *one* of them changes.
#     This results in non-conforming edge streams that contain multiple consecutive
#     pairs with a non-changing value.
#     
#     edges (iterable of (float, int) tuples)
#         An edge stream to filter for extraneous non-edges
#         
#     Yields an edge stream.
#     '''
#     prev_state = None
#     last_e = None
#     for e in edges:
#         if prev_state is None:
#             prev_state = e[1]
#             yield e
#         else:
#             if e[1] != prev_state:
#                 prev_state = e[1]
#                 last_e = None
#                 yield e
#             else: # Save last edge so we can yield it at the end
#                 last_e = e
#         
#     if last_e is not None:
#         yield last_e


import itertools
import math
import ripyl.streaming as stream
        import bisect
from ripyl.decode import *
from ripyl.util.enum import Enum
from ripyl.util.bitops import *
from ripyl.sigproc import remove_excess_edges
        bit_fields = self.packet.field_offsets(with_stuffing = True)
        
        fields = {}
        clock_period = USBClockPeriod[self.packet.speed]
        for field, (start, end) in bit_fields.items():
            fields[field] = (self.sop_end + start * clock_period, self.sop_end + (end + 1) * clock_period)

        if self.packet.pid == USBPID.EXT:
            # EXT packets need a special adjustment for the fields in the second half
            part2_delta = self.sop_end2 - self.sop_end

            start, end = fields['SubPID']
            fields['SubPID'] = (start + part2_delta, end + part2_delta)
            
            start, end = fields['Variable']
            fields['Variable'] = (start + part2_delta, end + part2_delta)
            
            start, end = fields['CRC5_2']
            fields['CRC5_2'] = (start + part2_delta, end + part2_delta)
            
        return fields
        
    def __repr__(self):
        status_text = USBStreamPacket.status_text(self.status)
        return 'USBStreamPacket({}, {})'.format(self.packet, status_text)


class USBStreamError(stream.StreamSegment):
    '''Contains partially decoded packet data after an error has been found
    in the data stream'''

# 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/sigproc.py
# def remove_excess_edges(edges):
#     '''Remove incorrect edge transitions from an edge stream
#     
#     This is a generator function.
#     
#     This function is most useful for conditioning the outputs of the protocol
#     synthesizers. For those protocols with multiple signals, the synthesizers
#     myst yield a new output set for *all* signals when any *one* of them changes.
#     This results in non-conforming edge streams that contain multiple consecutive
#     pairs with a non-changing value.
#     
#     edges (iterable of (float, int) tuples)
#         An edge stream to filter for extraneous non-edges
#         
#     Yields an edge stream.
#     '''
#     prev_state = None
#     last_e = None
#     for e in edges:
#         if prev_state is None:
#             prev_state = e[1]
#             yield e
#         else:
#             if e[1] != prev_state:
#                 prev_state = e[1]
#                 last_e = None
#                 yield e
#             else: # Save last edge so we can yield it at the end
#                 last_e = e
#         
#     if last_e is not None:
#         yield last_e


# Path: ripyl/protocol/usb.py
import itertools
import math
import ripyl.streaming as stream
        import bisect
from ripyl.decode import *
from ripyl.util.enum import Enum
from ripyl.util.bitops import *
from ripyl.sigproc import remove_excess_edges

        bit_fields = self.packet.field_offsets(with_stuffing = True)
        
        fields = {}
        clock_period = USBClockPeriod[self.packet.speed]
        for field, (start, end) in bit_fields.items():
            fields[field] = (self.sop_end + start * clock_period, self.sop_end + (end + 1) * clock_period)

        if self.packet.pid == USBPID.EXT:
            # EXT packets need a special adjustment for the fields in the second half
            part2_delta = self.sop_end2 - self.sop_end

            start, end = fields['SubPID']
            fields['SubPID'] = (start + part2_delta, end + part2_delta)
            
            start, end = fields['Variable']
            fields['Variable'] = (start + part2_delta, end + part2_delta)
            
            start, end = fields['CRC5_2']
            fields['CRC5_2'] = (start + part2_delta, end + part2_delta)
            
        return fields
        
    def __repr__(self):
        status_text = USBStreamPacket.status_text(self.status)
        return 'USBStreamPacket({}, {})'.format(self.packet, status_text)


class USBStreamError(stream.StreamSegment):
    '''Contains partially decoded packet data after an error has been found
    in the data stream'''

    def __init__(self, bounds, error_data, pid=-1, status=stream.StreamStatus.Error):