pypcapkit 1.3.3.post1__cp313-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.
- pcapkit/__init__.py +126 -0
- pcapkit/__main__.py +138 -0
- pcapkit/all.py +136 -0
- pcapkit/const/__init__.py +81 -0
- pcapkit/const/arp/__init__.py +25 -0
- pcapkit/const/arp/hardware.py +181 -0
- pcapkit/const/arp/operation.py +131 -0
- pcapkit/const/ftp/__init__.py +25 -0
- pcapkit/const/ftp/command.py +309 -0
- pcapkit/const/ftp/return_code.py +304 -0
- pcapkit/const/hip/__init__.py +94 -0
- pcapkit/const/hip/certificate.py +77 -0
- pcapkit/const/hip/cipher.py +65 -0
- pcapkit/const/hip/di.py +59 -0
- pcapkit/const/hip/ecdsa_curve.py +59 -0
- pcapkit/const/hip/ecdsa_low_curve.py +56 -0
- pcapkit/const/hip/eddsa_curve.py +65 -0
- pcapkit/const/hip/esp_transform_suite.py +98 -0
- pcapkit/const/hip/group.py +86 -0
- pcapkit/const/hip/hi_algorithm.py +86 -0
- pcapkit/const/hip/hit_suite.py +68 -0
- pcapkit/const/hip/nat_traversal.py +62 -0
- pcapkit/const/hip/notify_message.py +200 -0
- pcapkit/const/hip/packet.py +89 -0
- pcapkit/const/hip/parameter.py +377 -0
- pcapkit/const/hip/registration.py +68 -0
- pcapkit/const/hip/registration_failure.py +84 -0
- pcapkit/const/hip/suite.py +71 -0
- pcapkit/const/hip/transport.py +59 -0
- pcapkit/const/http/__init__.py +39 -0
- pcapkit/const/http/error_code.py +95 -0
- pcapkit/const/http/frame.py +95 -0
- pcapkit/const/http/method.py +184 -0
- pcapkit/const/http/setting.py +96 -0
- pcapkit/const/http/status_code.py +294 -0
- pcapkit/const/ipv4/__init__.py +57 -0
- pcapkit/const/ipv4/classification_level.py +64 -0
- pcapkit/const/ipv4/option_class.py +55 -0
- pcapkit/const/ipv4/option_number.py +137 -0
- pcapkit/const/ipv4/protection_authority.py +63 -0
- pcapkit/const/ipv4/qs_function.py +51 -0
- pcapkit/const/ipv4/router_alert.py +251 -0
- pcapkit/const/ipv4/tos_del.py +51 -0
- pcapkit/const/ipv4/tos_ecn.py +55 -0
- pcapkit/const/ipv4/tos_pre.py +63 -0
- pcapkit/const/ipv4/tos_rel.py +51 -0
- pcapkit/const/ipv4/tos_thr.py +51 -0
- pcapkit/const/ipv4/ts_flag.py +53 -0
- pcapkit/const/ipv6/__init__.py +53 -0
- pcapkit/const/ipv6/extension_header.py +66 -0
- pcapkit/const/ipv6/option.py +137 -0
- pcapkit/const/ipv6/option_action.py +55 -0
- pcapkit/const/ipv6/qs_function.py +51 -0
- pcapkit/const/ipv6/router_alert.py +266 -0
- pcapkit/const/ipv6/routing.py +80 -0
- pcapkit/const/ipv6/seed_id.py +55 -0
- pcapkit/const/ipv6/smf_dpd_mode.py +51 -0
- pcapkit/const/ipv6/tagger_id.py +62 -0
- pcapkit/const/ipx/__init__.py +27 -0
- pcapkit/const/ipx/packet.py +72 -0
- pcapkit/const/ipx/socket.py +104 -0
- pcapkit/const/l2tp/__init__.py +21 -0
- pcapkit/const/l2tp/type.py +51 -0
- pcapkit/const/mh/__init__.py +204 -0
- pcapkit/const/mh/access_type.py +92 -0
- pcapkit/const/mh/ack_status_code.py +71 -0
- pcapkit/const/mh/ani_suboption.py +74 -0
- pcapkit/const/mh/auth_subtype.py +53 -0
- pcapkit/const/mh/binding_ack_flag.py +66 -0
- pcapkit/const/mh/binding_error.py +51 -0
- pcapkit/const/mh/binding_revocation.py +59 -0
- pcapkit/const/mh/binding_update_flag.py +81 -0
- pcapkit/const/mh/cga_extension.py +66 -0
- pcapkit/const/mh/cga_sec.py +57 -0
- pcapkit/const/mh/cga_type.py +68 -0
- pcapkit/const/mh/dhcp_support_mode.py +53 -0
- pcapkit/const/mh/dns_status_code.py +65 -0
- pcapkit/const/mh/dsmip6_tls_packet.py +62 -0
- pcapkit/const/mh/dsmipv6_home_address.py +74 -0
- pcapkit/const/mh/enumerating_algorithm.py +56 -0
- pcapkit/const/mh/fb_ack_status.py +62 -0
- pcapkit/const/mh/fb_action.py +71 -0
- pcapkit/const/mh/fb_indication_trigger.py +65 -0
- pcapkit/const/mh/fb_type.py +59 -0
- pcapkit/const/mh/flow_id_status.py +77 -0
- pcapkit/const/mh/flow_id_suboption.py +71 -0
- pcapkit/const/mh/handoff_type.py +71 -0
- pcapkit/const/mh/handover_ack_flag.py +54 -0
- pcapkit/const/mh/handover_ack_status.py +92 -0
- pcapkit/const/mh/handover_initiate_flag.py +57 -0
- pcapkit/const/mh/handover_initiate_status.py +62 -0
- pcapkit/const/mh/home_address_reply.py +71 -0
- pcapkit/const/mh/lla_code.py +63 -0
- pcapkit/const/mh/lma_mag_suboption.py +59 -0
- pcapkit/const/mh/mn_group_id.py +59 -0
- pcapkit/const/mh/mn_id_subtype.py +77 -0
- pcapkit/const/mh/operator_id.py +63 -0
- pcapkit/const/mh/option.py +260 -0
- pcapkit/const/mh/packet.py +119 -0
- pcapkit/const/mh/qos_attribute.py +89 -0
- pcapkit/const/mh/revocation_status_code.py +83 -0
- pcapkit/const/mh/revocation_trigger.py +86 -0
- pcapkit/const/mh/status_code.py +232 -0
- pcapkit/const/mh/traffic_selector.py +62 -0
- pcapkit/const/mh/upa_status.py +71 -0
- pcapkit/const/mh/upn_reason.py +80 -0
- pcapkit/const/ospf/__init__.py +27 -0
- pcapkit/const/ospf/authentication.py +65 -0
- pcapkit/const/ospf/packet.py +71 -0
- pcapkit/const/pcapng/__init__.py +51 -0
- pcapkit/const/pcapng/block_type.py +152 -0
- pcapkit/const/pcapng/filter_type.py +48 -0
- pcapkit/const/pcapng/hash_algorithm.py +59 -0
- pcapkit/const/pcapng/option_type.py +233 -0
- pcapkit/const/pcapng/record_type.py +57 -0
- pcapkit/const/pcapng/secrets_type.py +56 -0
- pcapkit/const/pcapng/verdict_type.py +53 -0
- pcapkit/const/reg/__init__.py +34 -0
- pcapkit/const/reg/apptype.py +32702 -0
- pcapkit/const/reg/ethertype.py +714 -0
- pcapkit/const/reg/linktype.py +902 -0
- pcapkit/const/reg/transtype.py +523 -0
- pcapkit/const/tcp/__init__.py +35 -0
- pcapkit/const/tcp/checksum.py +55 -0
- pcapkit/const/tcp/flags.py +73 -0
- pcapkit/const/tcp/mp_tcp_option.py +80 -0
- pcapkit/const/tcp/option.py +198 -0
- pcapkit/const/vlan/__init__.py +23 -0
- pcapkit/const/vlan/priority_level.py +71 -0
- pcapkit/corekit/__init__.py +59 -0
- pcapkit/corekit/fields/__init__.py +45 -0
- pcapkit/corekit/fields/collections.py +282 -0
- pcapkit/corekit/fields/field.py +269 -0
- pcapkit/corekit/fields/ipaddress.py +274 -0
- pcapkit/corekit/fields/misc.py +722 -0
- pcapkit/corekit/fields/numbers.py +375 -0
- pcapkit/corekit/fields/strings.py +245 -0
- pcapkit/corekit/infoclass.py +394 -0
- pcapkit/corekit/io.py +506 -0
- pcapkit/corekit/module.py +39 -0
- pcapkit/corekit/multidict.py +626 -0
- pcapkit/corekit/protochain.py +263 -0
- pcapkit/corekit/version.py +33 -0
- pcapkit/dumpkit/__init__.py +15 -0
- pcapkit/dumpkit/common.py +199 -0
- pcapkit/dumpkit/null.py +77 -0
- pcapkit/dumpkit/pcap.py +144 -0
- pcapkit/foundation/__init__.py +45 -0
- pcapkit/foundation/engines/__init__.py +36 -0
- pcapkit/foundation/engines/dpkt.py +230 -0
- pcapkit/foundation/engines/engine.py +194 -0
- pcapkit/foundation/engines/pcap.py +188 -0
- pcapkit/foundation/engines/pcapng.py +310 -0
- pcapkit/foundation/engines/pyshark.py +166 -0
- pcapkit/foundation/engines/scapy.py +161 -0
- pcapkit/foundation/extraction.py +915 -0
- pcapkit/foundation/reassembly/__init__.py +49 -0
- pcapkit/foundation/reassembly/data/__init__.py +48 -0
- pcapkit/foundation/reassembly/data/ip.py +117 -0
- pcapkit/foundation/reassembly/data/tcp.py +145 -0
- pcapkit/foundation/reassembly/ip.py +192 -0
- pcapkit/foundation/reassembly/ipv4.py +50 -0
- pcapkit/foundation/reassembly/ipv6.py +50 -0
- pcapkit/foundation/reassembly/reassembly.py +389 -0
- pcapkit/foundation/reassembly/tcp.py +249 -0
- pcapkit/foundation/registry/__init__.py +41 -0
- pcapkit/foundation/registry/foundation.py +327 -0
- pcapkit/foundation/registry/protocols.py +885 -0
- pcapkit/foundation/traceflow/__init__.py +44 -0
- pcapkit/foundation/traceflow/data/__init__.py +30 -0
- pcapkit/foundation/traceflow/data/tcp.py +105 -0
- pcapkit/foundation/traceflow/tcp.py +159 -0
- pcapkit/foundation/traceflow/traceflow.py +390 -0
- pcapkit/interface/__init__.py +22 -0
- pcapkit/interface/core.py +185 -0
- pcapkit/interface/misc.py +120 -0
- pcapkit/protocols/__init__.py +85 -0
- pcapkit/protocols/application/NotImplemented/bgp.py +0 -0
- pcapkit/protocols/application/NotImplemented/dhcp.py +0 -0
- pcapkit/protocols/application/NotImplemented/dhcpv6.py +0 -0
- pcapkit/protocols/application/NotImplemented/dns.py +0 -0
- pcapkit/protocols/application/NotImplemented/imap.py +0 -0
- pcapkit/protocols/application/NotImplemented/ldap.py +0 -0
- pcapkit/protocols/application/NotImplemented/mqtt.py +0 -0
- pcapkit/protocols/application/NotImplemented/nntp.py +0 -0
- pcapkit/protocols/application/NotImplemented/ntp.py +0 -0
- pcapkit/protocols/application/NotImplemented/onc_rpc.py +0 -0
- pcapkit/protocols/application/NotImplemented/pop.py +0 -0
- pcapkit/protocols/application/NotImplemented/rip.py +0 -0
- pcapkit/protocols/application/NotImplemented/rtp.py +0 -0
- pcapkit/protocols/application/NotImplemented/sip.py +0 -0
- pcapkit/protocols/application/NotImplemented/smtp.py +0 -0
- pcapkit/protocols/application/NotImplemented/snmp.py +0 -0
- pcapkit/protocols/application/NotImplemented/ssh.py +0 -0
- pcapkit/protocols/application/NotImplemented/telnet.py +0 -0
- pcapkit/protocols/application/NotImplemented/tls.py +0 -0
- pcapkit/protocols/application/NotImplemented/xmpp.py +0 -0
- pcapkit/protocols/application/__init__.py +34 -0
- pcapkit/protocols/application/application.py +114 -0
- pcapkit/protocols/application/ftp.py +206 -0
- pcapkit/protocols/application/http.py +176 -0
- pcapkit/protocols/application/httpv1.py +320 -0
- pcapkit/protocols/application/httpv2.py +1255 -0
- pcapkit/protocols/data/__init__.py +192 -0
- pcapkit/protocols/data/application/__init__.py +57 -0
- pcapkit/protocols/data/application/ftp.py +59 -0
- pcapkit/protocols/data/application/httpv1.py +79 -0
- pcapkit/protocols/data/application/httpv2.py +293 -0
- pcapkit/protocols/data/data.py +25 -0
- pcapkit/protocols/data/internet/__init__.py +298 -0
- pcapkit/protocols/data/internet/ah.py +31 -0
- pcapkit/protocols/data/internet/hip.py +804 -0
- pcapkit/protocols/data/internet/hopopt.py +351 -0
- pcapkit/protocols/data/internet/ipv4.py +369 -0
- pcapkit/protocols/data/internet/ipv6.py +67 -0
- pcapkit/protocols/data/internet/ipv6_frag.py +29 -0
- pcapkit/protocols/data/internet/ipv6_opts.py +368 -0
- pcapkit/protocols/data/internet/ipv6_route.py +86 -0
- pcapkit/protocols/data/internet/ipx.py +56 -0
- pcapkit/protocols/data/internet/mh.py +509 -0
- pcapkit/protocols/data/link/__init__.py +33 -0
- pcapkit/protocols/data/link/arp.py +74 -0
- pcapkit/protocols/data/link/ethernet.py +28 -0
- pcapkit/protocols/data/link/l2tp.py +63 -0
- pcapkit/protocols/data/link/ospf.py +58 -0
- pcapkit/protocols/data/link/vlan.py +42 -0
- pcapkit/protocols/data/misc/__init__.py +109 -0
- pcapkit/protocols/data/misc/null.py +18 -0
- pcapkit/protocols/data/misc/pcap/__init__.py +18 -0
- pcapkit/protocols/data/misc/pcap/frame.py +56 -0
- pcapkit/protocols/data/misc/pcap/header.py +53 -0
- pcapkit/protocols/data/misc/pcapng.py +925 -0
- pcapkit/protocols/data/misc/raw.py +25 -0
- pcapkit/protocols/data/protocol.py +32 -0
- pcapkit/protocols/data/transport/__init__.py +71 -0
- pcapkit/protocols/data/transport/tcp.py +555 -0
- pcapkit/protocols/data/transport/udp.py +29 -0
- pcapkit/protocols/internet/NotImplemented/ecn.py +0 -0
- pcapkit/protocols/internet/NotImplemented/esp.py +97 -0
- pcapkit/protocols/internet/NotImplemented/icmp.py +0 -0
- pcapkit/protocols/internet/NotImplemented/icmpv6.py +0 -0
- pcapkit/protocols/internet/NotImplemented/igmp.py +0 -0
- pcapkit/protocols/internet/NotImplemented/shim6.py +0 -0
- pcapkit/protocols/internet/__init__.py +43 -0
- pcapkit/protocols/internet/ah.py +275 -0
- pcapkit/protocols/internet/hip.py +4727 -0
- pcapkit/protocols/internet/hopopt.py +1879 -0
- pcapkit/protocols/internet/internet.py +240 -0
- pcapkit/protocols/internet/ip.py +51 -0
- pcapkit/protocols/internet/ipsec.py +50 -0
- pcapkit/protocols/internet/ipv4.py +1782 -0
- pcapkit/protocols/internet/ipv6.py +361 -0
- pcapkit/protocols/internet/ipv6_frag.py +258 -0
- pcapkit/protocols/internet/ipv6_opts.py +1890 -0
- pcapkit/protocols/internet/ipv6_route.py +710 -0
- pcapkit/protocols/internet/ipx.py +230 -0
- pcapkit/protocols/internet/mh.py +2764 -0
- pcapkit/protocols/link/NotImplemented/dsl.py +0 -0
- pcapkit/protocols/link/NotImplemented/eapol.py +1 -0
- pcapkit/protocols/link/NotImplemented/fddi.py +0 -0
- pcapkit/protocols/link/NotImplemented/isdn.py +0 -0
- pcapkit/protocols/link/NotImplemented/ndp.py +0 -0
- pcapkit/protocols/link/NotImplemented/ppp.py +0 -0
- pcapkit/protocols/link/__init__.py +35 -0
- pcapkit/protocols/link/arp.py +421 -0
- pcapkit/protocols/link/ethernet.py +248 -0
- pcapkit/protocols/link/l2tp.py +267 -0
- pcapkit/protocols/link/link.py +140 -0
- pcapkit/protocols/link/ospf.py +342 -0
- pcapkit/protocols/link/rarp.py +82 -0
- pcapkit/protocols/link/vlan.py +225 -0
- pcapkit/protocols/misc/__init__.py +37 -0
- pcapkit/protocols/misc/null.py +129 -0
- pcapkit/protocols/misc/pcap/__init__.py +17 -0
- pcapkit/protocols/misc/pcap/frame.py +478 -0
- pcapkit/protocols/misc/pcap/header.py +358 -0
- pcapkit/protocols/misc/pcapng.py +5520 -0
- pcapkit/protocols/misc/raw.py +180 -0
- pcapkit/protocols/protocol.py +1216 -0
- pcapkit/protocols/schema/__init__.py +140 -0
- pcapkit/protocols/schema/application/__init__.py +40 -0
- pcapkit/protocols/schema/application/ftp.py +21 -0
- pcapkit/protocols/schema/application/httpv1.py +21 -0
- pcapkit/protocols/schema/application/httpv2.py +384 -0
- pcapkit/protocols/schema/internet/__init__.py +294 -0
- pcapkit/protocols/schema/internet/ah.py +40 -0
- pcapkit/protocols/schema/internet/hip.py +1184 -0
- pcapkit/protocols/schema/internet/hopopt.py +679 -0
- pcapkit/protocols/schema/internet/ipv4.py +576 -0
- pcapkit/protocols/schema/internet/ipv6.py +63 -0
- pcapkit/protocols/schema/internet/ipv6_frag.py +48 -0
- pcapkit/protocols/schema/internet/ipv6_opts.py +680 -0
- pcapkit/protocols/schema/internet/ipv6_route.py +198 -0
- pcapkit/protocols/schema/internet/ipx.py +40 -0
- pcapkit/protocols/schema/internet/mh.py +718 -0
- pcapkit/protocols/schema/link/__init__.py +19 -0
- pcapkit/protocols/schema/link/arp.py +39 -0
- pcapkit/protocols/schema/link/ethernet.py +51 -0
- pcapkit/protocols/schema/link/l2tp.py +88 -0
- pcapkit/protocols/schema/link/ospf.py +90 -0
- pcapkit/protocols/schema/link/vlan.py +69 -0
- pcapkit/protocols/schema/misc/__init__.py +108 -0
- pcapkit/protocols/schema/misc/null.py +18 -0
- pcapkit/protocols/schema/misc/pcap/__init__.py +10 -0
- pcapkit/protocols/schema/misc/pcap/frame.py +51 -0
- pcapkit/protocols/schema/misc/pcap/header.py +63 -0
- pcapkit/protocols/schema/misc/pcapng.py +1689 -0
- pcapkit/protocols/schema/misc/raw.py +24 -0
- pcapkit/protocols/schema/schema.py +809 -0
- pcapkit/protocols/schema/transport/__init__.py +69 -0
- pcapkit/protocols/schema/transport/tcp.py +928 -0
- pcapkit/protocols/schema/transport/udp.py +90 -0
- pcapkit/protocols/transport/NotImplemented/dccp.py +0 -0
- pcapkit/protocols/transport/NotImplemented/rsvp.py +0 -0
- pcapkit/protocols/transport/NotImplemented/sctp.py +0 -0
- pcapkit/protocols/transport/__init__.py +27 -0
- pcapkit/protocols/transport/tcp.py +3025 -0
- pcapkit/protocols/transport/transport.py +158 -0
- pcapkit/protocols/transport/udp.py +214 -0
- pcapkit/py.typed +0 -0
- pcapkit/toolkit/__init__.py +57 -0
- pcapkit/toolkit/dpkt.py +306 -0
- pcapkit/toolkit/pcap.py +212 -0
- pcapkit/toolkit/pcapng.py +251 -0
- pcapkit/toolkit/pyshark.py +99 -0
- pcapkit/toolkit/scapy.py +297 -0
- pcapkit/utilities/__init__.py +20 -0
- pcapkit/utilities/compat.py +196 -0
- pcapkit/utilities/decorators.py +192 -0
- pcapkit/utilities/exceptions.py +365 -0
- pcapkit/utilities/logging.py +55 -0
- pcapkit/utilities/warnings.py +185 -0
- pcapkit/vendor/__init__.py +105 -0
- pcapkit/vendor/__main__.py +92 -0
- pcapkit/vendor/arp/__init__.py +27 -0
- pcapkit/vendor/arp/hardware.py +29 -0
- pcapkit/vendor/arp/operation.py +29 -0
- pcapkit/vendor/default.py +474 -0
- pcapkit/vendor/ftp/__init__.py +27 -0
- pcapkit/vendor/ftp/command.py +244 -0
- pcapkit/vendor/ftp/return_code.py +256 -0
- pcapkit/vendor/hip/__init__.py +94 -0
- pcapkit/vendor/hip/certificate.py +29 -0
- pcapkit/vendor/hip/cipher.py +29 -0
- pcapkit/vendor/hip/di.py +29 -0
- pcapkit/vendor/hip/ecdsa_curve.py +29 -0
- pcapkit/vendor/hip/ecdsa_low_curve.py +29 -0
- pcapkit/vendor/hip/eddsa_curve.py +85 -0
- pcapkit/vendor/hip/esp_transform_suite.py +29 -0
- pcapkit/vendor/hip/group.py +87 -0
- pcapkit/vendor/hip/hi_algorithm.py +29 -0
- pcapkit/vendor/hip/hit_suite.py +29 -0
- pcapkit/vendor/hip/nat_traversal.py +29 -0
- pcapkit/vendor/hip/notify_message.py +29 -0
- pcapkit/vendor/hip/packet.py +88 -0
- pcapkit/vendor/hip/parameter.py +88 -0
- pcapkit/vendor/hip/registration.py +29 -0
- pcapkit/vendor/hip/registration_failure.py +29 -0
- pcapkit/vendor/hip/suite.py +29 -0
- pcapkit/vendor/hip/transport.py +29 -0
- pcapkit/vendor/http/__init__.py +39 -0
- pcapkit/vendor/http/error_code.py +95 -0
- pcapkit/vendor/http/frame.py +91 -0
- pcapkit/vendor/http/method.py +167 -0
- pcapkit/vendor/http/setting.py +93 -0
- pcapkit/vendor/http/status_code.py +185 -0
- pcapkit/vendor/ipv4/__init__.py +57 -0
- pcapkit/vendor/ipv4/classification_level.py +91 -0
- pcapkit/vendor/ipv4/option_class.py +80 -0
- pcapkit/vendor/ipv4/option_number.py +105 -0
- pcapkit/vendor/ipv4/protection_authority.py +84 -0
- pcapkit/vendor/ipv4/qs_function.py +78 -0
- pcapkit/vendor/ipv4/router_alert.py +93 -0
- pcapkit/vendor/ipv4/tos_del.py +78 -0
- pcapkit/vendor/ipv4/tos_ecn.py +95 -0
- pcapkit/vendor/ipv4/tos_pre.py +84 -0
- pcapkit/vendor/ipv4/tos_rel.py +78 -0
- pcapkit/vendor/ipv4/tos_thr.py +77 -0
- pcapkit/vendor/ipv4/ts_flag.py +79 -0
- pcapkit/vendor/ipv6/__init__.py +53 -0
- pcapkit/vendor/ipv6/extension_header.py +171 -0
- pcapkit/vendor/ipv6/option.py +104 -0
- pcapkit/vendor/ipv6/option_action.py +90 -0
- pcapkit/vendor/ipv6/qs_function.py +78 -0
- pcapkit/vendor/ipv6/router_alert.py +93 -0
- pcapkit/vendor/ipv6/routing.py +87 -0
- pcapkit/vendor/ipv6/seed_id.py +81 -0
- pcapkit/vendor/ipv6/smf_dpd_mode.py +78 -0
- pcapkit/vendor/ipv6/tagger_id.py +81 -0
- pcapkit/vendor/ipx/__init__.py +37 -0
- pcapkit/vendor/ipx/packet.py +123 -0
- pcapkit/vendor/ipx/socket.py +125 -0
- pcapkit/vendor/l2tp/__init__.py +21 -0
- pcapkit/vendor/l2tp/type.py +78 -0
- pcapkit/vendor/mh/__init__.py +204 -0
- pcapkit/vendor/mh/access_type.py +87 -0
- pcapkit/vendor/mh/ack_status_code.py +88 -0
- pcapkit/vendor/mh/ani_suboption.py +88 -0
- pcapkit/vendor/mh/auth_subtype.py +83 -0
- pcapkit/vendor/mh/binding_ack_flag.py +148 -0
- pcapkit/vendor/mh/binding_error.py +78 -0
- pcapkit/vendor/mh/binding_revocation.py +87 -0
- pcapkit/vendor/mh/binding_update_flag.py +147 -0
- pcapkit/vendor/mh/cga_extension.py +91 -0
- pcapkit/vendor/mh/cga_sec.py +91 -0
- pcapkit/vendor/mh/cga_type.py +74 -0
- pcapkit/vendor/mh/dhcp_support_mode.py +77 -0
- pcapkit/vendor/mh/dns_status_code.py +87 -0
- pcapkit/vendor/mh/dsmip6_tls_packet.py +87 -0
- pcapkit/vendor/mh/dsmipv6_home_address.py +87 -0
- pcapkit/vendor/mh/enumerating_algorithm.py +82 -0
- pcapkit/vendor/mh/fb_ack_status.py +87 -0
- pcapkit/vendor/mh/fb_action.py +88 -0
- pcapkit/vendor/mh/fb_indication_trigger.py +87 -0
- pcapkit/vendor/mh/fb_type.py +88 -0
- pcapkit/vendor/mh/flow_id_status.py +87 -0
- pcapkit/vendor/mh/flow_id_suboption.py +87 -0
- pcapkit/vendor/mh/handoff_type.py +87 -0
- pcapkit/vendor/mh/handover_ack_flag.py +143 -0
- pcapkit/vendor/mh/handover_ack_status.py +87 -0
- pcapkit/vendor/mh/handover_initiate_flag.py +143 -0
- pcapkit/vendor/mh/handover_initiate_status.py +87 -0
- pcapkit/vendor/mh/home_address_reply.py +87 -0
- pcapkit/vendor/mh/lla_code.py +97 -0
- pcapkit/vendor/mh/lma_mag_suboption.py +88 -0
- pcapkit/vendor/mh/mn_group_id.py +87 -0
- pcapkit/vendor/mh/mn_id_subtype.py +87 -0
- pcapkit/vendor/mh/operator_id.py +87 -0
- pcapkit/vendor/mh/option.py +83 -0
- pcapkit/vendor/mh/packet.py +82 -0
- pcapkit/vendor/mh/qos_attribute.py +87 -0
- pcapkit/vendor/mh/revocation_status_code.py +87 -0
- pcapkit/vendor/mh/revocation_trigger.py +87 -0
- pcapkit/vendor/mh/status_code.py +91 -0
- pcapkit/vendor/mh/traffic_selector.py +87 -0
- pcapkit/vendor/mh/upa_status.py +87 -0
- pcapkit/vendor/mh/upn_reason.py +87 -0
- pcapkit/vendor/ospf/__init__.py +27 -0
- pcapkit/vendor/ospf/authentication.py +29 -0
- pcapkit/vendor/ospf/packet.py +29 -0
- pcapkit/vendor/pcapng/__init__.py +51 -0
- pcapkit/vendor/pcapng/block_type.py +94 -0
- pcapkit/vendor/pcapng/filter_type.py +77 -0
- pcapkit/vendor/pcapng/hash_algorithm.py +82 -0
- pcapkit/vendor/pcapng/option_type.py +287 -0
- pcapkit/vendor/pcapng/record_type.py +81 -0
- pcapkit/vendor/pcapng/secrets_type.py +81 -0
- pcapkit/vendor/pcapng/verdict_type.py +79 -0
- pcapkit/vendor/reg/__init__.py +34 -0
- pcapkit/vendor/reg/apptype.py +338 -0
- pcapkit/vendor/reg/ethertype.py +121 -0
- pcapkit/vendor/reg/linktype.py +110 -0
- pcapkit/vendor/reg/transtype.py +111 -0
- pcapkit/vendor/tcp/__init__.py +35 -0
- pcapkit/vendor/tcp/checksum.py +80 -0
- pcapkit/vendor/tcp/flags.py +149 -0
- pcapkit/vendor/tcp/mp_tcp_option.py +90 -0
- pcapkit/vendor/tcp/option.py +103 -0
- pcapkit/vendor/vlan/__init__.py +23 -0
- pcapkit/vendor/vlan/priority_level.py +97 -0
- pypcapkit-1.3.3.post1.dist-info/LICENSE +29 -0
- pypcapkit-1.3.3.post1.dist-info/METADATA +236 -0
- pypcapkit-1.3.3.post1.dist-info/RECORD +466 -0
- pypcapkit-1.3.3.post1.dist-info/WHEEL +5 -0
- pypcapkit-1.3.3.post1.dist-info/entry_points.txt +3 -0
- pypcapkit-1.3.3.post1.dist-info/top_level.txt +1 -0
pcapkit/corekit/io.py
ADDED
@@ -0,0 +1,506 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
"""Seekable I/O Object
|
3
|
+
=========================
|
4
|
+
|
5
|
+
.. module:: pcapkit.corekit.io
|
6
|
+
|
7
|
+
:mod:`pcapkit.corekit.io` contains seekable I/O object
|
8
|
+
:class:`~pcapkit.corekit.io.SeekableReader`, which is a customised
|
9
|
+
implementation to :class:`io.BufferedReader`.
|
10
|
+
|
11
|
+
"""
|
12
|
+
import io
|
13
|
+
import tempfile
|
14
|
+
from typing import TYPE_CHECKING, cast
|
15
|
+
|
16
|
+
from pcapkit.utilities.exceptions import (SeekError, TruncateError, UnsupportedCall,
|
17
|
+
UnsupportedOperation, stacklevel)
|
18
|
+
from pcapkit.utilities.warnings import SeekWarning, warn
|
19
|
+
|
20
|
+
if TYPE_CHECKING:
|
21
|
+
from io import BytesIO, RawIOBase
|
22
|
+
from typing import IO, Iterable, Optional
|
23
|
+
|
24
|
+
from typing_extensions import Buffer
|
25
|
+
|
26
|
+
__all__ = ['SeekableReader']
|
27
|
+
|
28
|
+
|
29
|
+
class SeekableReader(io.BufferedReader):
|
30
|
+
"""Seekable buffered reader.
|
31
|
+
|
32
|
+
A buffered binary stream providing higher-level access to a readable, non seekable
|
33
|
+
:class:`~io.RawIOBase` raw binary stream. It inherits :class:`~io.BufferedIOBase`.
|
34
|
+
|
35
|
+
When reading data from this object, a larger amount of data may be requested from the
|
36
|
+
underlying raw stream, and kept in an internal buffer. The buffered data can then be returned
|
37
|
+
directly on subsequent reads.
|
38
|
+
|
39
|
+
The constructor creates a :class:`~io.BufferedReader` for the given readable ``raw`` stream and
|
40
|
+
``buffer_size``. If ``buffer_size`` is omitted, :data:`~io.DEFAULT_BUFFER_SIZE` is used.
|
41
|
+
|
42
|
+
Args:
|
43
|
+
raw: Underlying raw stream.
|
44
|
+
buffer_size: Buffer size.
|
45
|
+
buffer_save: Whether to save buffer to file.
|
46
|
+
buffer_path: Path to save buffer.
|
47
|
+
stream_closing: Whether the stream should be closed upon exiting.
|
48
|
+
|
49
|
+
"""
|
50
|
+
|
51
|
+
if TYPE_CHECKING:
|
52
|
+
#: Whether the stream should be closed upon exiting.
|
53
|
+
_closing: 'bool'
|
54
|
+
|
55
|
+
#: Whether the stream is closed.
|
56
|
+
_closed: 'bool'
|
57
|
+
#: Underlying raw stream.
|
58
|
+
_stream: 'IO[bytes]'
|
59
|
+
|
60
|
+
#: Current position of the stream.
|
61
|
+
_tell: 'int'
|
62
|
+
|
63
|
+
#: Buffer.
|
64
|
+
_buffer: 'BytesIO'
|
65
|
+
#: Buffer view.
|
66
|
+
_buffer_view: 'memoryview'
|
67
|
+
|
68
|
+
#: Buffer size.
|
69
|
+
_buffer_size: 'int'
|
70
|
+
#: Buffer start position.
|
71
|
+
_buffer_set: 'int'
|
72
|
+
#: Buffer current position.
|
73
|
+
_buffer_cur: 'int'
|
74
|
+
|
75
|
+
#: Path to save buffer.
|
76
|
+
_buffer_path: 'str'
|
77
|
+
#: File to save buffer.
|
78
|
+
_buffer_file: 'IO[bytes] | None'
|
79
|
+
|
80
|
+
@property
|
81
|
+
def closed(self) -> 'bool':
|
82
|
+
""":data:`True` if the stream is closed."""
|
83
|
+
return self._closed
|
84
|
+
|
85
|
+
@property
|
86
|
+
def raw(self) -> 'RawIOBase':
|
87
|
+
"""The underlying raw stream (a :class:`~io.RawIOBase` instance) that
|
88
|
+
:class:`~io.BufferedIOBase` deals with. This is not part of the :class:`~io.BufferedIOBase`
|
89
|
+
API and may not exist on some implementations."""
|
90
|
+
return cast('RawIOBase', self._stream)
|
91
|
+
|
92
|
+
@raw.setter
|
93
|
+
def raw(self, raw: 'RawIOBase', /) -> 'None':
|
94
|
+
raise UnsupportedCall("can't set attribute")
|
95
|
+
|
96
|
+
def __init__(self, raw: 'IO[bytes]', buffer_size: 'int' = io.DEFAULT_BUFFER_SIZE,
|
97
|
+
buffer_save: 'bool' = False, buffer_path: 'Optional[str]' = None, *,
|
98
|
+
stream_closing: 'bool' = True) -> 'None':
|
99
|
+
super().__init__(cast('RawIOBase', raw), buffer_size)
|
100
|
+
|
101
|
+
self._closed = False
|
102
|
+
self._closing = stream_closing
|
103
|
+
|
104
|
+
self._stream = raw
|
105
|
+
self._buffer = io.BytesIO(bytearray(buffer_size))
|
106
|
+
|
107
|
+
self._buffer_view = self._buffer.getbuffer()
|
108
|
+
self._buffer_size = buffer_size
|
109
|
+
|
110
|
+
if buffer_save:
|
111
|
+
if buffer_path is None:
|
112
|
+
self._buffer_file = tempfile.NamedTemporaryFile('wb', buffering=0)
|
113
|
+
self._buffer_path = self._buffer_file.name
|
114
|
+
else:
|
115
|
+
self._buffer_file = open(buffer_path, 'wb', buffering=0)
|
116
|
+
self._buffer_path = buffer_path
|
117
|
+
else:
|
118
|
+
self._buffer_file = None
|
119
|
+
self._buffer_path = ''
|
120
|
+
|
121
|
+
self._tell = self._buffer_set = self._buffer_cur = 0
|
122
|
+
|
123
|
+
def _write_buffer(self, buf: 'bytes', /) -> 'None':
|
124
|
+
if self._buffer_file is not None:
|
125
|
+
self._buffer_file.write(buf)
|
126
|
+
self._buffer_file.flush()
|
127
|
+
|
128
|
+
buf_len = len(buf)
|
129
|
+
old_ptr = self._buffer_cur
|
130
|
+
self._buffer_cur += buf_len
|
131
|
+
|
132
|
+
if self._buffer_cur > self._buffer_size:
|
133
|
+
if buf_len >= self._buffer_size:
|
134
|
+
self._buffer_view[:] = buf[-self._buffer_size:]
|
135
|
+
else:
|
136
|
+
self._buffer_view[:-buf_len] = self._buffer_view[old_ptr - (self._buffer_size - buf_len):old_ptr]
|
137
|
+
self._buffer_view[-buf_len:] = buf
|
138
|
+
|
139
|
+
self._buffer_set += self._buffer_cur - self._buffer_size
|
140
|
+
self._buffer_cur = self._buffer_size
|
141
|
+
|
142
|
+
# move the pointer to the end of the original contents
|
143
|
+
self._buffer.seek(-buf_len, io.SEEK_END)
|
144
|
+
else:
|
145
|
+
self._buffer_view[old_ptr:self._buffer_cur] = buf
|
146
|
+
|
147
|
+
def close(self) -> 'None':
|
148
|
+
"""Flush and close this stream. This method has no effect if the file is already closed.
|
149
|
+
Once the file is closed, any operation on the file (e.g. reading or writing) will raise
|
150
|
+
a :exc:`ValueError`.
|
151
|
+
|
152
|
+
As a convenience, it is allowed to call this method more than once; only the first call,
|
153
|
+
however, will have an effect.
|
154
|
+
|
155
|
+
"""
|
156
|
+
if self.closed:
|
157
|
+
return
|
158
|
+
self.flush()
|
159
|
+
|
160
|
+
if self._closing:
|
161
|
+
self._stream.close()
|
162
|
+
if self._buffer_file is not None:
|
163
|
+
self._buffer_file.close()
|
164
|
+
self._buffer.close()
|
165
|
+
|
166
|
+
self._closed = True
|
167
|
+
|
168
|
+
def fileno(self) -> 'int':
|
169
|
+
"""Return the underlying file descriptor (an integer) of the stream if it exists.
|
170
|
+
An :exc:`OSError` is raised if the IO object does not use a file descriptor."""
|
171
|
+
return self._stream.fileno()
|
172
|
+
|
173
|
+
def flush(self) -> 'None':
|
174
|
+
"""Flush the write buffers of the stream if applicable. This does nothing for
|
175
|
+
read-only and non-blocking streams."""
|
176
|
+
if self._buffer_file is not None:
|
177
|
+
self._buffer_file.flush()
|
178
|
+
self._stream.flush()
|
179
|
+
|
180
|
+
def isatty(self) -> 'bool':
|
181
|
+
"""Return :data:`True` if the stream is interactive (i.e., connected to a
|
182
|
+
terminal/tty device)."""
|
183
|
+
return self._stream.isatty()
|
184
|
+
|
185
|
+
def readable(self) -> 'bool':
|
186
|
+
"""Return :data:`True` if the stream can be read from. If :data:`False`,
|
187
|
+
:meth:`read` will raise :exc:`OSError`."""
|
188
|
+
return self._stream.readable()
|
189
|
+
|
190
|
+
def readline(self, size: 'int | None' = -1, /) -> 'bytes':
|
191
|
+
r"""Read and return one line from the stream. If ``size`` is specified, at most
|
192
|
+
``size`` bytes will be read.
|
193
|
+
|
194
|
+
The line terminator is always ``b'\n'`` for binary files; for text files, the
|
195
|
+
``newline`` argument to :func:`open` can be used to select the line
|
196
|
+
terminator(s) recognized.
|
197
|
+
|
198
|
+
"""
|
199
|
+
if size is None:
|
200
|
+
size = -1
|
201
|
+
|
202
|
+
if self._tell >= self._buffer_set + self._buffer_cur:
|
203
|
+
buf = self._stream.readline(size)
|
204
|
+
self._write_buffer(buf)
|
205
|
+
else:
|
206
|
+
if self._buffer_file is not None and self._tell < self._buffer_set:
|
207
|
+
with open(self._buffer_path, 'rb') as temp_file:
|
208
|
+
temp_file.seek(self._tell, io.SEEK_SET)
|
209
|
+
buf = temp_file.readline(size)
|
210
|
+
else:
|
211
|
+
buf = self._buffer.readline(min(size, self._buffer_cur - 1))
|
212
|
+
|
213
|
+
if not buf.endswith(b'\n') and (size_rem := size - len(buf)) > 0:
|
214
|
+
buf_tmp = self._stream.readline(size_rem)
|
215
|
+
self._write_buffer(buf_tmp)
|
216
|
+
buf += buf_tmp
|
217
|
+
|
218
|
+
self._tell += len(buf)
|
219
|
+
return buf
|
220
|
+
|
221
|
+
def readlines(self, hint: 'int' = -1, /) -> 'list[bytes]':
|
222
|
+
"""Read and return a list of lines from the stream. ``hint`` can be specified to control
|
223
|
+
the number of lines read: no more lines will be read if the total size (in
|
224
|
+
bytes/characters) of all lines so far exceeds ``hint``.
|
225
|
+
|
226
|
+
``hint`` values of ``0`` or less, as well as :obj:`None`, are treated as no hint.
|
227
|
+
|
228
|
+
Note that it's already possible to iterate on file objects using ``for line in file: ...``
|
229
|
+
without calling :meth:`file.readlines() <readlines>`.
|
230
|
+
|
231
|
+
"""
|
232
|
+
if hint is None or hint <= 0:
|
233
|
+
lines = [] # type: list[bytes]
|
234
|
+
while True:
|
235
|
+
line = self.readline()
|
236
|
+
if not line:
|
237
|
+
break
|
238
|
+
lines.append(line)
|
239
|
+
return lines
|
240
|
+
|
241
|
+
size = 0
|
242
|
+
lines = []
|
243
|
+
while size < hint:
|
244
|
+
line = self.readline(hint - size)
|
245
|
+
if not line:
|
246
|
+
break
|
247
|
+
lines.append(line)
|
248
|
+
size += len(line)
|
249
|
+
return lines
|
250
|
+
|
251
|
+
def seek(self, offset: 'int', whence: 'int' = io.SEEK_SET, /) -> 'int':
|
252
|
+
"""Change the stream position to the given byte ``offset``. ``offset`` is interpreted
|
253
|
+
relative to the position indicated by ``whence``. The default value for ``whence`` is
|
254
|
+
:data:`~io.SEEK_SET`. Values for ``whence`` are:
|
255
|
+
|
256
|
+
* :data:`~io.SEEK_SET` or ``0`` - start of the stream (the default); ``offset`` should
|
257
|
+
be zero or positive
|
258
|
+
* :data:`~io.SEEK_CUR` or ``1`` - current stream position; ``offset`` may be negative
|
259
|
+
* :data:`~io.SEEK_END` or ``2`` - end of the stream; ``offset`` is usually negative
|
260
|
+
|
261
|
+
Return the new absolute position.
|
262
|
+
|
263
|
+
"""
|
264
|
+
# NOTE: we mark the end of buffer content to the end of buffer
|
265
|
+
# so that it may trigger the IO to read more data to fill in
|
266
|
+
# the content.
|
267
|
+
buf_end = self._buffer_set + self._buffer_size
|
268
|
+
#buf_end = self._buffer_set + self._buffer_cur
|
269
|
+
|
270
|
+
if whence == io.SEEK_SET:
|
271
|
+
if offset < 0:
|
272
|
+
raise SeekError(f'negative seek value {offset}')
|
273
|
+
self._tell = offset
|
274
|
+
elif whence == io.SEEK_CUR:
|
275
|
+
self._tell += offset
|
276
|
+
elif whence == io.SEEK_END:
|
277
|
+
self._tell = buf_end + offset
|
278
|
+
else:
|
279
|
+
raise SeekError(f'invalid whence ({whence}, should be {io.SEEK_SET}, {io.SEEK_CUR} or {io.SEEK_END})')
|
280
|
+
|
281
|
+
if self._tell >= self._buffer_set:
|
282
|
+
if self._tell > buf_end:
|
283
|
+
warn(f'seek beyond the end of the buffer: {self._tell} > {buf_end}',
|
284
|
+
SeekWarning, stacklevel=stacklevel())
|
285
|
+
if self._tell > (tmp_end := self._buffer_set + self._buffer_cur):
|
286
|
+
# NOTE: if we do need to seek beyond the existing contents,
|
287
|
+
# then we'll do a quick read to make up the contents; the
|
288
|
+
# size of the read is set to be 1/4 size of the buffer or
|
289
|
+
# the size of the content to be read, whichever is larger.
|
290
|
+
# However, the length to fill must not be larger than the
|
291
|
+
# buffer size itself.
|
292
|
+
tmp_len = min(max(self._tell - tmp_end, self._buffer_size // 4), self._buffer_size)
|
293
|
+
self._tell = tmp_end
|
294
|
+
|
295
|
+
tmp_buf = self.read1(tmp_len)
|
296
|
+
self._tell = tmp_end + len(tmp_buf)
|
297
|
+
self._buffer.seek(self._tell - self._buffer_set, io.SEEK_SET)
|
298
|
+
else:
|
299
|
+
if self._buffer_file is None:
|
300
|
+
raise SeekError(f'cannot seek before the beginning of the buffer: {self._tell} < {self._buffer_set}')
|
301
|
+
self._buffer.seek(0, io.SEEK_SET)
|
302
|
+
return self._tell
|
303
|
+
|
304
|
+
def seekable(self) -> 'bool':
|
305
|
+
"""Return :data:`True` if the stream supports random access. If :data:`False`,
|
306
|
+
:meth:`seek`, :meth:`tell` and :meth:`truncate` will raise :exc:`OSError`."""
|
307
|
+
return True
|
308
|
+
|
309
|
+
def tell(self) -> 'int':
|
310
|
+
"""Return the current stream position."""
|
311
|
+
return self._tell
|
312
|
+
|
313
|
+
def truncate(self, size: 'int | None' = None, /) -> 'int':
|
314
|
+
"""Resize the stream to the given ``size`` in bytes (or the current position if ``size`` is
|
315
|
+
not specified). The current stream position isn't changed. This resizing can extend or
|
316
|
+
reduce the current file size. In case of extension, the contents of the new file area
|
317
|
+
depend on the platform (on most systems, additional bytes are zero-filled). The new file
|
318
|
+
size is returned."""
|
319
|
+
if size is None:
|
320
|
+
size = 0
|
321
|
+
if size < 0:
|
322
|
+
raise TruncateError(f'negative size value {size}')
|
323
|
+
self._buffer_view.release()
|
324
|
+
|
325
|
+
if size > self._buffer_size:
|
326
|
+
self._buffer = io.BytesIO(self._buffer.getvalue().zfill(size - self._buffer_size))
|
327
|
+
self._buffer_view = self._buffer.getbuffer()
|
328
|
+
else:
|
329
|
+
# keep the last ``size`` bytes
|
330
|
+
temp = self._buffer.getvalue()
|
331
|
+
|
332
|
+
self._buffer.truncate(size)
|
333
|
+
self._buffer_view = self._buffer.getbuffer()
|
334
|
+
|
335
|
+
self._buffer_view[:] = temp[-size:]
|
336
|
+
|
337
|
+
self._buffer_size = size
|
338
|
+
return self._buffer_size
|
339
|
+
|
340
|
+
def writeable(self) -> 'bool':
|
341
|
+
"""Return :obj:`True` if the stream supports writing. If :obj:`False`, :meth:`write` and
|
342
|
+
:meth:`truncate` will raise :exc:`OSError`."""
|
343
|
+
return False
|
344
|
+
|
345
|
+
def writelines(self, lines: 'Iterable[Buffer]', /) -> 'None':
|
346
|
+
"""Write a list of lines to the stream. Line separators are not added, so it is usual for
|
347
|
+
each of the lines provided to have a line separator at the end."""
|
348
|
+
raise UnsupportedOperation('write')
|
349
|
+
|
350
|
+
def detach(self) -> 'RawIOBase':
|
351
|
+
"""Separate the underlying raw stream from the buffer and return it.
|
352
|
+
|
353
|
+
After the raw stream has been detached, the buffer is in an unusable state.
|
354
|
+
|
355
|
+
Some buffers, like :class:`~io.BytesIO`, do not have the concept of a single raw stream to
|
356
|
+
return from this method. They raise :exc:`~io.UnsupportedOperation`.
|
357
|
+
|
358
|
+
"""
|
359
|
+
if hasattr(self._stream, 'detach'):
|
360
|
+
return self._stream.detach()
|
361
|
+
raise UnsupportedOperation('detach')
|
362
|
+
|
363
|
+
def read(self, size: 'int | None' = -1, /) -> 'bytes':
|
364
|
+
"""Read and return ``size`` bytes, or if ``size`` is not given or negative, until EOF or if
|
365
|
+
the read call would block in non-blocking mode."""
|
366
|
+
if size is None or size < 0:
|
367
|
+
size = -1
|
368
|
+
|
369
|
+
if self._tell >= self._buffer_set + self._buffer_cur:
|
370
|
+
buf = self._stream.read(size)
|
371
|
+
self._write_buffer(buf)
|
372
|
+
else:
|
373
|
+
if self._buffer_file is not None and self._tell < self._buffer_set:
|
374
|
+
with open(self._buffer_path, 'rb') as temp_file:
|
375
|
+
temp_file.seek(self._tell, io.SEEK_SET)
|
376
|
+
buf = temp_file.read(size)
|
377
|
+
else:
|
378
|
+
buf = self._buffer.read(min(size, self._buffer_cur - 1))
|
379
|
+
|
380
|
+
size_rem = -1
|
381
|
+
if size < 0 or (size_rem := size - len(buf)) > 0:
|
382
|
+
buf_tmp = self._stream.read(size_rem)
|
383
|
+
self._write_buffer(buf_tmp)
|
384
|
+
buf += buf_tmp
|
385
|
+
|
386
|
+
self._tell += len(buf)
|
387
|
+
return buf
|
388
|
+
|
389
|
+
def read1(self, size: 'int | None' = -1, /) -> 'bytes':
|
390
|
+
"""Read and return up to ``size`` bytes with only one call on the raw stream. If at least
|
391
|
+
one byte is buffered, only buffered bytes are returned. Otherwise, one raw stream read call
|
392
|
+
is made."""
|
393
|
+
if size is None:
|
394
|
+
size = -1
|
395
|
+
|
396
|
+
if self._tell >= self._buffer_set + self._buffer_cur:
|
397
|
+
if hasattr(self._stream, 'read1'):
|
398
|
+
buf = self._stream.read1(size)
|
399
|
+
else:
|
400
|
+
buf = self._stream.read(size)
|
401
|
+
self._write_buffer(buf)
|
402
|
+
else:
|
403
|
+
if self._buffer_file is not None and self._tell < self._buffer_set:
|
404
|
+
with open(self._buffer_path, 'rb') as temp_file:
|
405
|
+
temp_file.seek(self._tell, io.SEEK_SET)
|
406
|
+
buf = temp_file.read1(size)
|
407
|
+
else:
|
408
|
+
buf = self._buffer.read1(min(size, self._buffer_cur - 1))
|
409
|
+
|
410
|
+
if not buf: # only if the buffer is empty
|
411
|
+
size_rem = -1
|
412
|
+
if size < 0 or (size_rem := size - len(buf)) > 0:
|
413
|
+
if hasattr(self._stream, 'read1'):
|
414
|
+
buf_tmp = self._stream.read1(size_rem)
|
415
|
+
else:
|
416
|
+
buf_tmp = self._stream.read(size_rem)
|
417
|
+
self._write_buffer(buf_tmp)
|
418
|
+
buf += buf_tmp
|
419
|
+
|
420
|
+
self._tell += len(buf)
|
421
|
+
return buf
|
422
|
+
|
423
|
+
def readinto(self, b: 'Buffer', /) -> 'int':
|
424
|
+
"""Read bytes into a pre-allocated, writable :term:`bytes-like object` ``b`` and return the
|
425
|
+
number of bytes read. For example, ``b`` might be a :obj:`bytearray`.
|
426
|
+
|
427
|
+
Like :meth:`read`, multiple reads may be issued to the underlying raw stream, unless the
|
428
|
+
latter is interactive.
|
429
|
+
|
430
|
+
A :exc:`BlockingIOError` is raised if the underlying raw stream is in non blocking-mode,
|
431
|
+
and has no data available at the moment.
|
432
|
+
|
433
|
+
"""
|
434
|
+
if TYPE_CHECKING:
|
435
|
+
b = cast('memoryview', b)
|
436
|
+
|
437
|
+
buf = self.read(len(b))
|
438
|
+
buf_len = len(buf)
|
439
|
+
|
440
|
+
b[:buf_len] = buf
|
441
|
+
return buf_len
|
442
|
+
|
443
|
+
def readinto1(self, b: 'Buffer', /) -> 'int':
|
444
|
+
"""Read bytes into a pre-allocated, writable :term:`bytes-like object` ``b``, using at most
|
445
|
+
one call to the underlying raw stream's :meth:`read` (or :meth:`readinto`) method. Return
|
446
|
+
the number of bytes read.
|
447
|
+
|
448
|
+
A :exc:`BlockingIOError` is raised if the underlying raw stream is in non blocking-mode,
|
449
|
+
and has no data available at the moment.
|
450
|
+
|
451
|
+
"""
|
452
|
+
if TYPE_CHECKING:
|
453
|
+
b = cast('memoryview', b)
|
454
|
+
|
455
|
+
buf = self.read1(len(b))
|
456
|
+
buf_len = len(buf)
|
457
|
+
|
458
|
+
b[:buf_len] = buf
|
459
|
+
return buf_len
|
460
|
+
|
461
|
+
def write(self, b: 'Buffer', /) -> 'int':
|
462
|
+
"""Write the given :term:`bytes-like object`, ``b``, and return the number of bytes written
|
463
|
+
(always equal to the length of ``b`` in bytes, since if the write fails an :exc:`OSError`
|
464
|
+
will be raised). Depending on the actual implementation, these bytes may be readily written
|
465
|
+
to the underlying stream, or held in a buffer for performance and latency reasons.
|
466
|
+
|
467
|
+
When in non-blocking mode, a :exc:`BlockingIOError` is raised if the data needed to be
|
468
|
+
written to the raw stream but it couldn't accept all the data without blocking.
|
469
|
+
|
470
|
+
The caller may release or mutate ``b`` after this method returns, so the implementation
|
471
|
+
should only access ``b`` during the method call.
|
472
|
+
|
473
|
+
"""
|
474
|
+
raise UnsupportedOperation('write')
|
475
|
+
|
476
|
+
def peek(self, size: 'int' = 0) -> 'bytes':
|
477
|
+
"""Return bytes from the stream without advancing the position.
|
478
|
+
|
479
|
+
At most one single read on the raw stream is done to satisfy the call.
|
480
|
+
The number of bytes returned may be less or more than requested.
|
481
|
+
|
482
|
+
"""
|
483
|
+
if self._tell >= self._buffer_set + self._buffer_cur:
|
484
|
+
if hasattr(self._stream, 'peek'):
|
485
|
+
buf = self._stream.peek(size)
|
486
|
+
else:
|
487
|
+
buf = self._stream.read(size)
|
488
|
+
self._write_buffer(buf)
|
489
|
+
else:
|
490
|
+
if self._buffer_file is not None and self._tell < self._buffer_set:
|
491
|
+
with open(self._buffer_path, 'rb') as temp_file:
|
492
|
+
temp_file.seek(self._tell, io.SEEK_SET)
|
493
|
+
buf = temp_file.peek(size)
|
494
|
+
else:
|
495
|
+
buf = self._buffer.read(min(size, self._buffer_cur - 1))
|
496
|
+
|
497
|
+
if not buf and len(buf) < size: # only if the buffer is empty and/or not enough
|
498
|
+
size_rem = -1
|
499
|
+
if size < 0 or (size_rem := size - len(buf)) > 0:
|
500
|
+
if hasattr(self._stream, 'peek'):
|
501
|
+
buf_tmp = self._stream.peek(size_rem)
|
502
|
+
else:
|
503
|
+
buf_tmp = self._stream.read(size_rem)
|
504
|
+
self._write_buffer(buf_tmp)
|
505
|
+
buf += buf_tmp
|
506
|
+
return buf
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
"""Module Descriptor
|
3
|
+
=======================
|
4
|
+
|
5
|
+
.. module:: pcapkit.corekit.module
|
6
|
+
|
7
|
+
:mod:`pcapkit.corekit.module` contains :obj:`tuple`
|
8
|
+
like class :class:`~pcapkit.corekit.module.ModuleDescriptor`,
|
9
|
+
which is originally designed as :obj:`tuple[str, str] <tuple>`.
|
10
|
+
|
11
|
+
"""
|
12
|
+
import collections
|
13
|
+
import importlib
|
14
|
+
from typing import TYPE_CHECKING, Generic, TypeVar
|
15
|
+
|
16
|
+
__all__ = ['ModuleDescriptor']
|
17
|
+
|
18
|
+
if TYPE_CHECKING:
|
19
|
+
from typing import Type
|
20
|
+
|
21
|
+
_T = TypeVar('_T')
|
22
|
+
|
23
|
+
|
24
|
+
class ModuleDescriptor(collections.namedtuple('ModuleDescriptor', ['module', 'name']), Generic[_T]):
|
25
|
+
"""Module descriptor contains module name and class name, the actual
|
26
|
+
class can be imported by ``from module import name``."""
|
27
|
+
|
28
|
+
__slots__ = ()
|
29
|
+
|
30
|
+
#: Module name.
|
31
|
+
module: str
|
32
|
+
#: Class name.
|
33
|
+
name: str
|
34
|
+
|
35
|
+
@property
|
36
|
+
def klass(self) -> 'Type[_T]':
|
37
|
+
"""Import class from module."""
|
38
|
+
module = importlib.import_module(self.module)
|
39
|
+
return getattr(module, self.name)
|