polyfile-weave 0.5.5__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.

Potentially problematic release.


This version of polyfile-weave might be problematic. Click here for more details.

Files changed (585) hide show
  1. polyfile/__init__.py +15 -0
  2. polyfile/__main__.py +394 -0
  3. polyfile/arithmetic.py +27 -0
  4. polyfile/ast.py +114 -0
  5. polyfile/debugger.py +1039 -0
  6. polyfile/expressions.py +346 -0
  7. polyfile/fileutils.py +343 -0
  8. polyfile/html.py +135 -0
  9. polyfile/http/__init__.py +1 -0
  10. polyfile/http/defacto.py +37 -0
  11. polyfile/http/deprecated.py +51 -0
  12. polyfile/http/experimental.py +67 -0
  13. polyfile/http/http_11.py +548 -0
  14. polyfile/http/matcher.py +37 -0
  15. polyfile/http/structured_headers.py +48 -0
  16. polyfile/iterators.py +72 -0
  17. polyfile/jpeg.py +24 -0
  18. polyfile/kaitai/__init__.py +0 -0
  19. polyfile/kaitai/compiler.py +156 -0
  20. polyfile/kaitai/parser.py +312 -0
  21. polyfile/kaitai/parsers/__init__.py +0 -0
  22. polyfile/kaitai/parsers/aix_utmp.py +116 -0
  23. polyfile/kaitai/parsers/allegro_dat.py +367 -0
  24. polyfile/kaitai/parsers/andes_firmware.py +64 -0
  25. polyfile/kaitai/parsers/android_bootldr_asus.py +105 -0
  26. polyfile/kaitai/parsers/android_bootldr_huawei.py +181 -0
  27. polyfile/kaitai/parsers/android_bootldr_qcom.py +217 -0
  28. polyfile/kaitai/parsers/android_dto.py +138 -0
  29. polyfile/kaitai/parsers/android_img.py +319 -0
  30. polyfile/kaitai/parsers/android_nanoapp_header.py +83 -0
  31. polyfile/kaitai/parsers/android_opengl_shaders_cache.py +151 -0
  32. polyfile/kaitai/parsers/android_sparse.py +237 -0
  33. polyfile/kaitai/parsers/android_super.py +401 -0
  34. polyfile/kaitai/parsers/apm_partition_table.py +196 -0
  35. polyfile/kaitai/parsers/apple_single_double.py +180 -0
  36. polyfile/kaitai/parsers/asn1_der.py +235 -0
  37. polyfile/kaitai/parsers/au.py +138 -0
  38. polyfile/kaitai/parsers/avantes_roh60.py +112 -0
  39. polyfile/kaitai/parsers/avi.py +296 -0
  40. polyfile/kaitai/parsers/bcd.py +111 -0
  41. polyfile/kaitai/parsers/bitcoin_transaction.py +210 -0
  42. polyfile/kaitai/parsers/blender_blend.py +334 -0
  43. polyfile/kaitai/parsers/bmp.py +780 -0
  44. polyfile/kaitai/parsers/bson.py +411 -0
  45. polyfile/kaitai/parsers/btrfs_stream.py +318 -0
  46. polyfile/kaitai/parsers/bytes_with_io.py +27 -0
  47. polyfile/kaitai/parsers/chrome_pak.py +194 -0
  48. polyfile/kaitai/parsers/code_6502.py +456 -0
  49. polyfile/kaitai/parsers/compressed_resource.py +217 -0
  50. polyfile/kaitai/parsers/cpio_old_le.py +154 -0
  51. polyfile/kaitai/parsers/cramfs.py +344 -0
  52. polyfile/kaitai/parsers/creative_voice_file.py +342 -0
  53. polyfile/kaitai/parsers/dbf.py +274 -0
  54. polyfile/kaitai/parsers/dcmp_0.py +664 -0
  55. polyfile/kaitai/parsers/dcmp_1.py +422 -0
  56. polyfile/kaitai/parsers/dcmp_2.py +312 -0
  57. polyfile/kaitai/parsers/dcmp_variable_length_integer.py +66 -0
  58. polyfile/kaitai/parsers/dex.py +1086 -0
  59. polyfile/kaitai/parsers/dicom.py +4370 -0
  60. polyfile/kaitai/parsers/dime_message.py +201 -0
  61. polyfile/kaitai/parsers/dns_packet.py +569 -0
  62. polyfile/kaitai/parsers/doom_wad.py +654 -0
  63. polyfile/kaitai/parsers/dos_datetime.py +191 -0
  64. polyfile/kaitai/parsers/dos_mz.py +172 -0
  65. polyfile/kaitai/parsers/ds_store.py +513 -0
  66. polyfile/kaitai/parsers/dtb.py +310 -0
  67. polyfile/kaitai/parsers/dune_2_pak.py +126 -0
  68. polyfile/kaitai/parsers/edid.py +472 -0
  69. polyfile/kaitai/parsers/efivar_signature_list.py +331 -0
  70. polyfile/kaitai/parsers/elf.py +2482 -0
  71. polyfile/kaitai/parsers/ethernet_frame.py +114 -0
  72. polyfile/kaitai/parsers/exif.py +723 -0
  73. polyfile/kaitai/parsers/ext2.py +537 -0
  74. polyfile/kaitai/parsers/fallout2_dat.py +187 -0
  75. polyfile/kaitai/parsers/fallout_dat.py +156 -0
  76. polyfile/kaitai/parsers/fasttracker_xm_module.py +558 -0
  77. polyfile/kaitai/parsers/ftl_dat.py +90 -0
  78. polyfile/kaitai/parsers/genmidi_op2.py +161 -0
  79. polyfile/kaitai/parsers/gettext_mo.py +541 -0
  80. polyfile/kaitai/parsers/gif.py +492 -0
  81. polyfile/kaitai/parsers/gimp_brush.py +244 -0
  82. polyfile/kaitai/parsers/glibc_utmp.py +114 -0
  83. polyfile/kaitai/parsers/gltf_binary.py +132 -0
  84. polyfile/kaitai/parsers/google_protobuf.py +151 -0
  85. polyfile/kaitai/parsers/gpt_partition_table.py +175 -0
  86. polyfile/kaitai/parsers/gran_turismo_vol.py +140 -0
  87. polyfile/kaitai/parsers/grub2_font.py +337 -0
  88. polyfile/kaitai/parsers/gzip.py +232 -0
  89. polyfile/kaitai/parsers/hashcat_restore.py +60 -0
  90. polyfile/kaitai/parsers/hccap.py +111 -0
  91. polyfile/kaitai/parsers/hccapx.py +103 -0
  92. polyfile/kaitai/parsers/heaps_pak.py +177 -0
  93. polyfile/kaitai/parsers/heroes_of_might_and_magic_agg.py +116 -0
  94. polyfile/kaitai/parsers/heroes_of_might_and_magic_bmp.py +34 -0
  95. polyfile/kaitai/parsers/icmp_packet.py +136 -0
  96. polyfile/kaitai/parsers/ico.py +129 -0
  97. polyfile/kaitai/parsers/id3v1_1.py +220 -0
  98. polyfile/kaitai/parsers/id3v2_3.py +324 -0
  99. polyfile/kaitai/parsers/id3v2_4.py +423 -0
  100. polyfile/kaitai/parsers/ines.py +282 -0
  101. polyfile/kaitai/parsers/ipv4_packet.py +158 -0
  102. polyfile/kaitai/parsers/ipv6_packet.py +55 -0
  103. polyfile/kaitai/parsers/iso9660.py +544 -0
  104. polyfile/kaitai/parsers/java_class.py +1113 -0
  105. polyfile/kaitai/parsers/jpeg.py +361 -0
  106. polyfile/kaitai/parsers/luks.py +149 -0
  107. polyfile/kaitai/parsers/lzh.py +165 -0
  108. polyfile/kaitai/parsers/mac_os_resource_snd.py +493 -0
  109. polyfile/kaitai/parsers/mach_o.py +3033 -0
  110. polyfile/kaitai/parsers/mach_o_fat.py +92 -0
  111. polyfile/kaitai/parsers/magicavoxel_vox.py +391 -0
  112. polyfile/kaitai/parsers/manifest.json +1 -0
  113. polyfile/kaitai/parsers/mbr_partition_table.py +119 -0
  114. polyfile/kaitai/parsers/mcap.py +1015 -0
  115. polyfile/kaitai/parsers/microsoft_cfb.py +293 -0
  116. polyfile/kaitai/parsers/microsoft_network_monitor_v2.py +309 -0
  117. polyfile/kaitai/parsers/microsoft_pe.py +765 -0
  118. polyfile/kaitai/parsers/mifare_classic.py +706 -0
  119. polyfile/kaitai/parsers/minecraft_nbt.py +449 -0
  120. polyfile/kaitai/parsers/monomakh_sapr_chg.py +69 -0
  121. polyfile/kaitai/parsers/mozilla_mar.py +239 -0
  122. polyfile/kaitai/parsers/mp4.py +333 -0
  123. polyfile/kaitai/parsers/msgpack.py +467 -0
  124. polyfile/kaitai/parsers/nitf.py +1189 -0
  125. polyfile/kaitai/parsers/nt_mdt_pal.py +155 -0
  126. polyfile/kaitai/parsers/ogg.py +118 -0
  127. polyfile/kaitai/parsers/openpgp_message.py +993 -0
  128. polyfile/kaitai/parsers/packet_ppi.py +515 -0
  129. polyfile/kaitai/parsers/pcap.py +344 -0
  130. polyfile/kaitai/parsers/pcf_font.py +506 -0
  131. polyfile/kaitai/parsers/pcx.py +195 -0
  132. polyfile/kaitai/parsers/pcx_dcx.py +79 -0
  133. polyfile/kaitai/parsers/phar_without_stub.py +399 -0
  134. polyfile/kaitai/parsers/php_serialized_value.py +505 -0
  135. polyfile/kaitai/parsers/png.py +721 -0
  136. polyfile/kaitai/parsers/protocol_body.py +260 -0
  137. polyfile/kaitai/parsers/psx_tim.py +104 -0
  138. polyfile/kaitai/parsers/python_pickle.py +718 -0
  139. polyfile/kaitai/parsers/python_pyc_27.py +510 -0
  140. polyfile/kaitai/parsers/quake_mdl.py +441 -0
  141. polyfile/kaitai/parsers/quake_pak.py +112 -0
  142. polyfile/kaitai/parsers/quicktime_mov.py +634 -0
  143. polyfile/kaitai/parsers/rar.py +265 -0
  144. polyfile/kaitai/parsers/regf.py +569 -0
  145. polyfile/kaitai/parsers/renderware_binary_stream.py +877 -0
  146. polyfile/kaitai/parsers/resource_fork.py +611 -0
  147. polyfile/kaitai/parsers/respack.py +57 -0
  148. polyfile/kaitai/parsers/riff.py +409 -0
  149. polyfile/kaitai/parsers/rpm.py +964 -0
  150. polyfile/kaitai/parsers/rtcp_payload.py +579 -0
  151. polyfile/kaitai/parsers/rtp_packet.py +150 -0
  152. polyfile/kaitai/parsers/rtpdump.py +115 -0
  153. polyfile/kaitai/parsers/ruby_marshal.py +423 -0
  154. polyfile/kaitai/parsers/s3m.py +493 -0
  155. polyfile/kaitai/parsers/saints_row_2_vpp_pc.py +254 -0
  156. polyfile/kaitai/parsers/shapefile_index.py +174 -0
  157. polyfile/kaitai/parsers/shapefile_main.py +893 -0
  158. polyfile/kaitai/parsers/some_ip.py +209 -0
  159. polyfile/kaitai/parsers/some_ip_container.py +37 -0
  160. polyfile/kaitai/parsers/some_ip_sd.py +86 -0
  161. polyfile/kaitai/parsers/some_ip_sd_entries.py +160 -0
  162. polyfile/kaitai/parsers/some_ip_sd_options.py +374 -0
  163. polyfile/kaitai/parsers/specpr.py +404 -0
  164. polyfile/kaitai/parsers/sqlite3.py +472 -0
  165. polyfile/kaitai/parsers/ssh_public_key.py +252 -0
  166. polyfile/kaitai/parsers/standard_midi_file.py +390 -0
  167. polyfile/kaitai/parsers/stl.py +111 -0
  168. polyfile/kaitai/parsers/sudoers_ts.py +201 -0
  169. polyfile/kaitai/parsers/swf.py +406 -0
  170. polyfile/kaitai/parsers/systemd_journal.py +361 -0
  171. polyfile/kaitai/parsers/tcp_segment.py +57 -0
  172. polyfile/kaitai/parsers/tga.py +213 -0
  173. polyfile/kaitai/parsers/tls_client_hello.py +293 -0
  174. polyfile/kaitai/parsers/tr_dos_image.py +322 -0
  175. polyfile/kaitai/parsers/tsm.py +198 -0
  176. polyfile/kaitai/parsers/ttf.py +1847 -0
  177. polyfile/kaitai/parsers/udp_datagram.py +42 -0
  178. polyfile/kaitai/parsers/uefi_te.py +236 -0
  179. polyfile/kaitai/parsers/uimage.py +198 -0
  180. polyfile/kaitai/parsers/utf8_string.py +137 -0
  181. polyfile/kaitai/parsers/vfat.py +410 -0
  182. polyfile/kaitai/parsers/vlq_base128_be.py +104 -0
  183. polyfile/kaitai/parsers/vlq_base128_le.py +129 -0
  184. polyfile/kaitai/parsers/vmware_vmdk.py +167 -0
  185. polyfile/kaitai/parsers/vp8_ivf.py +112 -0
  186. polyfile/kaitai/parsers/warcraft_2_pud.py +423 -0
  187. polyfile/kaitai/parsers/wav.py +1014 -0
  188. polyfile/kaitai/parsers/websocket.py +167 -0
  189. polyfile/kaitai/parsers/windows_evt_log.py +304 -0
  190. polyfile/kaitai/parsers/windows_lnk_file.py +467 -0
  191. polyfile/kaitai/parsers/windows_minidump.py +575 -0
  192. polyfile/kaitai/parsers/windows_resource_file.py +243 -0
  193. polyfile/kaitai/parsers/windows_shell_items.py +190 -0
  194. polyfile/kaitai/parsers/windows_systemtime.py +52 -0
  195. polyfile/kaitai/parsers/wmf.py +502 -0
  196. polyfile/kaitai/parsers/xar.py +181 -0
  197. polyfile/kaitai/parsers/xwd.py +189 -0
  198. polyfile/kaitai/parsers/zip.py +685 -0
  199. polyfile/kaitai/parsers/zisofs.py +158 -0
  200. polyfile/kaitai/parsers/zx_spectrum_tap.py +184 -0
  201. polyfile/kaitaimatcher.py +113 -0
  202. polyfile/languagematcher.py +217 -0
  203. polyfile/logger.py +135 -0
  204. polyfile/magic.py +2983 -0
  205. polyfile/magic_defs/COPYING +29 -0
  206. polyfile/magic_defs/__init__.py +0 -0
  207. polyfile/magic_defs/acorn +102 -0
  208. polyfile/magic_defs/adi +13 -0
  209. polyfile/magic_defs/adventure +122 -0
  210. polyfile/magic_defs/aes +29 -0
  211. polyfile/magic_defs/algol68 +35 -0
  212. polyfile/magic_defs/allegro +9 -0
  213. polyfile/magic_defs/alliant +18 -0
  214. polyfile/magic_defs/alpha +32 -0
  215. polyfile/magic_defs/amanda +12 -0
  216. polyfile/magic_defs/amigaos +218 -0
  217. polyfile/magic_defs/android +259 -0
  218. polyfile/magic_defs/animation +1197 -0
  219. polyfile/magic_defs/aout +46 -0
  220. polyfile/magic_defs/apache +28 -0
  221. polyfile/magic_defs/apl +7 -0
  222. polyfile/magic_defs/apple +773 -0
  223. polyfile/magic_defs/application +7 -0
  224. polyfile/magic_defs/applix +13 -0
  225. polyfile/magic_defs/apt +52 -0
  226. polyfile/magic_defs/archive +2586 -0
  227. polyfile/magic_defs/aria +38 -0
  228. polyfile/magic_defs/arm +50 -0
  229. polyfile/magic_defs/asf +132 -0
  230. polyfile/magic_defs/assembler +18 -0
  231. polyfile/magic_defs/asterix +18 -0
  232. polyfile/magic_defs/att3b +41 -0
  233. polyfile/magic_defs/audio +1291 -0
  234. polyfile/magic_defs/avm +33 -0
  235. polyfile/magic_defs/basis +18 -0
  236. polyfile/magic_defs/beetle +7 -0
  237. polyfile/magic_defs/ber +65 -0
  238. polyfile/magic_defs/bflt +14 -0
  239. polyfile/magic_defs/bhl +10 -0
  240. polyfile/magic_defs/bioinformatics +178 -0
  241. polyfile/magic_defs/biosig +154 -0
  242. polyfile/magic_defs/blackberry +8 -0
  243. polyfile/magic_defs/blcr +25 -0
  244. polyfile/magic_defs/blender +50 -0
  245. polyfile/magic_defs/blit +24 -0
  246. polyfile/magic_defs/bm +10 -0
  247. polyfile/magic_defs/bout +11 -0
  248. polyfile/magic_defs/bsdi +33 -0
  249. polyfile/magic_defs/bsi +10 -0
  250. polyfile/magic_defs/btsnoop +13 -0
  251. polyfile/magic_defs/burp +7 -0
  252. polyfile/magic_defs/bytecode +41 -0
  253. polyfile/magic_defs/c-lang +110 -0
  254. polyfile/magic_defs/c64 +531 -0
  255. polyfile/magic_defs/cad +437 -0
  256. polyfile/magic_defs/cafebabe +107 -0
  257. polyfile/magic_defs/cbor +21 -0
  258. polyfile/magic_defs/ccf +14 -0
  259. polyfile/magic_defs/cddb +12 -0
  260. polyfile/magic_defs/chord +15 -0
  261. polyfile/magic_defs/cisco +12 -0
  262. polyfile/magic_defs/citrus +12 -0
  263. polyfile/magic_defs/clarion +27 -0
  264. polyfile/magic_defs/claris +48 -0
  265. polyfile/magic_defs/clipper +65 -0
  266. polyfile/magic_defs/clojure +30 -0
  267. polyfile/magic_defs/coff +98 -0
  268. polyfile/magic_defs/commands +201 -0
  269. polyfile/magic_defs/communications +22 -0
  270. polyfile/magic_defs/compress +461 -0
  271. polyfile/magic_defs/console +1213 -0
  272. polyfile/magic_defs/convex +69 -0
  273. polyfile/magic_defs/coverage +91 -0
  274. polyfile/magic_defs/cracklib +14 -0
  275. polyfile/magic_defs/crypto +31 -0
  276. polyfile/magic_defs/csv +8 -0
  277. polyfile/magic_defs/ctags +6 -0
  278. polyfile/magic_defs/ctf +23 -0
  279. polyfile/magic_defs/cubemap +8 -0
  280. polyfile/magic_defs/cups +56 -0
  281. polyfile/magic_defs/dact +11 -0
  282. polyfile/magic_defs/database +886 -0
  283. polyfile/magic_defs/dataone +47 -0
  284. polyfile/magic_defs/dbpf +15 -0
  285. polyfile/magic_defs/der +146 -0
  286. polyfile/magic_defs/diamond +12 -0
  287. polyfile/magic_defs/dif +33 -0
  288. polyfile/magic_defs/diff +41 -0
  289. polyfile/magic_defs/digital +59 -0
  290. polyfile/magic_defs/dolby +69 -0
  291. polyfile/magic_defs/dsf +25 -0
  292. polyfile/magic_defs/dump +96 -0
  293. polyfile/magic_defs/dwarfs +45 -0
  294. polyfile/magic_defs/dyadic +61 -0
  295. polyfile/magic_defs/ebml +8 -0
  296. polyfile/magic_defs/edid +11 -0
  297. polyfile/magic_defs/editors +43 -0
  298. polyfile/magic_defs/efi +15 -0
  299. polyfile/magic_defs/elf +379 -0
  300. polyfile/magic_defs/encore +22 -0
  301. polyfile/magic_defs/epoc +62 -0
  302. polyfile/magic_defs/erlang +21 -0
  303. polyfile/magic_defs/espressif +57 -0
  304. polyfile/magic_defs/esri +28 -0
  305. polyfile/magic_defs/etf +33 -0
  306. polyfile/magic_defs/fcs +9 -0
  307. polyfile/magic_defs/filesystems +2694 -0
  308. polyfile/magic_defs/finger +16 -0
  309. polyfile/magic_defs/firmware +133 -0
  310. polyfile/magic_defs/flash +62 -0
  311. polyfile/magic_defs/flif +36 -0
  312. polyfile/magic_defs/fonts +449 -0
  313. polyfile/magic_defs/forth +82 -0
  314. polyfile/magic_defs/fortran +9 -0
  315. polyfile/magic_defs/frame +62 -0
  316. polyfile/magic_defs/freebsd +164 -0
  317. polyfile/magic_defs/fsav +128 -0
  318. polyfile/magic_defs/fusecompress +12 -0
  319. polyfile/magic_defs/games +696 -0
  320. polyfile/magic_defs/gcc +17 -0
  321. polyfile/magic_defs/gconv +10 -0
  322. polyfile/magic_defs/gentoo +85 -0
  323. polyfile/magic_defs/geo +166 -0
  324. polyfile/magic_defs/geos +20 -0
  325. polyfile/magic_defs/gimp +77 -0
  326. polyfile/magic_defs/git +13 -0
  327. polyfile/magic_defs/glibc +21 -0
  328. polyfile/magic_defs/gnome +59 -0
  329. polyfile/magic_defs/gnu +173 -0
  330. polyfile/magic_defs/gnumeric +8 -0
  331. polyfile/magic_defs/gpt +240 -0
  332. polyfile/magic_defs/gpu +28 -0
  333. polyfile/magic_defs/grace +21 -0
  334. polyfile/magic_defs/graphviz +12 -0
  335. polyfile/magic_defs/gringotts +48 -0
  336. polyfile/magic_defs/guile +13 -0
  337. polyfile/magic_defs/hardware +12 -0
  338. polyfile/magic_defs/hitachi-sh +30 -0
  339. polyfile/magic_defs/hp +433 -0
  340. polyfile/magic_defs/human68k +26 -0
  341. polyfile/magic_defs/ibm370 +52 -0
  342. polyfile/magic_defs/ibm6000 +35 -0
  343. polyfile/magic_defs/icc +214 -0
  344. polyfile/magic_defs/iff +80 -0
  345. polyfile/magic_defs/images +4210 -0
  346. polyfile/magic_defs/inform +9 -0
  347. polyfile/magic_defs/intel +310 -0
  348. polyfile/magic_defs/interleaf +9 -0
  349. polyfile/magic_defs/island +10 -0
  350. polyfile/magic_defs/ispell +63 -0
  351. polyfile/magic_defs/isz +15 -0
  352. polyfile/magic_defs/java +52 -0
  353. polyfile/magic_defs/javascript +171 -0
  354. polyfile/magic_defs/jpeg +252 -0
  355. polyfile/magic_defs/json +8 -0
  356. polyfile/magic_defs/karma +9 -0
  357. polyfile/magic_defs/kde +11 -0
  358. polyfile/magic_defs/keepass +20 -0
  359. polyfile/magic_defs/kerberos +45 -0
  360. polyfile/magic_defs/kicad +85 -0
  361. polyfile/magic_defs/kml +34 -0
  362. polyfile/magic_defs/lammps +64 -0
  363. polyfile/magic_defs/lecter +6 -0
  364. polyfile/magic_defs/lex +12 -0
  365. polyfile/magic_defs/lif +50 -0
  366. polyfile/magic_defs/linux +557 -0
  367. polyfile/magic_defs/lisp +78 -0
  368. polyfile/magic_defs/llvm +22 -0
  369. polyfile/magic_defs/locoscript +12 -0
  370. polyfile/magic_defs/lua +31 -0
  371. polyfile/magic_defs/luks +126 -0
  372. polyfile/magic_defs/m4 +11 -0
  373. polyfile/magic_defs/mach +303 -0
  374. polyfile/magic_defs/macintosh +505 -0
  375. polyfile/magic_defs/macos +7 -0
  376. polyfile/magic_defs/magic +10 -0
  377. polyfile/magic_defs/magic.mgc +0 -0
  378. polyfile/magic_defs/mail.news +132 -0
  379. polyfile/magic_defs/make +21 -0
  380. polyfile/magic_defs/map +413 -0
  381. polyfile/magic_defs/maple +109 -0
  382. polyfile/magic_defs/marc21 +30 -0
  383. polyfile/magic_defs/mathcad +8 -0
  384. polyfile/magic_defs/mathematica +188 -0
  385. polyfile/magic_defs/matroska +17 -0
  386. polyfile/magic_defs/mcrypt +52 -0
  387. polyfile/magic_defs/measure +44 -0
  388. polyfile/magic_defs/mercurial +13 -0
  389. polyfile/magic_defs/metastore +8 -0
  390. polyfile/magic_defs/meteorological +53 -0
  391. polyfile/magic_defs/microfocus +21 -0
  392. polyfile/magic_defs/mime +9 -0
  393. polyfile/magic_defs/mips +120 -0
  394. polyfile/magic_defs/mirage +8 -0
  395. polyfile/magic_defs/misctools +140 -0
  396. polyfile/magic_defs/mkid +11 -0
  397. polyfile/magic_defs/mlssa +8 -0
  398. polyfile/magic_defs/mmdf +6 -0
  399. polyfile/magic_defs/modem +92 -0
  400. polyfile/magic_defs/modulefile +9 -0
  401. polyfile/magic_defs/motorola +71 -0
  402. polyfile/magic_defs/mozilla +37 -0
  403. polyfile/magic_defs/msdos +2304 -0
  404. polyfile/magic_defs/msooxml +68 -0
  405. polyfile/magic_defs/msvc +222 -0
  406. polyfile/magic_defs/msx +309 -0
  407. polyfile/magic_defs/mup +24 -0
  408. polyfile/magic_defs/music +17 -0
  409. polyfile/magic_defs/nasa +7 -0
  410. polyfile/magic_defs/natinst +24 -0
  411. polyfile/magic_defs/ncr +49 -0
  412. polyfile/magic_defs/neko +12 -0
  413. polyfile/magic_defs/netbsd +251 -0
  414. polyfile/magic_defs/netscape +26 -0
  415. polyfile/magic_defs/netware +11 -0
  416. polyfile/magic_defs/news +13 -0
  417. polyfile/magic_defs/nifty +202 -0
  418. polyfile/magic_defs/nim-lang +29 -0
  419. polyfile/magic_defs/nitpicker +14 -0
  420. polyfile/magic_defs/numpy +9 -0
  421. polyfile/magic_defs/oasis +12 -0
  422. polyfile/magic_defs/ocaml +14 -0
  423. polyfile/magic_defs/octave +6 -0
  424. polyfile/magic_defs/ole2compounddocs +760 -0
  425. polyfile/magic_defs/olf +98 -0
  426. polyfile/magic_defs/openfst +17 -0
  427. polyfile/magic_defs/opentimestamps +16 -0
  428. polyfile/magic_defs/oric +16 -0
  429. polyfile/magic_defs/os2 +186 -0
  430. polyfile/magic_defs/os400 +39 -0
  431. polyfile/magic_defs/os9 +80 -0
  432. polyfile/magic_defs/osf1 +10 -0
  433. polyfile/magic_defs/palm +156 -0
  434. polyfile/magic_defs/parix +13 -0
  435. polyfile/magic_defs/parrot +22 -0
  436. polyfile/magic_defs/pascal +39 -0
  437. polyfile/magic_defs/pbf +11 -0
  438. polyfile/magic_defs/pbm +8 -0
  439. polyfile/magic_defs/pc88 +24 -0
  440. polyfile/magic_defs/pc98 +77 -0
  441. polyfile/magic_defs/pci_ids +116 -0
  442. polyfile/magic_defs/pcjr +8 -0
  443. polyfile/magic_defs/pdf +51 -0
  444. polyfile/magic_defs/pdp +42 -0
  445. polyfile/magic_defs/perl +100 -0
  446. polyfile/magic_defs/pgf +52 -0
  447. polyfile/magic_defs/pgp +581 -0
  448. polyfile/magic_defs/pgp-binary-keys +388 -0
  449. polyfile/magic_defs/pkgadd +7 -0
  450. polyfile/magic_defs/plan9 +25 -0
  451. polyfile/magic_defs/playdate +57 -0
  452. polyfile/magic_defs/plus5 +18 -0
  453. polyfile/magic_defs/pmem +46 -0
  454. polyfile/magic_defs/polyfile_zip +5 -0
  455. polyfile/magic_defs/polyml +23 -0
  456. polyfile/magic_defs/printer +269 -0
  457. polyfile/magic_defs/project +10 -0
  458. polyfile/magic_defs/psdbms +14 -0
  459. polyfile/magic_defs/psl +14 -0
  460. polyfile/magic_defs/pulsar +13 -0
  461. polyfile/magic_defs/puzzle +17 -0
  462. polyfile/magic_defs/pwsafe +14 -0
  463. polyfile/magic_defs/pyramid +12 -0
  464. polyfile/magic_defs/python +305 -0
  465. polyfile/magic_defs/qt +30 -0
  466. polyfile/magic_defs/revision +66 -0
  467. polyfile/magic_defs/riff +840 -0
  468. polyfile/magic_defs/rinex +44 -0
  469. polyfile/magic_defs/ringdove +45 -0
  470. polyfile/magic_defs/rpi +52 -0
  471. polyfile/magic_defs/rpm +45 -0
  472. polyfile/magic_defs/rpmsg +7 -0
  473. polyfile/magic_defs/rst +11 -0
  474. polyfile/magic_defs/rtf +94 -0
  475. polyfile/magic_defs/ruby +55 -0
  476. polyfile/magic_defs/rust +21 -0
  477. polyfile/magic_defs/sc +7 -0
  478. polyfile/magic_defs/sccs +24 -0
  479. polyfile/magic_defs/scientific +144 -0
  480. polyfile/magic_defs/securitycerts +6 -0
  481. polyfile/magic_defs/selinux +24 -0
  482. polyfile/magic_defs/sendmail +37 -0
  483. polyfile/magic_defs/sequent +42 -0
  484. polyfile/magic_defs/sereal +35 -0
  485. polyfile/magic_defs/sgi +144 -0
  486. polyfile/magic_defs/sgml +161 -0
  487. polyfile/magic_defs/sharc +23 -0
  488. polyfile/magic_defs/sinclair +40 -0
  489. polyfile/magic_defs/sisu +18 -0
  490. polyfile/magic_defs/sketch +6 -0
  491. polyfile/magic_defs/smalltalk +25 -0
  492. polyfile/magic_defs/smile +34 -0
  493. polyfile/magic_defs/sniffer +482 -0
  494. polyfile/magic_defs/softquad +40 -0
  495. polyfile/magic_defs/sosi +40 -0
  496. polyfile/magic_defs/spec +21 -0
  497. polyfile/magic_defs/spectrum +184 -0
  498. polyfile/magic_defs/sql +288 -0
  499. polyfile/magic_defs/ssh +39 -0
  500. polyfile/magic_defs/ssl +20 -0
  501. polyfile/magic_defs/statistics +45 -0
  502. polyfile/magic_defs/subtitle +38 -0
  503. polyfile/magic_defs/sun +141 -0
  504. polyfile/magic_defs/svf +5 -0
  505. polyfile/magic_defs/sylk +36 -0
  506. polyfile/magic_defs/symbos +42 -0
  507. polyfile/magic_defs/sysex +429 -0
  508. polyfile/magic_defs/tcl +29 -0
  509. polyfile/magic_defs/teapot +6 -0
  510. polyfile/magic_defs/terminfo +63 -0
  511. polyfile/magic_defs/tex +141 -0
  512. polyfile/magic_defs/tgif +7 -0
  513. polyfile/magic_defs/ti-8x +239 -0
  514. polyfile/magic_defs/timezone +42 -0
  515. polyfile/magic_defs/tplink +95 -0
  516. polyfile/magic_defs/troff +38 -0
  517. polyfile/magic_defs/tuxedo +8 -0
  518. polyfile/magic_defs/typeset +8 -0
  519. polyfile/magic_defs/uf2 +72 -0
  520. polyfile/magic_defs/unicode +15 -0
  521. polyfile/magic_defs/unisig +12 -0
  522. polyfile/magic_defs/unknown +34 -0
  523. polyfile/magic_defs/usd +21 -0
  524. polyfile/magic_defs/uterus +16 -0
  525. polyfile/magic_defs/uuencode +28 -0
  526. polyfile/magic_defs/vacuum-cleaner +54 -0
  527. polyfile/magic_defs/varied.out +46 -0
  528. polyfile/magic_defs/varied.script +21 -0
  529. polyfile/magic_defs/vax +32 -0
  530. polyfile/magic_defs/vicar +17 -0
  531. polyfile/magic_defs/virtual +307 -0
  532. polyfile/magic_defs/virtutech +12 -0
  533. polyfile/magic_defs/visx +32 -0
  534. polyfile/magic_defs/vms +30 -0
  535. polyfile/magic_defs/vmware +6 -0
  536. polyfile/magic_defs/vorbis +155 -0
  537. polyfile/magic_defs/vxl +14 -0
  538. polyfile/magic_defs/warc +16 -0
  539. polyfile/magic_defs/weak +16 -0
  540. polyfile/magic_defs/web +18 -0
  541. polyfile/magic_defs/webassembly +17 -0
  542. polyfile/magic_defs/windows +1811 -0
  543. polyfile/magic_defs/wireless +7 -0
  544. polyfile/magic_defs/wordprocessors +630 -0
  545. polyfile/magic_defs/wsdl +23 -0
  546. polyfile/magic_defs/x68000 +25 -0
  547. polyfile/magic_defs/xdelta +13 -0
  548. polyfile/magic_defs/xenix +106 -0
  549. polyfile/magic_defs/xilinx +58 -0
  550. polyfile/magic_defs/xo65 +37 -0
  551. polyfile/magic_defs/xwindows +43 -0
  552. polyfile/magic_defs/yara +17 -0
  553. polyfile/magic_defs/zfs +96 -0
  554. polyfile/magic_defs/zilog +12 -0
  555. polyfile/magic_defs/zip +126 -0
  556. polyfile/magic_defs/zyxel +17 -0
  557. polyfile/nes.py +144 -0
  558. polyfile/nitf.py +15 -0
  559. polyfile/pdf.py +1264 -0
  560. polyfile/pickles.py +45 -0
  561. polyfile/polyfile.py +409 -0
  562. polyfile/profiling.py +115 -0
  563. polyfile/repl.py +624 -0
  564. polyfile/search.py +310 -0
  565. polyfile/serialization.py +323 -0
  566. polyfile/structmatcher.py +46 -0
  567. polyfile/structs.py +281 -0
  568. polyfile/templates/download.js +162 -0
  569. polyfile/templates/hexdump.css +268 -0
  570. polyfile/templates/hexdump.js +756 -0
  571. polyfile/templates/jquery-3.4.1.min.js +2 -0
  572. polyfile/templates/template.html +119 -0
  573. polyfile/wildcards.py +62 -0
  574. polyfile/zipmatcher.py +183 -0
  575. polyfile_weave-0.5.5.dist-info/METADATA +173 -0
  576. polyfile_weave-0.5.5.dist-info/RECORD +585 -0
  577. polyfile_weave-0.5.5.dist-info/WHEEL +5 -0
  578. polyfile_weave-0.5.5.dist-info/entry_points.txt +2 -0
  579. polyfile_weave-0.5.5.dist-info/licenses/LICENSE +202 -0
  580. polyfile_weave-0.5.5.dist-info/top_level.txt +2 -0
  581. polymerge/__init__.py +1 -0
  582. polymerge/__main__.py +296 -0
  583. polymerge/cfg.py +127 -0
  584. polymerge/polymerge.py +227 -0
  585. polymerge/polytracker.py +190 -0
