<commit_before>import binascii
import bitstring

from upb import mdid

class UPBMessage():
    GLOBAL_PACKET = 0
    DEFAULT_NETWORK_ID = 1
    DEFAULT_SOURCE_ID = 255
    DEFAULT_DESTINATION_ID = 1

    TRANSMIT_ONCE = '0b00'
    TRANSMIT_TWICE = '0b01'
    TRANSMIT_THRICE = '0b10'
    TRANSMIT_QUAD = '0b11'
    DEFAULT_TRANSMISSION_TIMES = TRANSMIT_QUAD

    REPEAT_Z = '0b00'
    REPEAT_ONCE = '0b01'
    REPEAT_TWICE = '0b10'
    REPEAT_QUAD = '0b11'
    DEFAULT_REPEAT = REPEAT_Z

    MDID = 0x00

    def __init__(self, **kwargs):
        self.network_id = UPBMessage.DEFAULT_NETWORK_ID
        self.destination_id = UPBMessage.DEFAULT_DESTINATION_ID
        self.link = False
        self.source_id = UPBMessage.DEFAULT_SOURCE_ID
        self.transmission_times = UPBMessage.DEFAULT_TRANSMISSION_TIMES
        self.ack = True
        self.id_pulse = False
        self.ack_msg = False
        self.repeat = UPBMessage.DEFAULT_REPEAT
        self.reply_repeat = False
        self.dirty = True
        self.ascii_packet = b''
        self.arguments = []

        for kwarg in kwargs:
            setattr(self, kwarg, kwargs[kwarg])

        self.length = 7 + len(self.arguments)

    def command(self):
        CTL = bitstring.BitArray(16)

        CTL[0] = self.link
        CTL[1:3] = self.repeat

        j = 3 + (5 - int.bit_length(self.length))
        CTL[j:8] = bin(self.length)

        CTL[9] = self.ack_msg
        CTL[10] = self.id_pulse
        CTL[11] = self.ack
        CTL[12:14] = self.transmission_times
        CTL[14] = False
        CTL[15] = False

        return [CTL[0:8].uint, CTL[8:16].uint]

    def construct_header(self):
        return self.command() + [self.network_id, self.destination_id, self.source_id]

    def construct_message(self):
        return [self.MDID] + self.arguments

    def construct_checksum(self, body):
        j = sum(body)
        k = (1 << int.bit_length(j)) - j
        #chk = bytes([bitstring.Bits(uint=k, length=8).uint])
        #chk = int.to_bytes(k, 1, 'little')
        chk = bytes.fromhex(hex(k)[-2:])
        return chk

    def construct_packet(self):
        hdr = self.construct_header()
        msg = self.construct_message()
        body = hdr + msg
        chk = self.construct_checksum(body)
        packet = bytes(body) + chk

        return binascii.hexlify(packet)

    def construct_ascii_packet(self):
        """
        Construct the packet to be sent to the PIM.  Note
        that the PIM takes in the packet in ASCII form, not the actual
        representation on the wire.
        """
        if not self.dirty:
            return self.ascii_packet
        else:
            self.ascii_packet = self.construct_packet()
            return self.ascii_packet

    @classmethod
    def create_from_packet(cls, packet):
        st = packet.decode('ascii')
        ctl = bitstring.Bits(hex=st[0:4])

        net = int(st[4:6], 16)
        dest = int(st[6:8], 16)
        source = int(st[8:10], 16)
        MDID = int(st[10:12], 16)
        link = ctl[0]
        repeat = ctl[1:3].uint
        ack = ctl[9]
        id_pul = ctl[10]
        ack_msg = ctl[11]
        trans_times = ctl[12:14].uint

        #info['len'] = ctl[3:8].uint

        args = []
        for i in range(12, len(st) - 2, 2):
            args.append(int(st[i:i+2], 16))

        upb_msg = cls(network_id = net, destination_id = dest, source_id = source,
                link = link, repeat = repeat, ack = ack, id_pulse = id_pul,
                ack_message = ack_msg, transmission_times = trans_times, arguments = args)

        upb_msg.MDID = MDID

        return upb_msg

class UPBSimpleMessage(UPBMessage):
    """
    UPB message without any arguments.
    """
    def __init__(self, dest_id, **kwargs):<commit_msg>added __str__ function to UPBMessage<commit_after>import binascii
import bitstring

from upb import mdid

