<commit_before>from hwt.code import log2ceil
from hwt.hdlObjects.constants import INTF_DIRECTION
from hwt.hdlObjects.transTmpl import TransTmpl
from hwt.hdlObjects.typeShortcuts import vecT
from hwt.hdlObjects.types.array import Array
from hwt.hdlObjects.types.bits import Bits
from hwt.hdlObjects.types.hdlType import HdlType
from hwt.hdlObjects.types.struct import HStruct
from hwt.hdlObjects.types.structUtils import BusFieldInfo
from hwt.interfaces.std import BramPort_withoutClk, RegCntrl, Signal, VldSynced
from hwt.interfaces.structIntf import StructIntf
from hwt.interfaces.utils import addClkRstn
from hwt.synthesizer.interfaceLevel.mainBases import InterfaceBase
from hwt.synthesizer.interfaceLevel.unit import Unit
from hwt.synthesizer.interfaceLevel.unitImplHelpers import getSignalName
from hwt.synthesizer.param import evalParam
from hwt.synthesizer.rtlLevel.mainBases import RtlSignalBase

def inRange(n, lower, end):
    return (n >= lower) & (n < end)

class BusEndpoint(Unit):
    """
    Abstract unit
    Delegate request from bus to fields of structure
    write has higher priority

    .. aafig::
        +------+    +----------+     +---------+
        | bus  +---->          +-----> field0  |
        |      <----+          <-----+         |
        +------+    |          |     +---------+
                    |          |
                    | endpoint |     +---------+
                    |          +-----> field1  |
                    |          <-----+         |
                    |          |     +---------+
                    |          |
                    |          |     +---------+
                    |          +-----> field2  |
                    |          <-----+         |
                    +----------+     +---------+

    """
    def __init__(self, structTemplate, offset=0, intfCls=None, shouldEnterFn=None):
        """
        :param structTemplate: instance of HStruct which describes address space of this endpoint
        :param offset: offset of address space of this endpoint
        :param intfCls: class of bus interface which should be used
        :param shouldEnterFn: function(transactionTemplate) which should return true if structuralized type like Array or HStruct
            should be interpreted as separate interfaces or not
        """
        assert intfCls is not None, "intfCls has to be specified"

        self._intfCls = intfCls
        self.STRUCT_TEMPLATE = structTemplate
        self.OFFSET = offset
        if shouldEnterFn is None:
            self.shouldEnterFn = lambda tmpl: not isinstance(tmpl.dtype, Array)
        else:
            self.shouldEnterFn = shouldEnterFn
        Unit.__init__(self)

    def _getWordAddrStep(self):
        raise NotImplementedError("Should be overridden in concrete implementation, this is abstract class")

    def _getAddrStep(self):
        raise NotImplementedError("Should be overridden in concrete implementation, this is abstract class")

    def _config(self):
        self._intfCls._config(self)

    def _declr(self):
        addClkRstn(self)

        with self._paramsShared():
            self.bus = self._intfCls()

        self.decoded = StructIntf(self.STRUCT_TEMPLATE, instantiateFieldFn=self._mkFieldInterface)

    def getPort(self, transTmpl):
        return self.decoded._fieldsToInterfaces[transTmpl.origin]

    def isInMyAddrRange(self, addrSig):
        return (addrSig >= self._getMinAddr()) & (addrSig < self._getMaxAddr())

    def _parseTemplate(self):
        self._directlyMapped = []
        self._bramPortMapped = []
        self.ADRESS_MAP = []

        self.WORD_ADDR_STEP = self._getWordAddrStep()
        self.ADDR_STEP = self._getAddrStep()

        AW = evalParam(self.ADDR_WIDTH).val
        SUGGESTED_AW = self._suggestedAddrWidth()
        assert SUGGESTED_AW <= AW, (SUGGESTED_AW, AW)
        tmpl = TransTmpl(self.STRUCT_TEMPLATE, bitAddr=self.OFFSET)
        fieldTrans = tmpl.walkFlatten(shouldEnterFn=self.shouldEnterFn)
        for (_, transactionTmpl) in fieldTrans:
            intf = self.getPort(transactionTmpl)

            if isinstance(intf, RegCntrl):
                self._directlyMapped.append(transactionTmpl)
            elif isinstance(intf, BramPort_withoutClk):
                self._bramPortMapped.append(transactionTmpl)
            else:
                raise NotImplementedError(intf)
            self.ADRESS_MAP.append(transactionTmpl)

    def _getMaxAddr(self):
        lastItem = self.ADRESS_MAP[-1]
        return lastItem.bitAddrEnd // self._getAddrStep()

    def _getMinAddr(self):
        return self.ADRESS_MAP[0].bitAddr // self._getAddrStep()

    def _suggestedAddrWidth(self):
        """
        Based on strut template and offset given resolve how many bits for
        address is needed
        """
        bitSize = self.STRUCT_TEMPLATE.bit_length()
        wordAddrStep = self._getWordAddrStep()
        addrStep = self._getAddrStep()

        maxAddr = (self.OFFSET + bitSize // addrStep)

        # align to word size
        if maxAddr % wordAddrStep != 0:
            wordAddrStep += wordAddrStep - (maxAddr % wordAddrStep)

        return maxAddr.bit_length()

    def propagateAddr(self, srcAddrSig, srcAddrStep, dstAddrSig, dstAddrStep, transTmpl):
        """
        :param srcAddrSig: input signal with address
        :param srcAddrStep: how many bits is addressing one unit of srcAddrSig
        :param dstAddrSig: output signal for address
        :param dstAddrStep: how many bits is addressing one unit of dstAddrSig
        :param transTmpl: TransTmpl which has metainformations about this address space transition
        """
        IN_ADDR_WIDTH = srcAddrSig._dtype.bit_length()

        # _prefix = transTmpl.getMyAddrPrefix(srcAddrStep)
        assert dstAddrStep % srcAddrStep == 0
        if not isinstance(transTmpl.dtype, Array):
            raise TypeError()
        assert transTmpl.bitAddr % dstAddrStep == 0, "Has to be addressable by address with this step"

        addrIsAligned = transTmpl.bitAddr % transTmpl.bit_length() == 0
        bitsForAlignment = ((dstAddrStep // srcAddrStep) - 1).bit_length()
        bitsOfSubAddr = ((transTmpl.bitAddrEnd - transTmpl.bitAddr - 1) // dstAddrStep).bit_length()

        if addrIsAligned:
            bitsOfPrefix = IN_ADDR_WIDTH - bitsOfSubAddr - bitsForAlignment
            prefix = (transTmpl.bitAddr // srcAddrStep) >> (bitsForAlignment + bitsOfSubAddr)
            addrIsInRange = srcAddrSig[IN_ADDR_WIDTH:(IN_ADDR_WIDTH - bitsOfPrefix)]._eq(prefix)
            addr_tmp = srcAddrSig
        else:
            _addr = transTmpl.bitAddr // srcAddrStep
            _addrEnd = transTmpl.bitAddrEnd // srcAddrStep
            addrIsInRange = inRange(srcAddrSig, _addr, _addrEnd)
            addr_tmp = self._sig(dstAddrSig._name + "_addr_tmp", vecT(self.ADDR_WIDTH))
            addr_tmp ** (srcAddrSig - _addr)

        connectedAddr = (dstAddrSig ** addr_tmp[(bitsOfSubAddr + bitsForAlignment):(bitsForAlignment)])

        return (addrIsInRange, connectedAddr)

    def _mkFieldInterface(self, field):
        t = field.dtype
        DW = evalParam(self.DATA_WIDTH).val

        if isinstance(t, Bits):
            p = RegCntrl()
            dw = t.bit_length()
        elif isinstance(t, Array):
            if self.shouldEnterFn(field):
                p = StructIntf(t.elmType, instantiateFieldFn=self._mkFieldInterface, multipliedBy=t.size)
                return p
            else:
                p = BramPort_withoutClk()
                dw = t.elmType.bit_length()
                p.ADDR_WIDTH.set(log2ceil(evalParam(t.size).val - 1))
        else:
            raise NotImplementedError(t)

        if dw == DW:
            # use param instead of value to improve readability
            dw = self.DATA_WIDTH
            p._replaceParam("DATA_WIDTH", dw)
        else:
            p.DATA_WIDTH.set(dw)

        return p

    @classmethod
    def _resolveRegStructFromIntfMap(cls, prefix, interfaceMap, DATA_WIDTH, aliginFields=False):
        """
        Generate flatened register map for HStruct

        :param prefix: prefix for register name
        :param interfaceMap: iterable of
            tuple (type, name) or
            interface or
            tuple (list of interface, prefix, [aliginFields])
            (aliginFields is optional flag if set all items from list will be aligned to bus word size, default is false)
        :param DATA_WIDTH: width of word
        :return: generator of tuple (type, name, BusFieldInfo)
        """
        for m in interfaceMap:
            if isinstance(m, (InterfaceBase, RtlSignalBase)):
                intf = m
                name = getSignalName(intf)
                if isinstance(intf, (RtlSignalBase, Signal)):
                    dtype = intf._dtype
                    access = "r"
                elif isinstance(intf, VldSynced):
                    # assert intf._direction == INTF_DIRECTION.SLAVE
                    dtype = intf.data._dtype
                    access = "w"
                elif isinstance(intf, RegCntrl):
                    dtype = intf.din._dtype
                    access = "rw"
                elif isinstance(intf, BramPort_withoutClk):
                    dtype = Array(vecT(evalParam(intf.DATA_WIDTH).val),
                                  2 ** evalParam(intf.ADDR_WIDTH).val)
                    access = "rw"
                else:
                    raise NotImplementedError(intf)

                info = BusFieldInfo(access=access, fieldInterface=intf)

                if aliginFields:
                    fillUpWidth = DATA_WIDTH - dtype.bit_length()
                    if fillUpWidth > 0:
                        yield (vecT(fillUpWidth), None, None)

                yield (dtype, prefix + name, info)
            else:
                l = len(m)
                if l == 2:
                    typeOrListOfInterfaces, nameOrPrefix = m
                    align = False
                else:
                    typeOrListOfInterfaces, nameOrPrefix, align = m

                if isinstance(typeOrListOfInterfaces, HdlType):
                    # tuple (type, name)
                    yield (typeOrListOfInterfaces, prefix + nameOrPrefix, None)
                    if align:
                        fillUpWidth = DATA_WIDTH - typeOrListOfInterfaces.bit_length()
                        if fillUpWidth > 0:
                            yield (vecT(fillUpWidth), None, None)
                else:
                    # tuple (list of interfaces, prefix)
                    yield from cls._resolveRegStructFromIntfMap(prefix + nameOrPrefix,
                                                                typeOrListOfInterfaces,
                                                                DATA_WIDTH,
                                                                align)

    @classmethod
    def _fromInterfaceMap(cls, parent, onParentName, bus, busDataWidth, configFn, interfaceMap):
        """
        Generate converter by specified struct and connect interfaces if are specified
        in impl phase

        :param parent: unit where converter should be instantiated
        :param onParentName: name of converter in parent
        :param bus: bus interface for converter
        :param configFn: function (converter) which should be used for configuring of converter
        :param interfaceMap: iterable of tuple (type, name) or interface
            or tuple (list of interface, prefix, optionally align)
            (align is optional flag if set all items from list will be aligned (little-endian)
            to bus word size, default is false)
            if interface is specified it will be automatically connected
        """

        regsFlatten = []
        intfMap = {}
        DATA_WIDTH = evalParam(bus.DATA_WIDTH).val
        # build flatten register map
        for typ, name, info in cls._resolveRegStructFromIntfMap("", interfaceMap, DATA_WIDTH):
            if info is not None:
                regsFlatten.append((typ, name, info))
                intfMap[name] = info.fieldInterface
            else:
                regsFlatten.append((typ, name))

        # instantiate converter
        conv = cls(HStruct(*regsFlatten))
        configFn(conv)

        setattr(parent, onParentName, conv)

        conv.bus ** bus

        # connect interfaces as was specified by register map
        for regName, intf in intfMap.items():
            convIntf = getattr(conv.decoded, regName)

            if isinstance(intf, Signal):
                assert intf._direction == INTF_DIRECTION.MASTER
                convIntf.din ** intf

            elif isinstance(intf, RtlSignalBase):
                convIntf.din ** intf

            elif isinstance(intf, RegCntrl):
                assert intf._direction == INTF_DIRECTION.SLAVE
                intf ** convIntf

            elif isinstance(intf, VldSynced):
                assert intf._direction == INTF_DIRECTION.SLAVE
                convIntf.dout ** intf

            elif isinstance(intf, BramPort_withoutClk):
                intf ** convIntf
            else:
                raise NotImplementedError(intf)
<commit_msg>fix AxiLite_wAgent<commit_after>from hwt.code import log2ceil
from hwt.hdlObjects.constants import INTF_DIRECTION
from hwt.hdlObjects.transTmpl import TransTmpl
from hwt.hdlObjects.typeShortcuts import vecT
from hwt.hdlObjects.types.array import Array
from hwt.hdlObjects.types.bits import Bits
from hwt.hdlObjects.types.hdlType import HdlType
from hwt.hdlObjects.types.struct import HStruct
from hwt.hdlObjects.types.structUtils import BusFieldInfo
from hwt.interfaces.std import BramPort_withoutClk, RegCntrl, Signal, VldSynced
from hwt.interfaces.structIntf import StructIntf
from hwt.interfaces.utils import addClkRstn
from hwt.synthesizer.interfaceLevel.mainBases import InterfaceBase
from hwt.synthesizer.interfaceLevel.unit import Unit
from hwt.synthesizer.interfaceLevel.unitImplHelpers import getSignalName
from hwt.synthesizer.param import evalParam
from hwt.synthesizer.rtlLevel.mainBases import RtlSignalBase
from copy import copy

def inRange(n, lower, end):
    return (n >= lower) & (n < end)

class BusEndpoint(Unit):
    """
    Abstract unit
    Delegate request from bus to fields of structure
    write has higher priority

    .. aafig::
        +------+    +----------+     +---------+
        | bus  +---->          +-----> field0  |
        |      <----+          <-----+         |
        +------+    |          |     +---------+
                    |          |
                    | endpoint |     +---------+
                    |          +-----> field1  |
                    |          <-----+         |
                    |          |     +---------+
                    |          |
                    |          |     +---------+
                    |          +-----> field2  |
                    |          <-----+         |
                    +----------+     +---------+

    """
    def __init__(self, structTemplate, offset=0, intfCls=None, shouldEnterFn=None):
        """
        :param structTemplate: instance of HStruct which describes address space of this endpoint
        :param offset: offset of address space of this endpoint
        :param intfCls: class of bus interface which should be used
        :param shouldEnterFn: function(transactionTemplate) which should return true if structuralized type like Array or HStruct
            should be interpreted as separate interfaces or not
        """
        assert intfCls is not None, "intfCls has to be specified"

        self._intfCls = intfCls
        self.STRUCT_TEMPLATE = structTemplate
        self.OFFSET = offset
        if shouldEnterFn is None:
            self.shouldEnterFn = lambda tmpl: not isinstance(tmpl.dtype, Array)
        else:
            self.shouldEnterFn = shouldEnterFn
        Unit.__init__(self)

    def _getWordAddrStep(self):
        raise NotImplementedError("Should be overridden in concrete implementation, this is abstract class")

    def _getAddrStep(self):
        raise NotImplementedError("Should be overridden in concrete implementation, this is abstract class")

    def _config(self):
        self._intfCls._config(self)

    def _declr(self):
        addClkRstn(self)

        with self._paramsShared():
            self.bus = self._intfCls()

        self.decoded = StructIntf(self.STRUCT_TEMPLATE, instantiateFieldFn=self._mkFieldInterface)

    def getPort(self, transTmpl):
        try:
            indexOnPort = transTmpl.indexOnPort
        except AttributeError:
            indexOnPort = None

        port = self.decoded._fieldsToInterfaces[transTmpl.origin]
        print(port)
        if indexOnPort is None:
            return port
        else:
            return port[indexOnPort]

    def isInMyAddrRange(self, addrSig):
        return (addrSig >= self._getMinAddr()) & (addrSig < self._getMaxAddr())

    def _parseTemplate(self):
        self._directlyMapped = []
        self._bramPortMapped = []
        self.ADRESS_MAP = []

        self.WORD_ADDR_STEP = self._getWordAddrStep()
        self.ADDR_STEP = self._getAddrStep()

        def getIndexOfPart(transTmpl):
            index = 0
            parentArray = transTmpl.parent
            while not (isinstance(parentArray.dtype, Array) and parentArray.bitAddrEnd >= transTmpl.bitAddrEnd):
                parentArray = parentArray.parent
                if isinstance(parentArray.dtype, Array):
                    index += (transTmpl.bitAddr - parentArray.bitAddr) // parentArray.getItemWidth()
                    # [FIXME] not working correctly for multi level arrays
            return index

        AW = evalParam(self.ADDR_WIDTH).val
        SUGGESTED_AW = self._suggestedAddrWidth()
        assert SUGGESTED_AW <= AW, (SUGGESTED_AW, AW)
        tmpl = TransTmpl(self.STRUCT_TEMPLATE, bitAddr=self.OFFSET)
        fieldTrans = tmpl.walkFlatten(shouldEnterFn=self.shouldEnterFn)
        for ((base, end), transTmpl) in fieldTrans:
            intf = self.getPort(transTmpl)

            if isinstance(intf, RegCntrl):
                if intf._multipliedBy is not None:
                    _transactionTmpl = copy(transTmpl)
                    _transactionTmpl.bitAddr = base
                    _transactionTmpl.bitAddrEnd = end
                    _transactionTmpl.indexOnPort = getIndexOfPart(_transactionTmpl)
                    self._directlyMapped.append(_transactionTmpl)
                    #self.decoded._fieldsToInterfaces[_transactionTmpl] =
                else:
                    self._directlyMapped.append(transTmpl)

            elif isinstance(intf, BramPort_withoutClk):
                self._bramPortMapped.append(transTmpl)
            else:
                raise NotImplementedError(intf)
            self.ADRESS_MAP.append(transTmpl)

    def _getMaxAddr(self):
        lastItem = self.ADRESS_MAP[-1]
        return lastItem.bitAddrEnd // self._getAddrStep()

    def _getMinAddr(self):
        return self.ADRESS_MAP[0].bitAddr // self._getAddrStep()

    def _suggestedAddrWidth(self):
        """
        Based on strut template and offset given resolve how many bits for
        address is needed
        """
        bitSize = self.STRUCT_TEMPLATE.bit_length()
        wordAddrStep = self._getWordAddrStep()
        addrStep = self._getAddrStep()

        maxAddr = (self.OFFSET + bitSize // addrStep)

        # align to word size
        if maxAddr % wordAddrStep != 0:
            wordAddrStep += wordAddrStep - (maxAddr % wordAddrStep)

        return maxAddr.bit_length()

    def propagateAddr(self, srcAddrSig, srcAddrStep, dstAddrSig, dstAddrStep, transTmpl):
        """
        :param srcAddrSig: input signal with address
        :param srcAddrStep: how many bits is addressing one unit of srcAddrSig
        :param dstAddrSig: output signal for address
        :param dstAddrStep: how many bits is addressing one unit of dstAddrSig
        :param transTmpl: TransTmpl which has metainformations about this address space transition
        """
        IN_ADDR_WIDTH = srcAddrSig._dtype.bit_length()

        # _prefix = transTmpl.getMyAddrPrefix(srcAddrStep)
        assert dstAddrStep % srcAddrStep == 0
        if not isinstance(transTmpl.dtype, Array):
            raise TypeError()
        assert transTmpl.bitAddr % dstAddrStep == 0, "Has to be addressable by address with this step"

        addrIsAligned = transTmpl.bitAddr % transTmpl.bit_length() == 0
        bitsForAlignment = ((dstAddrStep // srcAddrStep) - 1).bit_length()
        bitsOfSubAddr = ((transTmpl.bitAddrEnd - transTmpl.bitAddr - 1) // dstAddrStep).bit_length()

        if addrIsAligned:
            bitsOfPrefix = IN_ADDR_WIDTH - bitsOfSubAddr - bitsForAlignment
            prefix = (transTmpl.bitAddr // srcAddrStep) >> (bitsForAlignment + bitsOfSubAddr)
            addrIsInRange = srcAddrSig[IN_ADDR_WIDTH:(IN_ADDR_WIDTH - bitsOfPrefix)]._eq(prefix)
            addr_tmp = srcAddrSig
        else:
            _addr = transTmpl.bitAddr // srcAddrStep
            _addrEnd = transTmpl.bitAddrEnd // srcAddrStep
            addrIsInRange = inRange(srcAddrSig, _addr, _addrEnd)
            addr_tmp = self._sig(dstAddrSig._name + "_addr_tmp", vecT(self.ADDR_WIDTH))
            addr_tmp ** (srcAddrSig - _addr)

        connectedAddr = (dstAddrSig ** addr_tmp[(bitsOfSubAddr + bitsForAlignment):(bitsForAlignment)])

        return (addrIsInRange, connectedAddr)

    def _mkFieldInterface(self, field):
        t = field.dtype
        DW = evalParam(self.DATA_WIDTH).val

        if isinstance(t, Bits):
            p = RegCntrl()
            dw = t.bit_length()
        elif isinstance(t, Array):
            if self.shouldEnterFn(field):
                p = StructIntf(t.elmType, instantiateFieldFn=self._mkFieldInterface, multipliedBy=t.size)
                return p
            else:
                p = BramPort_withoutClk()
                dw = t.elmType.bit_length()
                p.ADDR_WIDTH.set(log2ceil(evalParam(t.size).val - 1))
        else:
            raise NotImplementedError(t)

        if dw == DW:
            # use param instead of value to improve readability
            dw = self.DATA_WIDTH
            p._replaceParam("DATA_WIDTH", dw)
        else:
            p.DATA_WIDTH.set(dw)

        return p

    @classmethod
    def _resolveRegStructFromIntfMap(cls, prefix, interfaceMap, DATA_WIDTH, aliginFields=False):
        """
        Generate flattened register map for HStruct

        :param prefix: prefix for register name
        :param interfaceMap: iterable of
            tuple (type, name) or
            interface or
            tuple (list of interface, prefix, [aliginFields])
            (aliginFields is optional flag if set all items from list will be aligned to bus word size, default is false)
        :param DATA_WIDTH: width of word
        :return: generator of tuple (type, name, BusFieldInfo)
        """
        for m in interfaceMap:
            if isinstance(m, (InterfaceBase, RtlSignalBase)):
                intf = m
                name = getSignalName(intf)
                if isinstance(intf, (RtlSignalBase, Signal)):
                    dtype = intf._dtype
                    access = "r"
                elif isinstance(intf, VldSynced):
                    # assert intf._direction == INTF_DIRECTION.SLAVE
                    dtype = intf.data._dtype
                    access = "w"
                elif isinstance(intf, RegCntrl):
                    dtype = intf.din._dtype
                    access = "rw"
                elif isinstance(intf, BramPort_withoutClk):
                    dtype = Array(vecT(evalParam(intf.DATA_WIDTH).val),
                                  2 ** evalParam(intf.ADDR_WIDTH).val)
                    access = "rw"
                else:
                    raise NotImplementedError(intf)

                info = BusFieldInfo(access=access, fieldInterface=intf)

                if aliginFields:
                    fillUpWidth = DATA_WIDTH - dtype.bit_length()
                    if fillUpWidth > 0:
                        yield (vecT(fillUpWidth), None, None)

                yield (dtype, prefix + name, info)
            else:
                l = len(m)
                if l == 2:
                    typeOrListOfInterfaces, nameOrPrefix = m
                    align = False
                else:
                    typeOrListOfInterfaces, nameOrPrefix, align = m

                if isinstance(typeOrListOfInterfaces, HdlType):
                    # tuple (type, name)
                    yield (typeOrListOfInterfaces, prefix + nameOrPrefix, None)
                    if align:
                        fillUpWidth = DATA_WIDTH - typeOrListOfInterfaces.bit_length()
                        if fillUpWidth > 0:
                            yield (vecT(fillUpWidth), None, None)
                else:
                    # tuple (list of interfaces, prefix)
                    yield from cls._resolveRegStructFromIntfMap(prefix + nameOrPrefix,
                                                                typeOrListOfInterfaces,
                                                                DATA_WIDTH,
                                                                align)

    @classmethod
    def _fromInterfaceMap(cls, parent, onParentName, bus, busDataWidth, configFn, interfaceMap):
        """
        Generate converter by specified struct and connect interfaces if are specified
        in impl phase

        :param parent: unit where converter should be instantiated
        :param onParentName: name of converter in parent
        :param bus: bus interface for converter
        :param configFn: function (converter) which should be used for configuring of converter
        :param interfaceMap: iterable of tuple (type, name) or interface
            or tuple (list of interface, prefix, optionally align)
            (align is optional flag if set all items from list will be aligned (little-endian)
            to bus word size, default is false)
            if interface is specified it will be automatically connected
        """

        regsFlatten = []
        intfMap = {}
        DATA_WIDTH = evalParam(bus.DATA_WIDTH).val
        # build flatten register map
        for typ, name, info in cls._resolveRegStructFromIntfMap("", interfaceMap, DATA_WIDTH):
            if info is not None:
                regsFlatten.append((typ, name, info))
                intfMap[name] = info.fieldInterface
            else:
                regsFlatten.append((typ, name))

        # instantiate converter
        conv = cls(HStruct(*regsFlatten))
        configFn(conv)

        setattr(parent, onParentName, conv)

        conv.bus ** bus

        # connect interfaces as was specified by register map
        for regName, intf in intfMap.items():
            convIntf = getattr(conv.decoded, regName)

            if isinstance(intf, Signal):
                assert intf._direction == INTF_DIRECTION.MASTER
                convIntf.din ** intf

            elif isinstance(intf, RtlSignalBase):
                convIntf.din ** intf

            elif isinstance(intf, RegCntrl):
                assert intf._direction == INTF_DIRECTION.SLAVE
                intf ** convIntf

            elif isinstance(intf, VldSynced):
                assert intf._direction == INTF_DIRECTION.SLAVE
                convIntf.dout ** intf

            elif isinstance(intf, BramPort_withoutClk):
                intf ** convIntf
            else:
                raise NotImplementedError(intf)
<|endoftext|>


<commit_before>import mimetypes

def guess_kind_from_filename(filepath):
    """Return a document kind (image, audio...) guessed from a filename. If
    no kind can be guessed, returns None."""
    if filepath:
        content_type, encoding = mimetypes.guess_type(filepath)
        return guess_kind_from_content_type(content_type)

def guess_kind_from_content_type(content_type):
    """Return a document kind (image, audio...) guessed from a content_type. If
    no kind can be guessed, returns None."""
    lookups = ['image', 'video', 'audio', 'text', 'pdf']
    if content_type:
        for lookup in lookups:
            if lookup in content_type:
                return lookup
<commit_msg>Don't define an unused variable<commit_after>import mimetypes

def guess_kind_from_filename(filepath):
    """Return a document kind (image, audio...) guessed from a filename. If
    no kind can be guessed, returns None."""
    if filepath:
        content_type, _ = mimetypes.guess_type(filepath)
        return guess_kind_from_content_type(content_type)

def guess_kind_from_content_type(content_type):
    """Return a document kind (image, audio...) guessed from a content_type. If
    no kind can be guessed, returns None."""
    lookups = ['image', 'video', 'audio', 'text', 'pdf']
    if content_type:
        for lookup in lookups:
            if lookup in content_type:
                return lookup
<|endoftext|>


<commit_before>import re
from iktomi.forms.convs import *
from iktomi.utils import N_

class Email(Char):

    regex = re.compile(
        # dot-atom
        r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"
        # Although quoted variant is allowed by spec it's actually not used
        # except by geeks that are looking for problems. But the characters
        # allowed in quoted string are not safe for HTML and XML, so quoted
        # e-mail can't be expressed in such formats directly which is quite
        # common. We prefer to forbid such valid but unsafe e-mails to avoid
        # security problems. To allow quoted names disable non-text characters
        # replacement and uncomment the following lines of regexp:
        ## quoted-string
        #r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|'
        #    r'\\[\001-011\013\014\016-\177])*"'
        r')@(?:[A-Z0-9-]+\.)+[A-Z]{2,6}$', re.IGNORECASE)
    error_regex = N_('incorrect e-mail address')

class ModelDictConv(Converter):
    '''Converts a dictionary to object of `model` class with the same fields.
    It is designed for use in FieldSet'''

    model = None

    def from_python(self, value):
        result = {}
        for field in self.field.fields:
            result[field.name] = getattr(value, field.name)
        return result

    def to_python(self, value):
        obj = self.model()
        for field in self.field.fields:
            setattr(obj, field.name, value[field.name])
        return obj
<commit_msg>ModelChoice (dirty copy from old lib)iktomi/unstable/forms/convs.py<commit_after>import re
from iktomi.forms.convs import *
from iktomi.utils import N_

class Email(Char):

    regex = re.compile(
        # dot-atom
        r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"
        # Although quoted variant is allowed by spec it's actually not used
        # except by geeks that are looking for problems. But the characters
        # allowed in quoted string are not safe for HTML and XML, so quoted
        # e-mail can't be expressed in such formats directly which is quite
        # common. We prefer to forbid such valid but unsafe e-mails to avoid
        # security problems. To allow quoted names disable non-text characters
        # replacement and uncomment the following lines of regexp:
        ## quoted-string
        #r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|'
        #    r'\\[\001-011\013\014\016-\177])*"'
        r')@(?:[A-Z0-9-]+\.)+[A-Z]{2,6}$', re.IGNORECASE)
    error_regex = N_('incorrect e-mail address')

class ModelDictConv(Converter):
    '''Converts a dictionary to object of `model` class with the same fields.
    It is designed for use in FieldSet'''

    model = None

    def from_python(self, value):
        result = {}
        for field in self.field.fields:
            result[field.name] = getattr(value, field.name)
        return result

    def to_python(self, value):
        obj = self.model()
        for field in self.field.fields:
            setattr(obj, field.name, value[field.name])
        return obj

class OptionLabel(unicode):

    published = False

class ModelChoice(EnumChoice):

    condition = None
    conv = Int(required=False)
    title_field = 'title'

    def __init__(self, *args, **kwargs):
        EnumChoice.__init__(self, *args, **kwargs)
        self.conv = self.conv(field=self.field)

    @property
    def query(self):
        query = self.env.db.query(self.model)
        if isinstance(self.condition, dict):
            query = query.filter_by(**self.condition)
        elif self.condition is not None:
            query = query.filter(self.condition)
        return query

    def from_python(self, value):
        if value is not None:
            return self.conv.from_python(value.id)
        else:
            return ''

    def to_python(self, value):
        try:
            value = self.conv.to_python(value)
        except ValidationError:
            return None
        else:
            if value is not None:
                return self.query.filter_by(id=value).first()

    def get_object_label(self, obj):
        label = OptionLabel(getattr(obj, self.title_field))
        try:
            label.published = obj.publish
        except AttributeError:
            pass
        return label

    def get_label(self, form_value):
        obj = self._safe_to_python(form_value)
        if obj is not None:
            return self.get_object_label(obj)

    def options(self):
        for obj in self.query.all():
            yield self.conv.from_python(obj.id), self.get_object_label(obj)
<|endoftext|>


<commit_before>"""
PIL formats for multiple images.
"""

import sys
import numpy as np

from .pillow import PillowFormat, ndarray_to_pil, image_as_uint

NeuQuant = None  # we can implement this when we need it

class TIFFFormat(PillowFormat):
    _modes = 'i'  # arg, why bother; people should use the tiffile version
    _description = 'TIFF format (Pillow)'

class GIFFormat(PillowFormat):
    """ A format for reading and writing static and animated GIF, based
    on Pillow.

    Images read with this format are always RGBA. Currently,
    the alpha channel is ignored when saving RGB images with this
    format.

    Parameters for reading
    ----------------------
    None

    Parameters for saving
    ---------------------
    loop : int
        The number of iterations. Default 0 (meaning loop indefinitely)
    duration : {float, list}
        The duration (in seconds) of each frame. Either specify one value
        that is used for all frames, or one value for each frame.
    fps : float
        The number of frames per second. If duration is not given, the
        duration for each frame is set to 1/fps. Default 10.
    palettesize : int
        The number of colors to quantize the image to. Is rounded to
        the nearest power of two. Default 256.
    subrectangles : bool
        If True, will try and optimize the GIF by storing only the
        rectangular parts of each frame that change with respect to the
        previous. Default False.
    """

    _modes = 'iI'
    _description = 'Static and animated gif (Pillow)'

    class Reader(PillowFormat.Reader):
        def _open(self, playback=None):  # compat with FI format
            return PillowFormat.Reader._open(self)

    class Writer(PillowFormat.Writer):
        def _open(self, loop=0, duration=None, fps=10, palettesize=256,
                  quantizer=0, subrectangles=False):

            # Check palettesize
            palettesize = int(palettesize)
            if palettesize < 2 or palettesize > 256:
                raise ValueError('GIF quantize param must be 2..256')
            if palettesize not in [2, 4, 8, 16, 32, 64, 128, 256]:
                palettesize = 2 ** int(np.log2(128) + 0.999)
                print('Warning: palettesize (%r) modified to a factor of '
                      'two between 2-256.' % palettesize)
            #  Duratrion / fps
            if duration is None:
                self._duration = 1.0 / float(fps)
            elif isinstance(duration, (list, tuple)):
                self._duration = [float(d) for d in duration]
            else:
                self._duration = float(duration)
            # loop
            loop = float(loop)
            if loop <= 0 or loop == float('inf'):
                loop = 0
            loop = int(loop)
            # Subrectangles / dispose
            subrectangles = bool(subrectangles)
            self._dispose = 1 if subrectangles else 2
            # The "0" (median cut) quantizer is by far the best

            fp = self.request.get_file()
            self._writer = GifWriter(fp, subrectangles, loop,
                                     quantizer, int(palettesize))

        def _close(self):
            self._writer.close()

        def _append_data(self, im, meta):
            im = image_as_uint(im, bitdepth=8)
            if im.ndim == 3 and im.shape[-1] == 1:
                im = im[:, :, 0]
            duration = self._duration
            if isinstance(duration, list):
                duration = duration[min(len(duration)-1, self._writer._count)]
            dispose = self._dispose
            self._writer.add_image(im, duration, dispose)

            return

if sys.version_info >= (3, ):
    intToBin = lambda i: i.to_bytes(2, byteorder='little')
else:
    def intToBin(i):
        """Integer to two bytes"""
        # No int.to_bytes() in Legacy Python
        i1 = i % 256
        i2 = int(i / 256)
        return chr(i1) + chr(i2)  # little endian

class GifWriter:
    """ Class that for helping write the animated GIF file. This is based on
    code from images2gif.py (part of visvis). The version here is modified
    to allow streamed writing.
    """

    def __init__(self, file, opt_subrectangle=True, opt_loop=0,
                 opt_quantizer=0, opt_palette_size=256):
        self.fp = file

        self.opt_subrectangle = opt_subrectangle
        self.opt_loop = opt_loop
        self.opt_quantizer = opt_quantizer
        self.opt_palette_size = opt_palette_size

        self._previous_image = None  # as np array
        self._global_palette = None  # as bytes
        self._count = 0

        from PIL.GifImagePlugin import getdata
        self.getdata = getdata

    def add_image(self, im, duration, dispose):

        # Prepare image
        im_rect, rect = im, (0, 0)
        if self.opt_subrectangle:
            im_rect, rect = self.getSubRectangle(im)
        im_pil = self.converToPIL(im_rect, self.opt_quantizer,
                                  self.opt_palette_size)

        # Get pallette - apparently, this is the 3d element of the header
        # (but it has not always been). Best we've got. Its not the same
        # as im_pil.palette.tobytes().
        from PIL.GifImagePlugin import getheader
        palette = getheader(im_pil)[0][3]

        # Write image
        if self._count == 0:
            self.write_header(im_pil, palette, self.opt_loop)
            self._global_palette = palette
        self.write_image(im_pil, palette, rect, duration, dispose)
        # assert len(palette) == len(self._global_palette)

        # Bookkeeping
        self._previous_image = im
        self._count += 1

    def write_header(self, im, globalPalette, loop):
        # Gather info
        header = self.getheaderAnim(im)
        appext = self.getAppExt(loop)
        # Write
        self.fp.write(header)
        self.fp.write(globalPalette)
        self.fp.write(appext)

    def close(self):
        self.fp.write(";".encode('utf-8'))  # end gif

    def write_image(self, im, palette, rect, duration, dispose):

        fp = self.fp

        # Gather local image header and data, using PIL's getdata. That
        # function returns a list of bytes objects, but which parts are
        # what has changed multiple times, so we put together the first
        # parts until we have enough to form the image header.
        data = self.getdata(im)
        imdes = b''
        while data and len(imdes) < 11:
            imdes += data.pop(0)
        assert len(imdes) == 11

        # Make image descriptor suitable for using 256 local color palette
        lid = self.getImageDescriptor(im, rect)
        graphext = self.getGraphicsControlExt(duration, dispose)

        # Write local header
        if (palette != self._global_palette) or (dispose != 2):
            # Use local color palette
            fp.write(graphext)
            fp.write(lid)  # write suitable image descriptor
            fp.write(palette)  # write local color table
            fp.write(b'\x08')  # LZW minimum size code
        else:
            # Use global color palette
            fp.write(graphext)
            fp.write(imdes)  # write suitable image descriptor

        # Write image data
        for d in data:
            fp.write(d)

    def getheaderAnim(self, im):
        """ Get animation header. To replace PILs getheader()[0]
        """
        bb = b"GIF89a"
        bb += intToBin(im.size[0])
        bb += intToBin(im.size[1])
        bb += b"\x87\x00\x00"
        return bb

    def getImageDescriptor(self, im, xy=None):
        """ Used for the local color table properties per image.
        Otherwise global color table applies to all frames irrespective of
        whether additional colors comes in play that require a redefined
        palette. Still a maximum of 256 color per frame, obviously.

        Written by Ant1 on 2010-08-22
        Modified by Alex Robinson in Janurari 2011 to implement subrectangles.
        """

        # Defaule use full image and place at upper left
        if xy is None:
            xy = (0, 0)

        # Image separator,
        bb = b'\x2C'

        # Image position and size
        bb += intToBin(xy[0])  # Left position
        bb += intToBin(xy[1])  # Top position
        bb += intToBin(im.size[0])  # image width
        bb += intToBin(im.size[1])  # image height

        # packed field: local color table flag1, interlace0, sorted table0,
        # reserved00, lct size111=7=2^(7 + 1)=256.
        bb += b'\x87'

        # LZW minimum size code now comes later, begining of [imagedata] blocks
        return bb

    def getAppExt(self, loop):
        """ Application extention. This part specifies the amount of loops.
        If loop is 0 or inf, it goes on infinitely.
        """

        if loop == 0:
            loop = 2 ** 16 - 1
        bb = b""
        if loop != 0:  # omit the extension if we would like a nonlooping gif
            bb = b"\x21\xFF\x0B"  # application extension
            bb += b"NETSCAPE2.0"
            bb += b"\x03\x01"
            bb += intToBin(loop)
            bb += b'\x00'  # end
        return bb

    def getGraphicsControlExt(self, duration=0.1, dispose=2):
        """ Graphics Control Extension. A sort of header at the start of
        each image. Specifies duration and transparancy.

        Dispose
        -------
          * 0 - No disposal specified.
          * 1 - Do not dispose. The graphic is to be left in place.
          * 2 -	Restore to background color. The area used by the graphic
            must be restored to the background color.
          * 3 -	Restore to previous. The decoder is required to restore the
            area overwritten by the graphic with what was there prior to
            rendering the graphic.
          * 4-7 -To be defined.
        """

        bb = b'\x21\xF9\x04'
        bb += chr((dispose & 3) << 2).encode('utf-8')
        # low bit 1 == transparency,
        # 2nd bit 1 == user input , next 3 bits, the low two of which are used,
        # are dispose.
        bb += intToBin(int(duration * 100))  # in 100th of seconds
        bb += b'\x00'  # no transparant color
        bb += b'\x00'  # end
        return bb

    def getSubRectangle(self, im):
        """ Calculate the minimal rectangle that need updating. Returns
        a two-element tuple containing the cropped image and an x-y tuple.

        Calculating the subrectangles takes extra time, obviously. However,
        if the image sizes were reduced, the actual writing of the GIF
        goes faster. In some cases applying this method produces a GIF faster.
        """

        # Cannot do subrectangle for first image
        if self._count == 0:
            return im, (0, 0)

        prev = self._previous_image

        # Get difference, sum over colors
        diff = np.abs(im - prev)
        if diff.ndim == 3:
            diff = diff.sum(2)
        # Get begin and end for both dimensions
        X = np.argwhere(diff.sum(0))
        Y = np.argwhere(diff.sum(1))
        # Get rect coordinates
        if X.size and Y.size:
            x0, x1 = int(X[0]), int(X[-1] + 1)
            y0, y1 = int(Y[0]), int(Y[-1] + 1)
        else:  # No change ... make it minimal
            x0, x1 = 0, 2
            y0, y1 = 0, 2

        return im[y0:y1, x0:x1], (x0, y0)

    def converToPIL(self, im, quantizer, palette_size=256):
        """Convert image to Paletted PIL image.

        PIL used to not do a very good job at quantization, but I guess
        this has improved a lot (at least in Pillow). I don't think we need
        neuqant (and we can add it later if we really want).
        """

        im_pil = ndarray_to_pil(im, 'gif')

        if quantizer in ('nq', 'neuquant'):
            # NeuQuant algorithm
            nq_samplefac = 10  # 10 seems good in general
            im_pil = im_pil.convert("RGBA")  # NQ assumes RGBA
            nqInstance = NeuQuant(im_pil, nq_samplefac)  # Learn colors
            im_pil = nqInstance.quantize(im_pil, colors=palette_size)
        elif quantizer in (0, 1, 2):
            # Adaptive PIL algorithm
            if quantizer == 2:
                im_pil = im_pil.convert("RGBA")
            else:
                im_pil = im_pil.convert("RGB")
            im_pil = im_pil.quantize(colors=palette_size, method=quantizer)
        else:
            raise ValueError('Invalid value for quantizer: %r' % quantizer)
        return im_pil
<commit_msg>disable looping in gifs functionality<commit_after>"""
PIL formats for multiple images.
"""

import sys
import numpy as np

from .pillow import PillowFormat, ndarray_to_pil, image_as_uint

NeuQuant = None  # we can implement this when we need it

class TIFFFormat(PillowFormat):
    _modes = 'i'  # arg, why bother; people should use the tiffile version
    _description = 'TIFF format (Pillow)'

class GIFFormat(PillowFormat):
    """ A format for reading and writing static and animated GIF, based
    on Pillow.

    Images read with this format are always RGBA. Currently,
    the alpha channel is ignored when saving RGB images with this
    format.

    Parameters for reading
    ----------------------
    None

    Parameters for saving
    ---------------------
    loop : int
        The number of iterations. Default 0 (meaning loop indefinitely).
        A loop of -1 disables looping.
    duration : {float, list}
        The duration (in seconds) of each frame. Either specify one value
        that is used for all frames, or one value for each frame.
    fps : float
        The number of frames per second. If duration is not given, the
        duration for each frame is set to 1/fps. Default 10.
    palettesize : int
        The number of colors to quantize the image to. Is rounded to
        the nearest power of two. Default 256.
    subrectangles : bool
        If True, will try and optimize the GIF by storing only the
        rectangular parts of each frame that change with respect to the
        previous. Default False.
    """

    _modes = 'iI'
    _description = 'Static and animated gif (Pillow)'

    class Reader(PillowFormat.Reader):
        def _open(self, playback=None):  # compat with FI format
            return PillowFormat.Reader._open(self)

    class Writer(PillowFormat.Writer):
        def _open(self, loop=0, duration=None, fps=10, palettesize=256,
                  quantizer=0, subrectangles=False):

            # Check palettesize
            palettesize = int(palettesize)
            if palettesize < 2 or palettesize > 256:
                raise ValueError('GIF quantize param must be 2..256')
            if palettesize not in [2, 4, 8, 16, 32, 64, 128, 256]:
                palettesize = 2 ** int(np.log2(128) + 0.999)
                print('Warning: palettesize (%r) modified to a factor of '
                      'two between 2-256.' % palettesize)
            #  Duratrion / fps
            if duration is None:
                self._duration = 1.0 / float(fps)
            elif isinstance(duration, (list, tuple)):
                self._duration = [float(d) for d in duration]
            else:
                self._duration = float(duration)
            # loop
            loop = float(loop)
            if loop < -1 or loop == float('inf'):
                loop = 0
            loop = int(loop)
            # Subrectangles / dispose
            subrectangles = bool(subrectangles)
            self._dispose = 1 if subrectangles else 2
            # The "0" (median cut) quantizer is by far the best

            fp = self.request.get_file()
            self._writer = GifWriter(fp, subrectangles, loop,
                                     quantizer, int(palettesize))

        def _close(self):
            self._writer.close()

        def _append_data(self, im, meta):
            im = image_as_uint(im, bitdepth=8)
            if im.ndim == 3 and im.shape[-1] == 1:
                im = im[:, :, 0]
            duration = self._duration
            if isinstance(duration, list):
                duration = duration[min(len(duration)-1, self._writer._count)]
            dispose = self._dispose
            self._writer.add_image(im, duration, dispose)

            return

if sys.version_info >= (3, ):
    intToBin = lambda i: i.to_bytes(2, byteorder='little')
else:
    def intToBin(i):
        """Integer to two bytes"""
        # No int.to_bytes() in Legacy Python
        i1 = i % 256
        i2 = int(i / 256)
        return chr(i1) + chr(i2)  # little endian

class GifWriter:
    """ Class that for helping write the animated GIF file. This is based on
    code from images2gif.py (part of visvis). The version here is modified
    to allow streamed writing.
    """

    def __init__(self, file, opt_subrectangle=True, opt_loop=0,
                 opt_quantizer=0, opt_palette_size=256):
        self.fp = file

        self.opt_subrectangle = opt_subrectangle
        self.opt_loop = opt_loop
        self.opt_quantizer = opt_quantizer
        self.opt_palette_size = opt_palette_size

        self._previous_image = None  # as np array
        self._global_palette = None  # as bytes
        self._count = 0

        from PIL.GifImagePlugin import getdata
        self.getdata = getdata

    def add_image(self, im, duration, dispose):

        # Prepare image
        im_rect, rect = im, (0, 0)
        if self.opt_subrectangle:
            im_rect, rect = self.getSubRectangle(im)
        im_pil = self.converToPIL(im_rect, self.opt_quantizer,
                                  self.opt_palette_size)

        # Get pallette - apparently, this is the 3d element of the header
        # (but it has not always been). Best we've got. Its not the same
        # as im_pil.palette.tobytes().
        from PIL.GifImagePlugin import getheader
        palette = getheader(im_pil)[0][3]

        # Write image
        if self._count == 0:
            self.write_header(im_pil, palette, self.opt_loop)
            self._global_palette = palette
        self.write_image(im_pil, palette, rect, duration, dispose)
        # assert len(palette) == len(self._global_palette)

        # Bookkeeping
        self._previous_image = im
        self._count += 1

    def write_header(self, im, globalPalette, loop):
        # Gather info
        header = self.getheaderAnim(im)
        appext = self.getAppExt(loop)
        # Write
        self.fp.write(header)
        self.fp.write(globalPalette)
        self.fp.write(appext)

    def close(self):
        self.fp.write(";".encode('utf-8'))  # end gif

    def write_image(self, im, palette, rect, duration, dispose):

        fp = self.fp

        # Gather local image header and data, using PIL's getdata. That
        # function returns a list of bytes objects, but which parts are
        # what has changed multiple times, so we put together the first
        # parts until we have enough to form the image header.
        data = self.getdata(im)
        imdes = b''
        while data and len(imdes) < 11:
            imdes += data.pop(0)
        assert len(imdes) == 11

        # Make image descriptor suitable for using 256 local color palette
        lid = self.getImageDescriptor(im, rect)
        graphext = self.getGraphicsControlExt(duration, dispose)

        # Write local header
        if (palette != self._global_palette) or (dispose != 2):
            # Use local color palette
            fp.write(graphext)
            fp.write(lid)  # write suitable image descriptor
            fp.write(palette)  # write local color table
            fp.write(b'\x08')  # LZW minimum size code
        else:
            # Use global color palette
            fp.write(graphext)
            fp.write(imdes)  # write suitable image descriptor

        # Write image data
        for d in data:
            fp.write(d)

    def getheaderAnim(self, im):
        """ Get animation header. To replace PILs getheader()[0]
        """
        bb = b"GIF89a"
        bb += intToBin(im.size[0])
        bb += intToBin(im.size[1])
        bb += b"\x87\x00\x00"
        return bb

    def getImageDescriptor(self, im, xy=None):
        """ Used for the local color table properties per image.
        Otherwise global color table applies to all frames irrespective of
        whether additional colors comes in play that require a redefined
        palette. Still a maximum of 256 color per frame, obviously.

        Written by Ant1 on 2010-08-22
        Modified by Alex Robinson in Janurari 2011 to implement subrectangles.
        """

        # Defaule use full image and place at upper left
        if xy is None:
            xy = (0, 0)

        # Image separator,
        bb = b'\x2C'

        # Image position and size
        bb += intToBin(xy[0])  # Left position
        bb += intToBin(xy[1])  # Top position
        bb += intToBin(im.size[0])  # image width
        bb += intToBin(im.size[1])  # image height

        # packed field: local color table flag1, interlace0, sorted table0,
        # reserved00, lct size111=7=2^(7 + 1)=256.
        bb += b'\x87'

        # LZW minimum size code now comes later, begining of [imagedata] blocks
        return bb

    def getAppExt(self, loop):
        """ Application extention. This part specifies the amount of loops.
        If loop is 0 or inf, it goes on infinitely and if loop is -1 it does not loop.
        """
        if loop == -1:
            return b""
        if loop == 0:
            loop = 2 ** 16 - 1
        bb = b""
        if loop != 0:  # omit the extension if we would like a nonlooping gif
            bb = b"\x21\xFF\x0B"  # application extension
            bb += b"NETSCAPE2.0"
            bb += b"\x03\x01"
            bb += intToBin(loop)
            bb += b'\x00'  # end
        return bb

    def getGraphicsControlExt(self, duration=0.1, dispose=2):
        """ Graphics Control Extension. A sort of header at the start of
        each image. Specifies duration and transparancy.

        Dispose
        -------
          * 0 - No disposal specified.
          * 1 - Do not dispose. The graphic is to be left in place.
          * 2 -	Restore to background color. The area used by the graphic
            must be restored to the background color.
          * 3 -	Restore to previous. The decoder is required to restore the
            area overwritten by the graphic with what was there prior to
            rendering the graphic.
          * 4-7 -To be defined.
        """

        bb = b'\x21\xF9\x04'
        bb += chr((dispose & 3) << 2).encode('utf-8')
        # low bit 1 == transparency,
        # 2nd bit 1 == user input , next 3 bits, the low two of which are used,
        # are dispose.
        bb += intToBin(int(duration * 100))  # in 100th of seconds
        bb += b'\x00'  # no transparant color
        bb += b'\x00'  # end
        return bb

    def getSubRectangle(self, im):
        """ Calculate the minimal rectangle that need updating. Returns
        a two-element tuple containing the cropped image and an x-y tuple.

        Calculating the subrectangles takes extra time, obviously. However,
        if the image sizes were reduced, the actual writing of the GIF
        goes faster. In some cases applying this method produces a GIF faster.
        """

        # Cannot do subrectangle for first image
        if self._count == 0:
            return im, (0, 0)

        prev = self._previous_image

        # Get difference, sum over colors
        diff = np.abs(im - prev)
        if diff.ndim == 3:
            diff = diff.sum(2)
        # Get begin and end for both dimensions
        X = np.argwhere(diff.sum(0))
        Y = np.argwhere(diff.sum(1))
        # Get rect coordinates
        if X.size and Y.size:
            x0, x1 = int(X[0]), int(X[-1] + 1)
            y0, y1 = int(Y[0]), int(Y[-1] + 1)
        else:  # No change ... make it minimal
            x0, x1 = 0, 2
            y0, y1 = 0, 2

        return im[y0:y1, x0:x1], (x0, y0)

    def converToPIL(self, im, quantizer, palette_size=256):
        """Convert image to Paletted PIL image.

        PIL used to not do a very good job at quantization, but I guess
        this has improved a lot (at least in Pillow). I don't think we need
        neuqant (and we can add it later if we really want).
        """

        im_pil = ndarray_to_pil(im, 'gif')

        if quantizer in ('nq', 'neuquant'):
            # NeuQuant algorithm
            nq_samplefac = 10  # 10 seems good in general
            im_pil = im_pil.convert("RGBA")  # NQ assumes RGBA
            nqInstance = NeuQuant(im_pil, nq_samplefac)  # Learn colors
            im_pil = nqInstance.quantize(im_pil, colors=palette_size)
        elif quantizer in (0, 1, 2):
            # Adaptive PIL algorithm
            if quantizer == 2:
                im_pil = im_pil.convert("RGBA")
            else:
                im_pil = im_pil.convert("RGB")
            im_pil = im_pil.quantize(colors=palette_size, method=quantizer)
        else:
            raise ValueError('Invalid value for quantizer: %r' % quantizer)
        return im_pil
<|endoftext|>


<commit_before>"""Views at the configuration root level."""

from django.contrib.auth.models import User
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from django.views.generic import TemplateView, CreateView, UpdateView
from imager_images.models import Photo, Album
from imager_profile.models import ImagerProfile
from .forms import AlbumForm, UserForm, ImagerProfileForm, UserProfileFormSet
DEFAULT_IMG_URL = 'media/django-magic.jpg'

class HomeView(TemplateView):
    """Generic home view showing public image to any user."""

    template_name = "home.html"

    def get_context_data(self, *args, **kwargs):
        """Return dictionary of context information for home view."""
        context_data = super(HomeView, self).get_context_data(*args, **kwargs)
        img_url = DEFAULT_IMG_URL
        user_photo = Photo.public.random()
        if user_photo:
            img_url = user_photo.img_file.url
        context_data['img_url'] = img_url
        return context_data

#####################
# Under construction consolidated class

class CreateOrEditMixin(object):
    """Flexible class view for creation and editing of albums and photos."""

    template_name = 'create_or_edit.html'
    success_url = '/images/library/'
    own_queryset_name = None
    rel_queryset_name = None

    def get(self, request, *args, **kwargs):
        """Allow only photos belonging to current user as the view queryset."""
        self.queryset = getattr(self.request.user, self.own_queryset_name)
        return super(CreateOrEditMixin, self).get(request, *args, **kwargs)

    def get_context_data(self, *args, **kwargs):
        """Provide context data to edit and create pages."""
        # import pdb;pdb.set_trace()
        context_data = super(
            CreateOrEditMixin, self).get_context_data(*args, **kwargs)
        path = self.request.path
        if '/add/' in path:
            context_data['cancel_url'] = self.success_url
            context_data['use_case'] = 'Create'
        else:
            context_data['cancel_url'] = path.replace('edit/', '')
            context_data['use_case'] = 'Edit'
        context_data['model_name'] = self.object.__class__.__name__
        return context_data

    def get_form(self, form_class=None):
        """Return an instance of the form to be used in this view."""
        form = super(CreateOrEditMixin, self).get_form(form_class=form_class)
        owner_rel_queryset = getattr(self.request.user, self.rel_queryset_name)
        form.fields[self.rel_queryset_name].queryset = owner_rel_queryset
        return form

    def form_valid(self, form):
        """Insert the user from request context into the form as the owner."""
        form.instance.owner = self.request.user
        return super(CreateOrEditMixin, self).form_valid(form)

class CreatePhotoView(CreateOrEditMixin, CreateView):
    """Create a new Photo to the database."""

    model = Photo
    fields = ['albums', 'img_file', 'title', 'description', 'published']
    own_queryset_name = 'photos'
    rel_queryset_name = 'albums'

class CreateAlbumView(CreateOrEditMixin, CreateView):
    """Create a new Album to the database."""

    model = Album
    form_class = AlbumForm
    own_queryset_name = 'albums'
    rel_queryset_name = 'photos'

class EditPhotoView(CreateOrEditMixin, UpdateView):
    """Allows user to edit their own photos."""

    model = Photo
    fields = ['albums', 'title', 'description', 'published']
    own_queryset_name = 'photos'
    rel_queryset_name = 'albums'

class EditAlbumView(CreateOrEditMixin, UpdateView):
    """Allows user to edit their own photos."""

    model = Album
    form_class = AlbumForm
    own_queryset_name = 'albums'
    rel_queryset_name = 'photos'

def edit_profile(request):
    """Allow user to edit their ImagerProfile, and limited fields of User."""
    user = request.user
    profile = request.user.profile
    if request.method == 'POST':
        user_form = UserForm(request.POST, instance=user)
        profile_form = ImagerProfileForm(request.POST, instance=profile)
        if user_form.is_valid() and profile_form.is_valid():
            user_form.save()
            profile_form.save()
            return HttpResponseRedirect('/profile/')
    user_form = UserForm(instance=user)
    profile_form = ImagerProfileForm(instance=profile)
    context = {'user_form': user_form, 'profile_form': profile_form}
    return render(request, 'edit_profile.html', context)

class EditProfileView(UpdateView):
    """Allow the user to edit their profile."""

    model = User
    form_class = UserProfileFormSet
    template_name = "edit_profile2.html"
    # fields = ['user__first_name', 'user__last_name', 'camera']
    success_url = '/profile/'

    def get_object(self, queryset=None):
        """Allow only photos belonging to current user as the view queryset."""
        self.kwargs['pk'] = self.request.user.pk
        return super(EditProfileView, self).get_object(queryset=queryset)

    # def get_context_data(self, *args, **kwargs):
    #     """Include the formset in the context data."""
    #     data = super(EditProfileView, self).get_context_data(*args, **kwargs)
    #     data['formset'] = UserProfileFormSet(instance=self.request.user)
    #     return data

    # def form_valid(self):
    #     pass
<commit_msg>Fixed model name reference in views.py and removed comments.<commit_after>"""Views at the configuration root level."""

from django.contrib.auth.models import User
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from django.views.generic import TemplateView, CreateView, UpdateView
from imager_images.models import Photo, Album
from imager_profile.models import ImagerProfile
from .forms import AlbumForm, UserForm, ImagerProfileForm, UserProfileFormSet
DEFAULT_IMG_URL = 'media/django-magic.jpg'

class HomeView(TemplateView):
    """Generic home view showing public image to any user."""

    template_name = "home.html"

    def get_context_data(self, *args, **kwargs):
        """Return dictionary of context information for home view."""
        context_data = super(HomeView, self).get_context_data(*args, **kwargs)
        img_url = DEFAULT_IMG_URL
        user_photo = Photo.public.random()
        if user_photo:
            img_url = user_photo.img_file.url
        context_data['img_url'] = img_url
        return context_data

class CreateOrEditMixin(object):
    """Flexible class view for creation and editing of albums and photos."""

    template_name = 'create_or_edit.html'
    success_url = '/images/library/'
    own_queryset_name = None
    rel_queryset_name = None

    def get(self, request, *args, **kwargs):
        """Allow only photos belonging to current user as the view queryset."""
        self.queryset = getattr(self.request.user, self.own_queryset_name)
        return super(CreateOrEditMixin, self).get(request, *args, **kwargs)

    def get_context_data(self, *args, **kwargs):
        """Provide context data to edit and create pages."""
        context_data = super(
            CreateOrEditMixin, self).get_context_data(*args, **kwargs)
        path = self.request.path
        if '/add/' in path:
            context_data['cancel_url'] = self.success_url
            context_data['use_case'] = 'Create'
        else:
            context_data['cancel_url'] = path.replace('edit/', '')
            context_data['use_case'] = 'Edit'
        context_data['model_name'] = self.model.__class__.__name__
        return context_data

    def get_form(self, form_class=None):
        """Return an instance of the form to be used in this view."""
        form = super(CreateOrEditMixin, self).get_form(form_class=form_class)
        owner_rel_queryset = getattr(self.request.user, self.rel_queryset_name)
        form.fields[self.rel_queryset_name].queryset = owner_rel_queryset
        return form

    def form_valid(self, form):
        """Insert the user from request context into the form as the owner."""
        form.instance.owner = self.request.user
        return super(CreateOrEditMixin, self).form_valid(form)

class CreatePhotoView(CreateOrEditMixin, CreateView):
    """Create a new Photo to the database."""

    model = Photo
    fields = ['albums', 'img_file', 'title', 'description', 'published']
    own_queryset_name = 'photos'
    rel_queryset_name = 'albums'

class CreateAlbumView(CreateOrEditMixin, CreateView):
    """Create a new Album to the database."""

    model = Album
    form_class = AlbumForm
    own_queryset_name = 'albums'
    rel_queryset_name = 'photos'

class EditPhotoView(CreateOrEditMixin, UpdateView):
    """Allows user to edit their own photos."""

    model = Photo
    fields = ['albums', 'title', 'description', 'published']
    own_queryset_name = 'photos'
    rel_queryset_name = 'albums'

class EditAlbumView(CreateOrEditMixin, UpdateView):
    """Allows user to edit their own photos."""

    model = Album
    form_class = AlbumForm
    own_queryset_name = 'albums'
    rel_queryset_name = 'photos'

def edit_profile(request):
    """Allow user to edit their ImagerProfile, and limited fields of User."""
    user = request.user
    profile = request.user.profile
    if request.method == 'POST':
        user_form = UserForm(request.POST, instance=user)
        profile_form = ImagerProfileForm(request.POST, instance=profile)
        if user_form.is_valid() and profile_form.is_valid():
            user_form.save()
            profile_form.save()
            return HttpResponseRedirect('/profile/')
    user_form = UserForm(instance=user)
    profile_form = ImagerProfileForm(instance=profile)
    context = {'user_form': user_form, 'profile_form': profile_form}
    return render(request, 'edit_profile.html', context)

class EditProfileView(UpdateView):
    """Allow the user to edit their profile."""

    model = User
    form_class = UserProfileFormSet
    template_name = "edit_profile2.html"
    # fields = ['user__first_name', 'user__last_name', 'camera']
    success_url = '/profile/'

    def get_object(self, queryset=None):
        """Allow only photos belonging to current user as the view queryset."""
        self.kwargs['pk'] = self.request.user.pk
        return super(EditProfileView, self).get_object(queryset=queryset)

    # def get_context_data(self, *args, **kwargs):
    #     """Include the formset in the context data."""
    #     data = super(EditProfileView, self).get_context_data(*args, **kwargs)
    #     data['formset'] = UserProfileFormSet(instance=self.request.user)
    #     return data

    # def form_valid(self):
    #     pass
<|endoftext|>


<commit_before>"""Views at the configuration root level."""

from django.views.generic import TemplateView
from imager_images.models import Photo

DEFAULT_IMG_URL = 'media/django-magic.jpg'

class HomeView(TemplateView):
    """Generic home view showing public image to any user."""

    template_name = "home.html"

    def get_context_data(self, *args, **kwargs):
        """Return dictionary of context information for home view."""
        img_url = DEFAULT_IMG_URL
        user_photo = Photo.public.random()
        if user_photo:
            img_url = user_photo.img_file.url

        return {'img_url': img_url}

class ProfileView(TemplateView):
    """Shows a User's profile page."""

    template_name = "profile.html"

    def get(request, *args, **kwargs):
        """Stand in for get."""
        pass<commit_msg>Set ProfileView for improvement.<commit_after>"""Views at the configuration root level."""

from django.views.generic import TemplateView
from imager_images.models import Photo

DEFAULT_IMG_URL = 'media/django-magic.jpg'

class HomeView(TemplateView):
    """Generic home view showing public image to any user."""

    template_name = "home.html"

    def get_context_data(self, *args, **kwargs):
        """Return dictionary of context information for home view."""
        img_url = DEFAULT_IMG_URL
        user_photo = Photo.public.random()
        if user_photo:
            img_url = user_photo.img_file.url

        return {'img_url': img_url}

class ProfileView(TemplateView):
    """Shows a User's profile page."""

    template_name = "profile.html"

    def get(self, request, *args, **kwargs):
        """Stand in for get."""
        pass
<|endoftext|>


<commit_before>from __future__ import absolute_import

# flake8: noqa

try:
    from pathlib import Path, PurePath
except ImportError:
    from pathlib2 import Path, PurePath                         # type: ignore

try:
    from abc import ABC                                         # type: ignore
except ImportError:
    from abc import ABCMeta

    class ABC(object):                                          # type: ignore
        __metaclass__ = ABCMeta

try:
    FileNotFoundError = FileNotFoundError                       # type: ignore
except NameError:
    FileNotFoundError = OSError

class PackageSpec(object):
	def __init__(self, **kwargs):
		vars(self).update(kwargs)

def package_spec(package):
	return getattr(package, '__spec__', None) or \
		PackageSpec(
			origin=package.__file__,
			loader=getattr(package, '__loader__', None),
		)
<commit_msg>Doubly ignore the type<commit_after>from __future__ import absolute_import

# flake8: noqa

try:
    from pathlib import Path, PurePath
except ImportError:
    from pathlib2 import Path, PurePath                         # type: ignore

try:
    from abc import ABC                                         # type: ignore
except ImportError:
    from abc import ABCMeta

    class ABC(object):                                          # type: ignore
        __metaclass__ = ABCMeta

try:
    FileNotFoundError = FileNotFoundError                       # type: ignore
except NameError:
    FileNotFoundError = OSError                                 # type: ignore

class PackageSpec(object):
	def __init__(self, **kwargs):
		vars(self).update(kwargs)

def package_spec(package):
	return getattr(package, '__spec__', None) or \
		PackageSpec(
			origin=package.__file__,
			loader=getattr(package, '__loader__', None),
		)
<|endoftext|>


<commit_before>#Cache Implementation

class cache:
    """A cache implementation"""
    def __init__(self, cacheSize, blockSize, mapping):
        #Simulation inputs
        self.cacheSize = cacheSize
        self.blockSize = blockSize

        #Calculate internal cache setup
        self.numBlocks = int(self.cacheSize / self.blockSize)
        if mapping != 0:
            self.cacheMap = mapping
        else:
            self.cacheMap = self.numBlocks
        self.numSets = int(self.cacheSize / (self.cacheMap * self.blockSize))

        #Create a 2D array of cacheline elements
        self.cache = [[{'valid':0, 'tag':0} for x in range(self.cacheMap)] for y in range(self.numSets)]

        #Create a 2D array for the lru
        self.lru = [[0 for x in range(self.cacheMap)] for y in range(self.numSets)]

    #Accepts a single atomic operation and runs it through the cache.
    def simulate_element(self, element):
        cacheHit = False

        #Read in the elements r/w and address
        read_write = element[0]
        address = element[1]

        #Find the set and tag based on the input address
        curr_set = int((address / self.blockSize) % self.numSets)
        curr_tag = int((address / self.blockSize) / self.numSets)

        #Increment every location in the LRU every time there is a cache access
        for i in range(self.numSets):
            for j in range(self.cacheMap):
                self.lru[i][j] += 1

        if read_write == 'read':
            found = False
            for i in range(self.cacheMap):
                if self.cache[curr_set][i]['tag'] == curr_tag and self.cache[curr_set][i]['valid'] != 0:
                    #If the tag matches and the data is valid then mark as found
                    #and as a hit and reset the LRU in this location.
                    cacheHit = True
                    found = True
                    self.lru[curr_set][i] = 0

            if not found:
                index = 0
                #Need to pull data into the cache, look for invalid locations
                #before using the lru to evict someone
                for j in range(self.cacheMap):
                    if self.cache[curr_set][j]['valid'] == 0 and not found:
                        #Loop until and invalid location is found.  Once found
                        #set found to true, reset the lru and mark the index that
                        #it was found in.
                        found = True
                        self.lru[curr_set][j] = 0
                        index = j

                #If there aren't any invalid locations then use the lru
                if not found:
                    for j in range(self.cacheMap):
                        if self.lru[curr_set][j] > self.lru[curr_set][index]:
                            index = j

                    #Reset the lru in the location choosen to be replaced
                    self.lru[curr_set][index] = 0

                #Update the cache information
                self.cache[curr_set][index]['tag'] = curr_tag
                self.cache[curr_set][index]['valid'] = 1

        elif read_write == 'write':
            found = False
            index = 0
            for i in range(self.cacheMap):
                if self.cache[curr_set][i]['tag'] == curr_tag and not found:
                    #If the tag matches and it has not been found yet
                    cacheHit = True
                    found = True
                    self.lru[curr_set][i] = 0
                    index = i

            if not found:
                for i in range(self.cacheMap):
                    if self.cache[curr_set][i]['valid'] == 0 and not found:
                        #Loop until and invalid location is found.  Once found
                        #set found to true, reset the lru and mark the index that
                        #it was found in.
                        found = True
                        self.lru[curr_set][i] = 0
                        index = i

                #If there aren't any invalid locations then use the lru
                if not found:
                    for i in range(self.cacheMap):
                        if self.lru[curr_set][i] > self.lru[curr_set][index]:
                            index = i

                    #Reset the lru in the location choosen to be replaced
                    self.lru[curr_set][index] = 0

                #Update the cache information
                self.cache[curr_set][index]['tag'] = curr_tag
                self.cache[curr_set][index]['valid'] = 1

        return cacheHit,curr_set,curr_tag

    def mark_invalid(self):
        for curr_set in self.cache:
            for i in curr_set:
                i['valid'] = 0

    def mark_line_invalid(self,address):
        curr_set = int((address / self.blockSize) % self.numSets)
        for i in self.cache[curr_set]:
            i['valid'] = 0

    def mark_partition_invalid(self,allowed_sets):
        low_set = allowed_sets[0]
        high_set = allowed_sets[1]
        for curr_set in range(low_set, high_set+1):
            for i in self.cache[curr_set]:
                i['valid'] = 0
                i['tag'] = 0

    def display_cache(self):
        pass
<commit_msg>More results in command_data_output.txt<commit_after>#Cache Implementation

class cache:
    """A cache implementation"""
    def __init__(self, cacheSize, blockSize, mapping):
        #Simulation inputs
        self.cacheSize = cacheSize
        self.blockSize = blockSize

        #Calculate internal cache setup
        self.numBlocks = int(self.cacheSize / self.blockSize)
        if mapping != 0:
            self.cacheMap = mapping
        else:
            self.cacheMap = self.numBlocks
        self.numSets = int(self.cacheSize / (self.cacheMap * self.blockSize))

        #Create a 2D array of cacheline elements
        self.cache = [[{'valid':0, 'tag':0} for x in range(self.cacheMap)] for y in range(self.numSets)]

        #Create a 2D array for the lru
        self.lru = [[0 for x in range(self.cacheMap)] for y in range(self.numSets)]

    #Accepts a single atomic operation and runs it through the cache.
    def simulate_element(self, element):
        cacheHit = False

        #Read in the elements r/w and address
        read_write = element[0]
        address = element[1]

        #Find the set and tag based on the input address
        curr_set = int((address / self.blockSize) % self.numSets)
        curr_tag = int((address / self.blockSize) / self.numSets)

        #Increment every location in the LRU every time there is a cache access
        for i in range(self.numSets):
            for j in range(self.cacheMap):
                self.lru[i][j] += 1

        if read_write == 'read':
            found = False
            for i in range(self.cacheMap):
                if self.cache[curr_set][i]['tag'] == curr_tag and self.cache[curr_set][i]['valid'] != 0:
                    #If the tag matches and the data is valid then mark as found
                    #and as a hit and reset the LRU in this location.
                    cacheHit = True
                    found = True
                    self.lru[curr_set][i] = 0

            if not found:
                index = 0
                #Need to pull data into the cache, look for invalid locations
                #before using the lru to evict someone
                for j in range(self.cacheMap):
                    if self.cache[curr_set][j]['valid'] == 0 and not found:
                        #Loop until and invalid location is found.  Once found
                        #set found to true, reset the lru and mark the index that
                        #it was found in.
                        found = True
                        self.lru[curr_set][j] = 0
                        index = j

                #If there aren't any invalid locations then use the lru
                if not found:
                    for j in range(self.cacheMap):
                        if self.lru[curr_set][j] > self.lru[curr_set][index]:
                            index = j

                    #Reset the lru in the location choosen to be replaced
                    self.lru[curr_set][index] = 0

                #Update the cache information
                self.cache[curr_set][index]['tag'] = curr_tag
                self.cache[curr_set][index]['valid'] = 1

        elif read_write == 'write':
            found = False
            index = 0
            for i in range(self.cacheMap):
                if self.cache[curr_set][i]['tag'] == curr_tag and not found:
                    #If the tag matches and it has not been found yet
                    cacheHit = True
                    found = True
                    self.lru[curr_set][i] = 0
                    index = i

            if not found:
                for i in range(self.cacheMap):
                    if self.cache[curr_set][i]['valid'] == 0 and not found:
                        #Loop until and invalid location is found.  Once found
                        #set found to true, reset the lru and mark the index that
                        #it was found in.
                        found = True
                        self.lru[curr_set][i] = 0
                        index = i

                #If there aren't any invalid locations then use the lru
                if not found:
                    for i in range(self.cacheMap):
                        if self.lru[curr_set][i] > self.lru[curr_set][index]:
                            index = i

                    #Reset the lru in the location choosen to be replaced
                    self.lru[curr_set][index] = 0

                #Update the cache information
                self.cache[curr_set][index]['tag'] = curr_tag
                self.cache[curr_set][index]['valid'] = 1

        return cacheHit,curr_set,curr_tag

    def mark_invalid(self):
        for curr_set in self.cache:
            for i in curr_set:
                i['valid'] = 0

    def mark_line_invalid(self,address):
        curr_set = int((address / self.blockSize) % self.numSets)
        for i in self.cache[curr_set]:
            i['valid'] = 0
            i['tag'] = 0

    def mark_partition_invalid(self,allowed_sets):
        low_set = allowed_sets[0]
        high_set = allowed_sets[1]
        for curr_set in range(low_set, high_set+1):
            for i in self.cache[curr_set]:
                i['valid'] = 0
                i['tag'] = 0

    def display_cache(self):
        pass
<|endoftext|>


<commit_before>import time
import functools
import inspect

class Cache(object):
    """Cache and memoizer."""

    def __init__(self, store, **kwargs):
        kwargs['store'] = store
        self.regions = dict(default=kwargs)

    def _expand_opts(self, key, opts):
        region = opts.get('region', 'default')
        for k, v in self.regions[region].iteritems():
            opts.setdefault(k, v)
        namespace = opts.get('namespace')
        if namespace:
            key = '%s:%s' % (namespace, key)
        return (key, opts['store'])

    def get(self, key, func=None, args=(), kwargs={}, **opts):
        key, store = self._expand_opts(key, opts)

        if not isinstance(key, str):
            raise TypeError('non-string key of type %s' % type(key))

        pair = store.get(key)
        if pair is not None:
            value, expiry = pair
            if expiry is None or expiry > time.time():
                return value
            try:
                del store[key]
            except KeyError:
                pass

        if func is None:
            return None

        value = func(*args, **kwargs)

        expiry = opts.get('expiry')
        maxage = opts.get('maxage')
        if maxage is not None:
            expiry = (expiry or time.time()) + maxage
        store[key] = (value, expiry)

        return value

    def delete(self, key, **opts):
        key, store = self._expand_opts(key, opts)
        try:
            del store[key]
        except KeyError:
            pass

    def expire_at(self, key, expiry, **opts):
        key, store = self._expand_opts(key, opts)
        pair = store.get(key)
        if pair is not None:
            store[key] = (pair[0], expiry)
        else:
            raise KeyError(key)

    def expire(self, key, maxage, **opts):
        self.expire_at(key, time.time() + maxage, **opts)

    def ttl(self, key, **opts):
        key, store = self._expand_opts(key, opts)
        pair = store.get(key)
        if pair is None:
            return None
        value, expiry = pair
        if expiry is not None:
            return max(0, expiry - time.time()) or None

    def exists(self, key, **opts):
        key, store = self._expand_opts(key, opts)
        return key in store

    def __call__(self, *args, **opts):
        """Decorator."""

        if args and hasattr(args[0], '__call__'):
            func = args[0]
            args = args[1:]
        else:
            # Build the decorator.
            return lambda func: self(func, *args, **opts)

        master_key = ','.join(map(repr, args)) if args else None
        return CachedFunction(self, func, master_key, opts)

class CachedFunction(object):

    def __init__(self, cache, func, master_key, opts):
        self.cache = cache
        self.func = func
        self.master_key = master_key
        self.opts = opts

    def __repr__(self):
        return '<%s of %s via %s>' % (self.__class__.__name__, self.func, self.cache)

    def get_key(self, args, kwargs):
        # We need to normalize the signature of the function. This is only
        # really possible if we wrap the "real" function.
        spec = inspect.getargspec(self.func)

        # Insert kwargs into the args list by name.
        orig_args = list(args)
        args = []
        for i, name in enumerate(spec.args):
            if name in kwargs:
                args.append(kwargs.pop(name))
            elif orig_args:
                args.append(orig_args.pop(0))
            else:
                break

        args.extend(orig_args)

        # Add on as many defaults as we need to.
        if spec.defaults:
            offset = len(spec.args) - len(spec.defaults)
            args.extend(spec.defaults[len(args) - offset:])

        arg_str_chunks = map(repr, args)
        for pair in kwargs.iteritems():
            arg_str_chunks.append('%s=%r' % pair)
        arg_str = ', '.join(arg_str_chunks)

        key = '%s.%s(%s)' % (self.func.__module__, self.func.__name__, arg_str)
        return self.master_key + ':' + key if self.master_key else key

    def __call__(self, *args, **kwargs):
        return self.cache.get(self.get_key(args, kwargs), self.func, args, kwargs, **self.opts)

    def delete(self, args=(), kwargs={}):
        self.cache.delete(self.get_key(args, kwargs))

    def expire(self, maxage, args=(), kwargs={}):
        self.cache.expire(self.get_key(args, kwargs), maxage)

    def expire_at(self, maxage, args=(), kwargs={}):
        self.cache.expire_at(self.get_key(args, kwargs), maxage)

    def ttl(self, args=(), kwargs={}):
        return self.cache.ttl(self.get_key(args, kwargs))

    def exists(self, args=(), kwargs={}):
        return self.cache.exists(self.get_key(args, kwargs))

<commit_msg>Methods of decorated function support opts.<commit_after>import time
import functools
import inspect

class Cache(object):
    """Cache and memoizer."""

    def __init__(self, store, **kwargs):
        kwargs['store'] = store
        self.regions = dict(default=kwargs)

    def _expand_opts(self, key, opts):
        region = opts.get('region', 'default')
        for k, v in self.regions[region].iteritems():
            opts.setdefault(k, v)
        namespace = opts.get('namespace')
        if namespace:
            key = '%s:%s' % (namespace, key)
        return (key, opts['store'])

    def get(self, key, func=None, args=(), kwargs={}, **opts):
        key, store = self._expand_opts(key, opts)

        if not isinstance(key, str):
            raise TypeError('non-string key of type %s' % type(key))

        pair = store.get(key)
        if pair is not None:
            value, expiry = pair
            if expiry is None or expiry > time.time():
                return value
            try:
                del store[key]
            except KeyError:
                pass

        if func is None:
            return None

        value = func(*args, **kwargs)

        expiry = opts.get('expiry')
        maxage = opts.get('maxage')
        if maxage is not None:
            expiry = (expiry or time.time()) + maxage
        store[key] = (value, expiry)

        return value

    def delete(self, key, **opts):
        key, store = self._expand_opts(key, opts)
        try:
            del store[key]
        except KeyError:
            pass

    def expire_at(self, key, expiry, **opts):
        key, store = self._expand_opts(key, opts)
        pair = store.get(key)
        if pair is not None:
            store[key] = (pair[0], expiry)
        else:
            raise KeyError(key)

    def expire(self, key, maxage, **opts):
        self.expire_at(key, time.time() + maxage, **opts)

    def ttl(self, key, **opts):
        key, store = self._expand_opts(key, opts)
        pair = store.get(key)
        if pair is None:
            return None
        value, expiry = pair
        if expiry is not None:
            return max(0, expiry - time.time()) or None

    def exists(self, key, **opts):
        key, store = self._expand_opts(key, opts)
        return key in store

    def __call__(self, *args, **opts):
        """Decorator."""

        if args and hasattr(args[0], '__call__'):
            func = args[0]
            args = args[1:]
        else:
            # Build the decorator.
            return lambda func: self(func, *args, **opts)

        master_key = ','.join(map(repr, args)) if args else None
        return CachedFunction(self, func, master_key, opts)

class CachedFunction(object):

    def __init__(self, cache, func, master_key, opts):
        self.cache = cache
        self.func = func
        self.master_key = master_key
        self.opts = opts

    def __repr__(self):
        return '<%s of %s via %s>' % (self.__class__.__name__, self.func, self.cache)

    def _expand_opts(self, opts):
        for k, v in self.opts.iteritems():
            opts.setdefault(k, v)

    def get_key(self, args, kwargs):
        # We need to normalize the signature of the function. This is only
        # really possible if we wrap the "real" function.
        spec = inspect.getargspec(self.func)

        # Insert kwargs into the args list by name.
        orig_args = list(args)
        args = []
        for i, name in enumerate(spec.args):
            if name in kwargs:
                args.append(kwargs.pop(name))
            elif orig_args:
                args.append(orig_args.pop(0))
            else:
                break

        args.extend(orig_args)

        # Add on as many defaults as we need to.
        if spec.defaults:
            offset = len(spec.args) - len(spec.defaults)
            args.extend(spec.defaults[len(args) - offset:])

        arg_str_chunks = map(repr, args)
        for pair in kwargs.iteritems():
            arg_str_chunks.append('%s=%r' % pair)
        arg_str = ', '.join(arg_str_chunks)

        key = '%s.%s(%s)' % (self.func.__module__, self.func.__name__, arg_str)
        return self.master_key + ':' + key if self.master_key else key

    def __call__(self, *args, **kwargs):
        return self.cache.get(self.get_key(args, kwargs), self.func, args, kwargs, **self.opts)

    def get(self, args=(), kwargs={}, **opts):
        self._expand_opts(opts)
        return self.cache.get(self.get_key(args, kwargs), self.func, args, kwargs, **opts)

    def delete(self, args=(), kwargs={}, **opts):
        self._expand_opts(opts)
        self.cache.delete(self.get_key(args, kwargs))

    def expire(self, maxage, args=(), kwargs={}, **opts):
        self._expand_opts(opts)
        self.cache.expire(self.get_key(args, kwargs), maxage)

    def expire_at(self, maxage, args=(), kwargs={}, **opts):
        self._expand_opts(opts)
        self.cache.expire_at(self.get_key(args, kwargs), maxage)

    def ttl(self, args=(), kwargs={}, **opts):
        self._expand_opts(opts)
        return self.cache.ttl(self.get_key(args, kwargs))

    def exists(self, args=(), kwargs={}, **opts):
        self._expand_opts(opts)
        return self.cache.exists(self.get_key(args, kwargs))

<|endoftext|>