polyfile/search.py ADDED
@@ -0,0 +1,310 @@
1
+ from collections import deque
2
+ import collections.abc
3
+ from typing import IO, Mapping, Sequence, Union
4
+
5
+ from . import serialization
6
+
7
+
8
+ @serialization.serializable
9
+ class TrieNode:
10
+ def __init__(self, value=None, sources=None, _children=None):
11
+ if _children is None:
12
+ self._children: Mapping[object, TrieNode] = {}
13
+ else:
14
+ self._children = _children
15
+ self.value = value
16
+ if sources is not None:
17
+ self._sources = set(sources)
18
+ else:
19
+ self._sources = set()
20
+
21
+ def __repr__(self):
22
+ return f"{self.__class__.__name__}(value={self.value!r}, sources={self.sources!r}, _children={self._children!r})"
23
+
24
+ def __len__(self):
25
+ return len(self._children)
26
+
27
+ def __iter__(self):
28
+ return iter(self._children.values())
29
+
30
+ def __hash__(self):
31
+ return hash(self.value)
32
+
33
+ def __eq__(self, other):
34
+ return self.value == other.value
35
+
36
+ def __ne__(self, other):
37
+ return not (self == other)
38
+
39
+ def __getitem__(self, key):
40
+ return self._children[key]
41
+
42
+ def __contains__(self, value):
43
+ if not isinstance(value, collections.abc.Sequence):
44
+ first, remainder, n = value, (), 1
45
+ else:
46
+ first, remainder, n = self._car_cdr_len(value)
47
+ if n == 1:
48
+ return first in self._children
49
+ else:
50
+ return self._find(first, remainder, n)
51
+
52
+ @staticmethod
53
+ def _car_cdr_len(sequence):
54
+ n = len(sequence)
55
+ if n == 0:
56
+ first = None
57
+ else:
58
+ first = sequence[0]
59
+ return first, sequence[1:], n
60
+
61
+ def _find(self, first, remainder, n):
62
+ if n == 0:
63
+ return len(self._sources) > 0
64
+ if first not in self._children:
65
+ return False
66
+ return self[first]._find(*self._car_cdr_len(remainder))
67
+
68
+ def find(self, key):
69
+ if isinstance(key, collections.abc.Sequence):
70
+ return self._find(*self._car_cdr_len(key))
71
+ else:
72
+ return self._find(key, (), 1)
73
+
74
+ @property
75
+ def children(self):
76
+ return dict(self._children)
77
+
78
+ @property
79
+ def sources(self):
80
+ return frozenset(self._sources)
81
+
82
+ def _add_child(self, value, sources=None):
83
+ new_child = TrieNode(value, sources)
84
+ self._children[value] = new_child
85
+ return new_child
86
+
87
+ def _add(self, sequence, source):
88
+ node = self
89
+ while True:
90
+ first, sequence, n = self._car_cdr_len(sequence)
91
+ if n == 0:
92
+ break
93
+ if first in node:
94
+ node = node[first]
95
+ else:
96
+ node = node._add_child(first)
97
+ node._sources.add(source)
98
+ return node
99
+
100
+ def add(self, sequence, source=None):
101
+ if source is None:
102
+ source = sequence
103
+ return self._add(sequence, source)
104
+
105
+ def find_prefix(self, prefix):
106
+ first, remainder, n = self._car_cdr_len(prefix)
107
+ if n == 0:
108
+ yield from iter(self._sources)
109
+ for child in self:
110
+ yield from child.find_prefix(prefix)
111
+ else:
112
+ if first in self._children:
113
+ yield from self[first].find_prefix(remainder)
114
+
115
+ def bfs(self):
116
+ queue = deque([self])
117
+ while queue:
118
+ head = queue.popleft()
119
+ yield head
120
+ queue.extend(head._children.values())
121
+
122
+ def dfs(self):
123
+ stack = [self]
124
+ visited = set()
125
+ while stack:
126
+ tail = stack.pop()
127
+ yield tail
128
+ children = tail._children.values()
129
+ stack.extend(child for child in children if id(child) not in visited)
130
+ visited |= set(id(c) for c in children)
131
+
132
+ def serialize(self):
133
+ return self.value, self._sources, self._children
134
+
135
+
136
+ @serialization.serializable
137
+ class ACNode(TrieNode):
138
+ """A data structure for implementing the Aho-Corasick multi-string matching algorithm"""
139
+ def __init__(self, value=None, sources=None, _children=None, parent=None, _fall=None):
140
+ super().__init__(value=value, sources=sources, _children=_children)
141
+ self.parent = parent
142
+ self.fall = _fall
143
+
144
+ def serialize(self):
145
+ return super().serialize() + (self.parent, self.fall)
146
+
147
+ def __repr__(self):
148
+ if self.fall is not self:
149
+ return f"{self.__class__.__name__}(value={self.value!r}, sources={self.sources!r}, _children={self._children!r}), parent={self.parent!r}, _fall={self.fall!r}"
150
+ else:
151
+ return f"{self.__class__.__name__}(value={self.value!r}, sources={self.sources!r}, _children={self._children!r}), parent={self.parent!r}, _fall=self"
152
+
153
+ def _add_child(self, value, sources=None):
154
+ new_child = ACNode(value, sources, parent=self)
155
+ self._children[value] = new_child
156
+ return new_child
157
+
158
+ def finalize(self):
159
+ self.fall = self
160
+ for n in self.bfs():
161
+ if n is self:
162
+ continue
163
+ new_fall = n.parent.fall
164
+ while n.value not in new_fall and new_fall is not self:
165
+ new_fall = new_fall.fall
166
+ if n.value not in new_fall:
167
+ # there is no suffix
168
+ n.fall = self
169
+ else:
170
+ n.fall = new_fall[n.value]
171
+ if n.fall is n:
172
+ n.fall = self
173
+
174
+ def to_dot(self, include_falls=False):
175
+ """Returns a Graphviz/Dot representation of this Trie"""
176
+ dot = "digraph G {\n"
177
+ node_ids = {}
178
+ falls = {}
179
+ for node in self.dfs():
180
+ assert node not in node_ids
181
+ nid = len(node_ids)
182
+ node_ids[id(node)] = nid
183
+ dot += f" node{nid}"
184
+ if node.value is None:
185
+ dot += f"[label=\"Root\"]"
186
+ else:
187
+ if node.value == ord('"'):
188
+ c = '\\"'
189
+ elif node.value == ord('\\'):
190
+ c = '\\\\'
191
+ elif 32 <= node.value <= 126:
192
+ c = chr(node.value)
193
+ else:
194
+ c = f"\\\\x{hex(node.value)[2:]}"
195
+ dot += f"[label=\"{c}\"]"
196
+ dot += ";\n"
197
+ if node.parent is not None:
198
+ dot += f" node{node_ids[id(node.parent)]} -> node{nid};\n"
199
+ if include_falls and node.fall is not None and node.fall is not node:
200
+ falls[id(node)] = id(node.fall)
201
+
202
+ for nodeid, fallid in falls.items():
203
+ dot += f" node{node_ids[nodeid]} -> node{node_ids[fallid]} [style=dashed,label=\"fall\"];\n"
204
+ dot += "}\n"
205
+ return dot
206
+
207
+
208
+ class MultiSequenceSearch:
209
+ """A datastructure for efficiently searching a sequence for multiple strings"""
210
+ def __init__(self, *sequences_to_find):
211
+ self.trie = ACNode()
212
+ for seq in sequences_to_find:
213
+ self.trie.add(seq)
214
+ self.trie.finalize()
215
+
216
+ def save(self, output_stream: IO):
217
+ serialization.dump(self.trie, output_stream)
218
+
219
+ @staticmethod
220
+ def load(input_stream: IO):
221
+ mss = MultiSequenceSearch()
222
+ mss.trie = serialization.load(input_stream)
223
+ print(mss.trie)
224
+ exit(0)
225
+ return mss
226
+
227
+ def search(self, source_sequence: Union[Sequence, IO]):
228
+ """The Aho-Corasick Algorithm"""
229
+ if hasattr(source_sequence, 'read'):
230
+ def iterator():
231
+ while True:
232
+ b = source_sequence.read(1)
233
+ if not b:
234
+ return
235
+ yield b[0]
236
+ else:
237
+ def iterator():
238
+ return iter(source_sequence)
239
+
240
+ state = self.trie
241
+ for stream_offset, c in enumerate(iterator()):
242
+ n = state
243
+
244
+ while c not in n and n is not self.trie:
245
+ n = n.fall
246
+
247
+ if n is self.trie:
248
+ if c in n:
249
+ n = n[c]
250
+ else:
251
+ n = n[c]
252
+
253
+ state = n
254
+
255
+ while n is not self.trie:
256
+ yield from ((stream_offset - len(source) + 1, source) for source in n.sources)
257
+ n = n.fall
258
+
259
+
260
+ class StartsWithMatcher:
261
+ def __init__(self, *sequences_to_find):
262
+ self.trie = TrieNode()
263
+ for seq in sequences_to_find:
264
+ self.trie.add(seq)
265
+
266
+ def search(self, source_sequence: Union[Sequence, IO]):
267
+ if hasattr(source_sequence, 'read'):
268
+ def iterator():
269
+ while True:
270
+ b = source_sequence.read(1)
271
+ if not b:
272
+ return
273
+ yield b[0]
274
+ else:
275
+ def iterator():
276
+ return iter(source_sequence)
277
+
278
+ state = self.trie
279
+ yield from ((0, s) for s in state.sources)
280
+
281
+ for c in iterator():
282
+ if c not in state:
283
+ return
284
+
285
+ state = state[c]
286
+ yield from ((0, s) for s in state.sources)
287
+
288
+
289
+ if __name__ == '__main__':
290
+ root = TrieNode()
291
+ root.add('The quick brown fox jumps over the lazy dog')
292
+ root.add('The quick person')
293
+ root.add('The best')
294
+ assert len(list(root.find_prefix('The'))) == 3
295
+ assert len(list(root.find_prefix('The quick'))) == 2
296
+ assert not root.find('The')
297
+ assert root.find('The best')
298
+
299
+ mss = MultiSequenceSearch(b'hack', b'hacker', b'crack', b'ack', b'kool')
300
+ to_search = b'This is a test to see if hack or hacker is in this string.'\
301
+ b'Can you crack it? If so, please ack, \'cause that would be kool.'
302
+ for offset, match in mss.search(to_search):
303
+ print(offset, match)
304
+ assert to_search[offset:offset+len(match)] == match
305
+
306
+ swm = StartsWithMatcher(b'hack', b'hacker', b'crack', b'ack', b'kool')
307
+ for match in swm.search(b'hacker'):
308
+ print(match)
309
+
310
+ print(ACNode.load(mss.trie.serialize()))
@@ -0,0 +1,323 @@
1
+ from enum import Enum
2
+ import io
3
+ from itertools import chain
4
+
5
+
6
+ def write_int(i:int, stream):
7
+ bits = max(i.bit_length(), 1)
8
+ for bit_group in reversed(range((bits - 1) // 7 + 1)):
9
+ b = (i >> (bit_group * 7)) & 0b01111111
10
+ if bit_group == 0:
11
+ b |= 0b10000000
12
+ stream.write(bytes([b]))
13
+
14
+
15
+ def read_int(stream):
16
+ i = 0
17
+ while True:
18
+ i <<= 7
19
+ b = ord(stream.read(1))
20
+ i |= (b & 0b01111111)
21
+ if b & 0b10000000:
22
+ break
23
+ return i
24
+
25
+ ENCODINGS_BY_TYPE = {}
26
+ ENCODINGS_BY_ID = {}
27
+ CUSTOM_ENCODINGS = {}
28
+ CUSTOM_ENCODINGS_BY_ID = {}
29
+
30
+
31
+ def encode_int(i, _, stream):
32
+ write_int(i, stream)
33
+
34
+
35
+ def decode_int(_, stream):
36
+ return read_int(stream)
37
+
38
+
39
+ def encode_bytes(s, _, stream):
40
+ write_int(len(s), stream)
41
+ stream.write(s)
42
+
43
+
44
+ def encode_string(s:str, _, stream):
45
+ encode_bytes(s.encode('utf-8'), None, stream)
46
+
47
+
48
+ def decode_bytes(_, stream):
49
+ length = read_int(stream)
50
+ return stream.read(length)
51
+
52
+
53
+ def decode_string(_, stream):
54
+ return decode_bytes(None, stream).decode('utf-8')
55
+
56
+
57
+ def encode_list(lst, obj_ids, stream):
58
+ for obj in lst:
59
+ write_int(obj_ids[id(obj)], stream)
60
+ write_int(EncodeTypes.END.encoding_id, stream)
61
+
62
+
63
+ encode_tuple = encode_list
64
+
65
+
66
+ encode_set = encode_list
67
+
68
+
69
+ encode_frozenset = encode_list
70
+
71
+
72
+ def _decode_to_end(stream):
73
+ while True:
74
+ i = read_int(stream)
75
+ if i == EncodeTypes.END.encoding_id:
76
+ break
77
+ yield i
78
+
79
+
80
+ def pairwise(iterable):
81
+ while True:
82
+ try:
83
+ a, b = next(iterable), next(iterable)
84
+ except StopIteration:
85
+ break
86
+ yield a, b
87
+
88
+
89
+ def decode_list(objs, stream):
90
+ return [objs[i] for i in _decode_to_end(stream)]
91
+
92
+
93
+ def decode_tuple(*args, **kwargs):
94
+ return tuple(decode_list(*args, **kwargs))
95
+
96
+
97
+ def decode_set(*args, **kwargs):
98
+ return set(decode_list(*args, **kwargs))
99
+
100
+
101
+ def decode_frozenset(*args, **kwargs):
102
+ return frozenset(decode_list(*args, **kwargs))
103
+
104
+
105
+ def encode_dict(d: dict, obj_ids, stream):
106
+ for k, v in d.items():
107
+ write_int(obj_ids[id(k)], stream)
108
+ write_int(obj_ids[id(v)], stream)
109
+ write_int(EncodeTypes.END.encoding_id, stream)
110
+
111
+
112
+ def decode_dict(objs, stream):
113
+ return {objs[k]: objs[v] for k, v in pairwise(_decode_to_end(stream))}
114
+
115
+
116
+ def encode_none(*args, **kwargs):
117
+ pass
118
+
119
+
120
+ def decode_none(*args, **kwargs):
121
+ return None
122
+
123
+
124
+ def encode_bool(b: bool, _, stream):
125
+ write_int(int(b), stream)
126
+
127
+
128
+ def decode_bool(_, stream):
129
+ return bool(read_int(stream))
130
+
131
+
132
+ def encode_custom(c, obj_ids, stream):
133
+ write_int(CUSTOM_ENCODINGS[type(c)], stream)
134
+ encode_list(c.serialize(), obj_ids, stream)
135
+
136
+
137
+ def decode_custom(objs, stream):
138
+ custom_type = CUSTOM_ENCODINGS_BY_ID[read_int(stream)]
139
+ args = decode_list(objs, stream)
140
+ return custom_type(*args)
141
+
142
+
143
+ class _EndObject:
144
+ pass
145
+
146
+
147
+ class _CustomObject:
148
+ pass
149
+
150
+
151
+ def serializable(SerializableClass):
152
+ if not hasattr(SerializableClass, 'serialize'):
153
+ raise ValueError(f'Serializable class {SerializableClass} must implement the `serialize` member function')
154
+ new_id = len(CUSTOM_ENCODINGS)
155
+ CUSTOM_ENCODINGS[SerializableClass] = new_id
156
+ CUSTOM_ENCODINGS_BY_ID[new_id] = SerializableClass
157
+ return SerializableClass
158
+
159
+
160
+ class EncodeTypes(Enum):
161
+ END = (0, _EndObject, None, None, None)
162
+ NONE = (1, type(None), encode_none, decode_none, lambda _: ())
163
+ BOOL = (2, bool, encode_bool, decode_bool, lambda _: ())
164
+ INT = (3, int, encode_int, decode_int, lambda _: ())
165
+ STRING = (4, str, encode_string, decode_string, lambda _: ())
166
+ BYTES = (5, bytes, encode_bytes, decode_bytes, lambda _: ())
167
+ LIST = (6, list, encode_list, decode_list, iter)
168
+ TUPLE = (7, tuple, encode_tuple, decode_tuple, iter)
169
+ DICT = (8, dict, encode_dict, decode_dict, lambda d: chain(d.keys(), d.values()))
170
+ SET = (9, set, encode_set, decode_set, iter)
171
+ FROZENSET = (10, frozenset, encode_frozenset, decode_frozenset, iter)
172
+ CUSTOM = (11, _CustomObject, encode_custom, decode_custom, lambda c: c.serialize())
173
+
174
+ def __init__(self, encoding_id, source_type, encoding_function, decoding_function, children):
175
+ self.encoding_id = encoding_id
176
+ self.source_type = source_type
177
+ self.encode = encoding_function
178
+ self.decode = decoding_function
179
+ self.children = children
180
+ ENCODINGS_BY_TYPE[self.source_type] = self
181
+ ENCODINGS_BY_ID[self.encoding_id] = self
182
+
183
+ @staticmethod
184
+ def get_by_type(source_type):
185
+ if source_type not in ENCODINGS_BY_TYPE:
186
+ return None
187
+ return ENCODINGS_BY_TYPE[source_type]
188
+
189
+ @staticmethod
190
+ def get_by_id(encoding_id):
191
+ if encoding_id not in ENCODINGS_BY_ID:
192
+ return None
193
+ return ENCODINGS_BY_ID[encoding_id]
194
+
195
+
196
+ class EncodingError(RuntimeError):
197
+ def __init__(self, *args):
198
+ super().__init__(*args)
199
+
200
+
201
+ def encode(obj, stream):
202
+ stack = [obj]
203
+ # Object ID 0 is reserved
204
+ obj_ids = {
205
+ 0: None
206
+ }
207
+ objs = [
208
+ (None, None)
209
+ ]
210
+
211
+ # Do a DFS traversal to assign IDs
212
+ while stack:
213
+ s = stack.pop()
214
+ encoding = EncodeTypes.get_by_type(type(s))
215
+ if encoding is None:
216
+ # See if there is a custom encoding:
217
+ if type(s) in CUSTOM_ENCODINGS:
218
+ encoding = EncodeTypes.CUSTOM
219
+ else:
220
+ raise EncodingError(f"No encoding implemented for objects of type {type(s)}")
221
+ already_expanded = id(s) in obj_ids
222
+ if already_expanded:
223
+ old_id = obj_ids[id(s)]
224
+ # We add one to new_id here because obj_id zero is reserved
225
+ new_id = len(objs)
226
+ obj_ids[id(s)] = new_id
227
+ objs.append((s, encoding))
228
+ if already_expanded:
229
+ objs[old_id] = (None, None)
230
+ # Remove all of the dependencies, since they now need to be added after:
231
+ # TODO: eventually do cycle detection here, and throw an error instead of livelock
232
+ for child in encoding.children(s):
233
+ if id(child) in obj_ids:
234
+ objs[obj_ids[id(child)]] = (None, None)
235
+ del obj_ids[id(child)]
236
+ stack.extend(encoding.children(s))
237
+
238
+ # write the objects to the stream in reverse
239
+ n = len(objs)
240
+ for i, (s, encoding) in enumerate(reversed(objs)):
241
+ obj_id = n - i - 1
242
+ if encoding is None:
243
+ # This object was referenced twice, and this was a duplicate
244
+ continue
245
+ write_int(obj_id, stream)
246
+ write_int(encoding.encoding_id, stream)
247
+ encoding.encode(s, obj_ids, stream)
248
+
249
+
250
+ def decode(stream):
251
+ objs = {}
252
+ while True:
253
+ b = stream.read(1)
254
+ if b is None or not b:
255
+ break
256
+ stream.seek(-1, 1)
257
+ obj_id = read_int(stream)
258
+ assert obj_id not in objs
259
+ encoding_id = read_int(stream)
260
+ encoding = EncodeTypes.get_by_id(encoding_id)
261
+ if encoding is None:
262
+ raise EncodingError(f"Unexpected encoded object of type #{obj_id}")
263
+ objs[obj_id] = encoding.decode(objs, stream)
264
+ return objs[1]
265
+
266
+
267
+ def dump(obj, stream):
268
+ return encode(obj, stream)
269
+
270
+
271
+ def load(stream):
272
+ return decode(stream)
273
+
274
+
275
+ def dumps(obj):
276
+ stream = io.BytesIO()
277
+ dump(obj, stream)
278
+ return stream.getvalue()
279
+
280
+
281
+ def loads(string:bytes):
282
+ with io.BytesIO(string) as stream:
283
+ return load(stream)
284
+
285
+
286
+ if __name__ == '__main__':
287
+ ref = ["list", "used", "twice"]
288
+ test_obj = {
289
+ 'testing': {
290
+ 'foo': {10},
291
+ 'bar': [1, 2, 3, b'1234\xFF', True, False],
292
+ 'ref': ref
293
+ },
294
+ 'baz': [
295
+ 'a', ('b',), 'c',
296
+ {'d': 5},
297
+ None,
298
+ frozenset([1, 1, 2, 3, 5, 8])
299
+ ],
300
+ 'ref': ref
301
+ }
302
+
303
+ #print(test_obj)
304
+ #encoded = encode(test_obj)
305
+ #print(encoded)
306
+ #decoded = decode(encoded)
307
+ #print(decoded)
308
+
309
+ for i in range(0, 2048):
310
+ assert loads(dumps(i)) == i
311
+
312
+ b = b"The quick brown fox jumps over the lazy dog"
313
+ s = b.decode('utf-8')
314
+ assert loads(dumps(b)) == b
315
+ assert loads(dumps(s)) == s
316
+
317
+ lst = list(range(1024))
318
+ assert loads(dumps(lst)) == lst
319
+
320
+ encoded = dumps(test_obj)
321
+ print(f"Encoded bytes: {len(encoded)}")
322
+
323
+ print(loads(encoded))
@@ -0,0 +1,46 @@
1
+ from typing import Iterator, Optional
2
+
3
+ from .fileutils import Tempfile
4
+ from .polyfile import InvalidMatch, Match, Matcher, Submatch
5
+ from .structs import Field, Struct, StructError
6
+
7
+
8
+ class PolyFileStruct(Struct):
9
+ __name__: Optional[str] = None
10
+
11
+ @property
12
+ def match_name(self) -> str:
13
+ if self.__name__ is not None:
14
+ return self.__name__
15
+ else:
16
+ return self.__class__.__name__
17
+
18
+ def match(self, matcher: Matcher, parent: Optional[Match] = None) -> Iterator[Submatch]:
19
+ m = Submatch(
20
+ self.match_name,
21
+ match_obj=self,
22
+ relative_offset=self.start_offset,
23
+ length=self.num_bytes,
24
+ parent=parent,
25
+ matcher=matcher
26
+ )
27
+ yield m
28
+ for field_name in self.fields.keys():
29
+ value: Field = getattr(self, field_name)
30
+ s = Submatch(
31
+ field_name,
32
+ match_obj=value,
33
+ relative_offset=value.start_offset - self.start_offset,
34
+ length=value.num_bytes,
35
+ parent=m,
36
+ matcher=matcher
37
+ )
38
+ yield s
39
+ try:
40
+ if isinstance(value, PolyFileStruct):
41
+ yield from value.match(matcher, s)
42
+ elif isinstance(value, bytes):
43
+ with Tempfile(value) as tmp:
44
+ yield from matcher.match(tmp, parent=s)
45
+ except (InvalidMatch, StructError):
46
+ pass