class UPBMessage():
    GLOBAL_PACKET = 0
    DEFAULT_NETWORK_ID = 1
    DEFAULT_SOURCE_ID = 255
    DEFAULT_DESTINATION_ID = 1

    TRANSMIT_ONCE = '0b00'
    TRANSMIT_TWICE = '0b01'
    TRANSMIT_THRICE = '0b10'
    TRANSMIT_QUAD = '0b11'
    DEFAULT_TRANSMISSION_TIMES = TRANSMIT_QUAD

    REPEAT_Z = '0b00'
    REPEAT_ONCE = '0b01'
    REPEAT_TWICE = '0b10'
    REPEAT_QUAD = '0b11'
    DEFAULT_REPEAT = REPEAT_Z

    MDID = 0x00

    def __init__(self, **kwargs):
        self.network_id = UPBMessage.DEFAULT_NETWORK_ID
        self.destination_id = UPBMessage.DEFAULT_DESTINATION_ID
        self.link = False
        self.source_id = UPBMessage.DEFAULT_SOURCE_ID
        self.transmission_times = UPBMessage.DEFAULT_TRANSMISSION_TIMES
        self.ack = True
        self.id_pulse = False
        self.ack_msg = False
        self.repeat = UPBMessage.DEFAULT_REPEAT
        self.reply_repeat = False
        self.dirty = True
        self.ascii_packet = b''
        self.arguments = []

        for kwarg in kwargs:
            setattr(self, kwarg, kwargs[kwarg])

        self.length = 7 + len(self.arguments)

    def command(self):
        CTL = bitstring.BitArray(16)

        CTL[0] = self.link
        CTL[1:3] = self.repeat

        j = 3 + (5 - int.bit_length(self.length))
        CTL[j:8] = bin(self.length)

        CTL[9] = self.ack_msg
        CTL[10] = self.id_pulse
        CTL[11] = self.ack
        CTL[12:14] = self.transmission_times
        CTL[14] = False
        CTL[15] = False

        return [CTL[0:8].uint, CTL[8:16].uint]

    def construct_header(self):
        return self.command() + [self.network_id, self.destination_id, self.source_id]

    def construct_message(self):
        return [self.MDID] + self.arguments

    def construct_checksum(self, body):
        j = sum(body)
        k = (1 << int.bit_length(j)) - j
        #chk = bytes([bitstring.Bits(uint=k, length=8).uint])
        #chk = int.to_bytes(k, 1, 'little')
        chk = bytes.fromhex(hex(k)[-2:])
        return chk

    def construct_packet(self):
        hdr = self.construct_header()
        msg = self.construct_message()
        body = hdr + msg
        chk = self.construct_checksum(body)
        packet = bytes(body) + chk

        return binascii.hexlify(packet)

    def construct_ascii_packet(self):
        """
        Construct the packet to be sent to the PIM.  Note
        that the PIM takes in the packet in ASCII form, not the actual
        representation on the wire.
        """
        if not self.dirty:
            return self.ascii_packet
        else:
            self.ascii_packet = self.construct_packet()
            return self.ascii_packet

    def __str__(self):
        return str(vars(self))

    @classmethod
    def create_from_packet(cls, packet):
        st = packet.decode('ascii')
        ctl = bitstring.Bits(hex=st[0:4])

        net = int(st[4:6], 16)
        dest = int(st[6:8], 16)
        source = int(st[8:10], 16)
        _mdid = int(st[10:12], 16)
        link = ctl[0]
        repeat = ctl[1:3].uint
        ack = ctl[9]
        id_pul = ctl[10]
        ack_msg = ctl[11]
        trans_times = ctl[12:14].uint

        #info['len'] = ctl[3:8].uint

        args = []
        for i in range(12, len(st) - 2, 2):
            args.append(int(st[i:i+2], 16))

        upb_msg = cls(network_id = net, destination_id = dest, source_id = source,
                link = link, repeat = repeat, ack = ack, id_pulse = id_pul,
                ack_message = ack_msg, transmission_times = trans_times, arguments = args)

        upb_msg.MDID = _mdid

        return upb_msg

class UPBSimpleMessage(UPBMessage):
    """
    UPB message without any arguments.
    """
    def __init__(self, dest_id, **kwargs):
{'fraction_non_alphanumeric': 0.10943643512450851, 'fraction_numerical': 0.027785058977719528, 'mean_word_length': 2.1716541978387367, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '180189', 'n_tokens_mistral': 2797, 'n_tokens_neox': 2593, 'n_words': 555}