tdl-xoa-driver 1.0.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tdl_xoa_driver-1.0.0b1.dist-info/LICENSE +202 -0
- tdl_xoa_driver-1.0.0b1.dist-info/METADATA +177 -0
- tdl_xoa_driver-1.0.0b1.dist-info/RECORD +325 -0
- tdl_xoa_driver-1.0.0b1.dist-info/WHEEL +5 -0
- tdl_xoa_driver-1.0.0b1.dist-info/top_level.txt +1 -0
- xoa_driver/__init__.py +2 -0
- xoa_driver/enums.py +399 -0
- xoa_driver/exceptions.py +77 -0
- xoa_driver/functions/__init__.py +0 -0
- xoa_driver/functions/anlt.py +744 -0
- xoa_driver/functions/anlt_ll_debug.py +429 -0
- xoa_driver/functions/cli.py +581 -0
- xoa_driver/functions/exceptions.py +72 -0
- xoa_driver/functions/headers.py +608 -0
- xoa_driver/functions/mgmt.py +515 -0
- xoa_driver/functions/tools.py +256 -0
- xoa_driver/hlfuncs.py +18 -0
- xoa_driver/internals/__init__.py +0 -0
- xoa_driver/internals/commands/__init__.py +31 -0
- xoa_driver/internals/commands/c_commands.py +2041 -0
- xoa_driver/internals/commands/enums.py +3289 -0
- xoa_driver/internals/commands/m4_commands.py +700 -0
- xoa_driver/internals/commands/m4e_commands.py +107 -0
- xoa_driver/internals/commands/m_commands.py +1875 -0
- xoa_driver/internals/commands/p4_commands.py +2221 -0
- xoa_driver/internals/commands/p4e_commands.py +160 -0
- xoa_driver/internals/commands/p4g_commands.py +7253 -0
- xoa_driver/internals/commands/p_commands.py +6000 -0
- xoa_driver/internals/commands/pc_commands.py +335 -0
- xoa_driver/internals/commands/pd_commands.py +355 -0
- xoa_driver/internals/commands/pe_commands.py +1018 -0
- xoa_driver/internals/commands/pec_commands.py +265 -0
- xoa_driver/internals/commands/ped_commands.py +1034 -0
- xoa_driver/internals/commands/pef_commands.py +2216 -0
- xoa_driver/internals/commands/pf_commands.py +379 -0
- xoa_driver/internals/commands/pl1_commands.py +1588 -0
- xoa_driver/internals/commands/pl_commands.py +178 -0
- xoa_driver/internals/commands/pm_commands.py +256 -0
- xoa_driver/internals/commands/pp_commands.py +2341 -0
- xoa_driver/internals/commands/pr_commands.py +812 -0
- xoa_driver/internals/commands/ps_commands.py +2311 -0
- xoa_driver/internals/commands/pt_commands.py +370 -0
- xoa_driver/internals/commands/px_commands.py +303 -0
- xoa_driver/internals/commands/subtypes.py +86 -0
- xoa_driver/internals/core/__init__.py +0 -0
- xoa_driver/internals/core/builders.py +39 -0
- xoa_driver/internals/core/exceptions.py +69 -0
- xoa_driver/internals/core/funcs.py +81 -0
- xoa_driver/internals/core/funcs.pyi +1072 -0
- xoa_driver/internals/core/interfaces.py +47 -0
- xoa_driver/internals/core/token.py +44 -0
- xoa_driver/internals/core/transporter/__init__.py +0 -0
- xoa_driver/internals/core/transporter/_processor.py +83 -0
- xoa_driver/internals/core/transporter/_publisher.py +101 -0
- xoa_driver/internals/core/transporter/_request_id_counter.py +28 -0
- xoa_driver/internals/core/transporter/_stream.py +99 -0
- xoa_driver/internals/core/transporter/_typings.py +43 -0
- xoa_driver/internals/core/transporter/exceptions.py +44 -0
- xoa_driver/internals/core/transporter/handler.py +127 -0
- xoa_driver/internals/core/transporter/logger/__init__.py +10 -0
- xoa_driver/internals/core/transporter/logger/__logger.py +94 -0
- xoa_driver/internals/core/transporter/logger/__state_off.py +32 -0
- xoa_driver/internals/core/transporter/logger/__state_on_default.py +70 -0
- xoa_driver/internals/core/transporter/logger/__state_on_loguru.py +51 -0
- xoa_driver/internals/core/transporter/logger/__state_on_user.py +48 -0
- xoa_driver/internals/core/transporter/protocol/__init__.py +0 -0
- xoa_driver/internals/core/transporter/protocol/_constants.py +77 -0
- xoa_driver/internals/core/transporter/protocol/_utils.py +59 -0
- xoa_driver/internals/core/transporter/protocol/exceptions.py +271 -0
- xoa_driver/internals/core/transporter/protocol/payload/__init__.py +70 -0
- xoa_driver/internals/core/transporter/protocol/payload/base_struct.py +283 -0
- xoa_driver/internals/core/transporter/protocol/payload/descriptor.py +119 -0
- xoa_driver/internals/core/transporter/protocol/payload/exceptions.py +20 -0
- xoa_driver/internals/core/transporter/protocol/payload/field.py +296 -0
- xoa_driver/internals/core/transporter/protocol/payload/types.py +173 -0
- xoa_driver/internals/core/transporter/protocol/payload/utils.py +53 -0
- xoa_driver/internals/core/transporter/protocol/struct_header.py +123 -0
- xoa_driver/internals/core/transporter/protocol/struct_request.py +65 -0
- xoa_driver/internals/core/transporter/protocol/struct_response.py +89 -0
- xoa_driver/internals/core/transporter/registry.py +43 -0
- xoa_driver/internals/exceptions/__init__.py +9 -0
- xoa_driver/internals/exceptions/modules.py +13 -0
- xoa_driver/internals/exceptions/testers.py +21 -0
- xoa_driver/internals/hli_v1/__init__.py +0 -0
- xoa_driver/internals/hli_v1/indices/__init__.py +0 -0
- xoa_driver/internals/hli_v1/indices/base_index.py +39 -0
- xoa_driver/internals/hli_v1/indices/connection_group/__init__.py +0 -0
- xoa_driver/internals/hli_v1/indices/connection_group/cg.py +186 -0
- xoa_driver/internals/hli_v1/indices/connection_group/histogram.py +78 -0
- xoa_driver/internals/hli_v1/indices/connection_group/l2.py +94 -0
- xoa_driver/internals/hli_v1/indices/connection_group/l3.py +130 -0
- xoa_driver/internals/hli_v1/indices/connection_group/raw.py +200 -0
- xoa_driver/internals/hli_v1/indices/connection_group/replay.py +109 -0
- xoa_driver/internals/hli_v1/indices/connection_group/tcp.py +314 -0
- xoa_driver/internals/hli_v1/indices/connection_group/tls.py +198 -0
- xoa_driver/internals/hli_v1/indices/connection_group/udp.py +133 -0
- xoa_driver/internals/hli_v1/indices/connection_group/user_state.py +28 -0
- xoa_driver/internals/hli_v1/indices/filter/__init__.py +0 -0
- xoa_driver/internals/hli_v1/indices/filter/base_filter.py +65 -0
- xoa_driver/internals/hli_v1/indices/filter/genuine_filter.py +20 -0
- xoa_driver/internals/hli_v1/indices/length_term.py +49 -0
- xoa_driver/internals/hli_v1/indices/macsecscs/__init__.py +0 -0
- xoa_driver/internals/hli_v1/indices/macsecscs/base_macsecsc.py +224 -0
- xoa_driver/internals/hli_v1/indices/macsecscs/genuine_macsecsc.py +72 -0
- xoa_driver/internals/hli_v1/indices/match_term.py +64 -0
- xoa_driver/internals/hli_v1/indices/port_dataset.py +72 -0
- xoa_driver/internals/hli_v1/indices/streams/__init__.py +0 -0
- xoa_driver/internals/hli_v1/indices/streams/base_stream.py +405 -0
- xoa_driver/internals/hli_v1/indices/streams/genuine_stream.py +64 -0
- xoa_driver/internals/hli_v1/modules/__init__.py +0 -0
- xoa_driver/internals/hli_v1/modules/__interfaces.py +21 -0
- xoa_driver/internals/hli_v1/modules/base_module.py +138 -0
- xoa_driver/internals/hli_v1/modules/module_chimera.py +366 -0
- xoa_driver/internals/hli_v1/modules/module_l23ve.py +73 -0
- xoa_driver/internals/hli_v1/modules/module_l47.py +397 -0
- xoa_driver/internals/hli_v1/modules/module_l47ve.py +9 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/__init__.py +0 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_combi.py +83 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_d.py +75 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_e.py +85 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_f.py +145 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_g.py +84 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_h.py +40 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_i.py +25 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_j.py +25 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_k.py +39 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_l.py +55 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_l1.py +800 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_m.py +25 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/family_n.py +40 -0
- xoa_driver/internals/hli_v1/modules/modules_l23/module_l23_base.py +383 -0
- xoa_driver/internals/hli_v1/ports/__init__.py +0 -0
- xoa_driver/internals/hli_v1/ports/base_port.py +125 -0
- xoa_driver/internals/hli_v1/ports/port_l23/__init__.py +0 -0
- xoa_driver/internals/hli_v1/ports/port_l23/bases/__init__.py +0 -0
- xoa_driver/internals/hli_v1/ports/port_l23/bases/port_capture.py +70 -0
- xoa_driver/internals/hli_v1/ports/port_l23/bases/port_l23.py +527 -0
- xoa_driver/internals/hli_v1/ports/port_l23/bases/port_l23_genuine.py +229 -0
- xoa_driver/internals/hli_v1/ports/port_l23/bases/port_reception_statistics.py +231 -0
- xoa_driver/internals/hli_v1/ports/port_l23/bases/port_transceiver.py +117 -0
- xoa_driver/internals/hli_v1/ports/port_l23/bases/port_transmission_statistics.py +131 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/__init__.py +0 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/filter_definition/__init__.py +0 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/filter_definition/_utils.py +15 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/filter_definition/general.py +396 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/filter_definition/shadow.py +104 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/filter_definition/working.py +36 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/pe_custom_distribution.py +125 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/pe_distribution.py +174 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/port_chimera.py +119 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/port_emulation.py +244 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/reception_statistics.py +24 -0
- xoa_driver/internals/hli_v1/ports/port_l23/chimera/transmission_statistics.py +24 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_combi.py +37 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_d.py +51 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_e.py +107 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_f.py +151 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_g.py +77 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_h.py +67 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_i.py +84 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_j.py +68 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_k.py +73 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_l.py +82 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_l1.py +166 -0
- xoa_driver/internals/hli_v1/ports/port_l23/family_m.py +29 -0
- xoa_driver/internals/hli_v1/ports/port_l23/fault_jkl.py +24 -0
- xoa_driver/internals/hli_v1/ports/port_l23/freya_l1.py +722 -0
- xoa_driver/internals/hli_v1/ports/port_l23/pcs_pma_ghijkl.py +369 -0
- xoa_driver/internals/hli_v1/ports/port_l23/pcs_pma_ijkl_chimera.py +60 -0
- xoa_driver/internals/hli_v1/ports/port_l23/pcs_pma_l.py +78 -0
- xoa_driver/internals/hli_v1/ports/port_l23/port_l23ve.py +101 -0
- xoa_driver/internals/hli_v1/ports/port_l47/__init__.py +0 -0
- xoa_driver/internals/hli_v1/ports/port_l47/counters.py +174 -0
- xoa_driver/internals/hli_v1/ports/port_l47/main.py +228 -0
- xoa_driver/internals/hli_v1/ports/port_l47/packet_engine.py +31 -0
- xoa_driver/internals/hli_v1/revisions.py +11 -0
- xoa_driver/internals/hli_v1/testers/__init__.py +0 -0
- xoa_driver/internals/hli_v1/testers/_base_tester.py +259 -0
- xoa_driver/internals/hli_v1/testers/genuine/__init__.py +0 -0
- xoa_driver/internals/hli_v1/testers/genuine/l_23/__init__.py +0 -0
- xoa_driver/internals/hli_v1/testers/genuine/l_23/health.py +16 -0
- xoa_driver/internals/hli_v1/testers/genuine/l_23/rest_api.py +38 -0
- xoa_driver/internals/hli_v1/testers/genuine/l_23/time_keeper.py +57 -0
- xoa_driver/internals/hli_v1/testers/genuine/l_23/upload_file.py +29 -0
- xoa_driver/internals/hli_v1/testers/genuine/management_interface.py +42 -0
- xoa_driver/internals/hli_v1/testers/l23_tester.py +196 -0
- xoa_driver/internals/hli_v1/testers/l23ve_tester.py +114 -0
- xoa_driver/internals/hli_v1/testers/l47_tester.py +106 -0
- xoa_driver/internals/hli_v1/testers/l47ve_tester.py +54 -0
- xoa_driver/internals/hli_v2/__init__.py +0 -0
- xoa_driver/internals/hli_v2/indices/__init__.py +0 -0
- xoa_driver/internals/hli_v2/indices/base_index.py +39 -0
- xoa_driver/internals/hli_v2/indices/connection_group/__init__.py +0 -0
- xoa_driver/internals/hli_v2/indices/connection_group/cg.py +115 -0
- xoa_driver/internals/hli_v2/indices/connection_group/histogram.py +59 -0
- xoa_driver/internals/hli_v2/indices/connection_group/l2.py +71 -0
- xoa_driver/internals/hli_v2/indices/connection_group/l3.py +96 -0
- xoa_driver/internals/hli_v2/indices/connection_group/raw.py +148 -0
- xoa_driver/internals/hli_v2/indices/connection_group/replay.py +89 -0
- xoa_driver/internals/hli_v2/indices/connection_group/tcp.py +261 -0
- xoa_driver/internals/hli_v2/indices/connection_group/tls.py +166 -0
- xoa_driver/internals/hli_v2/indices/connection_group/udp.py +112 -0
- xoa_driver/internals/hli_v2/indices/connection_group/user_state.py +25 -0
- xoa_driver/internals/hli_v2/indices/filter/__init__.py +0 -0
- xoa_driver/internals/hli_v2/indices/filter/base_filter.py +50 -0
- xoa_driver/internals/hli_v2/indices/filter/genuine_filter.py +17 -0
- xoa_driver/internals/hli_v2/indices/length_term.py +44 -0
- xoa_driver/internals/hli_v2/indices/match_term.py +49 -0
- xoa_driver/internals/hli_v2/indices/port_dataset.py +53 -0
- xoa_driver/internals/hli_v2/indices/streams/__init__.py +0 -0
- xoa_driver/internals/hli_v2/indices/streams/base_stream.py +234 -0
- xoa_driver/internals/hli_v2/indices/streams/genuine_stream.py +32 -0
- xoa_driver/internals/hli_v2/modules/__init__.py +0 -0
- xoa_driver/internals/hli_v2/modules/__interfaces.py +21 -0
- xoa_driver/internals/hli_v2/modules/base_module.py +125 -0
- xoa_driver/internals/hli_v2/modules/module_chimera.py +358 -0
- xoa_driver/internals/hli_v2/modules/module_l23ve.py +58 -0
- xoa_driver/internals/hli_v2/modules/module_l47.py +230 -0
- xoa_driver/internals/hli_v2/modules/module_l47ve.py +8 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/__init__.py +0 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_combi.py +73 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_d.py +75 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_e.py +85 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_f.py +144 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_g.py +84 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_h.py +40 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_i.py +25 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_j.py +25 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_k.py +39 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_l.py +55 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_l1.py +797 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_m.py +25 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/family_n.py +40 -0
- xoa_driver/internals/hli_v2/modules/modules_l23/module_l23_base.py +339 -0
- xoa_driver/internals/hli_v2/ports/__init__.py +0 -0
- xoa_driver/internals/hli_v2/ports/base_port.py +105 -0
- xoa_driver/internals/hli_v2/ports/port_l23/__init__.py +0 -0
- xoa_driver/internals/hli_v2/ports/port_l23/bases/__init__.py +0 -0
- xoa_driver/internals/hli_v2/ports/port_l23/bases/port_capture.py +64 -0
- xoa_driver/internals/hli_v2/ports/port_l23/bases/port_l23.py +441 -0
- xoa_driver/internals/hli_v2/ports/port_l23/bases/port_l23_genuine.py +172 -0
- xoa_driver/internals/hli_v2/ports/port_l23/bases/port_reception_statistics.py +156 -0
- xoa_driver/internals/hli_v2/ports/port_l23/bases/port_transceiver.py +117 -0
- xoa_driver/internals/hli_v2/ports/port_l23/bases/port_transmission_statistics.py +59 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/__init__.py +0 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/filter_definition/__init__.py +0 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/filter_definition/_utils.py +15 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/filter_definition/general.py +340 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/filter_definition/shadow.py +99 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/filter_definition/working.py +36 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/pe_custom_distribution.py +116 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/pe_distribution.py +102 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/port_chimera.py +113 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/port_emulation.py +420 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/reception_statistics.py +22 -0
- xoa_driver/internals/hli_v2/ports/port_l23/chimera/transmission_statistics.py +22 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_combi.py +36 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_d.py +49 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_e.py +96 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_f.py +144 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_g.py +77 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_h.py +60 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_i.py +66 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_j.py +53 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_k.py +58 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_l.py +67 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_l1.py +149 -0
- xoa_driver/internals/hli_v2/ports/port_l23/family_m.py +28 -0
- xoa_driver/internals/hli_v2/ports/port_l23/fault_jkl.py +22 -0
- xoa_driver/internals/hli_v2/ports/port_l23/pcs_pma_ghijkl.py +342 -0
- xoa_driver/internals/hli_v2/ports/port_l23/pcs_pma_ijkl_chimera.py +50 -0
- xoa_driver/internals/hli_v2/ports/port_l23/pcs_pma_l.py +65 -0
- xoa_driver/internals/hli_v2/ports/port_l23/port_l23ve.py +81 -0
- xoa_driver/internals/hli_v2/ports/port_l47/__init__.py +0 -0
- xoa_driver/internals/hli_v2/ports/port_l47/counters.py +146 -0
- xoa_driver/internals/hli_v2/ports/port_l47/main.py +137 -0
- xoa_driver/internals/hli_v2/ports/port_l47/packet_engine.py +20 -0
- xoa_driver/internals/hli_v2/revisions.py +11 -0
- xoa_driver/internals/hli_v2/testers/__init__.py +0 -0
- xoa_driver/internals/hli_v2/testers/_base_tester.py +207 -0
- xoa_driver/internals/hli_v2/testers/genuine/__init__.py +0 -0
- xoa_driver/internals/hli_v2/testers/genuine/l_23/__init__.py +0 -0
- xoa_driver/internals/hli_v2/testers/genuine/l_23/health.py +16 -0
- xoa_driver/internals/hli_v2/testers/genuine/l_23/rest_api.py +34 -0
- xoa_driver/internals/hli_v2/testers/genuine/l_23/time_keeper.py +50 -0
- xoa_driver/internals/hli_v2/testers/genuine/l_23/upload_file.py +26 -0
- xoa_driver/internals/hli_v2/testers/genuine/management_interface.py +38 -0
- xoa_driver/internals/hli_v2/testers/l23_tester.py +159 -0
- xoa_driver/internals/hli_v2/testers/l23ve_tester.py +98 -0
- xoa_driver/internals/hli_v2/testers/l47_tester.py +95 -0
- xoa_driver/internals/hli_v2/testers/l47ve_tester.py +50 -0
- xoa_driver/internals/state_storage/__init__.py +0 -0
- xoa_driver/internals/state_storage/_speed_detector.py +121 -0
- xoa_driver/internals/state_storage/modules_state.py +128 -0
- xoa_driver/internals/state_storage/ports_state.py +154 -0
- xoa_driver/internals/state_storage/testers_state.py +104 -0
- xoa_driver/internals/utils/__init__.py +0 -0
- xoa_driver/internals/utils/attributes.py +33 -0
- xoa_driver/internals/utils/cap_id.py +63 -0
- xoa_driver/internals/utils/con_traffic_light.py +88 -0
- xoa_driver/internals/utils/indices/__init__.py +0 -0
- xoa_driver/internals/utils/indices/_interfaces.py +26 -0
- xoa_driver/internals/utils/indices/header_modifier_manager.py +56 -0
- xoa_driver/internals/utils/indices/index_manager.py +95 -0
- xoa_driver/internals/utils/indices/observer.py +17 -0
- xoa_driver/internals/utils/kind.py +19 -0
- xoa_driver/internals/utils/managers/__init__.py +0 -0
- xoa_driver/internals/utils/managers/abc.py +44 -0
- xoa_driver/internals/utils/managers/exceptions.py +22 -0
- xoa_driver/internals/utils/managers/modules_manager.py +118 -0
- xoa_driver/internals/utils/managers/ports_manager.py +116 -0
- xoa_driver/internals/utils/rev_tool.py +21 -0
- xoa_driver/internals/utils/session.py +117 -0
- xoa_driver/internals/warn.py +32 -0
- xoa_driver/lli.py +15 -0
- xoa_driver/misc.py +57 -0
- xoa_driver/modules.py +448 -0
- xoa_driver/ports.py +332 -0
- xoa_driver/testers.py +37 -0
- xoa_driver/utils.py +12 -0
- xoa_driver/v2/__init__.py +11 -0
- xoa_driver/v2/misc.py +77 -0
- xoa_driver/v2/modules.py +308 -0
- xoa_driver/v2/ports.py +232 -0
- xoa_driver/v2/testers.py +24 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from abc import (
|
|
4
|
+
abstractmethod,
|
|
5
|
+
ABC
|
|
6
|
+
)
|
|
7
|
+
from io import BytesIO
|
|
8
|
+
import struct
|
|
9
|
+
|
|
10
|
+
from typing import (
|
|
11
|
+
Any,
|
|
12
|
+
Callable,
|
|
13
|
+
Generic,
|
|
14
|
+
Protocol,
|
|
15
|
+
Type,
|
|
16
|
+
TypeVar,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
from typing_extensions import (
|
|
20
|
+
NoReturn,
|
|
21
|
+
Self,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
from .field import FieldSpecs
|
|
25
|
+
from .exceptions import FirmwareVersionError
|
|
26
|
+
|
|
27
|
+
# region Types
|
|
28
|
+
|
|
29
|
+
GenericType = TypeVar("GenericType")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class SetInstance(Protocol):
|
|
33
|
+
_buffer: BytesIO
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class GetInstance(Protocol):
|
|
37
|
+
_buffer: memoryview
|
|
38
|
+
_stencil: tuple[tuple[str, int], ...]
|
|
39
|
+
|
|
40
|
+
# endregion
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class FieldDescriptor(ABC, Generic[GenericType]):
|
|
44
|
+
'''
|
|
45
|
+
Descriptor representing getter and setter of the field
|
|
46
|
+
'''
|
|
47
|
+
__slots__ = ("idx", "specs", "public_name",)
|
|
48
|
+
|
|
49
|
+
def __init__(self: Self, idx: int, specs: FieldSpecs) -> None:
|
|
50
|
+
# Will be called from the Meta class
|
|
51
|
+
self.idx = idx
|
|
52
|
+
self.specs = specs
|
|
53
|
+
|
|
54
|
+
def __set_name__(self, owner, name: str) -> None:
|
|
55
|
+
self.public_name = name
|
|
56
|
+
|
|
57
|
+
@abstractmethod
|
|
58
|
+
def __set__(self: Self, instance, value: GenericType) -> None:
|
|
59
|
+
# Executed at the runtimne
|
|
60
|
+
raise NotImplementedError()
|
|
61
|
+
|
|
62
|
+
@abstractmethod
|
|
63
|
+
def __get__(self: Self, instance, cls) -> GenericType | Self:
|
|
64
|
+
# Executed at the runtimne
|
|
65
|
+
raise NotImplementedError()
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class RequestFieldDescr(FieldDescriptor[GenericType]):
|
|
69
|
+
__slots__ = ("to_xmp_context", "fmt")
|
|
70
|
+
|
|
71
|
+
def __init__(self: Self, idx: int, specs: FieldSpecs, user_type: Type[Any]) -> None:
|
|
72
|
+
super().__init__(idx, specs)
|
|
73
|
+
self.fmt = self.specs.format()
|
|
74
|
+
self.to_xmp_context: Callable[[Any], Any] = self.specs.get_context_formatter(user_type, False)
|
|
75
|
+
|
|
76
|
+
def __set__(self: Self, instance: SetInstance, value: GenericType) -> None:
|
|
77
|
+
"""Transform values from Python to Bxmp and store them in to the buffer"""
|
|
78
|
+
# Executed at the runtimne
|
|
79
|
+
val_ = self.to_xmp_context(value)
|
|
80
|
+
instance._buffer.write(self.specs.pack(self.fmt, val=val_))
|
|
81
|
+
|
|
82
|
+
def __get__(self: Self, instance: SetInstance, cls) -> NoReturn | Self:
|
|
83
|
+
# Executed at the runtimne
|
|
84
|
+
if instance is None:
|
|
85
|
+
return self
|
|
86
|
+
raise RuntimeError from None
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class ResponseFieldDescr(FieldDescriptor[GenericType]):
|
|
90
|
+
__slots__ = ("to_py_context",)
|
|
91
|
+
|
|
92
|
+
def __init__(self: Self, idx: int, specs: FieldSpecs, user_type: Type[Any]) -> None:
|
|
93
|
+
super().__init__(idx, specs)
|
|
94
|
+
self.to_py_context: Callable[[Any], Any] = self.specs.get_context_formatter(user_type, True)
|
|
95
|
+
|
|
96
|
+
def __set__(self: Self, instance: GetInstance, value: GenericType) -> NoReturn:
|
|
97
|
+
# Executed at the runtimne
|
|
98
|
+
raise RuntimeError from None
|
|
99
|
+
|
|
100
|
+
def __get__(self: Self, instance: GetInstance, cls) -> GenericType | Self:
|
|
101
|
+
"""Unpack values from the buffer and converting to expected type if required"""
|
|
102
|
+
# Executed at the runtimne
|
|
103
|
+
if instance is None:
|
|
104
|
+
return self
|
|
105
|
+
format_, offset_ = instance._stencil[self.idx]
|
|
106
|
+
try:
|
|
107
|
+
val_ = self.specs.unpack(
|
|
108
|
+
format=format_,
|
|
109
|
+
buffer=instance._buffer,
|
|
110
|
+
offset=offset_,
|
|
111
|
+
)
|
|
112
|
+
except struct.error:
|
|
113
|
+
raise FirmwareVersionError(
|
|
114
|
+
cmd_name=instance.__class__.__qualname__,
|
|
115
|
+
field_name=self.public_name,
|
|
116
|
+
min_version=self.specs.min_version,
|
|
117
|
+
) from None
|
|
118
|
+
else:
|
|
119
|
+
return self.to_py_context(val_)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class XmpException(Exception):
|
|
5
|
+
...
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class FirmwareVersionError(XmpException):
|
|
9
|
+
def __init__(self, cmd_name: str, field_name: str, min_version: int | None) -> None:
|
|
10
|
+
self.cmd_name = cmd_name
|
|
11
|
+
self.field_name = field_name
|
|
12
|
+
self.min_version = min_version
|
|
13
|
+
self.msg = f"The field: [{self.field_name}] of command {self.cmd_name} is available only from the firmware version: {self.min_version}"
|
|
14
|
+
super().__init__(self.msg)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class FieldDeclarationError(TypeError):
|
|
18
|
+
def __init__(self, f_name: str) -> None:
|
|
19
|
+
self.msg = f"Structure Field {f_name!r} must be described with <field method>"
|
|
20
|
+
super().__init__(self.msg)
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from functools import lru_cache
|
|
3
|
+
|
|
4
|
+
from ipaddress import (
|
|
5
|
+
IPv4Address,
|
|
6
|
+
IPv6Address,
|
|
7
|
+
)
|
|
8
|
+
import struct
|
|
9
|
+
from typing import (
|
|
10
|
+
Any,
|
|
11
|
+
Callable,
|
|
12
|
+
List,
|
|
13
|
+
Tuple,
|
|
14
|
+
Type,
|
|
15
|
+
cast,
|
|
16
|
+
get_args,
|
|
17
|
+
)
|
|
18
|
+
from dataclasses import (
|
|
19
|
+
is_dataclass,
|
|
20
|
+
astuple,
|
|
21
|
+
)
|
|
22
|
+
from itertools import islice
|
|
23
|
+
|
|
24
|
+
from .utils import flatten
|
|
25
|
+
from .types import (
|
|
26
|
+
XmpType,
|
|
27
|
+
FMT_ORDER_NETWORK,
|
|
28
|
+
# Numerical
|
|
29
|
+
XmpInt,
|
|
30
|
+
XmpLong,
|
|
31
|
+
XmpByte,
|
|
32
|
+
XmpShort,
|
|
33
|
+
# Preconverted
|
|
34
|
+
XmpHex,
|
|
35
|
+
XmpIPv4Address,
|
|
36
|
+
XmpIPv6Address,
|
|
37
|
+
XmpMacAddress,
|
|
38
|
+
# Preconverted Dynamic
|
|
39
|
+
XmpStr,
|
|
40
|
+
XmpSequence,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
TYPES_FIXED = (
|
|
45
|
+
XmpInt,
|
|
46
|
+
XmpLong,
|
|
47
|
+
XmpByte,
|
|
48
|
+
XmpShort,
|
|
49
|
+
XmpIPv4Address,
|
|
50
|
+
XmpIPv6Address,
|
|
51
|
+
XmpMacAddress,
|
|
52
|
+
)
|
|
53
|
+
TYPES_COMBI = (XmpHex,)
|
|
54
|
+
TYPES_DYNAMIC = (XmpStr,)
|
|
55
|
+
TYPES_COMPOSED = (XmpSequence,)
|
|
56
|
+
|
|
57
|
+
# Important: The instances of the FieldSpecs will live as a class variables
|
|
58
|
+
# which mean wea are not able to update its attributes during runtime.
|
|
59
|
+
# Instead it suppose to provide values or methods which return an value under the instance of Pkt Body struct
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@lru_cache
|
|
63
|
+
def _build_format(format_letter: str, repetition: int | None = None) -> str:
|
|
64
|
+
return f"{FMT_ORDER_NETWORK}{repetition if repetition is not None else ''}{format_letter}"
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class FieldSpecs:
|
|
68
|
+
"""Executed at initialization time"""
|
|
69
|
+
__slots__ = (
|
|
70
|
+
"xmp_type",
|
|
71
|
+
"min_version",
|
|
72
|
+
"max_version",
|
|
73
|
+
"deprecated",
|
|
74
|
+
"deprecation_reason",
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
def __init__(
|
|
78
|
+
self,
|
|
79
|
+
xmp_type: XmpType,
|
|
80
|
+
min_version: int | None = None,
|
|
81
|
+
max_version: int | None = None,
|
|
82
|
+
deprecated: bool = False,
|
|
83
|
+
deprecation_reason: str | None = None,
|
|
84
|
+
) -> None:
|
|
85
|
+
self.xmp_type = xmp_type
|
|
86
|
+
self.min_version = min_version
|
|
87
|
+
self.max_version = max_version
|
|
88
|
+
self.deprecated = deprecated
|
|
89
|
+
self.deprecation_reason = deprecation_reason
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def is_dynamic(self) -> bool:
|
|
93
|
+
return False
|
|
94
|
+
|
|
95
|
+
def format(self, bsize: int | None = None) -> str:
|
|
96
|
+
return _build_format(self.xmp_type.data_format, self.xmp_type.repetitions)
|
|
97
|
+
|
|
98
|
+
def calc_bsize(self, buff: memoryview | None = None, left_offset: int = 0) -> int | None:
|
|
99
|
+
if self.is_dynamic:
|
|
100
|
+
return None
|
|
101
|
+
format_ = self.format()
|
|
102
|
+
return struct.calcsize(format_)
|
|
103
|
+
|
|
104
|
+
def get_context_formatter(self, client_type: Type[Any], is_response: bool) -> Callable[[Any], Any]:
|
|
105
|
+
if not isinstance(client_type, (int, IPv4Address, IPv6Address)):
|
|
106
|
+
if is_response:
|
|
107
|
+
return lambda v: client_type(self.xmp_type.client_format(v))
|
|
108
|
+
return lambda v: self.xmp_type.server_format(client_type(v))
|
|
109
|
+
if is_response:
|
|
110
|
+
return self.xmp_type.client_format
|
|
111
|
+
return self.xmp_type.server_format
|
|
112
|
+
|
|
113
|
+
def pack(self, format: str, val: Any) -> bytes:
|
|
114
|
+
return struct.pack(format, val)
|
|
115
|
+
|
|
116
|
+
def unpack(self, format: str, buffer: memoryview, offset: int) -> Any:
|
|
117
|
+
return next(iter(struct.unpack_from(format, buffer, offset)), b"")
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class StrSpec(FieldSpecs):
|
|
121
|
+
xmp_type: XmpStr
|
|
122
|
+
|
|
123
|
+
def __init__(
|
|
124
|
+
self,
|
|
125
|
+
xmp_type: XmpStr,
|
|
126
|
+
min_version: int | None = None,
|
|
127
|
+
max_version: int | None = None,
|
|
128
|
+
deprecated: bool = False,
|
|
129
|
+
deprecation_reason: str | None = None,
|
|
130
|
+
) -> None:
|
|
131
|
+
super().__init__(xmp_type, min_version, max_version, deprecated, deprecation_reason)
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
def is_dynamic(self) -> bool:
|
|
135
|
+
return True
|
|
136
|
+
|
|
137
|
+
def format(self, bsize: int | None = None) -> str:
|
|
138
|
+
return _build_format(self.xmp_type.data_format, bsize)
|
|
139
|
+
|
|
140
|
+
def calc_bsize(self, buff: memoryview | None = None, left_offset: int = 0) -> int | None:
|
|
141
|
+
if buff is None:
|
|
142
|
+
return None
|
|
143
|
+
in_memory_slice = buff[left_offset:]
|
|
144
|
+
current_size = next(
|
|
145
|
+
(
|
|
146
|
+
idx
|
|
147
|
+
for idx, ord_n in enumerate(in_memory_slice)
|
|
148
|
+
if ord_n == 0 and not bool(idx % 4)
|
|
149
|
+
),
|
|
150
|
+
in_memory_slice.nbytes
|
|
151
|
+
)
|
|
152
|
+
return max(self.xmp_type.min_len or 0, current_size)
|
|
153
|
+
|
|
154
|
+
def get_context_formatter(self, client_type: Type[Any], is_response: bool) -> Callable[[Any], Any]:
|
|
155
|
+
if is_response:
|
|
156
|
+
return self.xmp_type.client_format
|
|
157
|
+
return self.xmp_type.server_format
|
|
158
|
+
|
|
159
|
+
def pack(self, format: str, val: bytes) -> bytes:
|
|
160
|
+
return val
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class HexSpec(FieldSpecs):
|
|
164
|
+
xmp_type: XmpHex
|
|
165
|
+
|
|
166
|
+
def __init__(
|
|
167
|
+
self,
|
|
168
|
+
xmp_type: XmpHex,
|
|
169
|
+
min_version: int | None = None,
|
|
170
|
+
max_version: int | None = None,
|
|
171
|
+
deprecated: bool = False,
|
|
172
|
+
deprecation_reason: str | None = None,
|
|
173
|
+
) -> None:
|
|
174
|
+
super().__init__(xmp_type, min_version, max_version, deprecated, deprecation_reason)
|
|
175
|
+
|
|
176
|
+
@property
|
|
177
|
+
def is_dynamic(self) -> bool:
|
|
178
|
+
return self.xmp_type.repetitions is None
|
|
179
|
+
|
|
180
|
+
def format(self, bsize: int | None = None) -> str:
|
|
181
|
+
return _build_format(self.xmp_type.data_format, bsize)
|
|
182
|
+
|
|
183
|
+
def calc_bsize(self, buff: memoryview | None = None, left_offset: int = 0) -> int | None:
|
|
184
|
+
if self.is_dynamic:
|
|
185
|
+
if buff is None:
|
|
186
|
+
return None
|
|
187
|
+
return len(buff[left_offset:])
|
|
188
|
+
return self.xmp_type.repetitions
|
|
189
|
+
|
|
190
|
+
def pack(self, format: str, val: Any) -> bytes:
|
|
191
|
+
return val
|
|
192
|
+
|
|
193
|
+
def unpack(self, format: str, buffer: memoryview, offset: int) -> Any:
|
|
194
|
+
return next(iter(struct.unpack_from(format, buffer, offset)), b"")
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def _prepare_client_chunks(client_type: Type[Any], xmp_types_chunks: tuple) -> Callable[[Any], List[Tuple[Any, ...]]]:
|
|
198
|
+
"""Selecting the function for parsing data chunks from XMP types to Python types"""
|
|
199
|
+
def converted_dcls(val_):
|
|
200
|
+
type_paired = (zip(chunk, xmp_types_chunks) for chunk in val_)
|
|
201
|
+
return (map(lambda v: v[1].client_format(v[0]), pair) for pair in type_paired)
|
|
202
|
+
|
|
203
|
+
def converted_val(val_):
|
|
204
|
+
return map(xmp_types_chunks[0].client_format, val_)
|
|
205
|
+
|
|
206
|
+
converted = converted_dcls if is_dataclass(client_type) else converted_val
|
|
207
|
+
return lambda val: [client_type(*vals) for vals in converted(val)]
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
def _prepare_serv_chunks(client_type: Type[Any], xmp_types_chunks: tuple) -> Callable[[Any], List[Tuple[Any, ...]]]:
|
|
211
|
+
"""Selecting the function for parsing data chunks from Python types to XMP types"""
|
|
212
|
+
if is_dataclass(client_type):
|
|
213
|
+
return lambda val: [
|
|
214
|
+
tuple(map(lambda v: v[1].server_format(v[0]), zip(chunk, xmp_types_chunks)))
|
|
215
|
+
for chunk in map(astuple, val)
|
|
216
|
+
]
|
|
217
|
+
return lambda val: list(map(xmp_types_chunks[0].server_format, val))
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
class SequenceSpec(FieldSpecs):
|
|
221
|
+
xmp_type: XmpSequence
|
|
222
|
+
|
|
223
|
+
def __init__(
|
|
224
|
+
self,
|
|
225
|
+
xmp_type: XmpSequence,
|
|
226
|
+
min_version: int | None = None,
|
|
227
|
+
max_version: int | None = None,
|
|
228
|
+
deprecated: bool = False,
|
|
229
|
+
deprecation_reason: str | None = None,
|
|
230
|
+
) -> None:
|
|
231
|
+
super().__init__(xmp_type, min_version, max_version, deprecated, deprecation_reason)
|
|
232
|
+
|
|
233
|
+
@property
|
|
234
|
+
def is_dynamic(self) -> bool:
|
|
235
|
+
return self.xmp_type.length is None
|
|
236
|
+
|
|
237
|
+
def calc_bsize(self, buff: memoryview | None = None, left_offset: int = 0) -> int | None:
|
|
238
|
+
format_ = _build_format(self.xmp_type.data_format)
|
|
239
|
+
return struct.calcsize(format_) * (self.xmp_type.length or 1)
|
|
240
|
+
|
|
241
|
+
def get_context_formatter(self, client_type: Type[Any], is_response: bool) -> Callable[[Any], List[Tuple[Any, ...]]]:
|
|
242
|
+
try:
|
|
243
|
+
client_type = get_args(client_type)[0]
|
|
244
|
+
except IndexError as e:
|
|
245
|
+
raise e
|
|
246
|
+
if is_response:
|
|
247
|
+
return _prepare_client_chunks(
|
|
248
|
+
client_type=client_type,
|
|
249
|
+
xmp_types_chunks=self.xmp_type.types_chunk
|
|
250
|
+
)
|
|
251
|
+
return _prepare_serv_chunks(
|
|
252
|
+
client_type=client_type,
|
|
253
|
+
xmp_types_chunks=self.xmp_type.types_chunk
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
def pack(self, format: str, val: list[Any]) -> bytes:
|
|
257
|
+
length = self.xmp_type.length or len(val)
|
|
258
|
+
pack_fmt = f"{FMT_ORDER_NETWORK}{self.xmp_type.data_format * length}"
|
|
259
|
+
return struct.pack(pack_fmt, *flatten(val))
|
|
260
|
+
|
|
261
|
+
def unpack(self, format: str, buffer: memoryview, offset: int) -> list[Any]:
|
|
262
|
+
buff_ = buffer[offset:]
|
|
263
|
+
limit = len(buff_) % cast(int, self.calc_bsize())
|
|
264
|
+
buff_ = buff_[:-limit] if limit else buff_
|
|
265
|
+
raw_sequence = islice(struct.iter_unpack(format, buff_), self.xmp_type.length)
|
|
266
|
+
return list(raw_sequence)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def field(
|
|
270
|
+
xmp_type: XmpType,
|
|
271
|
+
*,
|
|
272
|
+
min_version: int | None = None,
|
|
273
|
+
max_version: int | None = None,
|
|
274
|
+
deprecated: bool = False,
|
|
275
|
+
deprecation_reason: str | None = None
|
|
276
|
+
) -> Any:
|
|
277
|
+
"""Method used for describe field parameters of an XMP packet structure"""
|
|
278
|
+
|
|
279
|
+
if isinstance(xmp_type, TYPES_COMPOSED):
|
|
280
|
+
specs_type = SequenceSpec
|
|
281
|
+
elif isinstance(xmp_type, TYPES_DYNAMIC):
|
|
282
|
+
specs_type = StrSpec
|
|
283
|
+
elif isinstance(xmp_type, TYPES_FIXED):
|
|
284
|
+
specs_type = FieldSpecs
|
|
285
|
+
elif isinstance(xmp_type, TYPES_COMBI):
|
|
286
|
+
specs_type = HexSpec
|
|
287
|
+
else:
|
|
288
|
+
return None
|
|
289
|
+
|
|
290
|
+
return specs_type(
|
|
291
|
+
xmp_type=xmp_type, # type: ignore[The type of xmp_type is already validated]
|
|
292
|
+
min_version=min_version,
|
|
293
|
+
max_version=max_version,
|
|
294
|
+
deprecated=deprecated,
|
|
295
|
+
deprecation_reason=deprecation_reason,
|
|
296
|
+
)
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from ipaddress import (
|
|
3
|
+
IPv4Address,
|
|
4
|
+
IPv6Address,
|
|
5
|
+
)
|
|
6
|
+
from typing import (
|
|
7
|
+
Any,
|
|
8
|
+
NewType,
|
|
9
|
+
Protocol,
|
|
10
|
+
TypeVar,
|
|
11
|
+
cast,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
FMT_ORDER_NETWORK = '!'
|
|
15
|
+
FMT_BYTES_STRING = 's'
|
|
16
|
+
FMT_SIG_CHAR = 'b'
|
|
17
|
+
FMT_U_SIG_CHAR = 'B'
|
|
18
|
+
FMT_LONG = 'q'
|
|
19
|
+
FMT_U_LONG = 'Q'
|
|
20
|
+
FMT_INT = 'i'
|
|
21
|
+
FMT_U_INT = 'I'
|
|
22
|
+
FMT_SHORT = 'h'
|
|
23
|
+
FMT_U_SHORT = 'H'
|
|
24
|
+
|
|
25
|
+
# region Base Type
|
|
26
|
+
|
|
27
|
+
GenericType = TypeVar("GenericType", covariant=True)
|
|
28
|
+
|
|
29
|
+
Hex = NewType("Hex", str)
|
|
30
|
+
"""Type alias of string for indicate as string suppose to contain only valid HEX symbols"""
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class XmpType(Protocol[GenericType]):
|
|
34
|
+
__slots__ = ("data_format", "repetitions",)
|
|
35
|
+
|
|
36
|
+
repetitions: int | None
|
|
37
|
+
data_format: str
|
|
38
|
+
|
|
39
|
+
def client_format(self, val: Any) -> Any:
|
|
40
|
+
return val
|
|
41
|
+
|
|
42
|
+
def server_format(self, val: Any) -> Any:
|
|
43
|
+
return val
|
|
44
|
+
|
|
45
|
+
# endregion
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# region Xmp Types
|
|
49
|
+
|
|
50
|
+
class XmpByte(XmpType[int]):
|
|
51
|
+
"""Description class of XMP Byte type representation"""
|
|
52
|
+
|
|
53
|
+
def __init__(self, *, signed: bool = False) -> None:
|
|
54
|
+
self.data_format = FMT_SIG_CHAR if signed else FMT_U_SIG_CHAR
|
|
55
|
+
self.repetitions = None
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class XmpInt(XmpType[int]):
|
|
59
|
+
"""Description class of XMP Int type representation"""
|
|
60
|
+
|
|
61
|
+
def __init__(self, *, signed: bool = True, climb: tuple[int, int] | None = None) -> None:
|
|
62
|
+
self.data_format = FMT_INT if signed else FMT_U_INT
|
|
63
|
+
self.repetitions = None
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class XmpShort(XmpType[int]):
|
|
67
|
+
"""Description class of XMP Short type representation"""
|
|
68
|
+
|
|
69
|
+
def __init__(self, *, signed: bool = True) -> None:
|
|
70
|
+
self.data_format = FMT_SHORT if signed else FMT_U_SHORT
|
|
71
|
+
self.repetitions = None
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class XmpLong(XmpType[int]):
|
|
75
|
+
"""Description class of XMP Long type representation"""
|
|
76
|
+
|
|
77
|
+
def __init__(self, *, signed: bool = True) -> None:
|
|
78
|
+
self.data_format = FMT_LONG if signed else FMT_U_LONG
|
|
79
|
+
self.repetitions = None
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class XmpHex(XmpType[Hex]):
|
|
83
|
+
"""Description class of XMP Hex type representation"""
|
|
84
|
+
|
|
85
|
+
def __init__(self, *, size: int | None = None) -> None:
|
|
86
|
+
"""
|
|
87
|
+
if size is None means Hex string are not having a limit
|
|
88
|
+
otherwise will use fixed size
|
|
89
|
+
"""
|
|
90
|
+
self.data_format = FMT_BYTES_STRING
|
|
91
|
+
self.repetitions = size
|
|
92
|
+
|
|
93
|
+
def client_format(self, val: bytes) -> Hex:
|
|
94
|
+
return Hex(val.hex())
|
|
95
|
+
|
|
96
|
+
def server_format(self, val: Hex) -> bytes:
|
|
97
|
+
if self.repetitions is not None:
|
|
98
|
+
size_ = self.repetitions * 2
|
|
99
|
+
if len(val) > size_:
|
|
100
|
+
raise ValueError(f"Expected Hex of size not bigger then {self.repetitions} bytes")
|
|
101
|
+
val = Hex(cast(str, val).zfill(size_))
|
|
102
|
+
return bytes.fromhex(val)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class XmpIPv6Address(XmpType[IPv6Address]):
|
|
106
|
+
"""Description class of XMP IPv6Address type representation"""
|
|
107
|
+
|
|
108
|
+
def __init__(self) -> None:
|
|
109
|
+
self.data_format = FMT_BYTES_STRING
|
|
110
|
+
self.repetitions = 16
|
|
111
|
+
|
|
112
|
+
def client_format(self, val: bytes) -> IPv6Address:
|
|
113
|
+
return IPv6Address(val)
|
|
114
|
+
|
|
115
|
+
def server_format(self, val: IPv6Address) -> bytes:
|
|
116
|
+
return val.packed
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class XmpIPv4Address(XmpType[IPv4Address]):
|
|
120
|
+
"""Description class of XMP IPv4Address type representation"""
|
|
121
|
+
|
|
122
|
+
def __init__(self) -> None:
|
|
123
|
+
self.data_format = FMT_BYTES_STRING
|
|
124
|
+
self.repetitions = 4
|
|
125
|
+
|
|
126
|
+
def client_format(self, val: bytes) -> IPv4Address:
|
|
127
|
+
return IPv4Address(val)
|
|
128
|
+
|
|
129
|
+
def server_format(self, val: IPv4Address) -> bytes:
|
|
130
|
+
return val.packed
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class XmpMacAddress(XmpHex):
|
|
134
|
+
"""Description class of XMP MacAddress type representation"""
|
|
135
|
+
|
|
136
|
+
def __init__(self) -> None:
|
|
137
|
+
self.data_format = FMT_BYTES_STRING
|
|
138
|
+
self.repetitions = 6
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class XmpStr(XmpType[str]):
|
|
142
|
+
"""Description class of XMP String type representation"""
|
|
143
|
+
|
|
144
|
+
__slots__ = ("min_len",)
|
|
145
|
+
|
|
146
|
+
def __init__(self, min_len: int | None = None) -> None:
|
|
147
|
+
self.data_format = FMT_BYTES_STRING
|
|
148
|
+
self.repetitions = None
|
|
149
|
+
self.min_len = min_len
|
|
150
|
+
|
|
151
|
+
def client_format(self, val: bytes) -> str:
|
|
152
|
+
return val.partition(b'\0')[0].decode()
|
|
153
|
+
|
|
154
|
+
def server_format(self, val: str) -> bytes:
|
|
155
|
+
return val.encode()
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
class XmpSequence(XmpType[tuple]):
|
|
159
|
+
"""Description class of XMP Sequence type representation"""
|
|
160
|
+
|
|
161
|
+
__slots__ = ("types_chunk", "length",)
|
|
162
|
+
|
|
163
|
+
def __init__(
|
|
164
|
+
self,
|
|
165
|
+
types_chunk: list[XmpByte | XmpInt | XmpShort | XmpLong | XmpHex | XmpIPv4Address | XmpIPv6Address | XmpMacAddress],
|
|
166
|
+
length: int | None = None
|
|
167
|
+
) -> None:
|
|
168
|
+
self.types_chunk = tuple(types_chunk)
|
|
169
|
+
self.length = length
|
|
170
|
+
self.repetitions = None
|
|
171
|
+
self.data_format = "".join(f"{t.repetitions or ''}{t.data_format}" for t in self.types_chunk)
|
|
172
|
+
|
|
173
|
+
# endregion
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import sys
|
|
3
|
+
from functools import partial
|
|
4
|
+
from typing import (
|
|
5
|
+
Dict,
|
|
6
|
+
ForwardRef,
|
|
7
|
+
Iterable,
|
|
8
|
+
Type,
|
|
9
|
+
Any,
|
|
10
|
+
Optional,
|
|
11
|
+
_eval_type, # type: ignore
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def resolve_annotations(raw_annotations: dict[str, Type[Any]], module_name: str | None) -> dict[str, Type[Any]]:
|
|
16
|
+
"""
|
|
17
|
+
Partially taken from typing.get_type_hints.
|
|
18
|
+
|
|
19
|
+
Resolve string or ForwardRef annotations into type objects if possible.
|
|
20
|
+
"""
|
|
21
|
+
base_globals: Optional[Dict[str, Any]] = None
|
|
22
|
+
if module_name:
|
|
23
|
+
if module := sys.modules.get(module_name, None):
|
|
24
|
+
base_globals = module.__dict__
|
|
25
|
+
|
|
26
|
+
validate_version = (3, 10) > sys.version_info >= (3, 9, 8) or sys.version_info >= (3, 10, 1)
|
|
27
|
+
forward_ref = (
|
|
28
|
+
partial(ForwardRef, is_argument=False, is_class=True)
|
|
29
|
+
if validate_version else
|
|
30
|
+
partial(ForwardRef, is_argument=False)
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
annotations = {}
|
|
34
|
+
for name, value in raw_annotations.items():
|
|
35
|
+
val_ = forward_ref(value) if isinstance(value, str) else value
|
|
36
|
+
try:
|
|
37
|
+
val_ = _eval_type(val_, base_globals, None)
|
|
38
|
+
except NameError:
|
|
39
|
+
pass
|
|
40
|
+
except TypeError:
|
|
41
|
+
if sys.version_info < (3, 9):
|
|
42
|
+
version_str = f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"
|
|
43
|
+
raise TypeError(f"The Python version you using is: {version_str} and it's supports type hints only from <typing> module") from None
|
|
44
|
+
annotations[name] = val_
|
|
45
|
+
return annotations
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def flatten(items, ignore_types=(str, bytes)):
|
|
49
|
+
for x in items:
|
|
50
|
+
if isinstance(x, Iterable) and not isinstance(x, ignore_types):
|
|
51
|
+
yield from flatten(x)
|
|
52
|
+
else:
|
|
53
|
+
yield x
|