def test_group_adapter(): s = Struct('groups' / commands.GroupListAdapter()) for left, right in [([], b'\x00'), ([0, 1], b'\x03'), ([i for i in range(8)], b'\xFF')]: assert s.build({'groups': left}) == right assert s.parse(right) == {'groups': left} with pytest.raises(ValueError): s.build({'groups': [8]})
def test_nested(): s = Struct( 'a' / Byte, 'b' / DeferredValue(Byte), 'c' / Byte, 'struct' / Struct('new_value' / Tell, WriteDeferredValue(this.new_value + 7, this._.b), 'x' / Byte)) # parsing assert s.parse(b'\x01\x02\x03\x04') == { 'a': 1, 'b': 2, 'c': 3, 'struct': { 'new_value': 3, 'x': 4 } } # building assert s.build({ 'a': 0xff, 'c': 0xfe, 'struct': { 'x': 0x42 } }) == b'\xff\x0a\xfe\x42'
def test_unexpected_placeholder(): def _change_placeholder(context): stream = context._io placeholder = context.a.placeholder_data[0] stream.seek(-1, os.SEEK_CUR) stream.write(bytes([(placeholder + 1) & 0xff])) s = Struct( 'a' / DeferredValue(Byte), Computed( _change_placeholder ), # overwrites placeholder with different value, should fail sanity check later WriteDeferredValue(0x42, this.a)) with pytest.raises(DeferredError): s.build({})
def _send_login_request(self): fmt = Struct( 'length' / Const(b'\x80\x01\x00\x00'), 'type' / Const(b'\x1e\x00\x00\x00'), 'pass_code' / Const(b'\x00\x00\x00\x00'), 'magic_number' / Const(b'\x01\x02\x00\x00'), 'account_id' / Bytes(64), 'app_label' / Bytes(256), 'os_version' / Bytes(16), 'model' / Bytes(16), 'pin_code' / Bytes(16), ) config = { 'app_label': b'PlayStation'.ljust(256, b'\x00'), 'account_id': self._credential.encode().ljust(64, b'\x00'), 'os_version': b'4.4'.ljust(16, b'\x00'), 'model': b'PS4 Waker'.ljust(16, b'\x00'), 'pin_code': b''.ljust(16, b'\x00'), } _LOGGER.debug('config %s', config) msg = fmt.build(config) self._send_msg(msg, encrypted=True)
def test_single(): s = Struct('a' / Byte, 'b' / DeferredValue(Byte), 'c' / Byte, 'new_value' / Tell, WriteDeferredValue(this.new_value, this.b)) # parsing assert s.parse(b'\x01\x02\x03') == {'a': 1, 'b': 2, 'c': 3, 'new_value': 3} # building assert s.build({'a': 0xff, 'c': 0xfe}) == b'\xff\x03\xfe'
def _send_hello_request(self): fmt = Struct( 'length' / Const(b'\x1c\x00\x00\x00'), 'type' / Const(b'\x70\x63\x63\x6f'), 'version' / Const(b'\x00\x00\x02\x00'), 'dummy' / Padding(16), ) msg = fmt.build({}) self._send_msg(msg)
def test_enumconvert(): class TestEnum(Enum): A = 0x42 @property def prop(self): return 1337 s = Struct('e' / EnumConvert(Byte, TestEnum), 'v' / Computed(lambda this: this.e.prop)) # valid assert s.parse(b'\x42') == {'e': TestEnum.A, 'v': 1337} assert s.build({'e': TestEnum.A}) == b'\x42' # invalid with pytest.raises(MappingError): s.parse(b'\x00') with pytest.raises(MappingError): s.build({'e': 0})
def _send_request( self, lba: int, request_format: construct.Struct, request_obj: Optional[Dict[str, Any]], response_format: construct.Struct, ) -> construct.Container: """Send a request to the meter, and read its response. Args: lba: the address of the block register to use, known valid addresses are 3, 4 and 5. request_format: a construct format identifier of the request to send request_obj: the object to format with the provided identifier response_format: a construct format identifier to parse the returned message with. Returns: The Container object parsed from the response received by the meter. Raises: lifescan.MalformedCommand if Construct fails to build the request or parse the response. """ try: request = request_format.build(request_obj) request_raw = _PACKET.build( {"data": { "value": { "message": request } }}) logging.debug("Request sent: %s", binascii.hexlify(request_raw)) self.scsi_.write10(lba, 1, request_raw) response_raw = self.scsi_.read10(lba, 1) logging.debug("Response received: %s", binascii.hexlify(response_raw.datain)) response_pkt = _PACKET.parse(response_raw.datain).data logging.debug("Response packet: %r", response_pkt) response = response_format.parse(response_pkt.value.message) logging.debug("Response parsed: %r", response) return response except construct.ConstructError as e: raise lifescan.MalformedCommand(str(e))
def _send_handshake_request(self, seed): fmt = Struct( 'length' / Const(b'\x18\x01\x00\x00'), 'type' / Const(b'\x20\x00\x00\x00'), 'key' / Bytes(256), 'seed' / Bytes(16), ) recipient_key = _get_public_key_rsa() cipher_rsa = PKCS1_OAEP.new(recipient_key) key = cipher_rsa.encrypt(self._random_seed) _LOGGER.debug('key %s', binascii.hexlify(key)) msg = fmt.build({'key': key, 'seed': seed}) self._send_msg(msg)
def test_complex_prefixed(): s = Struct( 'v' / Byte, 'a1' / Prefixed(Byte, Array(2, Struct('value' / DeferredValue(Byte)))), 'a2' / Array( 2, Struct( '@offset' / Tell, WriteDeferredValue(this['@offset'], lambda this: this._.a1[this._index].value), 'value' / Byte))) # parsing assert s.parse(b'\xff\x02\x41\x42\xe0\xe1') == { 'v': 0xff, 'a1': [{ 'value': 0x41 }, { 'value': 0x42 }], 'a2': [{ '@offset': 4, 'value': 0xe0 }, { '@offset': 5, 'value': 0xe1 }] } # building assert s.build({ 'v': 0xff, 'a1': [{}, {}], 'a2': [{ 'value': 0xe0 }, { 'value': 0xe1 }] }) == b'\xff\x02\x04\x05\xe0\xe1'
def _send_request( self, request_format: construct.Struct, request_obj: Optional[Dict[str, Any]], response_format: construct.Struct, ) -> construct.Container: try: request = request_format.build(request_obj) self._send_packet(request, acknowledge=False, disconnect=False) self.sent_counter_ = not self.sent_counter_ self._read_ack() response_pkt = self._read_packet() assert not response_pkt.link_control.acknowledge self.expect_receive_ = not self.expect_receive_ self._send_ack() return response_format.parse(response_pkt.message) except construct.ConstructError as e: raise lifescan.MalformedCommand(str(e))
def test_write_twice(): s = Struct('a' / DeferredValue(Byte), WriteDeferredValue(0x41, this.a), WriteDeferredValue(0x42, this.a)) with pytest.raises(DeferredError): s.build({})
def show_frame(*args): global Color_Min, Color_Max Color_Min = (Hue_Min, Saturation_Min, Value_Min) Color_Max = (Hue_Max, Saturation_Max, Value_Max) ret, frame1 = cap1.read() ret, frame2 = cap2.read() hsv1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2HSV) hsv2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2HSV) cxy, cyy, cntsy = colorDetector.object_pos(Color_Min, Color_Max, hsv1) cxy2, cyy2, cntsy2 = colorDetector.object_pos(Color_Min, Color_Max, hsv2) if cxy != None and cxy2 != None and X_SCREEN_DEPTH != None and Y_SCREEN_DEPTH != None: #Start Converting Pixel Coordinates To Angles CAMERA_ANGLE_AY = Coordinate_Calculations.pixels_to_camera_angle(X_SCREEN_DEPTH, cxy) CAMERA_ANGLE_YY1 = Coordinate_Calculations.pixels_to_camera_angle(Y_SCREEN_DEPTH, cyy) CAMERA_ANGLE_BY = Coordinate_Calculations.pixels_to_camera_angle(X_SCREEN_DEPTH, cxy2) CAMERA_ANGLE_YY2 = Coordinate_Calculations.pixels_to_camera_angle(Y_SCREEN_DEPTH, cyy2) #End Converting Pixel Coordinates To Angles #Start Calculating Variables Needed For Coordinate Calculations THETA_AY, THETA_BY = Coordinate_Calculations.topview_camera_angles_to_internal_angles(CAMERA_ANGLE_AY, CAMERA_ANGLE_BY) if THETA_AY or THETA_BY != 0: LAY, LBY = Coordinate_Calculations.topview_range_from_cams(Dis_Between_Cams, THETA_BY, THETA_AY) #End Calculating Variables Needed For Coordinate Calculations #Start Calculating Coordinates XY = Coordinate_Calculations.x_coord(THETA_AY, THETA_BY, LAY, LBY, Dis_Between_Cams) YY = Coordinate_Calculations.y_coord(THETA_AY, THETA_BY, LAY, LBY) ZY = Coordinate_Calculations.z_coord(CAMERA_ANGLE_YY1, YY, CAMERA_ANGLE_YY2, YY) #End Calculating Coordinates # Start sending information to Vridge print(XY, YY, ZY) # Specify the structure for the fancy position matrix structure = Struct( Const(Int32ul, 2), Const(Int32ul, 5), Const(Int32ul, 24), "data" / Padded(64, Array(3, Float32l)), ) offset = [0.0, 0.0, 0.0] # offset in case you want to define where the origin is (in centimeters) xyz = [(XY + offset[0]) / 100, (YY + offset[1]) / 100, (ZY + offset[2]) / 100] # Steam VR requires this information in meters byte_packet = structure.build(dict(data=xyz)) endpoint.send(byte_packet) print("Send: " + str(structure.parse(byte_packet))) endpoint.recv() # Stop sending information to vridge #Start Drawing Contours for (i, c) in enumerate(cntsy): # draw the contour (x, y), radius = cv2.minEnclosingCircle(c) cv2.drawContours(frame1, [c], -1, (0, 255, 255), 2) overlay1 = frame1.copy() cv2.rectangle(overlay1, (int(cxy+radius), cyy - 30), (int(cxy + radius + 200), cyy+60), (0, 0, 0), -1) cv2.addWeighted(overlay1, alpha, frame1, 1 - alpha, 0, frame1) if units: cv2.putText(frame1, "X Axis " + str(Coordinate_Calculations.ceiling(XY)) +"cm", (int(cxy + radius + 20), cyy), cv2.FONT_HERSHEY_DUPLEX, 0.6, (255, 150, 0), 1) cv2.putText(frame1, "Y Axis " + str(Coordinate_Calculations.ceiling(YY)) +"cm", (int(cxy + radius + 20), cyy + 20), cv2.FONT_HERSHEY_DUPLEX, 0.6, (0, 255, 0), 1) cv2.putText(frame1, "Z Axis " + str(Coordinate_Calculations.ceiling(ZY)) +"cm", (int(cxy + radius + 20), cyy + 40), cv2.FONT_HERSHEY_DUPLEX, 0.6, (0, 0, 255), 1) else: cv2.putText(frame1, "X Axis " + str(Coordinate_Calculations.ceiling(XY)), (int(cxy + radius + 20), cyy), cv2.FONT_HERSHEY_DUPLEX, 0.6, (255, 150, 0), 1) cv2.putText(frame1, "Y Axis " + str(Coordinate_Calculations.ceiling(YY)), (int(cxy + radius + 20), cyy + 20), cv2.FONT_HERSHEY_DUPLEX, 0.6, (0, 255, 0), 1) cv2.putText(frame1, "Z Axis " + str(Coordinate_Calculations.ceiling(ZY)), (int(cxy + radius + 20), cyy + 40), cv2.FONT_HERSHEY_DUPLEX, 0.6, (0, 0, 255), 1) for (i, c) in enumerate(cntsy2): # draw the contour (x, y), radius = cv2.minEnclosingCircle(c) cv2.drawContours(frame2, [c], -1, (0, 255, 255), 2) overlay2 = frame2.copy() cv2.rectangle(overlay2, (int(cxy2+radius), cyy2 - 30), (int(cxy2 + radius + 200), cyy2 + 60), (0, 0, 0), -1) cv2.addWeighted(overlay2, alpha, frame2, 1 - alpha, 0, frame2) if units: cv2.putText(frame2, "X Axis " + str(Coordinate_Calculations.ceiling(XY)) +"cm", (int(cxy2 + radius + 20), cyy2), cv2.FONT_HERSHEY_DUPLEX, 0.6, (255, 150, 0), 1) cv2.putText(frame2, "Y Axis " + str(Coordinate_Calculations.ceiling(YY)) +"cm", (int(cxy2 + radius + 20), cyy2 + 20), cv2.FONT_HERSHEY_DUPLEX, 0.6, (0, 255, 0), 1) cv2.putText(frame2, "Z Axis " + str(Coordinate_Calculations.ceiling(ZY)) +"cm", (int(cxy2 + radius + 20), cyy2 + 40), cv2.FONT_HERSHEY_DUPLEX, 0.6, (0, 0, 255), 1) else: cv2.putText(frame2, "X Axis " + str(Coordinate_Calculations.ceiling(XY)), (int(cxy2 + radius + 20), cyy2), cv2.FONT_HERSHEY_DUPLEX, 0.6, (255, 150, 0), 1) cv2.putText(frame2, "Y Axis " + str(Coordinate_Calculations.ceiling(YY)), (int(cxy2 + radius + 20), cyy2 + 20), cv2.FONT_HERSHEY_DUPLEX, 0.6, (0, 255, 0), 1) cv2.putText(frame2, "Z Axis " + str(Coordinate_Calculations.ceiling(ZY)), (int(cxy2 + radius + 20), cyy2 + 40), cv2.FONT_HERSHEY_DUPLEX, 0.6, (0, 0, 255), 1)
def test_build_from_nested_dicts(self): s = Struct(None, Struct('substruct1', Byte('field1'))) self.assertEqual(s.build(dict(substruct1=dict(field1=5))), b'\x05')
SERVER_INVITE_OPTION = 0x12 ), Switch("OptionData", lambda ctx: ctx["OptionID"], { "CLIENT_NICK_OPTION" : CString('Nickname'), "CLIENT_MEMBERSHIP_OPTION" : ClientMemberShipOption, "SERVER_OPTION" : Struct("ServerOption", ULInt16('Port')), "SERVER_CHANNELS_OPTION" : PrefixedArray(CString('Channels'), ULInt8("NumChannels")), "SERVER_INVITE_OPTION" : ServerInviteOption } ) ) peerPDU = Struct( 'peerPDU', CString('ClientID'), OptionalGreedyRepeater(Option) ) if __name__ == '__main__': data = peerPDU.build(Container(ClientID="Bob", Option=[ Container(OptionID="SERVER_INVITE_OPTION", OptionData=Container(ChannelID="TM2011", ClientID=["Alice", "Billy"])), Container(OptionID="CLIENT_NICK_OPTION", OptionData="Susan")] ) ) print repr(data) packet = peerPDU.parse(data) print packet
byte |= to_write & mask to_write >>= length more_bit = (to_write > 0) and self._get_more_bit(length) byte |= more_bit byte &= 0xFF stream_write(stream, int2byte(byte), 1, path) if not more_bit: break return obj if __name__ == "__main__": c = Struct("index" / Idx()) test_data = [ [0x0f, 0x40, 0xff], # 0x0f [0x4f, 0x40, 0xff], # (0x40 << 6) + 0x0f = 0x100f [0x8f, 0x40, 0xff], # -0x0f [0xcf, 0x40, 0xff], # -((0x40 << 6) + 0x0f) = 0x100f [0x4f, 0x80, 0x40, 0xff], # (0x40 << 13) + 0x0f = 0x8000f [0x4f, 0x80, 0x80, 0x40, 0xff], # (0x40 << 20) + 0x0f = 0x400000f [0x4f, 0x80, 0x80, 0x80, 0x8f, 0xff] # 0x8f << 27 + 0x0f = 0x47800000f ] expected_values = [ 0x0f, 0x100f, -0x0f, -0x100f, 0x8000f, 0x400000f, 0x47800000f ] for test, ev in zip(test_data, expected_values): assert c.parse(bytes(test)).index == ev new_bytes = c.build(dict(index=ev)) assert new_bytes == bytes(test[:len(new_bytes)]) print("All tests passed!")
def test_check_deferred(): s = Struct('a' / DeferredValue(Byte), CheckDeferredValues) with pytest.raises(DeferredError): s.build({})
def test_build_no_value(): s = Struct('a' / DeferredValue(Byte), WriteDeferredValue(0x42, this.a)) with pytest.raises(DeferredError): s.build({'a': 0xab})
def test_build_invalid_target(): s = Struct('a' / Byte, WriteDeferredValue(0x42, this.a)) with pytest.raises(DeferredError): s.build({'a': 0xff})