# Path: basil/utils/sim/Protocol.py
# class WriteRequest(ProtocolBase):
#     def __init__(self, address, data):
#         self.address = address
#         self.data = data
# 
#     def __str__(self):
#         return "WriteRequest: 0x%04x <- %s" % (self.address, self.data)
# 
# class ReadRequest(ProtocolBase):
#     def __init__(self, address, size):
#         self.address = address
#         self.size = size
# 
#     def __str__(self):
#         return "ReadRequest: 0x%04x (size %d)" % (self.address, self.size)
# 
# class ReadResponse(ProtocolBase):
#     def __init__(self, data):
#         self.data = data
# 
#     def __str__(self):
#         return "ReadResponse: %s" % str(self.data)
# 
# class PickleInterface(ProtocolBase):
#     def __init__(self, sock):
#         self.sock = sock
# 
#     def send(self, obj):
#         """Prepend a 4-byte length to the string"""
#         assert isinstance(obj, ProtocolBase)
#         string = pickle.dumps(obj)
#         length = len(string)
#         self.sock.sendall(struct.pack("<I", length) + string)
# 
#     def recv(self, blocking=True):
#         """Receive the next object from the socket"""
#         length = struct.unpack("<I", self.sock.recv(4))[0]
#         return self._get_next_obj(length)
# 
#     def try_recv(self):
#         """Return None immediately if nothing is waiting"""
#         try:
#             lenstr = self.sock.recv(4, socket.MSG_DONTWAIT)
#         except socket.error:
#             return None
#         if len(lenstr) < 4:
#             raise EOFError("Socket closed")
#         length = struct.unpack("<I", lenstr)[0]
#         return self._get_next_obj(length)
# 
#     def _get_next_obj(self, length):
#         """Assumes we've already read the object length"""
#         data = b""
#         while len(data) < length:
#             data += self.sock.recv(length - len(data))
# 
#         return pickle.loads(data)


import socket
import array
from basil.utils.sim.Protocol import WriteRequest, ReadRequest, ReadResponse, PickleInterface

    def GetFWVersion(self):
        return __version__

    def GetName(self):
        return "Simulated Device"

    def GetBoardId(self):
        return "%s:%d" % (self.simulation_host, self.simulation_port)

    def DownloadXilinx(self, bitfile):
        """We hijack this call to perform the socket connect"""
        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._sock.connect((self.simulation_host, self.simulation_port))
        self._iface = PickleInterface(self._sock)
        return True

    def WriteExternal(self, address, data):
        req = WriteRequest(self.BASE_ADDRESS_EXTERNAL + address, data)
        self._iface.send(req)

    def ReadExternal(self, address, size):
        req = ReadRequest(self.BASE_ADDRESS_EXTERNAL + address, size)
        self._iface.send(req)
        resp = self._iface.recv()
        if not isinstance(resp, ReadResponse):
            raise ValueError("Communication error with Simulation: got %s" % repr(resp))
        return array.array("B", resp.data)

    def FastBlockRead(self, size):

# Path: basil/utils/sim/Protocol.py
# class WriteRequest(ProtocolBase):
#     def __init__(self, address, data):
#         self.address = address
#         self.data = data
# 
#     def __str__(self):
#         return "WriteRequest: 0x%04x <- %s" % (self.address, self.data)
# 
# class ReadRequest(ProtocolBase):
#     def __init__(self, address, size):
#         self.address = address
#         self.size = size
# 
#     def __str__(self):
#         return "ReadRequest: 0x%04x (size %d)" % (self.address, self.size)
# 
# class ReadResponse(ProtocolBase):
#     def __init__(self, data):
#         self.data = data
# 
#     def __str__(self):
#         return "ReadResponse: %s" % str(self.data)
# 
# class PickleInterface(ProtocolBase):
#     def __init__(self, sock):
#         self.sock = sock
# 
#     def send(self, obj):
#         """Prepend a 4-byte length to the string"""
#         assert isinstance(obj, ProtocolBase)
#         string = pickle.dumps(obj)
#         length = len(string)
#         self.sock.sendall(struct.pack("<I", length) + string)
# 
#     def recv(self, blocking=True):
#         """Receive the next object from the socket"""
#         length = struct.unpack("<I", self.sock.recv(4))[0]
#         return self._get_next_obj(length)
# 
#     def try_recv(self):
#         """Return None immediately if nothing is waiting"""
#         try:
#             lenstr = self.sock.recv(4, socket.MSG_DONTWAIT)
#         except socket.error:
#             return None
#         if len(lenstr) < 4:
#             raise EOFError("Socket closed")
#         length = struct.unpack("<I", lenstr)[0]
#         return self._get_next_obj(length)
# 
#     def _get_next_obj(self, length):
#         """Assumes we've already read the object length"""
#         data = b""
#         while len(data) < length:
#             data += self.sock.recv(length - len(data))
# 
#         return pickle.loads(data)


# Path: basil/utils/sim/SiLibUsb.py
import socket
import array
from basil.utils.sim.Protocol import WriteRequest, ReadRequest, ReadResponse, PickleInterface


    def GetFWVersion(self):
        return __version__

    def GetName(self):
        return "Simulated Device"

    def GetBoardId(self):
        return "%s:%d" % (self.simulation_host, self.simulation_port)

    def DownloadXilinx(self, bitfile):
        """We hijack this call to perform the socket connect"""
        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._sock.connect((self.simulation_host, self.simulation_port))
        self._iface = PickleInterface(self._sock)
        return True

    def WriteExternal(self, address, data):
        req = WriteRequest(self.BASE_ADDRESS_EXTERNAL + address, data)
        self._iface.send(req)

    def ReadExternal(self, address, size):
        req = ReadRequest(self.BASE_ADDRESS_EXTERNAL + address, size)
        self._iface.send(req)
        resp = self._iface.recv()
        if not isinstance(resp, ReadResponse):
            raise ValueError("Communication error with Simulation: got %s" % repr(resp))
        return array.array("B", resp.data)

    def FastBlockRead(self, size):

        req = ReadRequest(self.BASE_ADDRESS_BLOCK, size)