Compare commits

..

1465 Commits
1.3.2 ... 3.0.1

Author SHA1 Message Date
Matt Nadareski
451fc0b394 Bump version 2026-07-06 09:57:11 -04:00
HeroponRikiBestest
79ca9f617e Add sim parsing for Steam2 sim/sid installers (#95)
* Add model for sim file

* Add sim parsing for steam2 installer set

* First round of fixes
2026-07-06 09:21:17 -04:00
Matt Nadareski
a602686551 Trim path separators from start of filenames on extract 2026-07-05 23:28:24 -04:00
Matt Nadareski
4083aed12f Some filenames in MS-CAB start with one or more separators 2026-07-01 10:18:20 -04:00
Matt Nadareski
717de3608c Add Logiqx serial and version machine fields 2026-06-22 16:35:03 -04:00
Matt Nadareski
88aae0dd26 Bump version 2026-06-12 08:56:35 -04:00
Matt Nadareski
499fc44004 Ensure a 2-byte read is possible 2026-06-07 21:56:17 -04:00
Matt Nadareski
07325be930 Clean up parameter 2026-05-29 22:27:27 -04:00
Matt Nadareski
481020bd08 Move useful helper to a better place 2026-05-22 09:24:03 -04:00
Matt Nadareski
5642f601a3 Minor cleanup 2026-05-21 10:38:38 -04:00
Deterous
b42a12f051 Recursive InfoPrint for ISO9660 and XDVDFS (#94)
* Recursive InfoPrint for XDVDFS / XboxISO

* Cleanup, full file paths

* Add safety

* Recursive ISO9660 printing

* Naive decode filename

* comment
2026-05-21 10:32:20 -04:00
Matt Nadareski
a5879b46f1 Slightly more cleanup around IS-CAB and printing 2026-05-18 19:52:44 -04:00
Matt Nadareski
9a14cc2620 Fix major issues in IS-CAB 2026-05-18 19:23:35 -04:00
Matt Nadareski
a777df13db Take directory into account for IS-CAB 2026-05-18 13:35:59 -04:00
Matt Nadareski
78d7bc310f Add placebo recursive flag for now 2026-05-18 10:24:30 -04:00
Matt Nadareski
ae3978241c Add expected header size as a comment 2026-05-18 10:03:57 -04:00
Matt Nadareski
390e39ef30 Add Z3DS metadata structures 2026-05-18 09:54:33 -04:00
Matt Nadareski
5ef595e01a Add Z3DS file header structure 2026-05-18 09:39:48 -04:00
Matt Nadareski
371623e3fa See if org-level CONTRIBUTING works 2026-05-16 14:59:41 -04:00
Matt Nadareski
7eb669cef3 Update CONTRIBUTING to be more accurate 2026-05-15 13:04:19 -04:00
Matt Nadareski
4eac10c15c Add CONTRIBUTING document 2026-05-15 10:58:39 -04:00
Matt Nadareski
495368f28d Update gitignore for new VSCode feature 2026-05-15 10:24:55 -04:00
Matt Nadareski
a2d15f301b Move it around 2026-05-14 20:52:12 -04:00
Matt Nadareski
d3c9849908 Attempt to fix detection issues 2026-05-14 20:08:32 -04:00
Matt Nadareski
249c51933b Update packages 2026-05-14 09:25:26 -04:00
Matt Nadareski
cf586f7af2 Add Nintendo Disc extensions tests 2026-05-12 22:47:19 -04:00
Matt Nadareski
b805c91cb3 Add notes and reconfigure based on IO porting 2026-05-12 21:55:11 -04:00
Matt Nadareski
2a0e8e2eb0 First round of cleanup for DolphinLib additions 2026-05-12 20:33:53 -04:00
Dimensional
49aa6895b6 Dolphin lib (#85)
* Add GCZ, WIA/RVZ, and NintendoDisc (GameCube/Wii) format support

Port of DolphinIsoLib into SabreTools.Serialization architecture:
- Data.Models: GCZ/, WIA/, NintendoDisc/ model subdirectories (15 files)
- Serialization.Readers: GCZ, WIA, NintendoDisc readers
- Serialization.Writers: GCZ, WIA writers (structural metadata; full round-trip TODO)
- Wrappers: NintendoDisc, GCZ, WIA wrappers with Encryption partial class
- Wrappers: WiaRvzCompressionHelper (BZip2/LZMA/LZMA2/Zstd, net462+ guarded)
- WrapperType + WrapperFactory: GCZ, WIA, NintendoDisc entries added

GetInnerWrapper() decompression and NintendoDisc.Extraction FST extraction
are stubbed with TODO comments pending full implementation.

* Implement GetInnerWrapper for GCZ and WIA, full NintendoDisc extraction

* Add GCZ/WIA/RVZ write pipeline and Nintendo disc compression helpers

* Add WIA/RVZ table decompression, NintendoDisc/GCZ printing, NintendoDisc detection for .iso files

* Fix NintendoDisc header layout, GC magic, and add embedded disc header to WIA/GCZ printing

- Fix GCMagicWord: 0xC23D3C1F -> 0xC2339F3D (confirmed from Dolphin DiscUtils.h)
- Fix disc header field layout to match Dolphin's confirmed offsets:
  MakerCode is bytes 4-5 of the 6-char GameId (no separate field at 0x006),
  DiscNumber at 0x006, DiscVersion at 0x007, unused region is 14 bytes (0x00A-0x017)
- Update NintendoDisc reader: derive MakerCode from GameId[4..5], fix skip count
- Add ParseDiscHeaderOnly() to reader for partial (short) stream parsing
- Guard DisableHash/DisableEnc reads at the 0x080 boundary for 128-byte embedded headers
- Guard DOL/FST skip for streams shorter than full 0x440 boot block
- Fix WrapperFactory: NintendoDisc magic detection now precedes .iso -> ISO9660 fallback
- Add GameId-prefix heuristic in WrapperFactory for GC discs lacking magic word
- Add GameId-prefix platform fallback in reader for GC discs without GCMagicWord
- Add DiscHeader property to WIA wrapper (parsed from Header2.DiscHeader bytes)
- Add DiscHeader property to GCZ wrapper (decompresses first block only)
- Add ReadDiscHeader() helper to GCZ for lightweight first-block decompression
- Print embedded disc header (Game ID, Maker, Disc/Rev, Title) in WIA.Printing.cs and GCZ.Printing.cs

* Fix Wii partition extraction: correct IV, FST size shift, partition naming

- Block decryption: IV is at raw block offset 0x3D0 (still-encrypted),
  matching Dolphin/DolphinIsoLib WiiPartitionDecryptor.DecryptBlock exactly.
- FST size field at boot.bin 0x428 is also stored >>2 on Wii; apply <<2
  to get true byte size.
- Partition folder naming now matches DolphinIsoLib WiiDiscExtractor exactly:
  type 0->GM+n, 1->UP+n, 2->CH+n, printable ASCII unknown->raw 4-char string,
  non-printable->P{index}. SSBB VC channels extract as HA8E, HA9E, etc.
- ExtractionTool peek buffer increased from 16 to 32 bytes.

Verified: SSBB GM0 extracts 5524 files, boot.bin/fst.bin byte-identical
to Dolphin reference extraction.

* Fix FST extraction: create zero-byte files instead of skipping them

Files with fileSize=0 in the FST were silently skipped. Now they are
created as empty files, matching Dolphin/DolphinIsoLib behavior.

Verified: SSBB now extracts 5958 files with 0 missing, 0 extra,
0 size mismatches, and 0 hash mismatches vs DolphinIsoLib reference.

* Add GCZ/WIA/RVZ virtual stream extraction via NintendoDisc wrapper

* Address PR #85 review comments (Copilot + mnadareski)

* Address PR #85 review comments

* Replace custom endian helpers and SHA1 with SabreTools.IO equivalents

* Update GCZ.Printing.cs

* Update NintendoDisc.Printing.cs

* Update WIA.Printing.cs

* Add WIA/RVZ Wii partition crypto round-trip support

- Add AesCbc internal helper (BouncyCastle AES-CBC encrypt/decrypt)
- Add NintendoDisc.CommonKeyProvider hook for injectable test keys
- Fix sha1.Terminate() missing in all three ComputeSha1 helpers in WIA.cs
- Fix Wii partition dataOff alignment to 0x8000 boundary
- Add WIA.EncryptWiiGroup (internal) for re-encrypting plaintext groups
- Add WIA.DumpIso to WIA.Writing.cs (WIA/RVZ -> flat ISO conversion)
- Add WiaVirtualStream on-demand group decompression
- Add _preDecryptedReader bypass on NintendoDisc for WIA extraction path
- Add WIATests.cs with Wii crypto round-trip test using synthetic data
- Move DumpIso from WIA.Extraction.cs to WIA.Writing.cs
- Bump DumpIso read buffer from 1 MiB to 2 MiB (aligns to WIA chunk size)
- Add InternalsVisibleTo SabreTools.Wrappers.Test in csproj

* Remove hardcoded Wii common keys from NintendoDisc.Encryption

- Delete the embedded WiiCommonKeyRetail and WiiCommonKeyKorean byte
  arrays from NintendoDisc.Encryption.cs.
- Make CommonKeyProvider public so any caller (not just tests) can
  inject keys; DecryptTitleKey now returns null when no key is
  available for the requested index rather than falling back to
  hardcoded values.
- Add NintendoDiscEncryptionTests.cs:
    - Argument guard and no-provider tests for DecryptTitleKey.
    - Fake-key round-trip test (encrypt then decrypt with injected key).
    - Integration test that reads TestData/NintendoDisc/keys.json,
      verifies each key against hardcoded SHA256 constants, and skips
      silently if the file is absent or the keys do not match.
    - LoadKeyProvider helper (named JSON format, index-keyed).
- Add [Collection(NintendoDisc)] to both NintendoDiscEncryptionTests
  and WIATests to prevent parallel access to the static
  CommonKeyProvider from racing between test classes.
- Add TestData/NintendoDisc/keys.json.example documenting the
  expected key file format.
- Add Newtonsoft.Json reference to SabreTools.Wrappers.Test.csproj.

* Didn't actually commit the changes. My bad. Fixed.

* Edited a comment

* Added in XUnit outputs that show up in Test Viewer in VS

---------

Co-authored-by: Matt Nadareski <mnadareski@outlook.com>
2026-05-12 10:41:32 -04:00
Matt Nadareski
3f71628600 Split WIA models into separate files 2026-05-04 11:47:49 -04:00
Matt Nadareski
f729eae48a Add GCZ, Nintendo disc, and WIA models
Code originally by https://github.com/Dimensional and split off from https://github.com/SabreTools/SabreTools.Serialization/pull/85/
2026-05-04 09:59:14 -04:00
Matt Nadareski
f6877d82cd Remove errant header field setting 2026-04-28 13:58:59 -04:00
Matt Nadareski
9ed671f595 Editorconfig cleanup 2026-04-28 09:26:49 -04:00
Deterous
a2b9db3afd PC Engine CD-ROM Header Support (#91) 2026-04-28 09:24:36 -04:00
Matt Nadareski
49ea4302b6 Add mostly-working version of JSON printing to older .NET 2026-04-27 18:56:10 -04:00
Matt Nadareski
59f76b1036 Editorconfig cleanup 2026-04-27 13:28:23 -04:00
Deterous
6fa3631c80 Add Opera FileSystem support (#90)
* Add Opera FileSystem support

* Fix tests
2026-04-27 13:24:30 -04:00
Matt Nadareski
b24f96ac0f Fix documentation 2026-04-25 21:51:42 -04:00
Matt Nadareski
201af08f5f Document alternative TGZ layout 2026-04-25 21:45:53 -04:00
Matt Nadareski
b9b1b24f67 Update date in license 2026-04-22 09:35:17 -04:00
Matt Nadareski
d28a88e193 Handle comments in XML in a smarter way 2026-04-21 14:23:35 -04:00
Matt Nadareski
c02698edcd Fix M1 and MESS parsing, similar to ListXML 2026-04-21 12:22:41 -04:00
Matt Nadareski
41bfe8edce Fix tests 2026-04-21 12:06:33 -04:00
Matt Nadareski
9c66f6ef57 RamOption was a problematic read 2026-04-21 12:03:08 -04:00
Matt Nadareski
3a6ee3a37c Remove preemptive filtering 2026-04-21 10:59:45 -04:00
Matt Nadareski
7227f01ebc Support old item type filter string 2026-04-21 09:30:24 -04:00
Matt Nadareski
2bf686675e Port Reports namespace from ST 2026-04-20 14:03:49 -04:00
Deterous
c179cf410b XboxISO separate functions for partition extraction (#89)
* XboxISO funcs for partition extraction

* Add new parameter with default
2026-04-19 23:59:39 -04:00
Deterous
ab4bb4cca3 Fix XDVDFS bug (#88)
* Fix XDVDFS bug

* Move check and seek earlier
2026-04-19 22:13:01 -04:00
Matt Nadareski
2462305e0b Editorconfig cleanup, use extensions 2026-04-19 09:33:55 -04:00
Deterous
e383771fb6 XRD File Support (#87) 2026-04-19 09:04:25 -04:00
Matt Nadareski
bba9bfcbd6 Editorconfig cleanup 2026-04-18 21:32:37 -04:00
Deterous
94f86fe1d1 Peek in XDVDFS, Support XB00104M (#86)
* Peek in XDVDFS, Support XB00104M

* var
2026-04-18 21:30:44 -04:00
Matt Nadareski
63c13254d7 Handle all empty elements 2026-04-18 21:20:56 -04:00
Matt Nadareski
7d6092452f Handle uncommon case of no find elements 2026-04-18 21:10:01 -04:00
Matt Nadareski
6c2098c5d2 Add "boot" element for OpenMSX, fix missing skip 2026-04-18 20:53:18 -04:00
Matt Nadareski
70bef7d6c9 EOF loops always need to skip 2026-04-18 20:31:37 -04:00
Matt Nadareski
87df32284d Fix issue with comments in OpenMSX 2026-04-18 20:24:07 -04:00
Matt Nadareski
fda2e39296 The lists of keys are actually useful 2026-04-18 16:34:20 -04:00
Matt Nadareski
fe58061a2d Found out why these helpers were this way 2026-04-18 12:45:58 -04:00
Deterous
9a59f7c540 Fix SVOD serialization and printing (#84)
* Fix SVOD printing

* Fix SVOD descriptor

* Clearer check
2026-04-17 09:39:10 -04:00
Matt Nadareski
25ab9acb57 Do not access dictionary with index 2026-04-17 09:14:39 -04:00
Matt Nadareski
ecd4e7d1df Make user logs more accurate 2026-04-17 08:48:08 -04:00
Matt Nadareski
024200ebc4 Minor cleanup around loops 2026-04-16 23:39:33 -04:00
Matt Nadareski
ad9828de3c Slight cleanup around bucketing 2026-04-16 23:22:48 -04:00
Matt Nadareski
d6e974a3ab Make grouping/bucketing a private class too 2026-04-16 23:09:48 -04:00
Matt Nadareski
c482160b5b Fix tests 2026-04-16 22:29:03 -04:00
Matt Nadareski
d9a50d0c9e Add removal helper method 2026-04-16 22:16:03 -04:00
Matt Nadareski
7acb97e78e Add and use IndexedTable private class 2026-04-16 22:08:03 -04:00
Matt Nadareski
c409c47ae5 Remove outdated note 2026-04-16 19:17:45 -04:00
Matt Nadareski
2caab2c9cf Remove items when machine is removed for DB 2026-04-16 17:00:16 -04:00
Matt Nadareski
0feb4130fe Fix some DB-specific tests 2026-04-16 16:56:02 -04:00
Matt Nadareski
c90dcd7d59 Fix missing and unnecessary assignments 2026-04-16 16:41:01 -04:00
Matt Nadareski
2884dcab5b Remove need for GetMachineForItem 2026-04-16 16:11:25 -04:00
Matt Nadareski
ff69b83e05 Get methods should return all info 2026-04-16 15:55:12 -04:00
Matt Nadareski
2a2a2a46f9 Remove need for GetSourceForItem 2026-04-16 15:37:41 -04:00
Matt Nadareski
cb8d2885aa Add constructors with index instead of object 2026-04-16 14:14:30 -04:00
Matt Nadareski
3e55071d41 Add machines but don't invoke ItemDB 2026-04-16 13:59:15 -04:00
Matt Nadareski
af568d6a57 Make callers responsible for machine and source setting 2026-04-16 13:52:58 -04:00
Matt Nadareski
8f746824d6 Allow callers to set source and machine index 2026-04-16 13:27:29 -04:00
Matt Nadareski
334ab130da Remove unnecessary framework gating 2026-04-16 13:03:34 -04:00
Matt Nadareski
b8966f5e37 Remove unnecessary RemapDatItemToMachine method 2026-04-16 13:00:13 -04:00
Matt Nadareski
096f9d4b96 Remove external item to machine mappings 2026-04-16 12:54:43 -04:00
Matt Nadareski
b6c6296c29 Remove external item to source mappings 2026-04-16 12:39:24 -04:00
Matt Nadareski
8173806537 Add machine and source indexes to DatItem, currently unused 2026-04-16 12:26:52 -04:00
Matt Nadareski
af12310504 Rename ItemDictionaryDB to ItemDatabase 2026-04-16 11:51:28 -04:00
Matt Nadareski
5694cdf9a9 Editorconfig cleanup 2026-04-15 08:44:42 -04:00
Deterous
dab850103b XDVDFS FileWriter (#83) 2026-04-15 08:41:55 -04:00
Matt Nadareski
c646141bdf Remove DesignerCategory attribute usage 2026-04-15 00:27:48 -04:00
Matt Nadareski
ca02ed6b09 Add CICM sidecar models 2026-04-14 22:56:09 -04:00
Matt Nadareski
5b22902d03 Add QD image writer 2026-04-14 12:45:31 -04:00
Matt Nadareski
4e70a7665c Add NES cart writer 2026-04-14 12:33:27 -04:00
Matt Nadareski
650402df39 Add FDS image writer 2026-04-14 12:17:42 -04:00
Matt Nadareski
fead0d781c Add LNX cart writer 2026-04-14 12:03:19 -04:00
Matt Nadareski
3896b75b3b Add A78 cart writer 2026-04-14 11:59:12 -04:00
Matt Nadareski
ea2a1daadf Add NES image writing 2026-04-14 10:55:09 -04:00
Matt Nadareski
5968a367e8 Add FDS image writing 2026-04-14 10:33:30 -04:00
Matt Nadareski
b439cc3e35 Attempt to avoid input file overwriting 2026-04-14 10:27:23 -04:00
Matt Nadareski
3675a8ac75 Fix flaw in writable interface 2026-04-14 10:25:05 -04:00
Matt Nadareski
e16b485a7b Add LNX cart writing 2026-04-14 10:19:04 -04:00
Matt Nadareski
b51879bbec Add A78 cart writing 2026-04-14 10:13:05 -04:00
Matt Nadareski
f26c5bfebc Add IWritable interface 2026-04-14 09:59:23 -04:00
Matt Nadareski
4d5e7eb755 Minor editorconfig change 2026-04-13 10:04:24 -04:00
Matt Nadareski
7d14681fc9 Editorconfig and some manual cleanup 2026-04-13 09:43:40 -04:00
Deterous
0e5380ad1a Xbox ISO Support (#81)
* Xbox ISO support

* Fixes

* Print XGDType

* Review
2026-04-13 09:39:29 -04:00
Matt Nadareski
2494b44647 Start scaffolding disc image wrapper helper 2026-04-11 20:56:46 -04:00
Matt Nadareski
3d33f44eca Make inverted DataArea less impactful 2026-04-09 23:56:36 -04:00
Matt Nadareski
5f9eaef9f2 Make inverted DiskArea less impactful 2026-04-09 23:36:50 -04:00
Matt Nadareski
b0a9464d2b Make inverted Part less impactful 2026-04-09 23:29:00 -04:00
Matt Nadareski
5d4453fb1e Minor formatting fix 2026-04-09 22:57:50 -04:00
Matt Nadareski
ca3ebf33a8 Flatten Analog out of existence 2026-04-09 22:21:15 -04:00
Matt Nadareski
853e2ff5c0 Flatten Extension out of existence 2026-04-09 22:06:41 -04:00
Matt Nadareski
967d9ffe87 Flatten Instance out of existence 2026-04-09 21:34:00 -04:00
Matt Nadareski
27a93fa86a Clean up Rom ordering 2026-04-09 21:16:45 -04:00
Matt Nadareski
770f6f75d5 Flatten Condition out of existence 2026-04-09 21:13:55 -04:00
Matt Nadareski
2a700dee9c Add skeleton filter overrides for nested items 2026-04-09 20:33:34 -04:00
Deterous
c88ea9ce30 Support optional header in STFS, fix endianness in Descriptor (#80)
* Fix endianness in STFS Descriptor

* Support optional header for installer packages

* Fix field types

* Fix syntax

* Fix build
2026-04-09 09:57:26 -04:00
Matt Nadareski
45956e9128 This enum no longer has use 2026-04-08 23:37:59 -04:00
Matt Nadareski
baf68f3f81 Replace all instances of XXXXXX with proper test values 2026-04-08 21:04:11 -04:00
Matt Nadareski
9d63be5cc7 Merge pull request #79 from SabreTools/attempt-metadata-overhaul 2026-04-08 10:16:06 -04:00
Matt Nadareski
c78bde1fb2 Merge branch 'main' into attempt-metadata-overhaul 2026-04-07 22:20:28 -04:00
Matt Nadareski
574b993985 Editorconfig cleanup of STFS 2026-04-07 22:20:14 -04:00
Deterous
7485a43364 Secure Transacted File System (STFS) Support (#78)
* Initial STFS support

* Fix build errors

* Fix more build errors

* Final fix

* Cleanup printer

* Fix indent
2026-04-07 22:14:39 -04:00
Matt Nadareski
0363b1dd96 Slight code cleanliness updates 2026-04-07 11:23:10 -04:00
Matt Nadareski
94658ae225 Filter tree is reflection-free 2026-04-07 11:17:57 -04:00
Matt Nadareski
76c5dc40e3 Checkpoint reflection replacement 2026-04-07 10:37:03 -04:00
Matt Nadareski
6ba4a5b3ab Checkpoint reflection replacement 2026-04-07 10:26:58 -04:00
Matt Nadareski
18b3152a6c Checkpoint reflection replacement 2026-04-07 10:14:54 -04:00
Matt Nadareski
3412bbf33a Checkpoint reflection replacement 2026-04-07 09:36:43 -04:00
Matt Nadareski
278bfafae5 Checkpoint reflection replacement 2026-04-07 09:24:23 -04:00
Matt Nadareski
b4be581879 Checkpoint reflection replacement 2026-04-07 09:12:27 -04:00
Matt Nadareski
39a31b3a97 Checkpoint reflection replacement 2026-04-06 19:10:40 -04:00
Matt Nadareski
2d6e9d7875 Add RomVault subheader 2026-04-06 18:51:09 -04:00
Matt Nadareski
f3d6adbe1d Add RV-specific deduped status 2026-04-06 18:37:56 -04:00
Matt Nadareski
0350d8f58f Checkpoint reflection replacement 2026-04-06 16:19:20 -04:00
Matt Nadareski
2aca55a895 Add machine type analogue filtering again 2026-04-06 15:39:40 -04:00
Matt Nadareski
4772768c1f Handle item type filtering properly again 2026-04-06 15:03:16 -04:00
Matt Nadareski
adfc2cde84 Checkpoint reflection replacement 2026-04-06 14:46:34 -04:00
Matt Nadareski
6cab41b58e Merge branch 'main' into attempt-metadata-overhaul 2026-04-06 10:46:53 -04:00
Matt Nadareski
adedc502e3 Editorconfig cleanup of Xenon 2026-04-06 10:46:04 -04:00
Deterous
388567c9c6 Initial XEX support (#77)
* Initial XEX support

* Fix build

* Fix reader

* Fix reader, again

* Rename field to CertificateOffset

* Update reader

* Update Printer

* Update Printer

* Parse Certificate

* More info

* Fix build
2026-04-06 10:43:32 -04:00
Matt Nadareski
c0872cb97b Checkpoint reflection replacement 2026-04-06 10:18:00 -04:00
Matt Nadareski
e2b2f4d8a5 Rename "CRC" to "CRC32" where appropriate 2026-04-06 07:44:19 -04:00
Matt Nadareski
6a7d6e16b7 Fix framework difference 2026-04-05 19:28:06 -04:00
Matt Nadareski
f6f5818767 This utility method has been relocated in ST 2026-04-05 14:58:29 -04:00
Matt Nadareski
fe0768dad7 DepotInformation should be responsible for path generation 2026-04-05 14:02:06 -04:00
Matt Nadareski
d6edc33dd2 TypeHelper was only used by Filter in general 2026-04-05 11:28:48 -04:00
Matt Nadareski
d78c1eb9ed GetProperties is only used by filters 2026-04-05 11:24:47 -04:00
Matt Nadareski
15794e07f7 Remove one reflection-based helper 2026-04-05 11:21:56 -04:00
Matt Nadareski
d8e4f963c0 Statically cache item type names to avoid slowdowns 2026-04-05 11:15:07 -04:00
Matt Nadareski
f93d254a64 Try to make DAT statistics less intense 2026-04-05 11:00:36 -04:00
Matt Nadareski
25f50d19e2 Convert the last ToArrays that can be converted 2026-04-05 10:42:19 -04:00
Matt Nadareski
752f5d31d4 Avoid round-trip collection conversion 2026-04-05 10:40:54 -04:00
Matt Nadareski
83407133d6 Be more explicit about per-type missing fields 2026-04-05 10:22:44 -04:00
Matt Nadareski
742c991deb Remove now-redundant Equals methods 2026-04-05 02:24:05 -04:00
Matt Nadareski
3caf65822f Forgot to clean up some typing 2026-04-05 02:09:11 -04:00
Matt Nadareski
0eb5da5fd4 Default sort is never done, so CompareTo is useless 2026-04-05 01:59:34 -04:00
Matt Nadareski
337d4c0fed Metadata DatItem should be abstract 2026-04-05 01:51:07 -04:00
Matt Nadareski
5ffc9fef43 Cleanup around DatItem and DatItem<T>
This is both big and not big. The not big part of this is that I essentially just moved some stuff up to the typed type that used to live in the untyped type. The big part is that this allows every single DatItem implementation to be significantly cleaner with their implementations of the methods and internal model.
2026-04-05 01:36:32 -04:00
Matt Nadareski
1a10e10fd6 ModelBackedItem had no actual utility anymore 2026-04-05 01:19:46 -04:00
Matt Nadareski
1997346988 ModelBackedItem doesn't need to be equatable 2026-04-05 01:08:41 -04:00
Matt Nadareski
0ed13167ba Invert some if statements to be clearer 2026-04-05 00:35:09 -04:00
Matt Nadareski
285f3a267e NoFilter attribute no longer matters 2026-04-05 00:26:23 -04:00
Matt Nadareski
2969324015 None of these are constants now 2026-04-05 00:25:56 -04:00
Matt Nadareski
72dac4d6e2 The smallest cleanup 2026-04-05 00:21:19 -04:00
Matt Nadareski
ed72df79a6 Make FilterObject slightly more maintainable, slightly 2026-04-05 00:15:40 -04:00
Matt Nadareski
bf852ef038 DictionaryBase is no more, bon voyage 2026-04-04 23:13:36 -04:00
Matt Nadareski
e31be83832 RomProperties, no, not that one 2026-04-04 22:31:23 -04:00
Matt Nadareski
0b99602bc7 Convert Metadata file keys to proper properties 2026-04-04 21:17:28 -04:00
Matt Nadareski
3b2b4bc525 Notes 2026-04-04 20:35:57 -04:00
Matt Nadareski
bd8c008610 Attempt to make Equals redirection less 2026-04-04 20:30:33 -04:00
Matt Nadareski
0491133329 Move hash-based equality checkers lower down the chain 2026-04-04 20:04:01 -04:00
Matt Nadareski
4b20273d42 EqualTo has obsoleted itself into the bin 2026-04-04 19:55:44 -04:00
Matt Nadareski
a4f844cd6a Not sure how these slipped by 2026-04-04 19:49:02 -04:00
Matt Nadareski
8fe2b51d6f Further reduce calls to EqualTo 2026-04-04 19:47:00 -04:00
Matt Nadareski
c819be57a5 Reduce calls to EqualTo 2026-04-04 19:14:11 -04:00
Matt Nadareski
040ad65a5e DeepClone was left as self-referential, like this commit message 2026-04-04 18:48:00 -04:00
Matt Nadareski
f9437314cb Finalize property conversion for header 2026-04-04 18:46:35 -04:00
Matt Nadareski
ebf67d39cf Lazily make OfflineList-specific header items properties 2026-04-04 18:24:58 -04:00
Matt Nadareski
ca2a289a3f This remark was wrong 2026-04-04 17:59:39 -04:00
Matt Nadareski
cd49a64c2b Split header skipper and header row into separate properties 2026-04-04 17:58:09 -04:00
Matt Nadareski
b547792799 Two more header keys to properties 2026-04-04 16:34:13 -04:00
Matt Nadareski
2f72349e7b Small fixes to Machine 2026-04-04 16:20:42 -04:00
Matt Nadareski
8f82d3a28d Properties are not fields 2026-04-04 16:07:37 -04:00
Matt Nadareski
7a9f5d1fa1 Machine is now propertyful 2026-04-04 16:06:07 -04:00
Matt Nadareski
b8d4adf0e7 Clean up machine properties 2026-04-04 15:21:16 -04:00
Matt Nadareski
d08427f1ba Trurip finally gets integrated, more at 11 2026-04-04 15:17:58 -04:00
Matt Nadareski
12e1086838 Convert Dump to using properties 2026-04-04 14:23:31 -04:00
Matt Nadareski
274919fd6a Convert Dump to using properties 2026-04-04 14:23:27 -04:00
Matt Nadareski
096f1d9534 Remove get/set name methods where appropriate 2026-04-04 14:07:37 -04:00
Matt Nadareski
5ab48845e3 Remove one more use of DeepClone 2026-04-04 13:39:14 -04:00
Matt Nadareski
4acd2d9fd6 Reduce generic DictionaryBase use 2026-04-04 13:31:12 -04:00
Matt Nadareski
0458489a4f Remove two places where DeepClone wasn't needed 2026-04-04 13:13:16 -04:00
Matt Nadareski
9c1d2e7b9c Streamline metadata cloning 2026-04-04 13:11:10 -04:00
Matt Nadareski
ba371d971d Clean up EqualTo helpers 2026-04-04 12:41:36 -04:00
Matt Nadareski
9828119bdd Further reduce use of GetName and SetName 2026-04-04 12:31:47 -04:00
Matt Nadareski
d72c7c9cc0 Convert most keys to properties for Machine 2026-04-04 12:21:09 -04:00
Matt Nadareski
eb2f5babd9 Migrate DataArea, DiskArea, and Part to property-driven 2026-04-04 11:40:48 -04:00
Matt Nadareski
872fdc2a10 Reduce redirection for Name setters and getters 2026-04-04 10:25:49 -04:00
Matt Nadareski
845a0cb998 Convert Archive fully over to properties 2026-04-04 02:18:55 -04:00
Matt Nadareski
3f3f73a56f Convert Slot fully over to properties 2026-04-04 01:46:00 -04:00
Matt Nadareski
4bb670ac15 Convert Port fully over to properties 2026-04-04 01:36:42 -04:00
Matt Nadareski
9e721c5c43 Convert Input fully over to properties 2026-04-04 01:28:17 -04:00
Matt Nadareski
9ffa2a5e23 Convert Disk fully over to properties 2026-04-04 01:15:40 -04:00
Matt Nadareski
e5e279a48d Convert Device fully over to properties 2026-04-04 00:25:50 -04:00
Matt Nadareski
f7ac1073b0 Convert subitems for Configuration and DipSwitch 2026-04-04 00:08:56 -04:00
Matt Nadareski
a8c060ff26 Turn Condition keys into properties as a test 2026-04-03 23:33:11 -04:00
Matt Nadareski
2fdecebe66 Reduce use of GetName and SetName, prefer direct 2026-04-03 22:57:58 -04:00
Matt Nadareski
cdc55e721e Split Input.Control and Input.ControlAttr 2026-04-03 22:31:10 -04:00
Matt Nadareski
b55a932b2b String Machine keys to properties 2026-04-03 22:17:31 -04:00
Matt Nadareski
8e2f519e15 Convert most of Media over to properties 2026-04-03 19:47:58 -04:00
Matt Nadareski
5b3ff31f85 Make ReleaseDetails more complete 2026-04-03 19:11:55 -04:00
Matt Nadareski
c623c2b1f6 Make Serials more complete 2026-04-03 18:50:04 -04:00
Matt Nadareski
97b04b26a3 Make SourceDetails more complete 2026-04-03 18:31:31 -04:00
Matt Nadareski
5ccfde54f5 Convert last long key to property 2026-04-03 17:49:45 -04:00
Matt Nadareski
9df08780db Handle an enum that needed to be handled 2026-04-03 17:41:36 -04:00
Matt Nadareski
e01537c2f4 Get rid of Software metadata item
Apparently this was a mistake that has proliferated over a very long time. The Software item that was being modeled was actually the game/machine equivilent from SoftwareList. But because there's both an item called SoftwareList and a DAT type called SoftwareList, some wire got crossed and they were mentally combined. Undoing this allows for a more proper internal model, including a couple of extraneous keys that were included originally.
2026-04-03 17:25:09 -04:00
Matt Nadareski
154be08a53 Disable broken tree test 2026-04-03 16:58:48 -04:00
Matt Nadareski
e3927ca3e6 Fix longstanding TODOs around Software items 2026-04-03 16:02:44 -04:00
Matt Nadareski
fb711001e9 Add TODO question because I have no idea 2026-04-03 14:05:34 -04:00
Matt Nadareski
52edf9d20c Convert Release fully over to properties 2026-04-03 14:02:03 -04:00
Matt Nadareski
62b2fd3325 Original is cloneable and comparable 2026-04-03 13:48:43 -04:00
Matt Nadareski
716abed8b8 Convert Input mostly over to properties 2026-04-03 13:38:26 -04:00
Matt Nadareski
b6ab8a19be Convert Driver fully over to properties 2026-04-03 13:22:17 -04:00
Matt Nadareski
1d5514b29d Convert Display and Video fully over to properties 2026-04-03 13:08:36 -04:00
Matt Nadareski
32dd30adab Fix test 2026-04-03 12:31:33 -04:00
Matt Nadareski
2ed0c1f732 Convert Video mostly over to properties 2026-04-03 12:31:24 -04:00
Matt Nadareski
4fecf8b498 Remove long specifier for concrete values 2026-04-03 12:02:24 -04:00
Matt Nadareski
c9c31af8ea Convert Display mostly over to properties 2026-04-03 11:57:30 -04:00
Matt Nadareski
e604ef314b Convert DipLocation fully over to properties 2026-04-03 11:15:57 -04:00
Matt Nadareski
e3d3fe7c1a Fix broken tests 2026-04-03 11:05:59 -04:00
Matt Nadareski
280e65775a Convert ConfLocation fully over to properties 2026-04-03 10:59:04 -04:00
Matt Nadareski
33958d37fd Use ICloneable implementations in DeepClone 2026-04-03 10:33:10 -04:00
Matt Nadareski
dc773dba5e Convert Chip fully over to properties 2026-04-03 10:26:20 -04:00
Matt Nadareski
cdb74a9e26 Use IEquatable where possible 2026-04-03 10:10:34 -04:00
Matt Nadareski
600b0a6dbd Fill in some accidental gaps 2026-04-03 10:04:32 -04:00
Matt Nadareski
3f82312943 Convert Control fully over to properties 2026-04-03 09:46:10 -04:00
Matt Nadareski
08e0aa5b77 Convert refresh rates to properties, fix format 2026-04-03 00:04:11 -04:00
Matt Nadareski
3c6cfef070 Convert size keys to size properties 2026-04-02 23:45:17 -04:00
Matt Nadareski
11803aa34c Convert Sound.Channels to long as a test 2026-04-02 22:45:33 -04:00
Matt Nadareski
2b472c6f37 Migrate DAT filename to a property (used by ST) 2026-04-02 22:17:39 -04:00
Matt Nadareski
a914ee12c3 Convert DAT format to a property 2026-04-02 22:16:04 -04:00
Matt Nadareski
49d3d9c096 Migrate most header string keys to properties 2026-04-02 22:01:42 -04:00
Matt Nadareski
0df6378713 Move item type override per-item 2026-04-02 21:07:41 -04:00
Matt Nadareski
c0fd4d1334 Turn dupe type key into a metadata property 2026-04-02 20:41:14 -04:00
Matt Nadareski
c87db265dd Turn removal key into a metadata property 2026-04-02 20:34:09 -04:00
Matt Nadareski
d3f5dccf5b Make Source inherent to DatItem instead of passing through 2026-04-02 17:06:01 -04:00
Matt Nadareski
61ea4b2668 Compare machines in DatItem equality 2026-04-02 16:25:52 -04:00
Matt Nadareski
355aa4b94c Make Machine inherent to DatItem instead of passing through 2026-04-02 16:23:16 -04:00
Matt Nadareski
ca95e96402 Make "simple" metadata items equatable 2026-04-02 16:07:34 -04:00
Matt Nadareski
1e27b5d720 Make "simple" metadata items cloneable 2026-04-02 15:49:06 -04:00
Matt Nadareski
11c4097cba Rename Clone extension to DeepClone to avoid conflicts 2026-04-02 15:32:24 -04:00
Matt Nadareski
12ec3678b8 Fill in a few more string properties 2026-04-02 14:28:46 -04:00
Matt Nadareski
7df083c0b2 Reduce use of SetName 2026-04-02 13:35:11 -04:00
Matt Nadareski
c74942362c Name property cleanup, fixes 2026-04-02 13:21:37 -04:00
Matt Nadareski
c61aea7eac Move common string-only to properties 2026-04-02 11:18:49 -04:00
Matt Nadareski
8356aed5b0 Device.Manadatory converted to property 2026-04-02 02:43:29 -04:00
Matt Nadareski
3ef7b5860d Make large filter helper static 2026-04-02 02:28:00 -04:00
Matt Nadareski
276448a914 Merge branch 'main' into attempt-metadata-overhaul 2026-04-02 02:25:22 -04:00
Deterous
9993e574a0 Fix Xbox Executable TLS offset (#76)
* Fix XBE TLS address

* Break early

* Fix relative address
2026-04-02 02:24:08 -04:00
Matt Nadareski
81c47b297d Editorconfig cleanup of ZAR 2026-04-02 02:23:02 -04:00
Deterous
5bb8557555 ZArchive support (#75)
* ZArchive support

* Fix offset record format

* Simplfiy Extensions

* Delete unused writers and test data

* Rework reader

* Fix build
2026-04-02 02:18:47 -04:00
Matt Nadareski
c4524d20f0 Enum type conversion to property 2026-04-02 02:18:08 -04:00
Matt Nadareski
4c9ff19cf3 Runnable is Runnable 2026-04-01 22:06:24 -04:00
Matt Nadareski
451e89afff Boolean stuff convert to property 2026-04-01 21:59:16 -04:00
Matt Nadareski
826df09a3e Handle "Default" properties 2026-04-01 16:52:55 -04:00
Matt Nadareski
dfa39947ce Add GetProperties helper method and use it 2026-04-01 15:40:04 -04:00
Matt Nadareski
88d182cfd1 The map is curiously BLANK 2026-04-01 14:24:43 -04:00
Matt Nadareski
d2b8a4aa2c Remove NameKey from all current locations 2026-04-01 13:42:07 -04:00
Matt Nadareski
5812d197a5 Change Name to concrete property 2026-04-01 13:18:45 -04:00
Matt Nadareski
6810dce2ed Remove redundant ItemType declarations 2026-04-01 11:37:44 -04:00
Matt Nadareski
3e2bba866d Change ItemType into concerete property 2026-04-01 11:24:33 -04:00
Matt Nadareski
4035d9db86 Add some common Metadata objects for NIDB 2026-04-01 10:37:25 -04:00
Matt Nadareski
1cec6fa918 Add No-Intro database export reader and writer 2026-03-31 22:09:32 -04:00
Matt Nadareski
b82d464b12 Add No-Intro database export models 2026-03-31 20:44:17 -04:00
Matt Nadareski
3f5b3d10fd Not sure why this enum was separate 2026-03-31 19:48:26 -04:00
Matt Nadareski
af5d161fe4 Use original XML writer settings 2026-03-31 18:30:16 -04:00
Matt Nadareski
e2e19db294 Correctness fix to include XML declaration 2026-03-31 18:15:36 -04:00
Matt Nadareski
0b055a563e Directly document No-Intro Logiqx info 2026-03-31 18:10:44 -04:00
Matt Nadareski
4d362bb791 Use XmlTextWriter for XML DAT writing 2026-03-31 18:08:40 -04:00
Matt Nadareski
0670231606 Use XmlTextReader for XML DAT reading 2026-03-31 00:01:44 -04:00
Matt Nadareski
ea2bfbcb1f XDVDFS editorconfig cleanup 2026-03-29 21:55:23 -04:00
Deterous
28f4808dbb Read/write with variable initial offset (#74) 2026-03-29 21:54:16 -04:00
Matt Nadareski
0debcaa8d1 Slightly fix wrapper factory 2026-03-28 23:25:58 -04:00
Matt Nadareski
f1558587c3 Printer was really redundant 2026-03-28 23:12:41 -04:00
Matt Nadareski
d39c2e81d0 XDVDFS editorconfig cleanup 2026-03-28 23:06:46 -04:00
Matt Nadareski
07fe4415fe Reduce complexity of ExtractionTool invocation 2026-03-28 23:01:50 -04:00
Deterous
00ee106f4a Xbox DVD Filesystem support (XISO) (#73)
* Xbox DVD Filesystem support (XISO)

* Apply file attributes to extracted files

* Fix

* Fix build and PR review

* Support Archive file attribute
2026-03-28 22:59:30 -04:00
Matt Nadareski
a2c7588e1c Size filters should be AND not OR to allow for ranges 2026-03-27 21:07:48 -04:00
Matt Nadareski
5898bec0e9 Pedanitcally fill other filter operations 2026-03-27 20:57:11 -04:00
Matt Nadareski
8f71041e7e DatFormat does not need to be a flag 2026-03-27 10:47:20 -04:00
Matt Nadareski
4fd89ced29 Remove ported extension 2026-03-27 10:40:39 -04:00
Matt Nadareski
55522bf59b Port split format extension from ST 2026-03-27 09:31:19 -04:00
Matt Nadareski
de4566ec26 Fix Linux publish script 2026-03-27 08:49:08 -04:00
Matt Nadareski
078cd88bcd Gate unpublished builds behind a flag 2026-03-27 08:45:40 -04:00
Matt Nadareski
e9902f0907 Reduce extension confusion 2026-03-27 00:48:44 -04:00
Matt Nadareski
e5679b9152 A couple more small cleanup items 2026-03-27 00:32:12 -04:00
Matt Nadareski
7d29c3d7d9 Fix build 2026-03-27 00:16:58 -04:00
Matt Nadareski
1212603414 Reduce Reflection use in object creation 2026-03-26 23:59:53 -04:00
Matt Nadareski
9929199f31 Remove Reflection from DatItem<T> 2026-03-26 23:46:20 -04:00
Matt Nadareski
a7a622e118 Revert incorrect assumption 2026-03-26 23:14:38 -04:00
Matt Nadareski
225922e5bc TypeHelper comment and formatting cleanup 2026-03-26 23:10:06 -04:00
Matt Nadareski
465ece5ea3 Fix namespace mixup 2026-03-26 23:07:12 -04:00
Matt Nadareski
8de1fbc52f Reduce enum overhead in metadata 2026-03-26 22:51:14 -04:00
Matt Nadareski
29620c0c4f Metadata code cleanup 2026-03-26 20:40:49 -04:00
Matt Nadareski
3a3b20df11 Reduce repeated lookups and reads 2026-03-26 16:52:07 -04:00
Matt Nadareski
85aefc8d90 Move required extension 2026-03-26 15:16:12 -04:00
Matt Nadareski
52ad2ff89c Move required extension 2026-03-26 15:15:59 -04:00
Matt Nadareski
8356fc5970 Thin out ModelBackedItem wrapper class 2026-03-26 13:52:00 -04:00
HeroponRikiBestest
e61aec89ea Use correct section size for matroschka package extraction (#71)
Not sure how it took this long for me to encounter an issue.
2026-03-26 13:40:21 -04:00
Matt Nadareski
363ffee738 AttributeHelper code was only ever used in converters 2026-03-26 11:30:40 -04:00
Matt Nadareski
ce2ddf1636 Simplify SabreTools.Metadata base namespace 2026-03-26 11:27:29 -04:00
Matt Nadareski
dd29c8245a Slight simplification to GetDepotPath 2026-03-26 11:23:30 -04:00
Matt Nadareski
fdee2103ad Rename GetAttribute to GetMappingAttribute to be more accurate 2026-03-26 11:17:43 -04:00
Matt Nadareski
b72fcfc60b Fill in a couple READMEs 2026-03-26 10:58:14 -04:00
Matt Nadareski
3f6e5c2383 Migrate these internal extensions to real extensions 2026-03-26 09:34:19 -04:00
Matt Nadareski
2ae3291a30 BSP and VBSP should not share lump types 2026-03-26 09:29:32 -04:00
Matt Nadareski
c216129b37 Be more explicit about support 2026-03-26 09:05:58 -04:00
Deterous
2fdc2407dd Extract blank directories from ISO9660 filesystem (#70) 2026-03-25 09:04:14 -04:00
Matt Nadareski
5205fac739 Add non-published packages to publish scripts 2026-03-24 21:20:11 -04:00
Matt Nadareski
8a51f5d8ab Wire through already-added CRC-16 and CRC-64 2026-03-24 21:19:09 -04:00
Matt Nadareski
9c7993f8f1 Run tests and fix the rest 2026-03-24 19:42:36 -04:00
Matt Nadareski
8f49e190d8 Fix everything 2026-03-24 19:17:25 -04:00
Matt Nadareski
e11a08b587 Port metadata functionality from ST 2026-03-24 18:03:01 -04:00
Matt Nadareski
5f0fdcfd8d Update to IO 2.0.0 2026-03-24 18:02:49 -04:00
Matt Nadareski
1053ff7f23 Add ConditionalHashEquals tests 2026-03-22 20:26:28 -04:00
Matt Nadareski
de6a08539a Wrong filename 2026-03-22 20:22:22 -04:00
Matt Nadareski
219392e3a0 Port DictionaryBase extensions from ST
Notably, this is missing the equality checking because ST introduces a new type called "ModelBackedItem", which is specifically a type backed by a DictionaryBase item, with extensions. It is very similar to a Wrapper, but has different common utility. If there is a way to migrate that here, then the equality methods can come here as well.
2026-03-22 20:22:04 -04:00
Matt Nadareski
2ade7495c7 This will be public anyway 2026-03-22 02:44:12 -04:00
Matt Nadareski
1acd448838 Make validation methods public 2026-03-22 02:05:43 -04:00
Matt Nadareski
a8ed7a38f8 Fix issue with 3DS key assignment 2026-03-22 01:58:11 -04:00
Matt Nadareski
5208fc3e33 Add removal comment 2026-03-22 01:53:40 -04:00
Matt Nadareski
3dfbd23867 Pass in fixed crypto key flag as bool 2026-03-22 01:52:26 -04:00
Matt Nadareski
994a366770 Put initial value generators in common region 2026-03-22 01:35:36 -04:00
Matt Nadareski
d1b061fac5 Port 3DS decrypt/encrypt in a functional manner 2026-03-22 01:34:36 -04:00
Matt Nadareski
6e73c93c89 Port PartitionKeys class from NDecrypt 2026-03-22 01:10:39 -04:00
Matt Nadareski
5544ab0b8a Add majority of data extensions tests, fix minor issues 2026-03-21 20:09:10 -04:00
Matt Nadareski
8bec2087eb Add removal note 2026-03-21 17:55:14 -04:00
Matt Nadareski
50e27f926d Use separate libraries as references in executables 2026-03-21 16:41:09 -04:00
Matt Nadareski
ecc88316bd Nicer readme linking 2026-03-21 16:34:52 -04:00
Matt Nadareski
7689c6dd07 Libraries
This change looks dramatic, but it's just separating out the already-split namespaces into separate top-level folders. In theory, every single one could be built into their own Nuget package. `SabreTools.Serialization` still builds the normal Nuget package that is used by all other projects and includes all namespaces.
2026-03-21 16:26:56 -04:00
Matt Nadareski
bec0aeb04c Another size read mismatch in IRD 2026-03-20 22:09:07 -04:00
Matt Nadareski
2f8ee5545e IRD game title is UTF-8 2026-03-20 22:07:35 -04:00
Matt Nadareski
015ad062ac Prefix sizes were being read incorrectly for IRD parsing 2026-03-20 22:01:13 -04:00
Matt Nadareski
ae6608e2a7 Allow GCF checksum header to have dummy0 value of 0 (fixes #69) 2026-03-19 16:18:24 -04:00
Matt Nadareski
ca78898e93 Move wrapper factory file after namespace change 2026-03-18 22:17:07 -04:00
Matt Nadareski
a6ee92da32 Fix build 2026-03-18 17:27:06 -04:00
Matt Nadareski
b2eb0b5e67 Extensions classes should be named as such 2026-03-18 17:15:03 -04:00
Matt Nadareski
685fadbfdf Move wrapper utility classes into Wrappers namespace 2026-03-18 16:55:48 -04:00
Matt Nadareski
638934e6b0 Attributes should live in the Models namespace where it's used 2026-03-18 16:49:14 -04:00
Matt Nadareski
cd2e170175 Move ported attribute to root 2026-03-18 16:42:23 -04:00
Matt Nadareski
68b5436f59 Wrappers to its own namespace 2026-03-18 16:37:59 -04:00
Matt Nadareski
b2f074048d Create extensions test project 2026-03-18 16:21:16 -04:00
Matt Nadareski
3147974879 Create OID test project 2026-03-18 16:20:00 -04:00
Matt Nadareski
1a53c093b8 OID to its own namespace 2026-03-18 16:18:10 -04:00
Matt Nadareski
e4d26d4d81 Put interfaces in respective namespaces 2026-03-18 16:13:02 -04:00
Matt Nadareski
b3e25bb6a6 Fix interface file names to match internal names 2026-03-18 16:02:40 -04:00
Matt Nadareski
37d5b79b96 Rename directories to visually help determine real namespace 2026-03-18 15:56:45 -04:00
Matt Nadareski
75fef90a14 Reader options apparently moved fully 2026-03-17 19:47:27 -04:00
Matt Nadareski
9389797448 Bump version 2026-03-15 20:23:35 -04:00
Matt Nadareski
8b7112d12f uint is more correct 2026-03-14 20:51:22 -04:00
Matt Nadareski
4add8f3e64 Update TODO for accuracy 2026-03-14 11:52:07 -04:00
Matt Nadareski
9e6c6af985 Fix missing section case, should never be hit 2026-03-14 11:24:29 -04:00
Matt Nadareski
c82b56d084 Better clarify comment 2026-03-14 11:23:29 -04:00
Matt Nadareski
ea4c51b9f2 Use first nonzero-sized section as overlay address basis 2026-03-14 11:20:40 -04:00
HeroponRikiBestest
463c3ba50d Accurately get OverlayAddress for UPX-compressed executables (#67)
* Add alternate path for OverlayAddress for upx-compressed executables, for benefit of extractions that need an accurate overlay address.

* Use SectionNames

* Update SabreTools.Serialization/Wrappers/PortableExecutable.cs

---------

Co-authored-by: Matt Nadareski <mnadareski@outlook.com>
2026-03-14 11:18:19 -04:00
Matt Nadareski
92356903cc Format alternate title IDs too 2026-03-13 21:15:34 -04:00
Matt Nadareski
82ed800a32 Add formatted Title ID output 2026-03-13 21:01:38 -04:00
Matt Nadareski
81cd284a80 Add debug/retail-adjusted values as passthru 2026-03-13 13:32:33 -04:00
Matt Nadareski
1eba7403a3 Add Cxbx-Reloaded references 2026-03-13 12:31:33 -04:00
Matt Nadareski
b47af580e3 Add remaining certificate fields 2026-03-13 12:29:17 -04:00
Matt Nadareski
cff722ba67 Fix issues found during testing 2026-03-13 12:10:45 -04:00
Matt Nadareski
810338d011 Create XBE wrapper 2026-03-13 11:40:01 -04:00
Matt Nadareski
76910047e7 Fill out XBE reader 2026-03-13 11:05:31 -04:00
Matt Nadareski
a8e53c2d07 Remove invalid extensions 2026-03-13 11:01:27 -04:00
Matt Nadareski
bb61a1b795 Add RVA mapping helpers for XBE 2026-03-13 10:52:54 -04:00
Matt Nadareski
1d83d40b9b Move XBE models, add skeleton reader 2026-03-13 10:51:31 -04:00
Matt Nadareski
3459c99b29 Add XBE models 2026-03-13 10:28:05 -04:00
Matt Nadareski
d102e2fc0b Add SNES models 2026-03-11 11:47:39 -04:00
Matt Nadareski
c7a932c07f Add secondary FDS/QD sources 2026-03-10 20:05:51 -04:00
Matt Nadareski
1c334dfb1b Add untested FDS <-> QD conversion 2026-03-10 19:49:12 -04:00
Matt Nadareski
a6656fd5e6 Add QD file support 2026-03-10 18:11:42 -04:00
Matt Nadareski
1e1bf2e27c Handle headerless FDS 2026-03-10 17:58:49 -04:00
Matt Nadareski
de5794b3ae Fix FDS reader 2026-03-10 17:47:11 -04:00
Matt Nadareski
f4192416f7 Fix build 2026-03-10 17:31:09 -04:00
Matt Nadareski
70fe830241 Add fwNES FDS file support 2026-03-10 17:27:58 -04:00
Matt Nadareski
e8394d6665 Rename NES cart models a bit 2026-03-10 17:06:01 -04:00
Matt Nadareski
2b64d34e7a Add Atari Lynx cart support 2026-03-10 14:28:09 -04:00
Matt Nadareski
1909851ed4 Add XGD security sector models 2026-03-10 13:18:58 -04:00
Matt Nadareski
9ce074529a Use documentation for endianness 2026-03-08 13:12:42 -04:00
Matt Nadareski
e2581fc423 Add Atari 7800 cart support 2026-03-07 21:27:11 -05:00
Matt Nadareski
f75bc21d54 Add NES cart extraction 2026-03-07 11:32:47 -05:00
Matt Nadareski
8844632fc7 Nicer NES formatting 2026-03-06 16:50:23 -05:00
Matt Nadareski
2f3ecb88f0 Remove unused enum 2026-03-06 16:26:19 -05:00
Matt Nadareski
6e93aa65b6 Split more things 2026-03-06 16:17:18 -05:00
Matt Nadareski
ca264ce91e Cleanup 2026-03-06 16:00:36 -05:00
Matt Nadareski
b339f213b8 Split NES 2.0 combined pieces 2026-03-06 15:53:16 -05:00
Matt Nadareski
93a6926b43 Split flag 10 2026-03-06 15:36:02 -05:00
Matt Nadareski
5e758d4b38 Split flag 7 2026-03-06 15:16:41 -05:00
Matt Nadareski
756d5fe03c Split flag 6 2026-03-06 14:59:19 -05:00
Matt Nadareski
ff67caee25 Make flags slightly more readable 2026-03-06 14:26:40 -05:00
Matt Nadareski
234f865234 Fix minor typo 2026-03-06 13:53:58 -05:00
Matt Nadareski
2d380770f5 Full printing for NES is overwhelming 2026-03-06 13:51:32 -05:00
Matt Nadareski
3f23df868f Fix logic inversion issue 2026-03-06 13:49:15 -05:00
Matt Nadareski
d150bde546 Add NES cart tests 2026-03-06 13:43:16 -05:00
Matt Nadareski
d108a815d7 Finish NES cart extension properties 2026-03-06 13:39:47 -05:00
Matt Nadareski
7dfb015dd5 Fix reading PRG and CHR 2026-03-06 13:23:17 -05:00
Matt Nadareski
5c973bac96 Fill in large number of extensions for NES cart 2026-03-06 13:18:49 -05:00
Matt Nadareski
c6b96d82dc Add simple extension properties 2026-03-06 12:51:02 -05:00
Matt Nadareski
9f2765edd0 Add NES cart printing 2026-03-06 12:47:59 -05:00
Matt Nadareski
b77e866be4 Add NES TODOs 2026-03-06 11:12:14 -05:00
Matt Nadareski
3995017174 Wire up NES cart to wrapper factories 2026-03-06 11:11:26 -05:00
Matt Nadareski
714c8d4901 Add generic NES cart wrapper 2026-03-06 11:08:41 -05:00
Matt Nadareski
9e68cf7abe Add NES cart reader 2026-03-06 11:03:54 -05:00
Matt Nadareski
1875adfe5f Add NES 1.0 and 2.0 models 2026-03-06 10:35:07 -05:00
Matt Nadareski
ebe4ff7426 Update packages 2026-03-05 11:27:45 -05:00
Matt Nadareski
e9eb3eb4be Generic resource entry is now used 2026-02-12 18:25:24 -05:00
Matt Nadareski
c99f86ee95 Add unused generic resource entry 2026-02-12 16:55:27 -05:00
Matt Nadareski
bb7b1c50a1 Move debug object parsers 2026-02-12 16:07:04 -05:00
Matt Nadareski
d56c8a3d83 Move unused parser 2026-02-12 16:04:16 -05:00
Matt Nadareski
c5f732584b Do the same for string table resource 2026-02-12 16:02:09 -05:00
Matt Nadareski
3e0a6dbf32 Move old version of AlignToBoundary 2026-02-12 15:53:40 -05:00
Matt Nadareski
b91c060dad Do the same for assembly manifest 2026-02-12 15:50:24 -05:00
Matt Nadareski
f0a0fc3137 Do the same for font groups 2026-02-12 15:46:50 -05:00
Matt Nadareski
ad3df18b24 Do the same for version info 2026-02-12 14:08:12 -05:00
Matt Nadareski
d089af71a4 Remove now-redundant As extensions 2026-02-12 13:54:53 -05:00
Matt Nadareski
5f9f037430 Add note about migration to IO 2026-02-12 13:48:21 -05:00
Matt Nadareski
939a2bab41 Move some extension parsers to more common location 2026-02-12 13:44:41 -05:00
Matt Nadareski
2d969048e3 Add currently-unused resource data base class 2026-02-12 13:09:44 -05:00
Matt Nadareski
dc86ed1456 Use accelerator table type 2026-02-12 13:04:37 -05:00
Matt Nadareski
a2b392234d Slight cleanup for clarity 2026-02-12 12:52:52 -05:00
Matt Nadareski
f56014b8a6 This can never be null 2026-02-12 12:46:49 -05:00
Matt Nadareski
3a485d34a1 Correct a couple of things 2026-02-12 12:27:36 -05:00
Matt Nadareski
e1da5f192c Do not overread PKZIP extra fields on malformed (fixes #65) 2026-01-29 14:05:36 -05:00
Matt Nadareski
c15809dd72 Remove unused usings 2026-01-28 21:31:59 -05:00
HeroponRikiBestest
89a67d1bd2 Implement model, reader, wrapper for valve SKU sis files. (#62)
* Try again

* Fix import alphebetization

* Fixes.

* first part of first attempt at a model

* Reimplement Sku Sis parsing

* First round of fixes

* Make sure stream isn't closed

* Missed this newline
2026-01-28 21:30:08 -05:00
Matt Nadareski
c4c6709478 Make note of why only partial driverstatus 2026-01-28 09:55:07 -05:00
Matt Nadareski
5e1f6ac4b3 Partially hook up driverstatus for CMP 2026-01-28 09:52:35 -05:00
Matt Nadareski
8f8d86d0bb Clean up some formatting things 2026-01-27 12:03:01 -05:00
HeroponRikiBestest
ecca11e2f3 Flush before closing in microsoftcabinet.extraction (#61)
I had previously been under the assumption that closing always guaranteed a flush. I don't know of any issues that were being caused, but I should push this before i forget.
2026-01-25 21:41:35 -05:00
Matt Nadareski
527b09c6bc Add debug flag to interface definitions (fixes #60) 2026-01-25 20:07:59 -05:00
Matt Nadareski
69b6595434 Missed this one too 2026-01-25 19:48:07 -05:00
Matt Nadareski
59b918c75f Apparently didn't rename this 2026-01-25 19:46:39 -05:00
Matt Nadareski
344132b50a Add editorconfig, fix issues 2026-01-25 16:15:05 -05:00
Matt Nadareski
a35e58e9cc Fix some errant formatting 2026-01-25 15:08:37 -05:00
Matt Nadareski
4300d94858 Use newer "is not null" syntax 2026-01-25 14:32:49 -05:00
Matt Nadareski
ee85a84d8f Use newer "is null" syntax 2026-01-25 14:30:18 -05:00
Matt Nadareski
2959d82231 Formatting cleanup 2026-01-25 13:38:52 -05:00
HeroponRikiBestest
5dfe6aefb0 Convert Installshield Executable code to use proper reader/wrapper instead of living in PortableExecutable (#59)
* Figure out how to access OverlayAddress in wrapper or reader (ideally the latter) for a non-PE reader/wrapper

* Code works

* Remove TODOs

* First round of fixes.

* use constants

* remove comment
2026-01-25 13:36:17 -05:00
HeroponRikiBestest
7f7d0f84ef Re-enable stream extraction for MScab (#58)
* Re-enable extraction from stream

* Remove todo pre PR

* Properly support all situations, remove whitespace
2026-01-25 12:24:28 -05:00
Matt Nadareski
4bfaf36e24 Formatting cleanup 2026-01-24 21:43:08 -05:00
HeroponRikiBestest
695fc4b0af Change mscab extraction to use state handling, break into more helper methods (#57)
* Attempt 1

* Use private helper class

* Remove comment

* Add missing summaries

* Don't use create pattern

* Remove removed variable summary

* Reduce what needs to be passed in

* Further reduce what needs to be passed in

* These didn't get tabbed for some reason

* First round of fixes.

* Second round of changes

* Add a few comments.
2026-01-24 21:41:23 -05:00
Matt Nadareski
f16ed9742f Support WoD info CMP block type 2026-01-24 11:37:29 -05:00
Matt Nadareski
6bfe68b8cf Formatting and comment cleanup 2026-01-24 10:24:35 -05:00
HeroponRikiBestest
2e5c5b3c79 Extract Ms-cabs while reading instead of loading all datablocks into memory (#56)
* WIP

* WIP 2

* Todo: you're missing a read somehow and getting misaligned by two bytes? maybe properly implementing the buffer will magically fix it

* continued blocks my behated

* Pre-major-testing

* Forgot to add summaries

* Attempt to properly roll back. The state i wanted to roll back to wasn't in a commit before.

* Figured out the issue with the rolled back commit, this has to be a while loop because of 0 byte files. Reimplemented clean code.

* Comment so I don't forget why it's like this

* Skip unsupported compression types before opening filestream.

* Reenable non-start cab skipping

* TODO so i don't forget

* TODO so I don't forget

* iterate on continued block correctly.

* Handle incomplete extraction better

* Remove TODOs to ready for PR comments

* Missed one

* Some minor fixes before rewriting everything

* Next round of fixes.

* Next set of fixes

* Fix debug output
2026-01-24 10:08:18 -05:00
Matt Nadareski
2a6e193756 Formatting cleanup 2026-01-05 13:48:36 -05:00
HeroponRikiBestest
65a86d87f0 Fix mszip relying on exceptions (#52)
* Better fix

* initial

* Fixed

* Move function to proper location, clear memory better

* work so far

* more

* more work

* No more per file seeking

* Finished work for now.

* First round of fixes.

* Return if array is empty too
2026-01-05 13:45:20 -05:00
HeroponRikiBestest
d7131dfa4c fix naming (#53) 2025-12-04 11:10:46 -05:00
HeroponRikiBestest
a228b16314 Fix GCF extraction (#48) 2025-12-04 10:46:13 -05:00
Matt Nadareski
b8c9048ac6 Update GrindCore to 0.6.5 2025-12-02 19:35:20 -05:00
HeroponRikiBestest
0b54350d59 Explicitly handle password-protected archives rather than repeatedly throwing exceptions (#47)
* Explicitly handle password-protected archives rather than repeatedly throwing exceptions

* Fix logic error

* Continues

* Remove bool
2025-12-02 09:38:11 -05:00
Deterous
59eddb7129 Fix ISO9660 extraction of large files (#46)
* ExtentLength is uint

* Fix

* fix2

* fix3

* fix4

* Invert multi extent final extent logic
2025-12-02 07:31:31 -05:00
Matt Nadareski
1096232f9d Update GC libraries 2025-11-30 19:40:35 -05:00
Matt Nadareski
4b39ee8d00 Add CRC-16 and CRC-64 dat support 2025-11-29 10:11:05 -05:00
Matt Nadareski
27a9b12bbf Bump version 2025-11-25 07:45:09 -05:00
Matt Nadareski
11319c3341 Update GC.SharpCompress 2025-11-25 07:44:29 -05:00
Matt Nadareski
4de061e0d1 Bump version 2025-11-24 08:59:19 -05:00
Matt Nadareski
258e894c30 Update GC.SharpCompress 2025-11-23 19:59:28 -05:00
Matt Nadareski
8658eaf4e0 Format GHA definitions 2025-11-17 08:39:16 -05:00
Matt Nadareski
6d341abc75 Fix comment about CFB 2025-11-17 08:33:00 -05:00
Matt Nadareski
4821d63b4a Off-by-one spacing 2025-11-15 09:10:34 -05:00
Matt Nadareski
0617bf3170 Process all folders in all MS-CAB files in a set (fixes #43) 2025-11-15 09:00:28 -05:00
Matt Nadareski
425d13a2ac Fix inconsistencies in IS-CAB 2025-11-14 23:21:04 -05:00
Matt Nadareski
8a1e90f537 Reduce unnecessary casts 2025-11-14 21:33:55 -05:00
Matt Nadareski
ddc00948ed Remove red herring zlib code 2025-11-14 21:08:55 -05:00
Matt Nadareski
c96ee81f06 Simplify fixed statements 2025-11-14 20:36:46 -05:00
Matt Nadareski
f6201e2c35 In-depth cleanup with .NET 10 concepts 2025-11-14 14:06:43 -05:00
Matt Nadareski
d63fcfcf7f Minor formatting change to external code 2025-11-14 10:30:15 -05:00
Matt Nadareski
dcc50c4c23 Remove empty .gitmodules 2025-11-14 10:28:55 -05:00
Matt Nadareski
60e46e580d Cache more properties using the field keyword 2025-11-14 10:14:50 -05:00
Matt Nadareski
0638998773 Use auto-fields where possible 2025-11-14 09:48:00 -05:00
Matt Nadareski
ad3113987b Add support for .NET 10 2025-11-14 09:06:59 -05:00
Matt Nadareski
f2f0d0f2e7 Try to fix self-referencing MS-CAB 2025-11-13 14:07:46 -05:00
Matt Nadareski
f7fd2f6f65 Name some type parameters 2025-11-11 09:57:38 -05:00
Matt Nadareski
281c18e21d Bump version 2025-11-06 08:08:10 -05:00
Matt Nadareski
1a9c8b5392 Scaffolding for the future 2025-11-06 08:01:04 -05:00
Deterous
831a272f4b Final ISO9660 fix (#41)
* debug

* using

* Test fix

* Final fix
2025-11-05 20:26:42 -05:00
Matt Nadareski
f47e68b9ba Add Mode0 and Mode2 formless models 2025-11-05 09:49:32 -05:00
Matt Nadareski
eaabd2ee77 Add static readers for CD-ROM sector types 2025-11-05 09:37:56 -05:00
Matt Nadareski
a269edd6ea Missed one explicit type 2025-11-05 09:20:48 -05:00
Matt Nadareski
3bb501ce0c Separate out some helper methods 2025-11-05 09:14:37 -05:00
Deterous
d0006a4653 Custom ISO Stream for full CDROM support (#40)
* Implement custom ISO stream for CDROM support

* Delete old files

* Delete old test

* Leaner CDROM wrapper

* Fix custom stream

* WrapperBase using ISO stream

* Reset stream after deserializing

* Fix SeekOrigin

* Return to cached position

* CDROM Constants

* correct ns

* fix href
2025-11-05 08:20:34 -05:00
Matt Nadareski
c48a1394bc Be descriptive about types 2025-11-04 14:15:39 -05:00
Matt Nadareski
fcf7fcfd44 Be descriptive about types 2025-11-04 10:49:03 -05:00
Matt Nadareski
cca08e7103 Use consistent naming 2025-11-04 10:27:00 -05:00
Matt Nadareski
b908732f5c Fix logical block extension 2025-11-04 10:25:55 -05:00
Matt Nadareski
4ee4a6e85f Slight extension cleanup 2025-11-04 10:07:57 -05:00
Matt Nadareski
7990f11bab Remove unnecessary null checks 2025-11-04 09:54:24 -05:00
Matt Nadareski
427f7c9136 Remove unnecessary null checks 2025-11-04 09:46:03 -05:00
Matt Nadareski
f938f1593d Formatting update for readability 2025-11-04 09:15:12 -05:00
Matt Nadareski
480a1834ed Logic inversion and slight cleanup 2025-11-03 20:16:54 -05:00
Matt Nadareski
df5acc648c Minor cleanup 2025-11-03 10:31:30 -05:00
Matt Nadareski
10569e6aa1 Add tests for CDROM 2025-11-03 10:29:52 -05:00
Matt Nadareski
e5103b4830 Fix format comment for ExtractionTool 2025-11-03 09:27:57 -05:00
Matt Nadareski
513646fc53 Fix ExtractionTool publish 2025-11-03 09:03:45 -05:00
Matt Nadareski
27f723bf2f CascLibSharp isn't used and can be removed 2025-11-03 08:53:04 -05:00
Matt Nadareski
6511ecb5ad Merge pull request #39 from SabreTools/storm
Directly include StormLibSharp
2025-11-03 08:39:47 -05:00
Matt Nadareski
7bf6e6f344 Code cleanup and slight modernization 2025-11-03 08:36:12 -05:00
Matt Nadareski
d3e340ae39 Add and use MPQ filename constants 2025-11-02 23:21:29 -05:00
Matt Nadareski
22167a9617 Recursion isn't needed now 2025-11-02 22:27:02 -05:00
Matt Nadareski
48bea55133 Enable extraction on all .NET versions (not OSes) 2025-11-02 22:20:21 -05:00
Matt Nadareski
42239919e5 Enable StormLib for all .NET versions 2025-11-02 22:07:40 -05:00
Matt Nadareski
4840d9df6e Remove NoWarn and fix issues 2025-11-02 21:41:58 -05:00
Matt Nadareski
1378b87ea6 Directly include StormLibSharp code 2025-11-02 21:11:39 -05:00
Matt Nadareski
6b48164b97 Remove StormLibSharp as submodule 2025-11-02 21:07:51 -05:00
Matt Nadareski
50b09aa249 Automated cleanup 2025-11-02 19:28:16 -05:00
Deterous
ecbd147f6d CD-ROM (Volume Descriptor Set) support (#37)
* CD-ROM Wrapper

* Fix CDROMVolume Reader

* Fix SectorMode enum
2025-11-02 19:21:19 -05:00
HeroponRikiBestest
c13df79848 Fix extraction of recent MPF-zipped logs (#38)
* Fix extraction of recent MPF-zipped logs

* Use greater than or equal to

* corrected logic
2025-11-02 08:35:02 -05:00
Deterous
48bcc1de5b ISO9660: Skip interleaved files and other fixes (#35)
* Skip interleaved files

* Fix warning logic

* Refactor

* Fix extraction

* Multi extent

* review
2025-11-01 22:52:41 -04:00
Matt Nadareski
d082f5de25 Auto formatting cleanup 2025-10-31 21:07:13 -04:00
Deterous
c2321669b6 Support ISO9660 Extended Attribute Record (#34)
* Support ISO9660 Extended Attribute Record

* fix

* Fix

* Don't extract multi-extent files

* ReadUInt16LittleEndian

* debug

* Fix

* Skip EAR when extracting files

* Add comment about EAR

* Fix same-name extraction

* Safer directory parsing

* even safer

* return null

* more directory record checks

* not nullable nullable

* init system use

* valid records should pass

* review

* remove empty case
2025-10-31 21:04:45 -04:00
Matt Nadareski
e382635b85 Fix accidental recursion 2025-10-31 14:01:25 -04:00
Matt Nadareski
b4e02d7f8c Ensure default values in models when not optional 2025-10-31 13:59:28 -04:00
Matt Nadareski
0dc8a0b6c0 One missed explicit endian read 2025-10-31 09:36:28 -04:00
Matt Nadareski
171834986d Fix build from previous cleanup 2025-10-31 00:01:35 -04:00
Matt Nadareski
97af686b73 ZSTD model cleanup 2025-10-30 23:59:25 -04:00
Matt Nadareski
7d627ffc6f XZP model cleanup 2025-10-30 23:59:08 -04:00
Matt Nadareski
d924f25eb2 XZ model cleanup 2025-10-30 23:57:15 -04:00
Matt Nadareski
abd8ef3b1f Xbox model cleanup 2025-10-30 23:55:08 -04:00
Matt Nadareski
e9b8dba3a6 WiseInstaller model cleanup 2025-10-30 23:54:22 -04:00
Matt Nadareski
aaff7e7332 WAD3 model cleanup 2025-10-30 23:50:44 -04:00
Matt Nadareski
2fa00d1a16 VPK model cleanup 2025-10-30 23:48:26 -04:00
Matt Nadareski
8a2a2ecd12 TAR model cleanup 2025-10-30 23:45:14 -04:00
Matt Nadareski
98517bdd8c StarForce model cleanup 2025-10-30 23:43:06 -04:00
Matt Nadareski
dfe76f7e7e SpoonInstaller model cleanup 2025-10-30 23:41:40 -04:00
Matt Nadareski
a2e24b1f5f SGA model cleanup 2025-10-30 23:40:45 -04:00
Matt Nadareski
6a4e76e245 SevenZip model cleanup 2025-10-30 23:34:20 -04:00
Matt Nadareski
1ebec97e0e SecuROM model cleanup 2025-10-30 23:34:06 -04:00
Matt Nadareski
b9f03b02f0 RealArcade model cleanup 2025-10-30 23:31:19 -04:00
Matt Nadareski
2c06760778 RAR model cleanup 2025-10-30 23:31:01 -04:00
Matt Nadareski
3f0ee70b71 Quantum model cleanup 2025-10-30 23:30:45 -04:00
Matt Nadareski
05b34f158b PortableExecutable model cleanup 2025-10-30 23:29:24 -04:00
Matt Nadareski
e08db935b4 PlayStation4 model cleanup 2025-10-30 23:07:12 -04:00
Matt Nadareski
47da068bd3 PlayStation3 model cleanup 2025-10-30 23:06:46 -04:00
Matt Nadareski
9de669606d PlayJ model cleanup 2025-10-30 23:05:24 -04:00
Matt Nadareski
a02d50e61d PKZIP model cleanup 2025-10-30 23:01:55 -04:00
Matt Nadareski
069dab7fba PIC model cleanup 2025-10-30 22:58:02 -04:00
Matt Nadareski
d65edadbbb PFF model cleanup 2025-10-30 22:56:23 -04:00
Matt Nadareski
6307a51c0a PAK model cleanup 2025-10-30 22:54:37 -04:00
Matt Nadareski
d27c602bdf OLE model cleanup 2025-10-30 22:52:56 -04:00
Matt Nadareski
59fe9cb113 Nitro model cleanup 2025-10-30 22:51:16 -04:00
Matt Nadareski
b4b7ba75cb NewExecutable model cleanup 2025-10-30 22:47:17 -04:00
Matt Nadareski
d02e0c16c4 NCF model cleanup 2025-10-30 22:39:08 -04:00
Matt Nadareski
4aa0eb54b7 N3DS model cleanup 2025-10-30 22:36:21 -04:00
Matt Nadareski
c4f73abcb6 MSDOS model cleanup 2025-10-30 22:15:10 -04:00
Matt Nadareski
73dec51a4d MoPaQ model cleanup 2025-10-30 22:12:06 -04:00
Matt Nadareski
b7c3c094ae MicrosoftCabinet model cleanup 2025-10-30 22:07:29 -04:00
Matt Nadareski
97702ab3d5 LZ model cleanup 2025-10-30 22:03:22 -04:00
Matt Nadareski
a9b5fe706c LinearExecutable model cleanup 2025-10-30 22:00:42 -04:00
Matt Nadareski
198d48610c LDSCRYPT model cleanup 2025-10-30 21:55:01 -04:00
Matt Nadareski
c0e0344914 IRD model cleanup 2025-10-30 21:54:27 -04:00
Matt Nadareski
d49b2f1b60 InstallShieldExecutable model cleanup 2025-10-30 21:52:20 -04:00
Matt Nadareski
ec7172466b InstallShieldCabinet model cleanup 2025-10-30 21:51:15 -04:00
Matt Nadareski
d75a512ead InstallShieldArchiveV3 model cleanup 2025-10-30 21:43:38 -04:00
Matt Nadareski
af8b6906b6 GZIP model cleanup 2025-10-30 21:40:25 -04:00
Matt Nadareski
96bc301e6d GCF model cleanup 2025-10-30 21:38:17 -04:00
Matt Nadareski
c10749f34d DVD model cleanup 2025-10-30 21:32:21 -04:00
Matt Nadareski
0e4235c8ba Delphi model cleanup 2025-10-30 21:30:41 -04:00
Matt Nadareski
b2d31bb87e CueSheets model cleanup 2025-10-30 21:30:13 -04:00
Matt Nadareski
3ee88793da COFF model cleanup 2025-10-30 21:29:24 -04:00
Matt Nadareski
ad0f01c3ef CHD model cleanup 2025-10-30 21:27:37 -04:00
Matt Nadareski
63a96a7cf8 CFB model cleanup 2025-10-30 21:26:19 -04:00
Matt Nadareski
b8d8ca9a5c BZip2 model cleanup 2025-10-30 21:22:33 -04:00
Matt Nadareski
6b0fca31ae BSP model cleanup 2025-10-30 21:21:56 -04:00
Matt Nadareski
c147b12b10 Bitmap model cleanup 2025-10-30 20:58:03 -04:00
Matt Nadareski
7884b0b775 BFPK model cleanup 2025-10-30 20:57:35 -04:00
Matt Nadareski
9f3c263328 BDPlus model cleanup 2025-10-30 20:55:39 -04:00
Matt Nadareski
b830ce3d73 AdvancedInstaller model cleanup 2025-10-30 20:54:32 -04:00
Matt Nadareski
e8b7f33bf0 AACS model cleanup 2025-10-30 20:52:35 -04:00
Matt Nadareski
eae75c5943 Allow byte arrays to be non-null in most models 2025-10-30 20:44:16 -04:00
Matt Nadareski
c1f5ebcae1 Remove experiments 2025-10-30 19:50:03 -04:00
Matt Nadareski
acb8e98fe2 Add ImgBurn and UltraISO check extensions 2025-10-30 17:04:29 -04:00
Matt Nadareski
a24a92e97c Add unset reserved bytes extension 2025-10-30 16:22:05 -04:00
Matt Nadareski
f2d2fe97bb Override 2025-10-30 12:06:42 -04:00
Matt Nadareski
705252eec7 Unify Skeleton to ISO-9660 2025-10-30 12:03:13 -04:00
Matt Nadareski
69ae0456f0 Add skeleton printing and tests 2025-10-30 11:50:37 -04:00
Deterous
f07bd07cce Redumper skeleton support (#32)
* Skeleton support

* hide ISO extract

* Return true

* Don't inherit ISO9660

* fix

* fix2

* Skeleton
2025-10-30 11:46:45 -04:00
Matt Nadareski
9db2d2ca05 Reduce complexity of Zstd filename generation 2025-10-30 10:23:50 -04:00
Deterous
85248b0135 ISO 9660 Extraction (#31)
* ISO9660 Extraction

* Fix build

* Decode strings in Printer

* Double comment
2025-10-30 10:00:10 -04:00
Matt Nadareski
8663edc7df Fix unsynced ISO position 2025-10-30 08:20:46 -04:00
Matt Nadareski
b9cc9e40fd Changes based on a code sweep with unrelated issue 2025-10-30 07:51:08 -04:00
HeroponRikiBestest
5ce085ad2b Implement basic ZSTD detection and extraction. (#30)
* Implement basic ZSTD detection and extraction.

* Fix comment

* Remove newline

* Add newline

* Move section

* more newlines banished to the ether

* fix comment and name

* fix final i think
2025-10-29 22:01:23 -04:00
Matt Nadareski
d24f8a2fce Add ECMA link to models readme 2025-10-29 10:11:39 -04:00
Matt Nadareski
a73e830209 This extension is useful 2025-10-29 09:46:12 -04:00
Matt Nadareski
146fb42fd0 Replace remaining Seek with SeekIfPossible 2025-10-29 09:34:52 -04:00
Matt Nadareski
5b54ed719e Better integrate new printing model 2025-10-29 09:23:45 -04:00
Matt Nadareski
02d011228e IRD wrapper exists and should be used 2025-10-29 08:57:01 -04:00
Matt Nadareski
07adfd20a3 Add tests for ISO9660 2025-10-29 08:55:45 -04:00
Matt Nadareski
1d00abd6cc Make printing a wrapper extension 2025-10-29 08:53:14 -04:00
Deterous
36c2cc2f15 ISO 9660 support (#29)
* Begin defining ISO9660 models

* Fix initial models

* Improve ISO9660 models

* ISO9660 models

* Fix fields

* Nullable and enums

* Fix flags attribute

* Start ISO9660 Reader code

* semicolon

* Fix build

* Use EqualsExactly

* Fix build

* Update ISO9660.cs

* Update ISO9660.cs

* Move DirectoryRecordDateTime class

* ParseDirectoryRecordDateTime function

* ST refactoring

* fix return

* return array

* ISO9660 wrapper

* Initial printing code

* semicolon

* Fix

* orphan variable name

* fix null ref

* ISO9660 Printer

* Fix DirectoryRecord parsing

* fix

* test

* test

* Fix reader

* extractable ISO

* partial wrapper class

* namespace

* extension property

* path tables

* Cleanup

* rename directory

* fix

* fix

* typo

* fix2

* Fix

* Cleanup reader

* Count list property

* Parse Path Tables

* fix model name

* fix

* fix2

* fix3

* print path table records

* debug errors

* debug error

* debug

* undo debug

* Fix casting

* Validate path table locations

* print table numbers

* Printer cleanup

* fix printer

* printer++

* Print DecDateTime

* else if

* BootSystemUse

* Use Linq

* custom zero check

* fix

* Update ISO9660.cs

* Update ISO9660.cs

* Update ISO9660.cs

* Update ISO9660.cs

* fix

* debug

* debug2

* debug3

* debug4

* debug5

* debug6

* debug7

* debug8

* Array.TrueForAll

* Update ISO9660.cs

* fix

* cleanup

* typo

* Use BothInt numerics

* using SabreTools.Numerics

* Test nonnull

* nonnull bothint

* Print invalid BothInts

* Print directory record

* typo

* fix

* null check

* directory descriptors

* cleanup printer

* semicolon

* Fix

* flags never null

* more non nullable

* no null

* AppendLineBothEndian

* fix

* rename to Directory

* fix

* namespace

* full namespace

* fix

* cleanup

* Parse directories

* fix

* Fix

* Test parse directories

* PeekByteValue

* Revert CI changes

* Dummy extractor

* Review and fixes

* Fixes

* Final fix

* big endian directory search

* fix big endian changes

* Final fix
2025-10-29 08:46:08 -04:00
Matt Nadareski
27cf01ce84 Add printing cases for empty alongside null 2025-10-28 09:52:53 -04:00
Matt Nadareski
1e94163693 Add both-endian StringBuilder extensions
This has to use a new name for the both-endian handling because otherwise the implicit type handling will otherwise cause compilation errors.
2025-10-28 09:49:38 -04:00
Matt Nadareski
db1f94775b Convert some known Peek calls 2025-10-27 22:55:25 -04:00
Matt Nadareski
ce394eb4e9 Seek, if possible 2025-10-27 22:43:56 -04:00
Matt Nadareski
15109bed88 Update IO to 1.8.0 2025-10-27 22:15:54 -04:00
Matt Nadareski
8a18c8de34 Update rolling tag 2025-10-26 20:31:03 -04:00
HeroponRikiBestest
2f093a80c7 increase buffer size for isexe reading / writing based on deterous's … (#28)
* increase buffer size for isexe reading / writing based on deterous's input

* remove comment
2025-10-26 18:54:35 -04:00
Matt Nadareski
5df1af9c17 Minor cleanup and additions 2025-10-23 16:05:12 -04:00
HeroponRikiBestest
d5ab37a5a6 Add extraction for installshield executables. (#27)
* Add extractor for installshield executables.

* Add comment

* Fix intendation.

* Ensure PRs recursively pull

* Rebase

* Fix formatting for parsex

* newline before obj.name

* Changed while loop check to a position vs length check

* Specify type for chunkSize

* declare chunksize as a const int outside of the loop

* Open file writer with using

* Call fs.flush after every write.

* Improved chunk writing loop.

* Remove now-unecessary variable

* Properly handle extracting files of size greater than int32.

* Use long for overlay address

* create deserializer outside of loop.

* Move null check.

* Don't cache position.

---------

Co-authored-by: Matt Nadareski <mnadareski@outlook.com>
2025-10-23 15:38:51 -04:00
Matt Nadareski
ed9ecf0da9 Ensure PRs recursively pull 2025-10-23 12:08:47 -04:00
Matt Nadareski
4fc17197ca Fix inverted logic of file only flag 2025-10-19 17:59:56 -04:00
Matt Nadareski
94a9cf0c3f Minor tweak to Wise debug statements 2025-10-17 09:56:04 -04:00
Matt Nadareski
1d9e12183f Bump version 2025-10-07 12:42:06 -04:00
Matt Nadareski
aaa8bbe709 This was inconsistent too 2025-10-07 11:25:35 -04:00
Matt Nadareski
805d1b9ad8 Not sure why this part was inconsistent 2025-10-07 11:21:39 -04:00
Matt Nadareski
d24d3e5adb Remove now-unused constants 2025-10-07 10:48:31 -04:00
Matt Nadareski
d3a7d552c3 Use main feature pattern with InfoPrint 2025-10-07 10:20:57 -04:00
Matt Nadareski
9f1c5e2bd2 Use main feature pattern with ExtractionTool 2025-10-07 10:04:19 -04:00
Matt Nadareski
1ec4ea8354 Update packages 2025-10-07 09:37:42 -04:00
Matt Nadareski
e4fab52489 Use CommandLine library for executables 2025-10-06 09:32:01 -04:00
Matt Nadareski
e029fa4833 Skip warning around GC.SharpCompress inclusion 2025-10-05 17:02:44 -04:00
Matt Nadareski
2c3f229a6a Bump version 2025-10-05 16:59:33 -04:00
Matt Nadareski
3558d3532c Do not update offset on name offset 2025-10-02 13:33:51 -04:00
Matt Nadareski
ad5314dc22 Minor tweak 2025-10-01 20:08:33 -04:00
Matt Nadareski
eaa5bb5662 Sections can't be null 2025-10-01 20:06:05 -04:00
Matt Nadareski
fcdc703595 Update readme to be accurate again 2025-09-30 20:58:52 -04:00
Matt Nadareski
ef9fa562ab More BZip documenting 2025-09-30 20:35:40 -04:00
Matt Nadareski
ac285c48fe Start documenting BZip in code 2025-09-30 20:25:18 -04:00
Matt Nadareski
e57ad65210 Migrate to GrindCore fork of SharpCompress 2025-09-30 19:52:14 -04:00
Matt Nadareski
0fc3a30422 Print a couple more XZ fields 2025-09-30 14:09:40 -04:00
Matt Nadareski
49f6704694 Add initial XZ printer 2025-09-30 14:05:34 -04:00
Matt Nadareski
6df712c538 Add XZ parsing to wrapper 2025-09-30 13:56:21 -04:00
Matt Nadareski
bda3076a30 Further XZ parsing fixes 2025-09-30 13:56:11 -04:00
Matt Nadareski
89e8e7c706 Fix more XZ parsing; use read-from-end 2025-09-30 13:22:26 -04:00
Matt Nadareski
c10835d221 Start fixing XZ parsing 2025-09-30 13:08:53 -04:00
Matt Nadareski
a6801350ea Fix issue with XZ enum 2025-09-30 12:48:12 -04:00
Matt Nadareski
c7a5a62041 Require exact versions for build 2025-09-30 11:09:37 -04:00
Matt Nadareski
749b35e5cb Slight tweak to CHD v5 model 2025-09-30 10:59:44 -04:00
Matt Nadareski
3c520d33eb Add XZ reader, fix some minor issues 2025-09-30 09:47:19 -04:00
Matt Nadareski
635170a051 Add reference for BZ2 2025-09-29 23:38:40 -04:00
Matt Nadareski
9619311d11 Store variable-length numbers as ulong 2025-09-29 23:32:58 -04:00
Matt Nadareski
4bee14835c Fix last couple of commits 2025-09-29 23:12:23 -04:00
Matt Nadareski
f44059e16a Add XZ variable length helper methods 2025-09-29 23:07:05 -04:00
Matt Nadareski
bfb206a06d Add XZ models 2025-09-29 22:56:53 -04:00
Matt Nadareski
6b7b05eb31 Port some extensions for GZip from ST 2025-09-29 22:04:10 -04:00
Matt Nadareski
a9a2a04332 Store raw extras field for odd formatting 2025-09-29 21:49:20 -04:00
Matt Nadareski
50459645dd Add a couple GZ constants 2025-09-29 21:39:37 -04:00
Matt Nadareski
564386038f Try using Environment instead of compiler flags 2025-09-29 12:29:14 -04:00
Matt Nadareski
9f229aad47 Bump version 2025-09-29 07:27:50 -04:00
Matt Nadareski
f6f6ea21b4 Sync README with help text 2025-09-28 21:47:37 -04:00
Matt Nadareski
ec416d5631 Document all local samples 2025-09-27 22:47:43 -04:00
Matt Nadareski
335cbca8fb Add clarification 2025-09-27 22:04:20 -04:00
Matt Nadareski
ab8d5ec475 Split unknown AddD field, fix TODO 2025-09-27 22:02:10 -04:00
Matt Nadareski
ef9f050fbf Signature is clearly a string 2025-09-27 21:47:55 -04:00
Matt Nadareski
46b1838d72 Clean up some things around AddD 2025-09-27 21:46:03 -04:00
HeroponRikiBestest
2b9a527743 Small fix just in case. (#25) 2025-09-27 12:59:02 -04:00
HeroponRikiBestest
cb41f8a8a6 Temporary fix for solid archive detection until SharpCompress makes another release. (#24) 2025-09-27 12:32:10 -04:00
Matt Nadareski
fcf003af7d Split Wise extraction to be smarter 2025-09-27 08:26:57 -04:00
Matt Nadareski
350924545c Fix bzip constants 2025-09-26 23:49:35 -04:00
Matt Nadareski
ae6bf0f2da Fix issues from manual testing 2025-09-26 22:52:09 -04:00
Matt Nadareski
7395d9842c Complete Spoon Installer extraction 2025-09-26 22:30:59 -04:00
Matt Nadareski
741a1e13d0 Add framework for Spoon Installer extraction 2025-09-26 22:27:27 -04:00
Matt Nadareski
447064afc1 Add Spoon Installer reader 2025-09-26 22:23:20 -04:00
Matt Nadareski
a443a6833a Add integer values for better research 2025-09-26 22:18:41 -04:00
Matt Nadareski
160239eba7 Add Spoon Installer models and notes 2025-09-26 22:12:27 -04:00
Matt Nadareski
04fb3fd363 Fix documentation issue 2025-09-26 22:02:35 -04:00
Matt Nadareski
ba60c9b516 Add extraction for Advanced Installer 2025-09-26 19:56:51 -04:00
Matt Nadareski
f8ddfcf5ae Add framework for Advanced Installer extraction 2025-09-26 19:43:39 -04:00
Matt Nadareski
c379bdcadc Fix description 2025-09-26 16:49:21 -04:00
Matt Nadareski
575caeda92 Make fixes from manual testing 2025-09-26 16:38:56 -04:00
Matt Nadareski
0d4dcf4a60 Start implementing Advanced Installer reader 2025-09-26 16:30:38 -04:00
Matt Nadareski
ddb14a69d0 Forgot to rename Writers folder 2025-09-26 16:29:16 -04:00
Matt Nadareski
f1ace61076 Introduce and use BaseMetadataSerializer 2025-09-26 16:00:33 -04:00
Matt Nadareski
0f5f866cd2 Rename IModelSerializer to ICrossModel 2025-09-26 15:48:36 -04:00
Matt Nadareski
bd866c5b05 Update package tags 2025-09-26 15:36:22 -04:00
Matt Nadareski
07ea1abbf8 Use correct block format for readme 2025-09-26 15:33:38 -04:00
Matt Nadareski
6853376f60 Unify type parameter naming 2025-09-26 15:28:53 -04:00
Matt Nadareski
0e67f0bff4 Move wrapper interfaces to better namespace 2025-09-26 15:20:49 -04:00
Matt Nadareski
6035c19f47 Move IPrinter interface to better namespace 2025-09-26 15:13:43 -04:00
Matt Nadareski
592a3d3505 Rename *Serializer interfaces to *Writer 2025-09-26 15:10:59 -04:00
Matt Nadareski
2c092ed665 Rename *Deserializer interfaces to *Reader 2025-09-26 15:02:43 -04:00
Matt Nadareski
2bd4a00df4 Rename Serializers to Writers 2025-09-26 14:59:45 -04:00
Matt Nadareski
f0639b28b9 Rename Deserializers to Readers 2025-09-26 14:57:20 -04:00
Matt Nadareski
775bab6656 Add AACS extension 2025-09-26 14:27:49 -04:00
Matt Nadareski
c82d865cd5 Move Extensions to Data path 2025-09-26 13:15:55 -04:00
Matt Nadareski
0b95b9509a Move Printers to Data path 2025-09-26 13:11:57 -04:00
Matt Nadareski
d8185e3970 Move Models to Data path 2025-09-26 13:06:18 -04:00
Matt Nadareski
b3a3766d77 Create and use Attributes namespace 2025-09-26 12:44:16 -04:00
Matt Nadareski
3681682fe8 Internal rename of OID namespace to have Data prefix 2025-09-26 12:29:52 -04:00
Matt Nadareski
12c292d038 Namespace reference cleanup 2025-09-26 12:27:10 -04:00
Matt Nadareski
5af4de2878 Migrate remaining models from Models 2025-09-26 12:09:34 -04:00
Matt Nadareski
2e7f18c407 Migrate non-executable models from Models 2025-09-26 11:57:18 -04:00
Matt Nadareski
48248b2832 Add namespace to the readme 2025-09-26 11:43:49 -04:00
Matt Nadareski
c6082fa7c7 Migrate support file models from Models 2025-09-26 11:42:28 -04:00
Matt Nadareski
3af19510a8 Migrate archive models from Models 2025-09-26 10:57:15 -04:00
Matt Nadareski
2a12b8132f Add README for Models namespace 2025-09-26 10:24:36 -04:00
Matt Nadareski
3daec985ba Migrate metadata models from Models 2025-09-26 10:20:48 -04:00
Matt Nadareski
4b79ee103c Simplify overlay address finding slightly 2025-09-25 21:34:41 -04:00
Matt Nadareski
077abd590a Use constants, add CFB detection to overlays and resources 2025-09-25 21:13:07 -04:00
Matt Nadareski
cab890b1d9 Remove erroneous duplicate code 2025-09-25 20:29:51 -04:00
Matt Nadareski
d3f0858ec4 Forgot the second adjustment 2025-09-25 20:28:25 -04:00
Matt Nadareski
97896b91d7 Cap overlay at 0x10000 bytes 2025-09-25 20:14:41 -04:00
Matt Nadareski
ca354b3b7f Comment about entry point data caching 2025-09-25 16:24:20 -04:00
Matt Nadareski
d035211a64 Off by one? 2025-09-25 16:20:15 -04:00
Matt Nadareski
75728a4d1d Handle large overlays in extraction 2025-09-25 14:07:01 -04:00
Matt Nadareski
265789ea84 Overlay address in PE should be long, fix caching 2025-09-25 13:55:44 -04:00
Matt Nadareski
4577311432 Adjust overlay address for PE using certificate table 2025-09-25 13:53:56 -04:00
Matt Nadareski
963c333c2e Cache the overlay length 2025-09-25 13:50:51 -04:00
Matt Nadareski
6eff6cf3b6 Add TODOs to handle large overlays 2025-09-25 13:41:51 -04:00
Matt Nadareski
c9794691bb Limit overlay caching to int.MaxValue 2025-09-25 13:40:29 -04:00
Matt Nadareski
9574232719 Bump version 2025-09-24 11:06:47 -04:00
Matt Nadareski
676bf584d6 Clean up some console writes 2025-09-24 10:55:39 -04:00
Matt Nadareski
0a4fd01ede Gate MS-CAB warning behind debug to avoid confusion 2025-09-24 10:51:27 -04:00
Matt Nadareski
6cb4023498 Update namespaces in README 2025-09-24 10:50:12 -04:00
Matt Nadareski
8f775dbb3b This should be ObjectIdentifier not strictly ASN.1 2025-09-24 10:47:00 -04:00
Matt Nadareski
91785eab1f Fix tests 2025-09-24 10:40:39 -04:00
Matt Nadareski
4f8751667a Namespace ASN models until Models is updated 2025-09-24 10:40:30 -04:00
Matt Nadareski
ad7508c464 Add some more OIDs 2025-09-24 10:11:21 -04:00
Matt Nadareski
97a9e141ae Add some more OIDs 2025-09-24 09:54:18 -04:00
Matt Nadareski
842a0c3daf Remove useless PathProcessor helper class 2025-09-24 09:43:27 -04:00
Matt Nadareski
b6acde9145 Make consistent with other deserializers 2025-09-24 09:27:24 -04:00
Matt Nadareski
b97dbc2ac5 Simplify extension code slightly 2025-09-24 09:22:23 -04:00
Matt Nadareski
e03852bd7e Simplify ASN.1 integration 2025-09-24 09:19:46 -04:00
Matt Nadareski
0db5de204e Rename TLV deserializer to be more consistent 2025-09-24 09:06:26 -04:00
Matt Nadareski
5fe3f14419 Make TypeLengthValue more model-like 2025-09-24 09:00:48 -04:00
Matt Nadareski
ffe1d9a82d Create and use TypeLengthValue deserializer 2025-09-24 08:54:25 -04:00
Matt Nadareski
11d6560290 Update IO to 1.7.5 2025-09-24 08:30:24 -04:00
Matt Nadareski
e29d8e6728 Integrate ASN.1 code from separate library 2025-09-24 08:25:11 -04:00
Matt Nadareski
918e81a4cb Move extensions to new namespace for cleanliness 2025-09-23 09:58:44 -04:00
Matt Nadareski
ad0ddede38 Fix reference issue 2025-09-22 21:21:43 -04:00
Matt Nadareski
e969b12884 Move wrapper factory up a level 2025-09-22 21:14:33 -04:00
Matt Nadareski
7a5475255f Fix the fake wrapper tests 2025-09-22 20:14:01 -04:00
Matt Nadareski
0ffd436de8 Update packages 2025-09-22 20:07:18 -04:00
Matt Nadareski
4f685187e9 COFF naming doesn't need to continue 2025-09-22 12:56:19 -04:00
Matt Nadareski
2b356b37b1 Sync NE overlay handling with PE 2025-09-22 10:08:46 -04:00
Matt Nadareski
7c56268eb1 Add PFF version 0 detection 2025-09-22 09:35:46 -04:00
Matt Nadareski
970a54e6e3 Add placeholder SFFS wrapper 2025-09-22 09:13:27 -04:00
Matt Nadareski
e35ddf0780 Always overwrite on output, ensure flushed streams 2025-09-21 21:10:40 -04:00
Matt Nadareski
bf35b7c10b Bump version 2025-09-21 12:35:37 -04:00
Matt Nadareski
4026b8ca09 Handle differently-encoded XMLs as textfiles 2025-09-21 12:10:58 -04:00
Matt Nadareski
6d2e2d8c3b Handle some invalid parsing cases that were missed previously 2025-09-21 11:44:58 -04:00
Matt Nadareski
a2b08157cc Fix issue with split resource tables 2025-09-21 11:23:53 -04:00
Matt Nadareski
0108ecf4c1 Bump version 2025-09-21 09:33:55 -04:00
Matt Nadareski
4921da0bb5 Fix issues from porting MPQ from BOS 2025-09-21 00:04:16 -04:00
Matt Nadareski
0c836bb3b1 Try one more thing? 2025-09-20 23:39:49 -04:00
Matt Nadareski
a8e41c1505 Try this 2025-09-20 23:24:12 -04:00
Matt Nadareski
f67e1c9d2b Bump version 2025-09-20 22:38:08 -04:00
Matt Nadareski
f0ce58a79e Move two things out of the lock 2025-09-20 22:32:54 -04:00
Matt Nadareski
b7f782c1b7 Update packages 2025-09-20 22:31:58 -04:00
Matt Nadareski
5e39e169b2 Clean up PE printing a bit 2025-09-20 20:17:38 -04:00
Matt Nadareski
104c5ccad4 XML resources and overlay 2025-09-20 19:48:45 -04:00
Matt Nadareski
d15b4d7d23 Bump version 2025-09-20 10:47:38 -04:00
Matt Nadareski
60e6a75d5e Make public again 2025-09-20 10:40:19 -04:00
Matt Nadareski
484415d0e5 Ensure the resource table has been parsed for version info 2025-09-20 10:36:09 -04:00
Matt Nadareski
0ef9b447c4 Remove extraneous semicolon 2025-09-20 10:34:08 -04:00
Matt Nadareski
8f64e2defd Minor cleanup to previous commit 2025-09-20 10:32:53 -04:00
HeroponRikiBestest
fbdadce129 Add Matroschka processing. (#23)
* Made changes

* Temporary hack to not rely on models without significantly changing current code. Revert all of this with offset-based reading later.

Also added unnecessary casting in wrapperfactory so serialization will build locally. Revert this, since I assume it somehow builds fine for GA/sabre/etc.

* small fixes

* Store matroschka section as PE extension

* Move extractor out of deserializer, remove weird hack

* Potential GA fix

* More potential GA fixes.

* I have no idea why GA hits that error but not me

* Giving up on GA for now

* fix locking issues

* Fix GA building; thank you sabre

* Minor improvements all around

* Catch some braced single-line if statements

* Use var more

* Seperate deserializer into helper methods

* Make file path reading much more sane

* Removed MatroschkaHeaderType enum

* Removed MatroschkaGapType enum, further simplify matgaphelper.

* Remove MatroschkaHasUnknown enum, further simplify Unknown value reading.

* Cache initial offset.

* Remove TryCreate patterns.

* Rename matroschka variable to package

* Newline after object

* Rename to obj

* Remove a few unecessary TODOs

* Seperate hexstring byte read to another line.

* Fix documentation.

* More private static

* Changed data.position setting to seeking. NTS: check if this broke anything later

* rename entries to obj

* MatroschkaEntry to var

* Newline

* Alphabetical

* More alphabetical.

* section to package

* Move private variables.

* Move to extension properties.

* Revert section finding.

* Remove uneeded _dataSource lock and access.

* combine lines and make var

* Combine two null checks.

* Packaged files, some past commits I think I forgot to push.

* Missed two

* newline

* space

* newline

* Combine two lines

* Removed comment

* Return false explicitly

* Change hashing string implementation

* Fix order.

* Use offset reading instead of filedataarray

* Change file reading around a little preemptively for BOS

---------

Co-authored-by: Matt Nadareski <mnadareski@outlook.com>
2025-09-20 10:00:54 -04:00
Matt Nadareski
d3e7abfaa3 Normalize ReadRangeFromSource use 2025-09-20 09:49:42 -04:00
Matt Nadareski
b2279e97b2 CHD is all big-endian 2025-09-18 21:18:43 -04:00
Matt Nadareski
7cf969336f Fix this bumble 2025-09-18 20:54:30 -04:00
Matt Nadareski
f73d48166a Source isn't needed here anymore 2025-09-18 09:46:01 -04:00
Matt Nadareski
53af618fe4 Proof-of-concept Wise section caching 2025-09-18 09:40:15 -04:00
Matt Nadareski
5d2cf58477 Fix this being finicky 2025-09-17 12:56:32 -04:00
Matt Nadareski
664e7dce28 Greater than but not equal 2025-09-17 10:30:35 -04:00
Matt Nadareski
14a8f00864 Clean up nonstandard deserializers 2025-09-16 23:24:49 -04:00
Matt Nadareski
0b889fdc06 Remove weird holdover property 2025-09-16 23:11:14 -04:00
Matt Nadareski
e336efc149 Do the same for serializers 2025-09-16 22:29:52 -04:00
Matt Nadareski
4cd52162eb Static implementations using reflection go away 2025-09-16 22:25:40 -04:00
Matt Nadareski
eab9fff711 One slipped through the cracks 2025-09-16 22:22:32 -04:00
Matt Nadareski
d4f3511060 These don't need to call the reflection one 2025-09-16 22:21:22 -04:00
Matt Nadareski
ed12bbb35c Avoid hidden reflection call for most cases 2025-09-16 22:20:13 -04:00
Matt Nadareski
aa4629fe99 MPQ needs a distinction 2025-09-16 22:12:18 -04:00
Matt Nadareski
1950f23cf4 This should actually be a different exception type 2025-09-16 22:08:50 -04:00
Matt Nadareski
ca7c88cef6 Add better summaries for things 2025-09-16 22:07:05 -04:00
Matt Nadareski
10848e6c51 Fix issue with seeking by introducing more constructors 2025-09-16 21:54:26 -04:00
Matt Nadareski
f5d0f065c1 Handle unknown AACS records a bit better for now 2025-09-16 20:11:41 -04:00
Matt Nadareski
17b0573b0b Handle memory-padded resources tables and non-local resources 2025-09-12 10:50:22 -04:00
Matt Nadareski
7f1d843d96 Minor bugfix in name retrieval 2025-09-12 09:28:27 -04:00
Matt Nadareski
cc4837c1d1 More partial classes for reasonable things 2025-09-12 09:09:40 -04:00
Matt Nadareski
588ee5bfe4 Make partial classes for extraction 2025-09-12 09:02:03 -04:00
Matt Nadareski
e9b1b2750f Fill out the placeholder 2025-09-11 12:32:44 -04:00
Matt Nadareski
1d6fa06e97 Placeholder for section table trailer data 2025-09-11 12:24:56 -04:00
Matt Nadareski
2c22924239 Seek to section table to match docs 2025-09-11 12:17:48 -04:00
Matt Nadareski
eb01dd1e25 Add note for later 2025-09-11 12:14:07 -04:00
Matt Nadareski
0a3cb79b1c Fix issue found in encrypted and obfuscated PE 2025-09-11 12:07:22 -04:00
Matt Nadareski
da9eace8cc Slight tweak to printing again 2025-09-11 11:47:07 -04:00
Matt Nadareski
526a02b8b6 Slight tweak to printing again 2025-09-11 11:44:58 -04:00
Matt Nadareski
658c7a1c3b Add another safeguard? 2025-09-11 11:10:11 -04:00
Matt Nadareski
af84474795 Fix invalid base relocation table parsing 2025-09-11 10:58:15 -04:00
Matt Nadareski
42913c6732 Invalid export should be null, not empty 2025-09-11 10:49:01 -04:00
Matt Nadareski
2cdf544518 Fix an oddly-reading format 2025-09-11 10:45:17 -04:00
Matt Nadareski
652ec58238 Fix certificate table info printing 2025-09-11 10:41:09 -04:00
Matt Nadareski
f8531daa5c Ensure overlay accounts for certificates properly 2025-09-11 10:40:09 -04:00
Matt Nadareski
e9e89b0b43 This has been consistently wrong 2025-09-11 10:33:10 -04:00
Matt Nadareski
55e788a894 Ignore invalid certificate entries 2025-09-11 10:21:51 -04:00
Matt Nadareski
b28bb93ccb Handle non-section data with valid RVA 2025-09-11 10:11:05 -04:00
Matt Nadareski
367aab0f83 Add placeholder for figuring something out later 2025-09-11 09:59:42 -04:00
Matt Nadareski
9dcf3b9e0a The offset needs to be passed all the way 2025-09-11 09:42:48 -04:00
Matt Nadareski
3c514110ce The offset needs to be passed fully 2025-09-11 09:29:46 -04:00
Matt Nadareski
c9b0c2dace Deliberately don't retain position 2025-09-11 09:27:56 -04:00
Matt Nadareski
d575b6977e Correctly parse resource data 2025-09-11 09:21:31 -04:00
Matt Nadareski
a00e6a5e2d Start cleaning up resource parsing more 2025-09-11 09:09:56 -04:00
Matt Nadareski
1b9ae83e8c Don't pad most tables to aligned size 2025-09-11 08:35:49 -04:00
Matt Nadareski
8b91eb1caf Bound the import and export tables 2025-09-11 08:33:59 -04:00
Matt Nadareski
2a6a7b5e9a Pass in the correct data 2025-09-11 08:14:24 -04:00
Matt Nadareski
a85943866e Start using table data only in already-bounded tables 2025-09-11 08:12:27 -04:00
Matt Nadareski
797fb519c1 Pass table data in, mostly unused 2025-09-11 07:49:17 -04:00
Matt Nadareski
3ba9d56363 Read table data directly 2025-09-11 07:44:28 -04:00
Matt Nadareski
04cd4e4056 Start wiring through size bounding on table reads 2025-09-11 07:41:17 -04:00
Matt Nadareski
348e170654 There 2025-09-10 21:54:10 -04:00
Matt Nadareski
f5a4ca6276 Finally figure out what I was doing 2025-09-10 21:37:05 -04:00
Matt Nadareski
672c010aa7 Fix a stupid issue 2025-09-10 21:04:09 -04:00
Matt Nadareski
2459d88951 Found the real issue 2025-09-10 20:46:32 -04:00
Matt Nadareski
350d1c8d31 I guess this can be null? 2025-09-10 20:29:26 -04:00
Matt Nadareski
98a3842a3e Fixx off-by-one error 2025-09-10 20:26:17 -04:00
Matt Nadareski
b52a4469ee Remove alignment, add TODO and comments 2025-09-10 11:21:34 -04:00
Matt Nadareski
e3143e21ba Fix comment to be more accurate 2025-09-10 11:18:53 -04:00
Matt Nadareski
1bf2181fd3 Make check a little nicer 2025-09-09 18:56:50 -04:00
Matt Nadareski
1460635aab Move hidden resources parsing to make method nicer 2025-09-09 18:52:35 -04:00
Matt Nadareski
935ec00c86 Notes about hidden resources 2025-09-09 17:15:25 -04:00
Matt Nadareski
473b6de09b Slight cleanup 2025-09-09 16:42:50 -04:00
Matt Nadareski
ba75f2ac2c Try to fix weird resource parsing 2025-09-09 14:54:54 -04:00
Matt Nadareski
a230b39fbc Make relocation block parsing safer 2025-09-09 13:51:40 -04:00
Matt Nadareski
8e963ac62a Fix a couple of potential logic bugs 2025-09-09 13:42:36 -04:00
Matt Nadareski
eaaa89847d Rename to pex and nex for readability 2025-09-09 13:11:27 -04:00
Matt Nadareski
ef76166978 Clean up a few more PE things 2025-09-09 13:11:09 -04:00
Matt Nadareski
72912586a1 Clean up COFF symbol table parsing 2025-09-09 12:18:46 -04:00
Matt Nadareski
fb241a4036 Make things easier to read, add some helpers 2025-09-09 09:57:53 -04:00
Matt Nadareski
368c8b0533 Add section table note 2025-09-09 09:37:03 -04:00
Matt Nadareski
4010325e65 Make note from Models 2025-09-09 09:31:53 -04:00
Matt Nadareski
11dd75ad95 Make import table easier to read 2025-09-08 23:21:45 -04:00
Matt Nadareski
d0480a1311 Make export table easier to read 2025-09-08 22:51:46 -04:00
Matt Nadareski
2be33b845d Be even more careful 2025-09-08 22:09:12 -04:00
Matt Nadareski
2ad42e3a0f Seek and ye shall find 2025-09-08 21:41:46 -04:00
Matt Nadareski
5d1f83800b Add SecuROM AddD deserializer 2025-09-08 21:20:47 -04:00
Matt Nadareski
30e89a7943 Clean this up 2025-09-08 21:13:34 -04:00
Matt Nadareski
61f5dc4cf2 Extract even more types of embedded data 2025-09-08 20:08:43 -04:00
Matt Nadareski
d056c179ed Add embedded UHA support 2025-09-08 08:51:40 -04:00
Matt Nadareski
b9c4bfc67e Expand the search window again 2025-09-08 08:17:01 -04:00
Matt Nadareski
6ab5ee0ae0 Add regions here for maybe future work 2025-09-08 08:03:07 -04:00
Matt Nadareski
94c1a86702 Add AssemblyName extension property to PE 2025-09-08 07:56:40 -04:00
Matt Nadareski
af6dd6a7fc Check for BZip2 and XZ in hidden places too 2025-09-08 07:52:41 -04:00
Matt Nadareski
45d4926d4c Toss the filename at the top of the infoprint output 2025-09-07 20:52:02 -04:00
Matt Nadareski
ce016c5eb0 Bump version 2025-09-06 08:18:43 -04:00
Matt Nadareski
2225c1f2d8 Update Nuget packages 2025-09-05 10:57:14 -04:00
Matt Nadareski
2d0c0d5845 Make a bunch of things cache more safer 2025-09-05 08:32:40 -04:00
Matt Nadareski
60f1756cbb Wrap places where ReadFrom was not being used but still could be parallel 2025-09-05 07:45:55 -04:00
Matt Nadareski
738a1d250a Add inherent locking the the data source in wrappers 2025-09-05 07:36:15 -04:00
Matt Nadareski
c8e65e1e30 Add section string lock 2025-09-03 13:46:12 -04:00
Matt Nadareski
ecb09ce6f2 Make sure source data isn't locked unnecessarily 2025-09-02 23:56:29 -04:00
Matt Nadareski
72a1484a71 More granular locks 2025-09-02 23:51:02 -04:00
Matt Nadareski
de31c10c7c Bump version 2025-09-02 19:22:47 -04:00
HeroponRikiBestest
84483c229c Final fixes. (#21) 2025-09-02 16:08:04 -04:00
Matt Nadareski
b7e35a8fa8 Virtual insanity 2025-09-02 15:53:14 -04:00
Matt Nadareski
8c190a26a5 Math.Max 2025-09-02 15:51:26 -04:00
Matt Nadareski
2e5705125b Ensure that the WISE section only reads section data 2025-09-02 15:01:28 -04:00
Matt Nadareski
daaa92def0 Deal with end offset data 2025-09-02 14:47:49 -04:00
Matt Nadareski
86ec97678e Prep for a different tomorrow 2025-09-02 14:45:00 -04:00
Matt Nadareski
d74b82dc55 Hacky hack hack 2025-09-02 14:30:20 -04:00
Matt Nadareski
821ade2006 That was funny 2025-09-02 13:27:52 -04:00
HeroponRikiBestest
3ee999dccd Fix wise version(?) check for pre-string bytes (#20)
Needed opposite range
2025-09-02 11:02:43 -04:00
Matt Nadareski
f91bda51e1 Non-nullable nullability 2025-09-02 09:01:19 -04:00
Matt Nadareski
47255fc331 Sync NE with PE Wise extraction 2025-09-02 08:00:51 -04:00
Matt Nadareski
f7488bed04 Make CExe helpers static 2025-09-02 07:56:19 -04:00
Matt Nadareski
a94b3a82c4 Update comment 2025-09-02 07:53:42 -04:00
Matt Nadareski
1c8f64f5e6 Search for MS-CAB in resources and overlay 2025-09-02 07:52:29 -04:00
Matt Nadareski
a015e4df3f Add tests for new deserializers and wrappers 2025-09-02 07:48:17 -04:00
Matt Nadareski
2489a49924 Implement Wise section header printer 2025-09-02 07:44:14 -04:00
Matt Nadareski
d418fbd60d Complete the circle of comments 2025-09-02 07:31:15 -04:00
Matt Nadareski
cc2e7704e6 Finding methods don't need debug logging 2025-09-02 07:23:16 -04:00
Matt Nadareski
a980a56dfa Make consistent with other files 2025-09-01 21:12:05 -04:00
Matt Nadareski
da588e3bc0 That was annoying 2025-09-01 21:11:54 -04:00
Matt Nadareski
8b6f45d9b7 Detangle Wise a bit more 2025-09-01 20:37:23 -04:00
Matt Nadareski
9bdfe33baf Move some Wise things around to make more sense in broader context 2025-09-01 20:27:46 -04:00
Matt Nadareski
13d338f615 Fix some issues with desynced wrappers 2025-09-01 18:56:51 -04:00
Matt Nadareski
36a8641c8d I definitely missed these 2025-09-01 18:50:31 -04:00
Matt Nadareski
7bde6f99fc Fix porting issue with Wise 2025-09-01 18:46:15 -04:00
Matt Nadareski
45428ce991 Fix limit issue 2025-09-01 18:42:40 -04:00
Matt Nadareski
8eb5898ef6 Handle some big TODOs 2025-09-01 18:38:43 -04:00
Matt Nadareski
556e1c972c Update packages and upstream changes 2025-09-01 16:43:21 -04:00
Matt Nadareski
df8f3e7122 Clean up usings 2025-08-31 22:08:03 -04:00
Matt Nadareski
da1d575806 MPQ decryption should live separately 2025-08-31 22:07:15 -04:00
Matt Nadareski
c4d40a1dde Fix a couple of missed issues in MPQ 2025-08-31 21:53:27 -04:00
Matt Nadareski
912de926d0 Fix various issues with parsing MPQ; simplify 2025-08-31 21:51:06 -04:00
Matt Nadareski
c60fc1e31f Remove outdated comments 2025-08-31 21:45:35 -04:00
Matt Nadareski
386e607887 Add BET/HET handling based on documentation, not tested 2025-08-31 01:20:33 -04:00
Matt Nadareski
94c9b8d057 Fix MPQ v1 parsing, add hash and block table decrypt 2025-08-31 01:03:15 -04:00
Matt Nadareski
5f81275b10 Add some project references 2025-08-29 14:03:25 -04:00
Matt Nadareski
37c484411b Reimplment MPQ extraction via StormLib 2025-08-29 13:37:54 -04:00
Matt Nadareski
ad1f890742 Add StormLib as submodule 2025-08-29 13:34:59 -04:00
Matt Nadareski
2924529fa7 Start bundling runtimes 2025-08-29 13:31:19 -04:00
Matt Nadareski
ebe675cae1 Add StormLib runtimes 2025-08-29 13:29:15 -04:00
Matt Nadareski
a40c666775 Bundle libraries 2025-08-29 12:59:33 -04:00
Matt Nadareski
2ea060d3b3 Readme 2025-08-29 12:55:21 -04:00
Matt Nadareski
f8a67839dd Clean up some TODOs 2025-08-29 12:34:59 -04:00
Matt Nadareski
2773b12c9b Fix odd write-size mismatches 2025-08-29 12:14:55 -04:00
Matt Nadareski
929e12f976 These values need to be signed 2025-08-29 11:48:19 -04:00
Matt Nadareski
8fbc6c4662 Remove erroneous check 2025-08-29 11:28:37 -04:00
Matt Nadareski
797378e9c8 Better error messages 2025-08-29 11:26:17 -04:00
Matt Nadareski
113464a7d1 Privatize Reader class 2025-08-29 11:09:45 -04:00
Matt Nadareski
a13c837202 Probably fix the MD5 bug in IS-CAB 2025-08-29 11:06:37 -04:00
Matt Nadareski
48765f1ae5 Fix IS-CAB deserialization bug 2025-08-29 10:44:51 -04:00
Matt Nadareski
091ee56368 Remove Extractor, finally 2025-08-29 10:20:51 -04:00
Matt Nadareski
015a971147 Be smarter about volume opening 2025-08-29 10:17:07 -04:00
Matt Nadareski
7575a01a28 Keep track of the data offset 2025-08-29 10:11:53 -04:00
Matt Nadareski
7aa14cafea This never gets set again 2025-08-29 10:10:52 -04:00
Matt Nadareski
db10721386 Privatize 2025-08-29 10:04:52 -04:00
Matt Nadareski
6112cf8d60 This needed a rename 2025-08-29 10:04:24 -04:00
Matt Nadareski
50caeba322 Sort some filename pattern stuff 2025-08-29 10:03:56 -04:00
Matt Nadareski
b3499984b3 Start porting some functionality 2025-08-29 09:58:40 -04:00
Matt Nadareski
a5609a7a82 More descriptive class name 2025-08-29 09:41:25 -04:00
Matt Nadareski
8626a87860 Start cleaning up duplicate and unnecessary code 2025-08-29 09:37:03 -04:00
Matt Nadareski
fa31cd0e98 Let's see how UnshieldSharp goes 2025-08-29 09:14:33 -04:00
Matt Nadareski
6b6b7c6289 Reduce complexity of MS-CAB extraction paths 2025-08-29 08:29:05 -04:00
Matt Nadareski
baa3b272ab Extraction tool can pretend everything works 2025-08-29 08:20:55 -04:00
Matt Nadareski
d7c4f244cc Make the if/else chain into a switch 2025-08-29 08:13:58 -04:00
Matt Nadareski
e21d226564 Use wrapper description to simplify cases 2025-08-29 08:08:02 -04:00
Matt Nadareski
6ff6a7d4a4 Uncomment MPQ, still not hooked back up 2025-08-29 08:03:01 -04:00
Matt Nadareski
daf19a561c Add UnshieldSharp to ExtractionTool directly 2025-08-29 08:01:27 -04:00
Matt Nadareski
26226a75ff Update nuget packages 2025-08-29 07:56:51 -04:00
Matt Nadareski
4473edf476 Comments cleanup 2025-08-29 07:54:20 -04:00
Matt Nadareski
54cf0a6470 Expand the search window for embedded data 2025-08-28 23:56:05 -04:00
Matt Nadareski
0eb8f7e538 Extract overlay data for NE 2025-08-28 23:52:09 -04:00
Matt Nadareski
23b72c65ba Forgot to use the resource offset 2025-08-28 23:02:25 -04:00
Matt Nadareski
db7d89600c Handle PKZIP SFX by extracting the archive portion 2025-08-28 23:01:55 -04:00
Matt Nadareski
67d51ad1d6 Handle RAR SFX by extracting the archive portion 2025-08-28 22:42:15 -04:00
Matt Nadareski
56b71cf7fe Overlay deals with real data only 2025-08-28 22:41:49 -04:00
Matt Nadareski
e0ec2a521f Handle 7z SFX by extracting the archive portion 2025-08-28 22:21:25 -04:00
Matt Nadareski
e8589ac7b5 Fix offset read issues in resource table 2025-08-28 21:52:35 -04:00
Matt Nadareski
21e425acee Split up PE parsing a bit for readability 2025-08-28 21:35:05 -04:00
Matt Nadareski
ee316052ae Add ExtractionTool to readme 2025-08-28 20:14:08 -04:00
Matt Nadareski
3463936ae0 Fix extracting SFX archives 2025-08-28 20:00:05 -04:00
Matt Nadareski
5ff947b279 Add non-model constructors for PKZIP 2025-08-28 19:59:24 -04:00
Matt Nadareski
fdf2ea84ec Fix intermittent 7z solid issues 2025-08-28 19:59:06 -04:00
Matt Nadareski
ad9b001b6a Downstream from IO 2025-08-28 19:47:34 -04:00
Matt Nadareski
1308571c10 Smarter handling 2025-08-28 15:53:16 -04:00
Matt Nadareski
b8cb3419c1 Fix odd resource parsing issues 2025-08-28 15:49:02 -04:00
Matt Nadareski
02533cf947 Somewhat add SFX support 2025-08-28 15:26:37 -04:00
Matt Nadareski
bf8bd04dc7 Fix missing package 2025-08-28 15:22:05 -04:00
Matt Nadareski
1894376ab6 Initial migration of ExtractionTool 2025-08-28 15:11:21 -04:00
Matt Nadareski
c789e4df44 Replace simpler gzip extract with more robust version 2025-08-28 14:17:15 -04:00
Matt Nadareski
884685de4a Fix GZip extraction 2025-08-28 14:15:39 -04:00
Matt Nadareski
7fda7be457 Fix significant issue with how view streams are used 2025-08-28 14:10:08 -04:00
Matt Nadareski
5daf759033 Add debug logging for tar extraction 2025-08-28 13:16:39 -04:00
Matt Nadareski
589ab0896a Replace SharpCompress with native extract for tar 2025-08-28 13:03:59 -04:00
Matt Nadareski
7645ab978f Fix obvious bug 2025-08-28 12:59:50 -04:00
Matt Nadareski
e6497289da Add experimental tar extraction 2025-08-28 12:56:43 -04:00
Matt Nadareski
95a9f4769d Workaround to read block data 2025-08-28 12:16:07 -04:00
Matt Nadareski
7917601f7a Slight formatting cleanup 2025-08-28 12:14:48 -04:00
Matt Nadareski
3400238fc5 Make tar printing a bit more comprehensive 2025-08-28 12:13:00 -04:00
Matt Nadareski
cbd335c6aa Add and update tests 2025-08-28 10:12:08 -04:00
Matt Nadareski
9feaadd32a Implement gzip parsing and printing 2025-08-28 09:56:52 -04:00
Matt Nadareski
2ec008b3b7 Add extension property to tar 2025-08-28 09:13:02 -04:00
Matt Nadareski
c9a462a1c6 Fix tar parsing and printing 2025-08-28 09:11:04 -04:00
Matt Nadareski
ab44aa7e68 Start implementing tar 2025-08-28 08:14:38 -04:00
Matt Nadareski
9b9d3176ec Slightly more work 2025-08-28 07:54:22 -04:00
Matt Nadareski
5dda3e2c81 Add shell deserializers for gzip and tar 2025-08-28 07:52:43 -04:00
Matt Nadareski
4b8dc12c98 Add PKZIP extension properties 2025-08-27 21:59:30 -04:00
Matt Nadareski
044e4c4c75 Fill out remaining models, add printing 2025-08-27 21:48:01 -04:00
Matt Nadareski
2149630865 Fill in the remaining extras that have models 2025-08-27 20:40:56 -04:00
Matt Nadareski
3d435a1d7e Start parsing some PKZIP extras 2025-08-27 19:20:07 -04:00
Matt Nadareski
f2d993a958 Fix UTF-8 encoded strings 2025-08-27 18:14:11 -04:00
Matt Nadareski
7bf75b8dc5 Minor cleanup 2025-08-27 17:59:11 -04:00
Matt Nadareski
dfbdce1dc8 Be more strictly correct about ZIP64 reading 2025-08-27 17:54:35 -04:00
Matt Nadareski
63f5566e65 Minor formatting fix 2025-08-27 16:45:20 -04:00
Matt Nadareski
4b0f43f6c0 Clean up PKZIP printing 2025-08-27 16:41:00 -04:00
Matt Nadareski
98e1ef7362 Rearrange code to make models updates easier 2025-08-27 15:49:31 -04:00
Matt Nadareski
4e0ffcb3c8 Return nothing and be happy 2025-08-27 13:04:01 -04:00
Matt Nadareski
a93a46d6c0 Start fixing PKZIP deserializing
This does a forward-reading approach on the archive instead of the "proper" way of reading from the end. This change introduces potential issues, as both "deleted" entries and normal ones will be included. It also makes it more difficult to determine if the archive is ZIP64 or not. But it is far more stable than the read-from-the-end approach of the old code.
2025-08-27 12:54:36 -04:00
Matt Nadareski
e163302522 Add part-finding helpers and tests 2025-08-26 21:14:25 -04:00
Matt Nadareski
838afc35c3 Order of operations 2025-08-26 06:52:47 -04:00
Matt Nadareski
3a62bfab57 Fix copy-paste 2025-08-26 06:45:21 -04:00
Matt Nadareski
560b3a246c Use file part count, not partial files 2025-08-26 06:41:01 -04:00
Matt Nadareski
4360916750 Handle archive parts 2025-08-25 22:20:24 -04:00
Matt Nadareski
3f31edc1c0 Fix return comments 2025-08-25 21:02:08 -04:00
Matt Nadareski
bd874d436b Slight renaming to be more accurate 2025-08-25 21:01:20 -04:00
Matt Nadareski
fbc47425f4 Use using to use usings 2025-08-25 20:57:35 -04:00
Matt Nadareski
c9df6ff059 Rename to be consistent 2025-08-25 20:53:25 -04:00
Matt Nadareski
ef6ff85e96 Port more PE extraction 2025-08-25 20:51:35 -04:00
Matt Nadareski
bb93792f57 Remove restriction from RAR 2025-08-25 13:25:07 -04:00
Matt Nadareski
1f7ab4fccb Simpler completeness checks 2025-08-25 13:23:49 -04:00
Matt Nadareski
2535e82618 Maybe fix multipart 7z, RAR, and PKZIP archives 2025-08-25 13:19:28 -04:00
Matt Nadareski
66d80c8523 Add basic PE extraction 2025-08-25 13:06:22 -04:00
Matt Nadareski
834a17fe82 Add region note 2025-08-25 12:50:16 -04:00
Matt Nadareski
ea85167e06 Upstream changes to string reading until IO updated 2025-08-25 12:45:45 -04:00
Matt Nadareski
e007a06dda Allow direct data source access 2025-08-23 21:31:13 -04:00
Matt Nadareski
02f9e1e935 Temporarily downstream class from IO 2025-08-23 21:29:22 -04:00
Matt Nadareski
21b7d431a7 More concise naming 2025-08-23 13:38:19 -04:00
Matt Nadareski
307b932f87 A couple more clarifications 2025-08-23 13:37:39 -04:00
Matt Nadareski
6983d1cd3c This can't be null anymore 2025-08-23 13:36:59 -04:00
Matt Nadareski
a193c9bb3c Remove unnecessary comment 2025-08-23 13:23:44 -04:00
Matt Nadareski
aa67c7ad6d Rename to be simpler 2025-08-23 13:19:26 -04:00
Matt Nadareski
70fc686249 DataSource is a Stream type now 2025-08-23 13:18:46 -04:00
Matt Nadareski
c87a456a46 Move things to base classes 2025-08-23 12:58:09 -04:00
Matt Nadareski
456bb1e95b Intermediary step for extractable shells 2025-08-23 12:23:44 -04:00
Matt Nadareski
b0b334103d Implement shell wrappers for extractable types without a current model 2025-08-23 11:55:54 -04:00
Matt Nadareski
78851e3b57 Pass through data source property, make private 2025-08-20 08:11:48 -04:00
Matt Nadareski
850a883e14 Methods to properties 2025-08-20 08:08:53 -04:00
Matt Nadareski
6e0ced5ffe One more GetEndOffset removal 2025-08-20 08:04:01 -04:00
Matt Nadareski
64cd8febaa This doesn't need private set 2025-08-20 08:00:45 -04:00
Matt Nadareski
6fbe1cffaa GetEndOffset really shouldn't be used 2025-08-20 07:54:52 -04:00
Matt Nadareski
601e781ef9 Data source shennanigans 2025-08-19 22:01:10 -04:00
Matt Nadareski
d26ad35573 Create a new DataSource helper class 2025-08-19 20:49:47 -04:00
Matt Nadareski
b70c510734 Be consistent with model 2025-08-19 20:25:56 -04:00
Matt Nadareski
29a7158488 Clarify that Matching is being used 2025-08-19 15:30:23 -04:00
Matt Nadareski
1227ca020a Fix CreateExecutableWrapper 2025-08-19 09:18:50 -04:00
Matt Nadareski
cd7e6ff98d Fix some logic bugs due to offsets 2025-08-19 09:09:33 -04:00
Matt Nadareski
510a0f77f6 Stop reinventing the wheel 2025-08-19 07:43:21 -04:00
Matt Nadareski
6d1dabb1db Handle only cases where long mattered 2025-08-19 07:41:29 -04:00
Matt Nadareski
2e337891da Fix logic bug with end of file check 2025-08-19 07:36:33 -04:00
Matt Nadareski
d49e18a83e Replace _byteArrayOffset with _initialPosition 2025-08-19 07:34:51 -04:00
Matt Nadareski
c14560ec18 Add initial position to wrapper, currently unused 2025-08-19 07:29:59 -04:00
Matt Nadareski
e3e31cd9f2 Separate files 2025-08-19 07:27:39 -04:00
Matt Nadareski
adf9627045 Stricter with COFF tables 2025-08-17 15:25:25 -04:00
Matt Nadareski
c7b03c7765 This should be a file offset 2025-08-17 15:20:51 -04:00
Matt Nadareski
b5f83215d5 Don't exit parsing unnecessarily 2025-08-17 15:04:38 -04:00
Matt Nadareski
96e3fc5533 Cleanups to PE deserialization 2025-08-17 14:53:03 -04:00
Matt Nadareski
828e7dda03 Add file-only info printing flag 2025-08-13 12:03:06 -04:00
Matt Nadareski
8ef50c30d5 Add and implement IExtractable 2025-08-11 11:39:15 -04:00
Matt Nadareski
cbe1d5b608 Resync NE overlay finding 2025-08-11 11:11:51 -04:00
Matt Nadareski
7123a9e986 Add more NE deserializers 2025-08-10 20:37:42 -04:00
Matt Nadareski
af5996b972 Fill out LE/LX methods at all 2025-08-01 09:04:30 -04:00
Matt Nadareski
15e947784b Use NE helpers 2025-08-01 08:56:14 -04:00
Matt Nadareski
1b382c201e Simplify references in NE 2025-08-01 08:43:01 -04:00
Matt Nadareski
8deca4fb0c Fill out NE methods more 2025-08-01 08:39:14 -04:00
Matt Nadareski
96c4372609 Add data-reading methods for NE 2025-08-01 08:19:41 -04:00
Matt Nadareski
ca7a109037 Add more NE extensions 2025-08-01 07:58:54 -04:00
Matt Nadareski
c54f5b3c5d Add MS-DOS stub extension for LE/LX 2025-07-31 14:35:35 -04:00
Matt Nadareski
652942ab9f Add extensions based on external need 2025-07-31 14:00:55 -04:00
Matt Nadareski
2cc19a9c36 Add some more IS-CAB extensions 2025-07-31 13:44:15 -04:00
Matt Nadareski
6ffb3f4bbd Add IS-CAB OpenVolume helper 2025-07-31 13:34:35 -04:00
Matt Nadareski
bab4278318 Better linking in IS-CAB open set 2025-07-31 13:26:10 -04:00
Matt Nadareski
013d18a426 Better file descriptor method 2025-07-31 13:23:45 -04:00
Matt Nadareski
e94e27910e Add a couple of IS-CAB extensions 2025-07-31 13:20:40 -04:00
Matt Nadareski
34cea6e74a Double-chain IS-CAB like MS-CAB 2025-07-31 13:18:29 -04:00
Matt Nadareski
640e160863 Slight cleanup to the PE deserializer 2025-07-31 12:06:51 -04:00
Matt Nadareski
3100963250 Fix build issue 2025-07-31 11:57:20 -04:00
Matt Nadareski
2086358762 Slight cleanup to the PE wrapper 2025-07-31 11:52:39 -04:00
Matt Nadareski
ae273c589d Use simpler extension where possible 2025-07-31 11:28:09 -04:00
Matt Nadareski
a229015fcd Move major version helper out of deserializer 2025-07-31 11:26:54 -04:00
Matt Nadareski
b001680674 Remove unnecessary code regions for XMID and XeMID 2025-07-31 11:12:35 -04:00
Matt Nadareski
e684133f72 Add InfoPrint to the readme 2025-07-31 11:08:11 -04:00
Matt Nadareski
2b020eecc7 Output hashes to separate file 2025-07-31 10:30:13 -04:00
Matt Nadareski
78f4d6faca Add file hashing option to InfoPrint 2025-07-31 10:26:03 -04:00
Matt Nadareski
f07b7a049e Ensure endianness of reads 2025-07-31 09:41:36 -04:00
Matt Nadareski
544637779c Exception debugging should use Error stream 2025-07-31 09:14:22 -04:00
Matt Nadareski
38b6427e4e Wire through include debug flag 2025-07-31 09:11:43 -04:00
Matt Nadareski
e36822a19c Add more extension properties; clean up 2025-07-31 08:57:35 -04:00
Matt Nadareski
e1a114976f Use correct mask for v3 CFB files 2025-07-30 16:56:15 -04:00
Matt Nadareski
5ba9ab3457 Fix DIFAT assumptions for directory entries 2025-07-30 16:28:54 -04:00
Matt Nadareski
36edf9ed54 Fix parsing of large DIFAT tables in CFB 2025-07-30 15:46:19 -04:00
Matt Nadareski
e788ffa851 Fix MS-CAB block continuation 2025-07-30 15:18:29 -04:00
Matt Nadareski
e0d819b88d Fix spanned blocks, previously skipped 2025-07-30 14:54:19 -04:00
Matt Nadareski
e3b216ad09 Wrap MS-ZIP compression in case of failure 2025-07-30 14:21:13 -04:00
Matt Nadareski
55d0fd452d Add new extension property for CFB 2025-07-30 11:33:49 -04:00
Matt Nadareski
089fd02b2e Sync remaining extraction bits for CFB 2025-07-30 11:32:25 -04:00
Matt Nadareski
8cfd820dcd Sync back extraction fixes for CFB 2025-07-30 11:29:27 -04:00
Matt Nadareski
67ed9860fe Sync back deserialization fixes for CFB 2025-07-30 11:26:04 -04:00
Matt Nadareski
ee924e3a34 Backport some CFB work 2025-07-30 11:04:25 -04:00
Matt Nadareski
9e5085ba79 Add CFB extraction placeholders 2025-07-30 08:31:00 -04:00
Matt Nadareski
dbfdbbff20 Fix CFB stream name handling 2025-07-30 08:21:20 -04:00
Matt Nadareski
21dc72bf11 Decode CFB stream names 2025-07-30 08:08:27 -04:00
Matt Nadareski
c8295c4724 Make CFB printing pretty again 2025-07-29 23:43:22 -04:00
Matt Nadareski
44b4dd3d1b Fix reading CFB v3 directory entries 2025-07-29 23:41:42 -04:00
Matt Nadareski
7e543c6acb Fix some issues with CFB deserialization 2025-07-29 23:08:37 -04:00
Matt Nadareski
63514d149f CFB directory entry names are UTF-16 2025-07-29 22:51:04 -04:00
Matt Nadareski
d7e559749d Normalize extraction methods
This does a few things:
- Ensures that all output directories are normalized for the current operating system
- Ensures that all output files are flushed in case of systematic issues
- Brings MS-CAB extraction up to the same return value quality as other extractors
2025-07-29 21:13:53 -04:00
Matt Nadareski
a2be40fcbc Add CHD version extension 2025-07-29 20:39:48 -04:00
Matt Nadareski
771df5c372 Fall back on OpenNext if needed 2025-07-29 11:52:59 -04:00
Matt Nadareski
2d3d6348ad Remove redundant code 2025-07-29 11:51:28 -04:00
Matt Nadareski
a2bf15f0bc Fix method ordering 2025-07-29 11:49:07 -04:00
Matt Nadareski
0aa25df88f More graceful handling of MS-CAB sets 2025-07-29 11:48:34 -04:00
Matt Nadareski
36afb1c0ee Split out MS-ZIP handling for cleaner code 2025-07-29 11:38:38 -04:00
Matt Nadareski
c9d61906fb Only derive the compression type once per folder 2025-07-29 11:26:23 -04:00
Matt Nadareski
d8440a01d3 Remove redundant check 2025-07-29 08:30:17 -04:00
Matt Nadareski
74d92312ef Split out MS-CAB ExtractFile logic 2025-07-29 08:26:53 -04:00
Matt Nadareski
0dc9823d2b Fix assumption about MS-CAB sets 2025-07-29 08:04:02 -04:00
Matt Nadareski
9c69737073 Fix comments to make more sense 2025-07-28 21:23:18 -04:00
Matt Nadareski
66187dcf04 Keep tweaking extraction 2025-07-28 21:20:47 -04:00
Matt Nadareski
79943560bc Keep tweaking extraction 2025-07-28 21:14:51 -04:00
Matt Nadareski
b3321f9c9a Keep tweaking extraction 2025-07-28 20:58:49 -04:00
Matt Nadareski
428c269a49 Keep tweaking extraction 2025-07-28 20:56:23 -04:00
Matt Nadareski
e84964a321 Add MS-CAB extract and decompression 2025-07-28 20:31:40 -04:00
Matt Nadareski
0394ea5356 Remove unused using 2025-07-28 19:43:53 -04:00
Matt Nadareski
852b086920 Add IS-CAB obfuscation code 2025-07-28 19:41:07 -04:00
Matt Nadareski
b7fceee2b7 Port more MS-CAB helpers from BOS 2025-07-28 15:22:28 -04:00
Matt Nadareski
ecf6c957c9 Port OpenNext/OpenPrevious from BOS 2025-07-28 15:13:19 -04:00
Matt Nadareski
5e0b0070ff Make MS-CAB doubly-linked 2025-07-28 12:45:23 -04:00
Matt Nadareski
9934bc31a3 Fix build 2025-07-28 12:31:03 -04:00
Matt Nadareski
7b4711f5cf Implement OpenSet for MS-CAB 2025-07-28 12:27:18 -04:00
Matt Nadareski
844066815d Add extension properties for MS-CAB 2025-07-28 12:09:28 -04:00
Matt Nadareski
3a6293e696 Port some code from UnshieldSharp 2025-07-28 11:57:54 -04:00
Matt Nadareski
3210b8601d Add IS-CAB CreateFilenamePattern from UnshieldSharp 2025-07-28 11:35:24 -04:00
Matt Nadareski
181788802d Move PathProcessors to the correct namespace 2025-07-28 10:27:11 -04:00
Matt Nadareski
4b627ce776 Move wrapper-specific helpers to correct namespace 2025-07-28 10:25:25 -04:00
Matt Nadareski
8b799bb5c8 Port Nitro decryption step 2025-07-28 08:47:26 -04:00
Matt Nadareski
5bc8336fce Move StringBuilderExtensions to better namespace 2025-07-27 20:56:15 -04:00
Matt Nadareski
4f9f8ddcec Fix build 2025-07-27 20:49:18 -04:00
Matt Nadareski
29f1f63ef8 Add nested dir support for Logiqx, fix existing dir support 2025-07-27 20:48:49 -04:00
Matt Nadareski
48ecdff5f7 Fix AlignToBoundary a bit 2025-07-24 10:56:31 -04:00
Matt Nadareski
411acd2d5a Add AlignToBoundary for byte arrays 2025-07-24 10:55:52 -04:00
Matt Nadareski
e6742fe889 Fix missed AlignToBoundary case 2025-07-24 10:47:21 -04:00
Matt Nadareski
b6561719a7 Add SecuROM DFA 2025-07-24 10:40:31 -04:00
Matt Nadareski
2bf3d6f9a6 Use more constants in GetFileType 2025-07-24 10:19:20 -04:00
Matt Nadareski
b2700b5975 Add MESS ListXML support 2025-07-24 09:36:37 -04:00
Matt Nadareski
95b28874da Add MESS ListXML support 2025-07-24 09:36:13 -04:00
Matt Nadareski
4934ee837c Be consistent about end-of-file newlines 2025-07-24 09:31:28 -04:00
Matt Nadareski
3cbfd5cd10 Add .NET Standard 2.0 and 2.1 2025-07-24 09:19:38 -04:00
Matt Nadareski
da28ce310b Update nuget packages 2025-07-24 09:16:11 -04:00
HeroponRikiBestest
ac6d93a3b9 Add extra validity checks for GCF (#17)
* Add extra validity checks for GCF

* Remove "for validity"
2025-07-12 15:49:35 -04:00
Matt Nadareski
104028204d Fix relocation table parsing issues (fixes #16) 2025-06-28 20:00:21 -04:00
Matt Nadareski
d3e61b42dd Attempt to fix export table name table 2025-06-24 17:14:25 -04:00
Matt Nadareski
6351cabb62 Add CMP tests for non-quote serialization 2025-05-28 09:51:45 -04:00
Matt Nadareski
ddef42126b Fix old .NET 2025-05-19 12:15:30 -04:00
Matt Nadareski
9dd39a7f02 Bump version 2025-05-19 12:13:35 -04:00
Matt Nadareski
ca7f7e97e7 Omit namespaces on XML writing 2025-05-19 12:12:05 -04:00
Matt Nadareski
8a40349b0c Write tests for ReadQuotedString, fix issues 2025-05-14 20:52:59 -04:00
Matt Nadareski
6ec6fa4973 Remove now-unused using 2025-05-13 11:26:17 -04:00
Matt Nadareski
f0644710e6 Remove faulty offset code 2025-05-13 09:44:59 -04:00
Matt Nadareski
34048726ab Fix cref formatting in summaries 2025-05-13 09:25:06 -04:00
Matt Nadareski
60ce6c9370 Handle offset sizes for Logiqx rom 2025-05-13 09:24:01 -04:00
Matt Nadareski
554fccc236 Update IO to 1.6.3 2025-05-12 08:26:42 -04:00
Matt Nadareski
7611c043c3 Fix how conditions are used for references 2025-02-25 21:17:17 -05:00
Matt Nadareski
976d793474 Fix currently non-affecting bug 2024-12-30 23:17:52 -05:00
Matt Nadareski
f0f997fadd Bump version 2024-12-30 22:51:13 -05:00
Matt Nadareski
0ce3c9892d Remove attempt at caching version info strings 2024-12-30 22:40:52 -05:00
Matt Nadareski
9743565285 Update copyright 2024-12-30 21:39:36 -05:00
Matt Nadareski
fcfe9e4790 Remove unnecessary action step 2024-12-30 21:39:30 -05:00
Matt Nadareski
be36432296 Update packages 2024-12-30 21:28:13 -05:00
Matt Nadareski
fb725bff19 Bump version 2024-12-30 20:55:30 -05:00
Matt Nadareski
2384cf9f9f Add source data lock on cached values 2024-12-30 20:47:12 -05:00
Matt Nadareski
1261930fd9 Ensure .NET versions are installed for testing 2024-12-19 10:53:19 -05:00
Matt Nadareski
120de4e49f Allow symbols to be packed 2024-12-18 08:05:16 -05:00
Matt Nadareski
354a51769b Bump version 2024-12-18 08:01:07 -05:00
Matt Nadareski
a9f937baa3 Find remaining non-explicit endinaness calls 2024-12-17 22:38:57 -05:00
Matt Nadareski
1790d82a6e Cap overlay checks to 16 MiB 2024-12-17 15:50:02 -05:00
Matt Nadareski
261c20e95a Get rid of erroneous double semicolons 2024-12-17 15:43:22 -05:00
Matt Nadareski
ed6556b1f0 Cache version info strings 2024-12-17 01:05:41 -05:00
Matt Nadareski
a86af8c32a Expand printed detections 2024-12-17 00:52:24 -05:00
Matt Nadareski
1670ab45a0 Fix SFO deserialization 2024-12-17 00:27:30 -05:00
Deterous
7dc4750f3b Add Deserializer for AppPkgHeader (#14)
* Add Deserializer for AppPkgHeader

* Fix typo

* add using System.Text

* Fix typo
2024-12-17 00:10:38 -05:00
Matt Nadareski
b5f366680d Explicit endianness in extensions 2024-12-17 00:00:28 -05:00
Matt Nadareski
fa9e9a0b2b Be explicit about endianness 2024-12-16 23:08:45 -05:00
Matt Nadareski
2239b82a4b Update packages 2024-12-16 15:00:44 -05:00
Matt Nadareski
3b631678f5 Port Quantum extraction (nw) 2024-12-13 14:30:38 -05:00
Matt Nadareski
2b111a9688 Port BFPK extraction 2024-12-13 14:25:32 -05:00
Matt Nadareski
0bda1f4f88 Bump version 2024-12-13 10:44:00 -05:00
Matt Nadareski
7d50e0e1c5 Fix filename map 2024-12-11 21:17:39 -05:00
Matt Nadareski
224a4caab0 Add secondary link for ISAv3 2024-12-11 14:42:00 -05:00
Matt Nadareski
b4689da404 Add reference from UnshieldSharp 2024-12-11 14:39:27 -05:00
Matt Nadareski
af66657399 Slightly safer indexing 2024-12-11 14:34:11 -05:00
Matt Nadareski
0f3e2d8275 Add 2 more extension properties 2024-12-11 14:25:46 -05:00
Matt Nadareski
d664b6defc Use const for data offset 2024-12-11 14:18:32 -05:00
Matt Nadareski
adbf74a6e0 Add ISAv3 extraction 2024-12-11 14:17:35 -05:00
Matt Nadareski
7eb401efed Port obvious things from UnshieldSharp 2024-12-11 14:04:29 -05:00
Matt Nadareski
ba97381b99 Add more ISAv3 stuff 2024-12-11 13:56:01 -05:00
Matt Nadareski
3de92de225 Add Compression package 2024-12-11 13:31:54 -05:00
Matt Nadareski
01a195c8aa Bump version 2024-12-10 15:44:48 -05:00
Matt Nadareski
12d43ef68a Update Models to 1.5.6 2024-12-10 15:41:12 -05:00
Matt Nadareski
0df806a6d1 Display debug in selected options 2024-12-06 11:46:28 -05:00
Matt Nadareski
f8c713b260 Use publish script and update README 2024-12-06 11:42:22 -05:00
Matt Nadareski
4d0122f97c Trust nobody, not even yourself 2024-12-03 02:12:39 -05:00
Matt Nadareski
7874950a7a Bump version 2024-12-03 01:04:46 -05:00
Matt Nadareski
577afc8947 Fix issue with PE extensions 2024-12-03 01:02:22 -05:00
Matt Nadareski
5a3e69e8ed Bump version 2024-11-30 21:32:15 -05:00
Matt Nadareski
67ee595eb4 More clearing out of old null checks 2024-11-30 02:49:10 -05:00
Matt Nadareski
992f8eaeb8 Reduce more nullable-array-nullable 2024-11-29 22:54:36 -05:00
Matt Nadareski
dde5a57136 Fix some misconfigured framework gating 2024-11-29 22:20:46 -05:00
Matt Nadareski
ae49950ae6 Go back to Vector3D direct deserialization 2024-11-29 21:41:49 -05:00
Matt Nadareski
b56ea3a479 Remove now-unneeded guards in printers 2024-11-29 21:35:56 -05:00
Matt Nadareski
03d4ea046d Update Models and IO 2024-11-29 20:48:50 -05:00
Matt Nadareski
248741b2c0 Add one forgotten check to a test 2024-11-29 02:00:01 -05:00
Matt Nadareski
ef307664e2 Remove now-redundant real metadata files 2024-11-29 01:57:32 -05:00
Matt Nadareski
05c497a5a0 Add roundtrip serialization tests for metadata files 2024-11-29 01:54:40 -05:00
Matt Nadareski
f8239780b2 Improve OpenMSX test, add AttractMode test 2024-11-29 00:21:10 -05:00
Matt Nadareski
ff12bf8205 Add serializer boundary tests; migrate old file 2024-11-29 00:04:02 -05:00
Matt Nadareski
0c3adf055c Add wrapper tests 2024-11-28 23:22:53 -05:00
Matt Nadareski
d9b1f5d45f Fix issue found by tests 2024-11-28 23:06:09 -05:00
Matt Nadareski
5ab3dded30 Remove while true from cuesheet parsing 2024-11-28 23:00:31 -05:00
Matt Nadareski
991d9ead27 Deserializers should have their own guards 2024-11-28 22:57:12 -05:00
Matt Nadareski
25c0d036f2 Length can throw on read-forward streams 2024-11-28 22:24:37 -05:00
Matt Nadareski
c06d8151e6 Add short-circuit for 0-length arrays 2024-11-28 22:15:25 -05:00
Matt Nadareski
0e9ba25637 Add required extension property 2024-11-28 22:09:07 -05:00
Matt Nadareski
bd7ca7f3a7 CanSeek can throw on read-forward streams 2024-11-28 22:01:03 -05:00
Matt Nadareski
26146554a3 Ensure read errors don't throw on wrapper creation 2024-11-28 21:58:49 -05:00
Matt Nadareski
884746a5a1 Add more extension properties 2024-11-28 20:50:43 -05:00
Matt Nadareski
ab0e68110c Move helper classes out of Wrappers 2024-11-27 23:43:50 -05:00
Matt Nadareski
e166d18903 Add extensions based on common use 2024-11-27 22:38:05 -05:00
Matt Nadareski
2152ba43a8 Minor formatting changes in extensions 2024-11-27 22:07:48 -05:00
Matt Nadareski
f42c5d04ee Fix issues from BSP29 (unsupported) 2024-11-27 21:45:26 -05:00
Matt Nadareski
ea535fa393 Read Vector3D manually 2024-11-27 21:33:24 -05:00
Matt Nadareski
e6d118e8cc Fix build 2024-11-27 21:26:23 -05:00
Matt Nadareski
35a921e436 Update Models to 1.5.4 2024-11-27 21:22:24 -05:00
Matt Nadareski
25cc3e42f3 Do length checks in V/BSP 2024-11-27 21:05:04 -05:00
Matt Nadareski
14344756da Port all non-compression extraction from BOS 2024-11-27 20:54:13 -05:00
Matt Nadareski
cb270d3185 Fix SizeOf issue in old .NET 2024-11-27 20:37:07 -05:00
Matt Nadareski
d5cef39f1b Forgot one named entity 2024-11-27 20:31:56 -05:00
Matt Nadareski
b782af427e Move simple extraction from BOS back for V/BSP 2024-11-27 20:30:48 -05:00
Matt Nadareski
6b503a0733 Perform more deserializer cleanup 2024-11-27 20:30:31 -05:00
Matt Nadareski
4a3741312e Reduce unncessary methods in deserialization 2024-11-27 16:14:56 -05:00
Matt Nadareski
aed140a684 Be smarter with using statements in tests 2024-11-27 14:25:53 -05:00
Matt Nadareski
5b93df9703 Split old monolithic deserializer test file 2024-11-27 14:18:08 -05:00
Matt Nadareski
5ae162400c Handle unexpected deserializer results 2024-11-27 14:04:20 -05:00
Matt Nadareski
f828b57159 Perform correctness and TODO cleanup 2024-11-27 13:47:07 -05:00
Matt Nadareski
d0cfc67f07 Update Deserializers and add empty/null/invalid tests 2024-11-27 12:43:52 -05:00
Matt Nadareski
2f48c3110c Update CrossModel converters and add tests 2024-11-27 10:16:23 -05:00
Matt Nadareski
6cdc35c82f Update packages 2024-11-26 19:51:39 -05:00
Matt Nadareski
9214a22cc9 Bump version 2024-11-20 20:05:03 -05:00
Matt Nadareski
5ba1156245 Fix return comments 2024-11-20 20:02:36 -05:00
Matt Nadareski
cb91cdff1d Minor formatting quibbles 2024-11-20 20:01:28 -05:00
Matt Nadareski
4df6a4e79d Reduce use of IEnumerable where not necessary 2024-11-20 19:51:49 -05:00
Matt Nadareski
5b82a48267 Update ASN.1 to 1.4.2 2024-11-20 16:06:00 -05:00
Matt Nadareski
8f70c50a48 Trim strings and only include them if the right length 2024-11-20 15:48:12 -05:00
Matt Nadareski
5fe4d81fa4 Ensure strings are read properly 2024-11-20 15:42:24 -05:00
Matt Nadareski
7d3addbf0a Print embedded zip as embedded zip 2024-11-20 15:12:23 -05:00
Matt Nadareski
b7d5873eb7 Wrap ASN.1 call until fixed in library 2024-11-20 15:07:13 -05:00
Matt Nadareski
4e40cc19d5 TODO cleanup 2024-11-20 14:54:22 -05:00
Matt Nadareski
1bc9316bc1 Update packages 2024-11-20 14:35:37 -05:00
Matt Nadareski
c995ec1dca Miscellaneous cleanup 2024-11-19 12:40:32 -05:00
Matt Nadareski
4d2fbbae04 Update Models to 1.5.2 2024-11-19 01:04:50 -05:00
Matt Nadareski
2776928946 Bump version 2024-11-15 22:38:35 -05:00
Matt Nadareski
8cc87c6540 Recombine WrapperBase files 2024-11-15 22:26:45 -05:00
Matt Nadareski
3c212022aa Use safe enumeration 2024-11-15 22:25:28 -05:00
Matt Nadareski
511c4d09e5 Update ASN1 to 1.4.1 and IO to 1.5.1 2024-11-15 22:22:22 -05:00
Matt Nadareski
d7eba27dc5 Framework only matters for executable 2024-11-15 21:10:27 -05:00
Matt Nadareski
09370618ca Reorder some methods 2024-11-14 20:51:25 -05:00
Matt Nadareski
2197167088 Add remaining easy sizes per partition 2024-11-14 20:48:42 -05:00
Matt Nadareski
b527635fe7 Add remaining easy offsets per partition 2024-11-14 20:46:56 -05:00
Matt Nadareski
695309bc32 Bump version 2024-11-14 13:32:19 -05:00
Matt Nadareski
97b2f68ec7 Use offsets instead of guessing... 2024-11-14 13:27:02 -05:00
Matt Nadareski
593044dbf3 Fix code binary check in N3DS 2024-11-14 12:49:16 -05:00
Matt Nadareski
1fcf44fb8d Bump version 2024-11-14 11:32:17 -05:00
Matt Nadareski
a2a472baf9 Fix top level printing issue 2024-11-14 11:24:08 -05:00
Matt Nadareski
b5b4a50d94 Fix deserialization of NCCH extended header
The actual fix to this is somewhere in the conversion code where an array of Enum values somehow just... fails? I'm not totally sure how that's happening but this is the easiest way around it until that auto stuff can be fixed.
2024-11-14 11:20:46 -05:00
Matt Nadareski
f1b5464052 Extend N3DS wrapper further 2024-11-14 03:17:11 -05:00
Matt Nadareski
2c0224db22 Fix byte order for N3DS IV 2024-11-14 00:12:35 -05:00
Matt Nadareski
1e78eecb40 Bump version 2024-11-13 23:13:55 -05:00
Matt Nadareski
3626faea60 Fix building N3DS cart image 2024-11-13 23:05:26 -05:00
Matt Nadareski
a0177f1174 Add bitmasks helper method 2024-11-13 21:29:43 -05:00
Matt Nadareski
db5fe4a2cd Add extension property for backup header 2024-11-13 21:25:46 -05:00
Matt Nadareski
5716143168 Bump version 2024-11-13 20:48:55 -05:00
Matt Nadareski
2a59b23149 Add more extensions to N3DS wrapper 2024-11-13 20:47:25 -05:00
Matt Nadareski
bdbec4ed02 Update Models to 1.5.1 2024-11-13 20:41:13 -05:00
Matt Nadareski
25193f1805 Start making fixes to N3DS 2024-11-13 20:21:32 -05:00
Matt Nadareski
4840c816a2 Bump version 2024-11-13 02:51:46 -05:00
Matt Nadareski
d0a8e3770b Fix serialization issue 2024-11-13 02:48:38 -05:00
Matt Nadareski
1cf3d50864 Add .NET 9 to target frameworks 2024-11-13 02:42:14 -05:00
Matt Nadareski
d1b98f7d6d HashSet does what I need 2024-11-12 19:41:04 -05:00
Matt Nadareski
4bc87ff812 Use list sorting instead of Linq sorting 2024-11-12 19:35:08 -05:00
Matt Nadareski
e1df11b360 Build cached strings differently 2024-11-12 19:30:28 -05:00
Matt Nadareski
34606a4f04 Easier to read archive count in VPK 2024-11-12 17:05:10 -05:00
Matt Nadareski
c4c5fc4bf6 Array.Find works differently than I thought 2024-11-12 16:58:21 -05:00
Matt Nadareski
cd87ce5373 Unrolling Linq is more efficient 2024-11-12 16:44:41 -05:00
Matt Nadareski
90fc16b888 Reduce more Linq steps 2024-11-12 16:29:47 -05:00
Matt Nadareski
c2d0b71d22 Generic types all have ToString 2024-11-12 16:18:56 -05:00
Matt Nadareski
e54473682c Use TrueForAll 2024-11-12 16:11:15 -05:00
Matt Nadareski
1c8d64d98c Clean up usings 2024-11-12 16:07:31 -05:00
Matt Nadareski
a19437f42f More efficient checks 2024-11-12 16:07:27 -05:00
Matt Nadareski
855e2f2c77 Another overload I never knew about 2024-11-12 16:02:21 -05:00
Matt Nadareski
bd3cf88123 As I said, they're fun 2024-11-12 16:00:05 -05:00
Matt Nadareski
e4578ad3fc Match collections are fun 2024-11-12 15:56:31 -05:00
Matt Nadareski
39e56ef864 Remove one more unnecessary cast 2024-11-12 15:47:49 -05:00
Matt Nadareski
51b77da760 Reduce use of Cast 2024-11-12 15:46:36 -05:00
Matt Nadareski
4b83219a9b Fix conversion 2024-11-12 15:33:48 -05:00
Matt Nadareski
3ed07dd299 Linq is good, but it can be better 2024-11-12 15:30:33 -05:00
Matt Nadareski
bb7daed7f6 Reduce Linq steps 2024-11-12 15:06:28 -05:00
Matt Nadareski
0c84c47752 Explicitly add Linq library 2024-11-12 15:03:28 -05:00
Matt Nadareski
c18a185474 Fix old .NET 2024-11-12 14:56:53 -05:00
Matt Nadareski
8ff66b04d8 Reduce Linq to better query 2024-11-12 14:49:42 -05:00
Matt Nadareski
94d6556e04 Ignore additional elements 2024-11-12 14:40:43 -05:00
Matt Nadareski
6d960265e4 Minor Linq reduction 2024-11-12 14:27:34 -05:00
Matt Nadareski
cf4ca76e10 Select 2024-11-12 14:10:00 -05:00
Matt Nadareski
c7760e9903 Any 2024-11-12 13:10:47 -05:00
Matt Nadareski
d51bedceb6 ToArray 2024-11-12 13:03:06 -05:00
Matt Nadareski
125dc021d5 Disallow CRC-32 variants 2024-11-12 12:37:42 -05:00
Matt Nadareski
5bce481648 Update Hashing to 1.3.0 2024-11-12 12:36:46 -05:00
Matt Nadareski
20153f62cf Update Hashing to 1.2.3 2024-11-06 21:56:44 -05:00
Matt Nadareski
e302dfccf1 Attempt to reduce nesting in GHA builds 2024-11-05 13:53:34 -05:00
Matt Nadareski
594b841490 Make GitHub action Debug-only 2024-11-04 15:09:10 -05:00
Matt Nadareski
40c354f79f Add releases links for convenience 2024-11-04 13:17:55 -05:00
Matt Nadareski
b77959f300 Rename test executable 2024-11-04 12:14:28 -05:00
Matt Nadareski
59d6026a2b Create helper method for string reading; add UTF-8 2024-11-02 20:23:20 -04:00
Matt Nadareski
14226d1270 Completely reset cached data 2024-11-02 19:53:21 -04:00
Matt Nadareski
955f4da708 Fix minor formatting issue 2024-11-02 19:42:32 -04:00
Matt Nadareski
700b0359ea Limit fully repeating strings 2024-11-02 19:40:02 -04:00
Matt Nadareski
fe95b894d7 Bump version 2024-10-31 15:23:59 -04:00
Matt Nadareski
38a2712a8f Fake readable compressor names 2024-10-31 13:51:29 -04:00
Matt Nadareski
d1ea091574 Remove "press enter" on failure 2024-10-31 13:49:08 -04:00
Matt Nadareski
6bc812fc2f Fix formatting for CHD printing 2024-10-31 13:38:42 -04:00
Matt Nadareski
61b89fbd72 Fix typo in N3DS 2024-10-31 12:10:53 -04:00
Matt Nadareski
a2c065bdf2 Add CHD to factory 2024-10-31 12:09:36 -04:00
Matt Nadareski
88479f674b Add CHD printer 2024-10-31 12:06:25 -04:00
Matt Nadareski
5edbacde74 Add CHD printer 2024-10-31 12:03:34 -04:00
Matt Nadareski
67fc51224b Fix lack of ValueTuple in switch 2024-10-31 11:51:14 -04:00
Matt Nadareski
101f3294b4 Add CHD wrapper 2024-10-31 11:47:58 -04:00
Matt Nadareski
6c5622f732 Add CHD header deserialization 2024-10-31 11:40:50 -04:00
Matt Nadareski
f2a6fe1445 Update Models to 1.4.11 2024-10-31 11:34:45 -04:00
Matt Nadareski
b0b593443f Update packages 2024-10-24 17:27:55 -04:00
Matt Nadareski
9b05185add Fix old .NET compatibility 2024-10-14 00:20:02 -04:00
Matt Nadareski
17316da536 Port numerous extensions from NDecrypt 2024-10-14 00:15:14 -04:00
Matt Nadareski
f3ca4dd989 Port logic from UnshieldSharp 2024-10-03 11:14:41 -04:00
Matt Nadareski
e2b7bdac8c Temporary fix for IS-CAB file group parsing 2024-10-03 02:51:37 -04:00
Matt Nadareski
f86f6dc438 Bump version 2024-10-01 14:08:18 -04:00
Matt Nadareski
2bac0ed505 Update packages 2024-10-01 14:06:53 -04:00
Matt Nadareski
ae4078bb7f Fix inconsistencies in build and publish 2024-08-08 20:17:42 -04:00
Matt Nadareski
afaffbd9a2 Fix 3DS serialization and printing 2024-08-08 19:46:05 -04:00
TheRogueArchivist
b878e59e2e Fix typo in PortableExecutable Printer (#11) 2024-07-12 11:08:50 -04:00
Matt Nadareski
4bb3f625dd Make PE debug table parsing safer 2024-06-20 11:23:28 -04:00
Matt Nadareski
b7978cafa5 Bump version 2024-06-13 11:12:40 -04:00
Matt Nadareski
17f376c76f Remove all instances of this. 2024-06-05 22:49:27 -04:00
Matt Nadareski
2774fdf158 Clean up enumerables and namespace use 2024-06-05 22:48:42 -04:00
Matt Nadareski
11081efcb0 Make PE header reading even saferer 2024-06-05 22:22:22 -04:00
TheRogueArchivist
1b412c3027 Add header length safeguards to PortableExecutable wrapper (#9) 2024-06-05 22:19:35 -04:00
Matt Nadareski
73ec66e627 Fix ISv3 deserialization 2024-06-03 11:55:12 -04:00
Matt Nadareski
4ae4cd80b1 Bump version 2024-05-30 21:07:04 -04:00
Matt Nadareski
6eb27c66fc Merge pull request #8 from TheRogueArchivist/streamdatalock
Add lock for reading data from stream
2024-05-30 12:30:33 -04:00
TheRogueArchivist
f96fd17fd3 Add lock for reading data from stream 2024-05-27 15:36:04 -06:00
Matt Nadareski
c255a2494d Fix IS-CAB file group name parsing 2024-05-18 21:27:09 -04:00
Matt Nadareski
86a9846300 Bump version 2024-05-15 15:10:58 -04:00
Matt Nadareski
db877d253c Update Models, fix build 2024-05-15 14:59:55 -04:00
Matt Nadareski
0acf1e3b08 Handle bounds-defying reads 2024-05-15 13:38:44 -04:00
Matt Nadareski
362ed3a9b6 Protect against odd end-of-stream issues 2024-05-15 13:08:51 -04:00
Matt Nadareski
758878a229 Bump version 2024-05-15 12:02:21 -04:00
Matt Nadareski
ffb6dfc333 Update packages 2024-05-13 16:29:53 -04:00
Matt Nadareski
66da74e00a Fix resource table issues with NE 2024-05-12 11:46:05 -04:00
Matt Nadareski
d41a0045cb Fix input paths for test program 2024-05-09 21:54:30 -04:00
Matt Nadareski
b65629ba0e Combine magic and extension checks; helps with complex situations 2024-05-09 21:34:58 -04:00
Matt Nadareski
9518e6d1a0 Unicode (UTF-16) not UTF-8 2024-05-08 12:09:11 -04:00
Matt Nadareski
4f374ee885 Only read resources that are valid 2024-05-08 12:02:48 -04:00
Matt Nadareski
afa239056e Handle future model fix 2024-05-07 08:55:54 -04:00
Matt Nadareski
886825af11 Bump version 2024-05-07 05:17:06 -04:00
Matt Nadareski
198de925aa Update IO 2024-05-07 05:13:30 -04:00
Matt Nadareski
3f7b71e9a5 Bump version 2024-05-06 22:23:45 -04:00
Matt Nadareski
95baaf8603 Update SabreTools.IO 2024-05-06 22:12:14 -04:00
Matt Nadareski
3673264bab Bump version 2024-04-28 19:37:10 -04:00
Matt Nadareski
64fb5a6b63 Update SabreTools.IO 2024-04-28 19:32:06 -04:00
Matt Nadareski
e9c959ccdb Update SabreTools.IO 2024-04-28 17:39:30 -04:00
Matt Nadareski
4b7487e92e More rudimentary ZIP64 fixes 2024-04-28 00:24:35 -04:00
Matt Nadareski
52dbcffd8e Add shortcut if any other valid PKZIP blocks found 2024-04-27 23:57:32 -04:00
Matt Nadareski
24ae354bc2 Fix an indicator for ZIP64 2024-04-27 23:50:03 -04:00
Matt Nadareski
b30b91fd91 Remove redunant fix in StringBuilderExtensions 2024-04-27 23:48:55 -04:00
Matt Nadareski
efb63afc74 Fix PKZIP data printing 2024-04-27 23:45:33 -04:00
Matt Nadareski
16706f7169 Force writing values with proper width 2024-04-27 23:42:37 -04:00
Matt Nadareski
d7c32676b5 Add PKZIP printer implementation 2024-04-27 23:40:02 -04:00
Matt Nadareski
c8c45446bc Add PKZIP archive extra data record parsing 2024-04-27 23:01:50 -04:00
Matt Nadareski
f4de2e27d7 Notes cleanup 2024-04-27 22:49:09 -04:00
Matt Nadareski
970fcbd93b Add PKZIP shell wrapper 2024-04-27 22:45:49 -04:00
Matt Nadareski
57d1cd7f1e Initial code for PKZIP deserialization 2024-04-27 22:41:22 -04:00
Matt Nadareski
522fc372fa Fix instance of wrong extension 2024-04-27 22:23:33 -04:00
Matt Nadareski
7141690fcb Add override for compression handling 2024-04-27 22:04:52 -04:00
Matt Nadareski
c7d9177e68 Allow decompression to be skipped 2024-04-27 22:04:38 -04:00
Matt Nadareski
00b3ea40d9 Bump version 2024-04-26 21:33:56 -04:00
Matt Nadareski
c9afe939dc Update packages 2024-04-26 21:32:55 -04:00
Matt Nadareski
4171ae6516 Update build scripts, action 2024-04-26 21:27:58 -04:00
Matt Nadareski
35a42c49d5 Uncomment large amount of items but return null explicitly 2024-04-24 19:18:38 -04:00
Matt Nadareski
e4dbf56b49 Integrate test program data into main library 2024-04-24 19:15:28 -04:00
Matt Nadareski
76eeb10c47 Update README 2024-04-24 19:04:05 -04:00
Matt Nadareski
9fa73ad54f Rename PrintExtensions to Printer 2024-04-24 19:04:01 -04:00
Matt Nadareski
6034a4fd06 Port Printing into Serialization 2024-04-24 18:53:10 -04:00
Matt Nadareski
9d15310b04 Bump version 2024-04-24 16:17:19 -04:00
Matt Nadareski
f04ec3e465 Remove unused test files from porting 2024-04-24 14:38:47 -04:00
Matt Nadareski
0071e7a462 Create GetTestFilePath helper method 2024-04-24 13:50:36 -04:00
Matt Nadareski
d697461cc2 Reduce unncessary line space 2024-04-24 13:26:39 -04:00
Matt Nadareski
517ff00a0f Rename test classes to be more explicit 2024-04-24 13:25:37 -04:00
Matt Nadareski
d06017c045 Copy serialization tests from SabreTools.Test, fix issues 2024-04-24 13:23:51 -04:00
Matt Nadareski
1b819d96a5 Bump version 2024-04-24 10:17:14 -04:00
Matt Nadareski
ad2bfc31bc Update SabreTools.Models 2024-04-24 10:15:27 -04:00
Matt Nadareski
66b4f12fb3 Port one more extension from UnshieldSharp 2024-04-24 00:39:27 -04:00
Matt Nadareski
40de2575bb Add last extension property from UnshieldSharp 2024-04-24 00:33:24 -04:00
Matt Nadareski
be4a95fe91 Handle nullable better 2024-04-24 00:30:03 -04:00
Matt Nadareski
c685b5e679 Add extension properties from UnshieldSharp 2024-04-24 00:29:27 -04:00
Matt Nadareski
99baeba735 Make Linux publish script executable 2024-04-23 22:27:35 -04:00
Matt Nadareski
bc6b6d39da Add publish scripts 2024-04-23 22:27:26 -04:00
Matt Nadareski
2bb814e170 Remove now-unnecessary code 2024-04-23 22:22:04 -04:00
Matt Nadareski
3bf78c78e3 Bump version 2024-04-23 21:53:36 -04:00
Matt Nadareski
e38ecaec4c Fix build 2024-04-23 21:49:57 -04:00
Matt Nadareski
af40c78b56 Handle more directly-marshalled types 2024-04-23 21:45:54 -04:00
Matt Nadareski
12b206f9fa Update SabreTools.Models 2024-04-23 21:07:42 -04:00
Matt Nadareski
2cc51ba089 Fix build, oops 2024-04-23 21:05:50 -04:00
Matt Nadareski
52f0846d5d Add and fix some deserializers 2024-04-23 21:00:10 -04:00
Matt Nadareski
3fa8848e77 Make more parsing methods public 2024-04-23 15:38:33 -04:00
Matt Nadareski
41276e3d7e Port more helpers 2024-04-23 15:38:21 -04:00
Matt Nadareski
4cef93c95e Port some accessors from UnshieldSharp 2024-04-23 15:27:07 -04:00
Matt Nadareski
cdd999ee03 Fix other instances of string reading 2024-04-23 15:18:18 -04:00
Matt Nadareski
4f253323db Fix IS-CAB deserialization 2024-04-23 15:14:18 -04:00
Matt Nadareski
351f749e20 Add ISAv3 deserializer 2024-04-23 15:12:42 -04:00
Matt Nadareski
1e83fc4b9a Update packages 2024-04-23 15:12:39 -04:00
Matt Nadareski
c532bd1063 Bump version 2024-04-18 12:16:02 -04:00
Matt Nadareski
e4631a8176 Update SabreTools.IO 2024-04-18 12:04:54 -04:00
Matt Nadareski
ee8dad0c87 Bump version 2024-04-17 13:00:07 -04:00
Matt Nadareski
4163b2f22a Create non-typed variants of IWrapper and WrapperBase 2024-04-17 12:28:08 -04:00
Matt Nadareski
6aaf3afa38 Fix namespace issues 2024-04-17 11:52:22 -04:00
Matt Nadareski
2a7eb44281 Bump version 2024-04-17 11:45:26 -04:00
Matt Nadareski
08bbc93793 Update SabreTools.IO 2024-04-17 11:44:58 -04:00
Matt Nadareski
789478df13 Update SabreTools.IO 2024-04-16 13:16:59 -04:00
Matt Nadareski
cd4f1c9d97 Merge pull request #7 from SabreTools/deserializer-base
Deserializer base
2024-04-04 14:17:57 -04:00
Matt Nadareski
1a2e9fb942 Add PlayJ playlist wrapper 2024-04-04 14:15:27 -04:00
Matt Nadareski
d0865739de Add PIC wrapper 2024-04-04 14:13:03 -04:00
Matt Nadareski
0696bbab72 Add MoPaQ wrapper 2024-04-04 14:06:59 -04:00
Matt Nadareski
4b4c17ac24 Make model type inherent to interface 2024-04-04 14:03:02 -04:00
Matt Nadareski
d768172da1 Update README 2024-04-04 12:03:19 -04:00
Matt Nadareski
2a4d24309d Create base class for serializers 2024-04-04 12:03:19 -04:00
Matt Nadareski
bc01ce4552 Enforce IStreamDeserializer in base class 2024-04-04 12:03:19 -04:00
Matt Nadareski
ef0efe66bd Migrate IFileDeserializer implementation to base class 2024-04-04 12:03:19 -04:00
Matt Nadareski
7c21f65723 Migrate IByteSerializer implementation to base class 2024-04-04 12:03:19 -04:00
Matt Nadareski
cec53e907f Move static deserializers to base class 2024-04-04 12:03:19 -04:00
Matt Nadareski
006ced0430 Bump version 2024-04-04 12:00:53 -04:00
Matt Nadareski
bee6c0ba11 Add byte deserializers for remaining stream deserializers 2024-04-03 23:25:54 -04:00
Matt Nadareski
3cb880ff3f Update SabreTools.Models 2024-04-03 22:54:30 -04:00
Matt Nadareski
f1d54e4a14 Add XML byte deserialization 2024-04-03 22:41:49 -04:00
Matt Nadareski
f4aaed7f9c Move overlay extension method 2024-04-03 22:31:24 -04:00
Matt Nadareski
46ad76c5d2 Add flag for long/short SeparatedValue writing 2024-04-03 22:26:23 -04:00
Matt Nadareski
8f731cebc8 Add array constants for AttractMode 2024-04-03 22:21:39 -04:00
Matt Nadareski
6dbf9dacd6 Add flag for long/short AttractMode writing 2024-04-03 22:18:05 -04:00
Matt Nadareski
94ab760c67 Remove unnecessary code 2024-04-03 21:57:14 -04:00
Matt Nadareski
4ed3880bad Use SabreTools.Hashing for hash types 2024-04-03 21:56:21 -04:00
Matt Nadareski
ff8dcd30a5 Move some constants to the deserializer 2024-04-03 21:46:35 -04:00
Matt Nadareski
8ced91d0fa Move some constants to the deserializer 2024-04-03 21:44:02 -04:00
Matt Nadareski
f2c6fa2b8e Convert string serialization to new framework 2024-04-03 21:42:08 -04:00
Matt Nadareski
9b1bacd167 Move serializers to new organization 2024-04-03 21:27:50 -04:00
Matt Nadareski
964c97200c Move stream deserializers to new organization 2024-04-03 20:55:02 -04:00
Matt Nadareski
a3f3384ac9 Move file deserializers to new organization 2024-04-03 17:27:08 -04:00
Matt Nadareski
8b546fbf27 Start splitting serialziation differently for clarity 2024-04-03 16:41:54 -04:00
Matt Nadareski
15da711087 Rename IByteSerializer to IByteDeserializer 2024-04-03 16:37:26 -04:00
Matt Nadareski
bfee7dd449 Use better naming 2024-04-03 16:35:54 -04:00
Matt Nadareski
9de2a91e80 Fix inheritdoc 2024-04-03 16:15:48 -04:00
Matt Nadareski
bf50c801b2 Simplify some static deserializers 2024-04-03 16:00:18 -04:00
Matt Nadareski
c19a4a94f4 Use new static stream serializer 2024-04-03 15:50:06 -04:00
Matt Nadareski
b6fe94116b Add static serializers for IStreamSerializer 2024-04-03 15:43:36 -04:00
Matt Nadareski
bcf604c773 Use new static stream deserializer 2024-04-03 15:23:49 -04:00
Matt Nadareski
74984a9114 Add static deserializers for IStreamSerializer 2024-04-03 15:22:35 -04:00
Matt Nadareski
8c1e241286 Add static serializers for IFileSerializer 2024-04-03 14:58:06 -04:00
Matt Nadareski
f666d737cb Add static deserializers for IFileSerializer 2024-04-03 14:28:47 -04:00
Matt Nadareski
a01609f1d1 Add static serializers for IByteSerializer 2024-04-03 14:06:23 -04:00
Matt Nadareski
8ca9ccaf00 Handle invalid texture counts 2024-04-02 16:55:43 -04:00
Matt Nadareski
fc5374108c Bump version 2024-04-02 16:15:29 -04:00
Matt Nadareski
15452ded52 Use new IO extension 2024-04-02 16:12:08 -04:00
Matt Nadareski
49c6c4412b Update SabreTools.IO 2024-04-02 16:10:58 -04:00
Matt Nadareski
cfc53f66a8 Fix cuesheet serialization 2024-04-02 15:30:43 -04:00
Matt Nadareski
ec1fb7247c Add file serializers for all stream variants 2024-04-02 14:28:30 -04:00
Matt Nadareski
54b1eef8ae Better handle version 3 CFB files, probably (fixes #3) 2024-04-02 12:54:54 -04:00
Matt Nadareski
f448314309 Add file serializer for CFB 2024-04-02 12:45:31 -04:00
Matt Nadareski
c4e8debb15 Detect invalid dialog item counts (fixes #5) 2024-04-02 12:35:14 -04:00
Matt Nadareski
822839c813 Add file serializers for executable types 2024-04-02 12:06:56 -04:00
Matt Nadareski
27d36a11ca Add skeleton test executable 2024-04-02 11:56:27 -04:00
Matt Nadareski
92d9ca932d Move library code to subfolder 2024-04-02 11:51:39 -04:00
Deterous
69e1f5ff0b De/Serialize XboxOne/XSX catalog.js files (#6)
* Add JSON/catalog.js logic

* Proper json deserialize

* Update packages

* Catalog is UTF-16 LE, make BaseJsonFile encoding independent

* Bump version, use ST.Models 1.4.1

* Implement JsonFile as interface with UTF8 as default

* typo
2024-04-02 08:46:12 -07:00
Matt Nadareski
d265c14841 Bump version 2024-03-25 14:25:28 -04:00
Matt Nadareski
1148245226 Surface NE/LE/PE methods for other library use 2024-03-24 21:09:12 -04:00
Matt Nadareski
f53d9f94e6 Break if StringFileInfo child is total size 0 2024-03-22 23:46:05 -04:00
Matt Nadareski
4e3d832834 Ensure Listrom serializes to the correct model type 2024-03-19 15:47:13 -04:00
Matt Nadareski
0713dfafb2 Bump version 2024-03-12 16:35:45 -04:00
Matt Nadareski
c0d4f403c3 Update IO package 2024-03-12 16:34:32 -04:00
Matt Nadareski
5ed79166cf Update Models library 2024-03-12 16:29:05 -04:00
Matt Nadareski
17030cfb9f Fix Listxml type key issues 2024-03-12 12:58:27 -04:00
Matt Nadareski
530fa69d3c Fix OpenMSX cross-model serialization keys 2024-03-12 00:46:46 -04:00
Matt Nadareski
7a5956f599 Fix capitalization in RomCenter INI stream serializer 2024-03-11 23:08:10 -04:00
Matt Nadareski
5562768509 Fix separated value cross-model serialization 2024-03-11 22:47:38 -04:00
Matt Nadareski
aa538df229 All doctype overloads to take nullable objects 2024-03-11 22:31:40 -04:00
Matt Nadareski
b7b22cba32 Fix AttractMode writing 2024-03-11 14:52:32 -04:00
Matt Nadareski
fc489125d9 Fix serialization problem for listrom 2024-03-10 00:39:23 -05:00
Matt Nadareski
036589473d Fix serialziation problem for archive.org 2024-03-10 00:36:31 -05:00
Matt Nadareski
432ce85f89 Bump version 2024-03-05 11:16:22 -05:00
Matt Nadareski
438e8067eb Update SabreTools.IO 2024-03-05 11:12:59 -05:00
Matt Nadareski
9715507aaf Add nuget package and PR workflows 2024-02-27 19:17:20 -05:00
2230 changed files with 255823 additions and 28852 deletions

167
.editorconfig Normal file
View File

@@ -0,0 +1,167 @@
# top-most EditorConfig file
root = true
# C# files
[*.cs]
# Indentation and spacing
charset = utf-8
indent_size = 4
indent_style = space
tab_width = 4
trim_trailing_whitespace = true
# New line preferences
end_of_line = lf
insert_final_newline = true
max_line_length = unset
# using directive preferences
csharp_using_directive_placement = outside_namespace
dotnet_diagnostic.IDE0005.severity = error
# Code-block preferences
csharp_style_namespace_declarations = block_scoped
csharp_style_prefer_method_group_conversion = true
csharp_style_prefer_top_level_statements = false
# Expression-level preferences
csharp_prefer_simple_default_expression = true
csharp_style_inlined_variable_declaration = true
csharp_style_unused_value_assignment_preference = discard_variable
csharp_style_unused_value_expression_statement_preference = discard_variable
dotnet_diagnostic.IDE0001.severity = warning
dotnet_diagnostic.IDE0002.severity = warning
dotnet_diagnostic.IDE0004.severity = warning
dotnet_diagnostic.IDE0010.severity = error
dotnet_diagnostic.IDE0051.severity = warning
dotnet_diagnostic.IDE0052.severity = warning
dotnet_diagnostic.IDE0072.severity = warning
dotnet_diagnostic.IDE0080.severity = warning
dotnet_diagnostic.IDE0100.severity = error
dotnet_diagnostic.IDE0110.severity = error
dotnet_diagnostic.IDE0120.severity = warning
dotnet_diagnostic.IDE0121.severity = warning
dotnet_diagnostic.IDE0240.severity = error
dotnet_diagnostic.IDE0241.severity = error
dotnet_style_coalesce_expression = true
dotnet_style_namespace_match_folder = false
dotnet_style_null_propagation = true
dotnet_style_prefer_auto_properties = true
dotnet_style_prefer_collection_expression = when_types_loosely_match
dotnet_style_prefer_is_null_check_over_reference_equality_method = true
dotnet_style_prefer_compound_assignment = true
csharp_style_prefer_simple_property_accessors = true
dotnet_style_prefer_simplified_interpolation = true
dotnet_style_prefer_simplified_boolean_expressions = true
csharp_style_prefer_unbound_generic_type_in_nameof = true
# Field preferences
dotnet_diagnostic.IDE0044.severity = warning
dotnet_style_readonly_field = true
# Language keyword vs. framework types preferences
dotnet_diagnostic.IDE0049.severity = error
dotnet_style_predefined_type_for_locals_parameters_members = true
dotnet_style_predefined_type_for_member_access = true
# Modifier preferences
csharp_prefer_static_local_function = true
csharp_style_prefer_readonly_struct = true
dotnet_diagnostic.IDE0036.severity = warning
dotnet_diagnostic.IDE0040.severity = error
dotnet_diagnostic.IDE0380.severity = error
dotnet_style_require_accessibility_modifiers = always
# New-line preferences
dotnet_diagnostic.IDE2000.severity = warning
dotnet_diagnostic.IDE2002.severity = warning
dotnet_diagnostic.IDE2003.severity = warning
dotnet_diagnostic.IDE2004.severity = warning
dotnet_diagnostic.IDE2005.severity = warning
dotnet_diagnostic.IDE2006.severity = warning
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = false
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = false
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false
dotnet_style_allow_multiple_blank_lines_experimental = false
dotnet_style_allow_statement_immediately_after_block_experimental = false
# Null-checking preferences
csharp_style_conditional_delegate_call = true
# Parameter preferences
dotnet_code_quality_unused_parameters = all
dotnet_diagnostic.IDE0280.severity = error
# Parentheses preferences
dotnet_diagnostic.IDE0047.severity = warning
dotnet_diagnostic.IDE0048.severity = warning
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
dotnet_style_parentheses_in_other_operators = always_for_clarity
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
# Pattern-matching preferences
dotnet_diagnostic.IDE0019.severity = warning
dotnet_diagnostic.IDE0020.severity = warning
dotnet_diagnostic.IDE0038.severity = warning
dotnet_diagnostic.IDE0066.severity = none
dotnet_diagnostic.IDE0083.severity = warning
dotnet_diagnostic.IDE0260.severity = warning
csharp_style_pattern_matching_over_as_with_null_check = true
csharp_style_pattern_matching_over_is_with_cast_check = true
csharp_style_prefer_not_pattern = true
csharp_style_prefer_pattern_matching = true
# this. and Me. preferences
dotnet_style_qualification_for_event = false
dotnet_style_qualification_for_field = false
dotnet_style_qualification_for_method = false
dotnet_style_qualification_for_property = false
# var preferences
csharp_style_var_for_built_in_types = false
csharp_style_var_when_type_is_apparent = true
# .NET formatting options
dotnet_separate_import_directive_groups = false
dotnet_sort_system_directives_first = true
# C# formatting options
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = false
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true
csharp_new_line_before_catch = true
csharp_new_line_before_else = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_anonymous_types = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_open_brace = all
csharp_new_line_between_query_expression_clauses = true
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_comma = true
csharp_space_after_dot = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_after_semicolon_in_for_statement = true
csharp_space_around_binary_operators = before_and_after
csharp_space_around_declaration_statements = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_before_comma = false
csharp_space_before_dot = false
csharp_space_before_open_square_brackets = false
csharp_space_before_semicolon_in_for_statement = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_parentheses = false
csharp_space_between_square_brackets = false

48
.github/workflows/build_and_test.yml vendored Normal file
View File

@@ -0,0 +1,48 @@
name: Build and Test
on:
push:
branches: ["main"]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: |
8.0.x
9.0.x
10.0.x
- name: Run tests
run: dotnet test
- name: Run publish script
run: ./publish-nix.sh -d
- name: Update rolling tag
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git tag -f rolling
git push origin :refs/tags/rolling || true
git push origin rolling --force
- name: Upload to rolling
uses: ncipollo/release-action@v1.20.0
with:
allowUpdates: True
artifacts: "*.nupkg,*.snupkg,*.zip"
body: "Last built commit: ${{ github.sha }}"
name: "Rolling Release"
prerelease: True
replacesArtifacts: True
tag: "rolling"
updateOnlyUnreleased: True

23
.github/workflows/check_pr.yml vendored Normal file
View File

@@ -0,0 +1,23 @@
name: Build PR
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Setup .NET
uses: actions/setup-dotnet@v5
with:
dotnet-version: |
8.0.x
9.0.x
10.0.x
- name: Build
run: dotnet build
- name: Run tests
run: dotnet test

329
.gitignore vendored
View File

@@ -1,22 +1,18 @@
*.swp
*.*~
project.lock.json
.DS_Store
*.pyc
nupkg/
# Visual Studio Code
.vscode
# Rider
.idea
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.lscache
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
@@ -24,15 +20,312 @@ nupkg/
[Rr]eleases/
x64/
x86/
build/
bld/
[Bb]in/
[Oo]bj/
[Oo]ut/
msbuild.log
msbuild.err
msbuild.wrn
[Ll]og/
# Visual Studio 2015
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/

42
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,42 @@
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (ExtractionTool)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/ExtractionTool/bin/Debug/net10.0/ExtractionTool.dll",
"args": [],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false,
"justMyCode": false
},
{
"name": ".NET Core Launch (InfoPrint)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/InfoPrint/bin/Debug/net10.0/InfoPrint.dll",
"args": [],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false,
"justMyCode": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
}

24
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,24 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "shell",
"args": [
"build",
// Ask dotnet build to generate full paths for file names.
"/property:GenerateFullPaths=true",
// Do not generate summary otherwise it leads to duplicate errors in Problems panel
"/consoleloggerparameters:NoSummary"
],
"group": "build",
"presentation": {
"reveal": "silent"
},
"problemMatcher": "$msCompile"
}
]
}

View File

@@ -1,14 +0,0 @@
namespace SabreTools.Serialization
{
/// <summary>
/// Separated value serializer/deserializer for AttractMode romlists
/// </summary>
public static class AttractMode
{
public const string HeaderWithoutRomname = "#Name;Title;Emulator;CloneOf;Year;Manufacturer;Category;Players;Rotation;Control;Status;DisplayCount;DisplayType;AltRomname;AltTitle;Extra;Buttons";
public const int HeaderWithoutRomnameCount = 17;
public const string HeaderWithRomname = "#Romname;Title;Emulator;Cloneof;Year;Manufacturer;Category;Players;Rotation;Control;Status;DisplayCount;DisplayType;AltRomname;AltTitle;Extra;Buttons;Favourite;Tags;PlayedCount;PlayedTime;FileIsAvailable";
public const int HeaderWithRomnameCount = 22;
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.AACS;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class AACS : IByteSerializer<MediaKeyBlock>
{
/// <inheritdoc/>
public MediaKeyBlock? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.AACS().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.BDPlus;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class BDPlus : IByteSerializer<SVM>
{
/// <inheritdoc/>
public SVM? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.BDPlus().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.BFPK;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class BFPK : IByteSerializer<Archive>
{
/// <inheritdoc/>
public Archive? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.BFPK().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class BSP : IByteSerializer<Models.BSP.File>
{
/// <inheritdoc/>
public Models.BSP.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.BSP().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.CFB;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class CFB : IByteSerializer<Binary>
{
/// <inheritdoc/>
public Binary? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.CFB().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class CIA : IByteSerializer<Models.N3DS.CIA>
{
/// <inheritdoc/>
public Models.N3DS.CIA? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.CIA().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class GCF : IByteSerializer<Models.GCF.File>
{
/// <inheritdoc/>
public Models.GCF.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.GCF().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class IRD : IByteSerializer<Models.IRD.File>
{
/// <inheritdoc/>
public Models.IRD.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.IRD().Deserialize(dataStream);
}
}
}

View File

@@ -1,26 +0,0 @@
using System.IO;
using SabreTools.Models.InstallShieldCabinet;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
// TODO: Add multi-cabinet reading
public partial class InstallShieldCabinet : IByteSerializer<Cabinet>
{
/// <inheritdoc/>
public Cabinet? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.InstallShieldCabinet().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.LinearExecutable;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class LinearExecutable : IByteSerializer<Executable>
{
/// <inheritdoc/>
public Executable? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.LinearExecutable().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.MSDOS;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class MSDOS : IByteSerializer<Executable>
{
/// <inheritdoc/>
public Executable? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.MSDOS().Deserialize(dataStream);
}
}
}

View File

@@ -1,26 +0,0 @@
using System.IO;
using SabreTools.Models.MicrosoftCabinet;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
// TODO: Add multi-cabinet reading
public partial class MicrosoftCabinet : IByteSerializer<Cabinet>
{
/// <inheritdoc/>
public Cabinet? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.MicrosoftCabinet().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.MoPaQ;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class MoPaQ : IByteSerializer<Archive>
{
/// <inheritdoc/>
public Archive? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.MoPaQ().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.N3DS;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class N3DS : IByteSerializer<Cart>
{
/// <inheritdoc/>
public Cart? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.N3DS().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class NCF : IByteSerializer<Models.NCF.File>
{
/// <inheritdoc/>
public Models.NCF.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.NCF().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.NewExecutable;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class NewExecutable : IByteSerializer<Executable>
{
/// <inheritdoc/>
public Executable? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.NewExecutable().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.Nitro;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class Nitro : IByteSerializer<Cart>
{
/// <inheritdoc/>
public Cart? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.Nitro().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class PAK : IByteSerializer<Models.PAK.File>
{
/// <inheritdoc/>
public Models.PAK.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.PAK().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.PFF;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class PFF : IByteSerializer<Archive>
{
/// <inheritdoc/>
public Archive? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.PFF().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.PlayJ;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class PlayJAudio : IByteSerializer<AudioFile>
{
/// <inheritdoc/>
public AudioFile? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.PlayJAudio().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.PlayJ;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class PlayJPlaylist : IByteSerializer<Playlist>
{
/// <inheritdoc/>
public Playlist? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.PlayJPlaylist().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.PortableExecutable;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class PortableExecutable : IByteSerializer<Executable>
{
/// <inheritdoc/>
public Executable? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.PortableExecutable().Deserialize(dataStream);
}
}
}

View File

@@ -1,25 +0,0 @@
using System.IO;
using SabreTools.Models.Quantum;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class Quantum : IByteSerializer<Archive>
{
/// <inheritdoc/>
public Archive? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.Quantum().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class SGA : IByteSerializer<Models.SGA.File>
{
/// <inheritdoc/>
public Models.SGA.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.SGA().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class VBSP : IByteSerializer<Models.VBSP.File>
{
/// <inheritdoc/>
public Models.VBSP.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.VBSP().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class VPK : IByteSerializer<Models.VPK.File>
{
/// <inheritdoc/>
public Models.VPK.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.VPK().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class WAD : IByteSerializer<Models.WAD.File>
{
/// <inheritdoc/>
public Models.WAD.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.WAD().Deserialize(dataStream);
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Bytes
{
public partial class XZP : IByteSerializer<Models.XZP.File>
{
/// <inheritdoc/>
public Models.XZP.File? Deserialize(byte[]? data, int offset)
{
// If the data is invalid
if (data == null)
return null;
// If the offset is out of bounds
if (offset < 0 || offset >= data.Length)
return null;
// Create a memory stream and parse that
MemoryStream dataStream = new MemoryStream(data, offset, data.Length - offset);
return new Streams.XZP().Deserialize(dataStream);
}
}
}

View File

@@ -1,117 +0,0 @@
using System;
using System.Linq;
using SabreTools.Models.ArchiveDotOrg;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class ArchiveDotOrg : IModelSerializer<Models.ArchiveDotOrg.Files, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.ArchiveDotOrg.Files? Deserialize(Models.Metadata.MetadataFile? obj)
{
if (obj == null)
return null;
var files = new Models.ArchiveDotOrg.Files();
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Any())
{
files.File = machines
.Where(m => m != null)
.SelectMany(ConvertFromInternalModel)
.ToArray();
}
return files;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Machine"/> to an array of <cref="Models.ArchiveDotOrg.File"/>
/// </summary>
private static Models.ArchiveDotOrg.File[] ConvertFromInternalModel(Models.Metadata.Machine item)
{
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
if (roms == null)
return [];
return roms
.Where(r => r != null)
.Select(ConvertFromInternalModel).ToArray();
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.ArchiveDotOrg.File"/>
/// </summary>
private static Models.ArchiveDotOrg.File ConvertFromInternalModel(Models.Metadata.Rom item)
{
var file = new Models.ArchiveDotOrg.File
{
Name = item.ReadString(Models.Metadata.Rom.NameKey),
Source = item.ReadString(Models.Metadata.Rom.SourceKey),
BitTorrentMagnetHash = item.ReadString(Models.Metadata.Rom.BitTorrentMagnetHashKey),
LastModifiedTime = item.ReadString(Models.Metadata.Rom.LastModifiedTimeKey),
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
MD5 = item.ReadString(Models.Metadata.Rom.MD5Key),
CRC32 = item.ReadString(Models.Metadata.Rom.CRCKey),
SHA1 = item.ReadString(Models.Metadata.Rom.SHA1Key),
FileCount = item.ReadString(Models.Metadata.Rom.FileCountKey),
Format = item.ReadString(Models.Metadata.Rom.FormatKey),
Original = item.ReadString(Models.Metadata.Rom.OriginalKey),
Summation = item.ReadString(Models.Metadata.Rom.SummationKey),
MatrixNumber = item.ReadString(Models.Metadata.Rom.MatrixNumberKey),
CollectionCatalogNumber = item.ReadString(Models.Metadata.Rom.CollectionCatalogNumberKey),
Comment = item.ReadString(Models.Metadata.Rom.CommentKey),
ASRDetectedLang = item.ReadString(Models.Metadata.Rom.ASRDetectedLangKey),
ASRDetectedLangConf = item.ReadString(Models.Metadata.Rom.ASRDetectedLangConfKey),
ASRTranscribedLang = item.ReadString(Models.Metadata.Rom.ASRTranscribedLangKey),
WhisperASRModuleVersion = item.ReadString(Models.Metadata.Rom.WhisperASRModuleVersionKey),
WhisperModelHash = item.ReadString(Models.Metadata.Rom.WhisperModelHashKey),
WhisperModelName = item.ReadString(Models.Metadata.Rom.WhisperModelNameKey),
WhisperVersion = item.ReadString(Models.Metadata.Rom.WhisperVersionKey),
ClothCoverDetectionModuleVersion = item.ReadString(Models.Metadata.Rom.ClothCoverDetectionModuleVersionKey),
hOCRCharToWordhOCRVersion = item.ReadString(Models.Metadata.Rom.hOCRCharToWordhOCRVersionKey),
hOCRCharToWordModuleVersion = item.ReadString(Models.Metadata.Rom.hOCRCharToWordModuleVersionKey),
hOCRFtsTexthOCRVersion = item.ReadString(Models.Metadata.Rom.hOCRFtsTexthOCRVersionKey),
hOCRFtsTextModuleVersion = item.ReadString(Models.Metadata.Rom.hOCRFtsTextModuleVersionKey),
hOCRPageIndexhOCRVersion = item.ReadString(Models.Metadata.Rom.hOCRPageIndexhOCRVersionKey),
hOCRPageIndexModuleVersion = item.ReadString(Models.Metadata.Rom.hOCRPageIndexModuleVersionKey),
TesseractOCR = item.ReadString(Models.Metadata.Rom.TesseractOCRKey),
TesseractOCRConverted = item.ReadString(Models.Metadata.Rom.TesseractOCRConvertedKey),
TesseractOCRDetectedLang = item.ReadString(Models.Metadata.Rom.TesseractOCRDetectedLangKey),
TesseractOCRDetectedLangConf = item.ReadString(Models.Metadata.Rom.TesseractOCRDetectedLangConfKey),
TesseractOCRDetectedScript = item.ReadString(Models.Metadata.Rom.TesseractOCRDetectedScriptKey),
TesseractOCRDetectedScriptConf = item.ReadString(Models.Metadata.Rom.TesseractOCRDetectedScriptConfKey),
TesseractOCRModuleVersion = item.ReadString(Models.Metadata.Rom.TesseractOCRModuleVersionKey),
TesseractOCRParameters = item.ReadString(Models.Metadata.Rom.TesseractOCRParametersKey),
PDFModuleVersion = item.ReadString(Models.Metadata.Rom.PDFModuleVersionKey),
WordConfidenceInterval0To10 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval0To10Key),
WordConfidenceInterval11To20 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval11To20Key),
WordConfidenceInterval21To30 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval21To30Key),
WordConfidenceInterval31To40 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval31To40Key),
WordConfidenceInterval41To50 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval41To50Key),
WordConfidenceInterval51To60 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval51To60Key),
WordConfidenceInterval61To70 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval61To70Key),
WordConfidenceInterval71To80 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval71To80Key),
WordConfidenceInterval81To90 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval81To90Key),
WordConfidenceInterval91To100 = item.ReadString(Models.Metadata.Rom.WordConfidenceInterval91To100Key),
Album = item.ReadString(Models.Metadata.Rom.AlbumKey),
Artist = item.ReadString(Models.Metadata.Rom.ArtistKey),
Bitrate = item.ReadString(Models.Metadata.Rom.BitrateKey),
Creator = item.ReadString(Models.Metadata.Rom.CreatorKey),
Height = item.ReadString(Models.Metadata.Rom.HeightKey),
Length = item.ReadString(Models.Metadata.Rom.LengthKey),
PreviewImage = item.ReadString(Models.Metadata.Rom.PreviewImageKey),
Rotation = item.ReadString(Models.Metadata.Rom.RotationKey),
Title = item.ReadString(Models.Metadata.Rom.TitleKey),
Track = item.ReadString(Models.Metadata.Rom.TrackKey),
Width = item.ReadString(Models.Metadata.Rom.WidthKey),
};
return file;
}
}
}

View File

@@ -1,132 +0,0 @@
using System.Linq;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class ArchiveDotOrg : IModelSerializer<Models.ArchiveDotOrg.Files, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.Metadata.MetadataFile? Serialize(Models.ArchiveDotOrg.Files? item)
{
if (item == null)
return null;
var metadataFile = new Models.Metadata.MetadataFile
{
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
};
if (item?.File != null && item.File.Any())
{
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.File
.Where(f => f != null)
.Select(ConvertMachineToInternalModel)
.Where(m => m != null)
.ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.ArchiveDotOrg.Files"/> to <cref="Models.Metadata.Header"/>
/// </summary>
private static Models.Metadata.Header ConvertHeaderToInternalModel(Models.ArchiveDotOrg.Files item)
{
var header = new Models.Metadata.Header
{
[Models.Metadata.Header.NameKey] = "archive.org",
};
return header;
}
/// <summary>
/// Convert from <cref="Models.ArchiveDotOrg.File"/> to <cref="Models.Metadata.Machine"/>
/// </summary>
private static Models.Metadata.Machine ConvertMachineToInternalModel(Models.ArchiveDotOrg.File? item)
{
var machine = new Models.Metadata.Machine
{
[Models.Metadata.Machine.RomKey] = ConvertToInternalModel(item),
};
return machine;
}
/// <summary>
/// Convert from <cref="Models.ArchiveDotOrg.File"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
private static Models.Metadata.Rom? ConvertToInternalModel(Models.ArchiveDotOrg.File? item)
{
if (item == null)
return null;
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.NameKey] = item.Name,
[Models.Metadata.Rom.SourceKey] = item.Source,
[Models.Metadata.Rom.BitTorrentMagnetHashKey] = item.BitTorrentMagnetHash,
[Models.Metadata.Rom.LastModifiedTimeKey] = item.LastModifiedTime,
[Models.Metadata.Rom.SizeKey] = item.Size,
[Models.Metadata.Rom.MD5Key] = item.MD5,
[Models.Metadata.Rom.CRCKey] = item.CRC32,
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
[Models.Metadata.Rom.FileCountKey] = item.FileCount,
[Models.Metadata.Rom.FormatKey] = item.Format,
[Models.Metadata.Rom.OriginalKey] = item.Original,
[Models.Metadata.Rom.SummationKey] = item.Summation,
[Models.Metadata.Rom.MatrixNumberKey] = item.MatrixNumber,
[Models.Metadata.Rom.CollectionCatalogNumberKey] = item.CollectionCatalogNumber,
[Models.Metadata.Rom.PublisherKey] = item.Publisher,
[Models.Metadata.Rom.CommentKey] = item.Comment,
[Models.Metadata.Rom.ASRDetectedLangKey] = item.ASRDetectedLang,
[Models.Metadata.Rom.ASRDetectedLangConfKey] = item.ASRDetectedLangConf,
[Models.Metadata.Rom.ASRTranscribedLangKey] = item.ASRTranscribedLang,
[Models.Metadata.Rom.WhisperASRModuleVersionKey] = item.WhisperASRModuleVersion,
[Models.Metadata.Rom.WhisperModelHashKey] = item.WhisperModelHash,
[Models.Metadata.Rom.WhisperModelNameKey] = item.WhisperModelName,
[Models.Metadata.Rom.WhisperVersionKey] = item.WhisperVersion,
[Models.Metadata.Rom.ClothCoverDetectionModuleVersionKey] = item.ClothCoverDetectionModuleVersion,
[Models.Metadata.Rom.hOCRCharToWordhOCRVersionKey] = item.hOCRCharToWordhOCRVersion,
[Models.Metadata.Rom.hOCRCharToWordModuleVersionKey] = item.hOCRCharToWordModuleVersion,
[Models.Metadata.Rom.hOCRFtsTexthOCRVersionKey] = item.hOCRFtsTexthOCRVersion,
[Models.Metadata.Rom.hOCRFtsTextModuleVersionKey] = item.hOCRFtsTextModuleVersion,
[Models.Metadata.Rom.hOCRPageIndexhOCRVersionKey] = item.hOCRPageIndexhOCRVersion,
[Models.Metadata.Rom.hOCRPageIndexModuleVersionKey] = item.hOCRPageIndexModuleVersion,
[Models.Metadata.Rom.TesseractOCRKey] = item.TesseractOCR,
[Models.Metadata.Rom.TesseractOCRConvertedKey] = item.TesseractOCRConverted,
[Models.Metadata.Rom.TesseractOCRDetectedLangKey] = item.TesseractOCRDetectedLang,
[Models.Metadata.Rom.TesseractOCRDetectedLangConfKey] = item.TesseractOCRDetectedLangConf,
[Models.Metadata.Rom.TesseractOCRDetectedScriptKey] = item.TesseractOCRDetectedScript,
[Models.Metadata.Rom.TesseractOCRDetectedScriptConfKey] = item.TesseractOCRDetectedScriptConf,
[Models.Metadata.Rom.TesseractOCRModuleVersionKey] = item.TesseractOCRModuleVersion,
[Models.Metadata.Rom.TesseractOCRParametersKey] = item.TesseractOCRParameters,
[Models.Metadata.Rom.PDFModuleVersionKey] = item.PDFModuleVersion,
[Models.Metadata.Rom.WordConfidenceInterval0To10Key] = item.WordConfidenceInterval0To10,
[Models.Metadata.Rom.WordConfidenceInterval11To20Key] = item.WordConfidenceInterval11To20,
[Models.Metadata.Rom.WordConfidenceInterval21To30Key] = item.WordConfidenceInterval21To30,
[Models.Metadata.Rom.WordConfidenceInterval31To40Key] = item.WordConfidenceInterval31To40,
[Models.Metadata.Rom.WordConfidenceInterval41To50Key] = item.WordConfidenceInterval41To50,
[Models.Metadata.Rom.WordConfidenceInterval51To60Key] = item.WordConfidenceInterval51To60,
[Models.Metadata.Rom.WordConfidenceInterval61To70Key] = item.WordConfidenceInterval61To70,
[Models.Metadata.Rom.WordConfidenceInterval71To80Key] = item.WordConfidenceInterval71To80,
[Models.Metadata.Rom.WordConfidenceInterval81To90Key] = item.WordConfidenceInterval81To90,
[Models.Metadata.Rom.WordConfidenceInterval91To100Key] = item.WordConfidenceInterval91To100,
[Models.Metadata.Rom.AlbumKey] = item.Album,
[Models.Metadata.Rom.ArtistKey] = item.Artist,
[Models.Metadata.Rom.BitrateKey] = item.Bitrate,
[Models.Metadata.Rom.CreatorKey] = item.Creator,
[Models.Metadata.Rom.HeightKey] = item.Height,
[Models.Metadata.Rom.LengthKey] = item.Length,
[Models.Metadata.Rom.PreviewImageKey] = item.PreviewImage,
[Models.Metadata.Rom.RotationKey] = item.Rotation,
[Models.Metadata.Rom.TitleKey] = item.Title,
[Models.Metadata.Rom.TrackKey] = item.Track,
[Models.Metadata.Rom.WidthKey] = item.Width,
};
return rom;
}
}
}

View File

@@ -1,91 +0,0 @@
using System;
using System.Linq;
using SabreTools.Models.AttractMode;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class AttractMode : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public MetadataFile? Deserialize(Models.Metadata.MetadataFile? obj)
{
if (obj == null)
return null;
var header = obj.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
var metadataFile = header != null ? ConvertHeaderFromInternalModel(header) : new MetadataFile();
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Any())
{
metadataFile.Row = machines
.Where(m => m != null)
.SelectMany(ConvertMachineFromInternalModel)
.ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Header"/> to <cref="Models.AttractMode.MetadataFile"/>
/// </summary>
private static MetadataFile ConvertHeaderFromInternalModel(Models.Metadata.Header item)
{
var metadataFile = new MetadataFile
{
Header = item.ReadStringArray(Models.Metadata.Header.HeaderKey),
};
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Machine"/> to an array of <cref="Models.AttractMode.Row"/>
/// </summary>
private static Row[] ConvertMachineFromInternalModel(Models.Metadata.Machine item)
{
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
if (roms == null || !roms.Any())
return [];
return roms
.Where(r => r != null)
.Select(rom => ConvertFromInternalModel(rom, item))
.ToArray();
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.AttractMode.Row"/>
/// </summary>
private static Row ConvertFromInternalModel(Models.Metadata.Rom item, Models.Metadata.Machine parent)
{
var row = new Row
{
Name = parent.ReadString(Models.Metadata.Machine.NameKey),
Title = item.ReadString(Models.Metadata.Rom.NameKey),
Emulator = parent.ReadString(Models.Metadata.Machine.EmulatorKey),
CloneOf = parent.ReadString(Models.Metadata.Machine.CloneOfKey),
Year = parent.ReadString(Models.Metadata.Machine.YearKey),
Manufacturer = parent.ReadString(Models.Metadata.Machine.ManufacturerKey),
Category = parent.ReadString(Models.Metadata.Machine.CategoryKey),
Players = parent.ReadString(Models.Metadata.Machine.PlayersKey),
Rotation = parent.ReadString(Models.Metadata.Machine.RotationKey),
Control = parent.ReadString(Models.Metadata.Machine.ControlKey),
Status = parent.ReadString(Models.Metadata.Machine.StatusKey),
DisplayCount = parent.ReadString(Models.Metadata.Machine.DisplayCountKey),
DisplayType = parent.ReadString(Models.Metadata.Machine.DisplayTypeKey),
AltRomname = item.ReadString(Models.Metadata.Rom.AltRomnameKey),
AltTitle = item.ReadString(Models.Metadata.Rom.AltTitleKey),
Extra = parent.ReadString(Models.Metadata.Machine.ExtraKey),
Buttons = parent.ReadString(Models.Metadata.Machine.ButtonsKey),
Favorite = parent.ReadString(Models.Metadata.Machine.FavoriteKey),
Tags = parent.ReadString(Models.Metadata.Machine.TagsKey),
PlayedCount = parent.ReadString(Models.Metadata.Machine.PlayedCountKey),
PlayedTime = parent.ReadString(Models.Metadata.Machine.PlayedTimeKey),
FileIsAvailable = item.ReadString(Models.Metadata.Rom.FileIsAvailableKey),
};
return row;
}
}
}

View File

@@ -1,93 +0,0 @@
using System.Linq;
using SabreTools.Models.AttractMode;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class AttractMode : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{
if (obj == null)
return null;
var metadataFile = new Models.Metadata.MetadataFile
{
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj),
};
if (obj?.Row != null && obj.Row.Any())
{
metadataFile[Models.Metadata.MetadataFile.MachineKey] = obj.Row
.Where(r => r != null)
.Select(ConvertMachineToInternalModel)
.Where(m => m != null)
.ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.AttractMode.MetadataFile"/> to <cref="Models.Metadata.Header"/>
/// </summary>
private static Models.Metadata.Header ConvertHeaderToInternalModel(MetadataFile item)
{
var header = new Models.Metadata.Header
{
[Models.Metadata.Header.HeaderKey] = item.Header,
};
return header;
}
/// <summary>
/// Convert from <cref="Models.AttractMode.Row"/> to <cref="Models.Metadata.Machine"/>
/// </summary>
private static Models.Metadata.Machine? ConvertMachineToInternalModel(Row? item)
{
if (item == null)
return null;
var machine = new Models.Metadata.Machine
{
[Models.Metadata.Machine.NameKey] = item.Name,
[Models.Metadata.Machine.EmulatorKey] = item.Emulator,
[Models.Metadata.Machine.CloneOfKey] = item.CloneOf,
[Models.Metadata.Machine.YearKey] = item.Year,
[Models.Metadata.Machine.ManufacturerKey] = item.Manufacturer,
[Models.Metadata.Machine.CategoryKey] = item.Category,
[Models.Metadata.Machine.PlayersKey] = item.Players,
[Models.Metadata.Machine.RotationKey] = item.Rotation,
[Models.Metadata.Machine.ControlKey] = item.Control,
[Models.Metadata.Machine.StatusKey] = item.Status,
[Models.Metadata.Machine.DisplayCountKey] = item.DisplayCount,
[Models.Metadata.Machine.DisplayTypeKey] = item.DisplayType,
[Models.Metadata.Machine.ExtraKey] = item.Extra,
[Models.Metadata.Machine.ButtonsKey] = item.Buttons,
[Models.Metadata.Machine.FavoriteKey] = item.Favorite,
[Models.Metadata.Machine.TagsKey] = item.Tags,
[Models.Metadata.Machine.PlayedCountKey] = item.PlayedCount,
[Models.Metadata.Machine.PlayedTimeKey] = item.PlayedTime,
[Models.Metadata.Machine.PlayedTimeKey] = item.PlayedTime,
[Models.Metadata.Machine.RomKey] = ConvertToInternalModel(item),
};
return machine;
}
/// <summary>
/// Convert from <cref="Models.AttractMode.Row"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
private static Models.Metadata.Rom ConvertToInternalModel(Row item)
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.NameKey] = item.Title,
[Models.Metadata.Rom.AltRomnameKey] = item.AltRomname,
[Models.Metadata.Rom.AltTitleKey] = item.AltTitle,
[Models.Metadata.Rom.FileIsAvailableKey] = item.FileIsAvailable,
};
return rom;
}
}
}

View File

@@ -1,394 +0,0 @@
using System.Linq;
using SabreTools.Models.ClrMamePro;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class ClrMamePro : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public MetadataFile? Deserialize(Models.Metadata.MetadataFile? obj) => Deserialize(obj, false);
/// <inheritdoc cref="Deserialize(Models.Metadata.MetadataFile)"/>
public MetadataFile? Deserialize(Models.Metadata.MetadataFile? obj, bool game)
{
if (obj == null)
return null;
var metadataFile = new MetadataFile();
var header = obj.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
if (header != null)
metadataFile.ClrMamePro = ConvertHeaderFromInternalModel(header);
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Any())
{
metadataFile.Game = machines
.Where(m => m != null)
.Select(machine => ConvertMachineFromInternalModel(machine, game))
.ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Header"/> to <cref="Models.ClrMamePro.ClrMamePro"/>
/// </summary>
private static Models.ClrMamePro.ClrMamePro ConvertHeaderFromInternalModel(Models.Metadata.Header item)
{
var clrMamePro = new Models.ClrMamePro.ClrMamePro
{
Name = item.ReadString(Models.Metadata.Header.NameKey),
Description = item.ReadString(Models.Metadata.Header.DescriptionKey),
RootDir = item.ReadString(Models.Metadata.Header.RootDirKey),
Category = item.ReadString(Models.Metadata.Header.CategoryKey),
Version = item.ReadString(Models.Metadata.Header.VersionKey),
Date = item.ReadString(Models.Metadata.Header.DateKey),
Author = item.ReadString(Models.Metadata.Header.AuthorKey),
Homepage = item.ReadString(Models.Metadata.Header.HomepageKey),
Url = item.ReadString(Models.Metadata.Header.UrlKey),
Comment = item.ReadString(Models.Metadata.Header.CommentKey),
Header = item.ReadString(Models.Metadata.Header.HeaderKey),
Type = item.ReadString(Models.Metadata.Header.TypeKey),
ForceMerging = item.ReadString(Models.Metadata.Header.ForceMergingKey),
ForceZipping = item.ReadString(Models.Metadata.Header.ForceZippingKey),
ForcePacking = item.ReadString(Models.Metadata.Header.ForcePackingKey),
};
return clrMamePro;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Archive"/> to <cref="Models.ClrMamePro.Machine"/>
/// </summary>
private static GameBase ConvertMachineFromInternalModel(Models.Metadata.Machine item, bool game = false)
{
GameBase gameBase = game ? new Models.ClrMamePro.Game() : new Models.ClrMamePro.Machine();
gameBase.Name = item.ReadString(Models.Metadata.Machine.NameKey);
gameBase.Description = item.ReadString(Models.Metadata.Machine.DescriptionKey);
gameBase.Year = item.ReadString(Models.Metadata.Machine.YearKey);
gameBase.Manufacturer = item.ReadString(Models.Metadata.Machine.ManufacturerKey);
gameBase.Category = item.ReadString(Models.Metadata.Machine.CategoryKey);
gameBase.CloneOf = item.ReadString(Models.Metadata.Machine.CloneOfKey);
gameBase.RomOf = item.ReadString(Models.Metadata.Machine.RomOfKey);
gameBase.SampleOf = item.ReadString(Models.Metadata.Machine.SampleOfKey);
var releases = item.Read<Models.Metadata.Release[]>(Models.Metadata.Machine.ReleaseKey);
if (releases != null && releases.Any())
{
gameBase.Release = releases
.Where(r => r != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var biosSets = item.Read<Models.Metadata.BiosSet[]>(Models.Metadata.Machine.BiosSetKey);
if (biosSets != null && biosSets.Any())
{
gameBase.BiosSet = biosSets
.Where(r => r != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
if (roms != null && roms.Any())
{
gameBase.Rom = roms
.Where(r => r != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var disks = item.Read<Models.Metadata.Disk[]>(Models.Metadata.Machine.DiskKey);
if (disks != null && disks.Any())
{
gameBase.Disk = disks
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var medias = item.Read<Models.Metadata.Media[]>(Models.Metadata.Machine.MediaKey);
if (medias != null && medias.Any())
{
gameBase.Media = medias
.Where(m => m != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var samples = item.Read<Models.Metadata.Sample[]>(Models.Metadata.Machine.SampleKey);
if (samples != null && samples.Any())
{
gameBase.Sample = samples
.Where(m => m != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var archives = item.Read<Models.Metadata.Archive[]>(Models.Metadata.Machine.ArchiveKey);
if (archives != null && archives.Any())
{
gameBase.Archive = archives
.Where(m => m != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var chips = item.Read<Models.Metadata.Chip[]>(Models.Metadata.Machine.ChipKey);
if (chips != null && chips.Any())
{
gameBase.Chip = chips
.Where(m => m != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var videos = item.Read<Models.Metadata.Video[]>(Models.Metadata.Machine.VideoKey);
if (videos != null && videos.Any())
{
gameBase.Video = videos
.Where(m => m != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var sound = item.Read<Models.Metadata.Sound>(Models.Metadata.Machine.SoundKey);
if (sound != null)
gameBase.Sound = ConvertFromInternalModel(sound);
var input = item.Read<Models.Metadata.Input>(Models.Metadata.Machine.InputKey);
if (input != null)
gameBase.Input = ConvertFromInternalModel(input);
var dipSwitches = item.Read<Models.Metadata.DipSwitch[]>(Models.Metadata.Machine.DipSwitchKey);
if (dipSwitches != null && dipSwitches.Any())
{
gameBase.DipSwitch = dipSwitches
.Where(m => m != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var driver = item.Read<Models.Metadata.Driver>(Models.Metadata.Machine.DriverKey);
if (driver != null)
gameBase.Driver = ConvertFromInternalModel(driver);
return gameBase;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Archive"/> to <cref="Models.ClrMamePro.Archive"/>
/// </summary>
private static Archive ConvertFromInternalModel(Models.Metadata.Archive item)
{
var archive = new Archive
{
Name = item.ReadString(Models.Metadata.Archive.NameKey),
};
return archive;
}
/// <summary>
/// Convert from <cref="Models.Metadata.BiosSet"/> to <cref="Models.ClrMamePro.BiosSet"/>
/// </summary>
private static BiosSet ConvertFromInternalModel(Models.Metadata.BiosSet item)
{
var biosset = new BiosSet
{
Name = item.ReadString(Models.Metadata.BiosSet.NameKey),
Description = item.ReadString(Models.Metadata.BiosSet.DescriptionKey),
Default = item.ReadString(Models.Metadata.BiosSet.DefaultKey),
};
return biosset;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Chip"/> to <cref="Models.ClrMamePro.Chip"/>
/// </summary>
private static Chip ConvertFromInternalModel(Models.Metadata.Chip item)
{
var chip = new Chip
{
Type = item.ReadString(Models.Metadata.Chip.ChipTypeKey),
Name = item.ReadString(Models.Metadata.Chip.NameKey),
Flags = item.ReadString(Models.Metadata.Chip.FlagsKey),
Clock = item.ReadString(Models.Metadata.Chip.ClockKey),
};
return chip;
}
/// <summary>
/// Convert from <cref="Models.Metadata.DipSwitch"/> to <cref="Models.ClrMamePro.DipSwitch"/>
/// </summary>
private static DipSwitch ConvertFromInternalModel(Models.Metadata.DipSwitch item)
{
var dipswitch = new DipSwitch
{
Name = item.ReadString(Models.Metadata.DipSwitch.NameKey),
Entry = item[Models.Metadata.DipSwitch.EntryKey] as string[],
Default = item.ReadString(Models.Metadata.DipSwitch.DefaultKey),
};
return dipswitch;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Disk"/> to <cref="Models.ClrMamePro.Disk"/>
/// </summary>
private static Disk ConvertFromInternalModel(Models.Metadata.Disk item)
{
var disk = new Disk
{
Name = item.ReadString(Models.Metadata.Disk.NameKey),
MD5 = item.ReadString(Models.Metadata.Disk.MD5Key),
SHA1 = item.ReadString(Models.Metadata.Disk.SHA1Key),
Merge = item.ReadString(Models.Metadata.Disk.MergeKey),
Status = item.ReadString(Models.Metadata.Disk.StatusKey),
Flags = item.ReadString(Models.Metadata.Disk.FlagsKey),
};
return disk;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Driver"/> to <cref="Models.ClrMamePro.Driver"/>
/// </summary>
private static Driver ConvertFromInternalModel(Models.Metadata.Driver item)
{
var driver = new Driver
{
Status = item.ReadString(Models.Metadata.Driver.StatusKey),
Color = item.ReadString(Models.Metadata.Driver.ColorKey),
Sound = item.ReadString(Models.Metadata.Driver.SoundKey),
PaletteSize = item.ReadString(Models.Metadata.Driver.PaletteSizeKey),
Blit = item.ReadString(Models.Metadata.Driver.BlitKey),
};
return driver;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Input"/> to <cref="Models.ClrMamePro.Input"/>
/// </summary>
private static Input ConvertFromInternalModel(Models.Metadata.Input item)
{
var input = new Input
{
Players = item.ReadString(Models.Metadata.Input.PlayersKey),
Control = item.ReadString(Models.Metadata.Input.ControlKey),
Buttons = item.ReadString(Models.Metadata.Input.ButtonsKey),
Coins = item.ReadString(Models.Metadata.Input.CoinsKey),
Tilt = item.ReadString(Models.Metadata.Input.TiltKey),
Service = item.ReadString(Models.Metadata.Input.ServiceKey),
};
return input;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Media"/> to <cref="Models.ClrMamePro.Media"/>
/// </summary>
private static Media ConvertFromInternalModel(Models.Metadata.Media item)
{
var media = new Media
{
Name = item.ReadString(Models.Metadata.Media.NameKey),
MD5 = item.ReadString(Models.Metadata.Media.MD5Key),
SHA1 = item.ReadString(Models.Metadata.Media.SHA1Key),
SHA256 = item.ReadString(Models.Metadata.Media.SHA256Key),
SpamSum = item.ReadString(Models.Metadata.Media.SpamSumKey),
};
return media;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Release"/> to <cref="Models.ClrMamePro.Release"/>
/// </summary>
private static Release ConvertFromInternalModel(Models.Metadata.Release item)
{
var release = new Release
{
Name = item.ReadString(Models.Metadata.Release.NameKey),
Region = item.ReadString(Models.Metadata.Release.RegionKey),
Language = item.ReadString(Models.Metadata.Release.LanguageKey),
Date = item.ReadString(Models.Metadata.Release.DateKey),
Default = item.ReadString(Models.Metadata.Release.DefaultKey),
};
return release;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.ClrMamePro.Rom"/>
/// </summary>
private static Rom ConvertFromInternalModel(Models.Metadata.Rom item)
{
var rom = new Rom
{
Name = item.ReadString(Models.Metadata.Rom.NameKey),
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
CRC = item.ReadString(Models.Metadata.Rom.CRCKey),
MD5 = item.ReadString(Models.Metadata.Rom.MD5Key),
SHA1 = item.ReadString(Models.Metadata.Rom.SHA1Key),
SHA256 = item.ReadString(Models.Metadata.Rom.SHA256Key),
SHA384 = item.ReadString(Models.Metadata.Rom.SHA384Key),
SHA512 = item.ReadString(Models.Metadata.Rom.SHA512Key),
SpamSum = item.ReadString(Models.Metadata.Rom.SpamSumKey),
xxHash364 = item.ReadString(Models.Metadata.Rom.xxHash364Key),
xxHash3128 = item.ReadString(Models.Metadata.Rom.xxHash3128Key),
Merge = item.ReadString(Models.Metadata.Rom.MergeKey),
Status = item.ReadString(Models.Metadata.Rom.StatusKey),
Region = item.ReadString(Models.Metadata.Rom.RegionKey),
Flags = item.ReadString(Models.Metadata.Rom.FlagsKey),
Offs = item.ReadString(Models.Metadata.Rom.OffsetKey),
Serial = item.ReadString(Models.Metadata.Rom.SerialKey),
Header = item.ReadString(Models.Metadata.Rom.HeaderKey),
Date = item.ReadString(Models.Metadata.Rom.DateKey),
Inverted = item.ReadString(Models.Metadata.Rom.InvertedKey),
MIA = item.ReadString(Models.Metadata.Rom.MIAKey),
};
return rom;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Sample"/> to <cref="Models.ClrMamePro.Sample"/>
/// </summary>
private static Sample ConvertFromInternalModel(Models.Metadata.Sample item)
{
var sample = new Sample
{
Name = item.ReadString(Models.Metadata.Sample.NameKey),
};
return sample;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Sound"/> to <cref="Models.ClrMamePro.Sound"/>
/// </summary>
private static Sound ConvertFromInternalModel(Models.Metadata.Sound item)
{
var sound = new Sound
{
Channels = item.ReadString(Models.Metadata.Sound.ChannelsKey),
};
return sound;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Video"/> to <cref="Models.ClrMamePro.Video"/>
/// </summary>
private static Video ConvertFromInternalModel(Models.Metadata.Video item)
{
var video = new Video
{
Screen = item.ReadString(Models.Metadata.Video.ScreenKey),
Orientation = item.ReadString(Models.Metadata.Video.OrientationKey),
X = item.ReadString(Models.Metadata.Video.WidthKey),
Y = item.ReadString(Models.Metadata.Video.HeightKey),
AspectX = item.ReadString(Models.Metadata.Video.AspectXKey),
AspectY = item.ReadString(Models.Metadata.Video.AspectYKey),
Freq = item.ReadString(Models.Metadata.Video.RefreshKey),
};
return video;
}
}
}

View File

@@ -1,381 +0,0 @@
using System.Linq;
using SabreTools.Models.ClrMamePro;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class ClrMamePro : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{
if (obj == null)
return null;
var metadataFile = new Models.Metadata.MetadataFile();
if (obj?.ClrMamePro != null)
metadataFile[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj.ClrMamePro);
if (obj?.Game != null && obj.Game.Any())
{
metadataFile[Models.Metadata.MetadataFile.MachineKey] = obj.Game
.Where(g => g != null)
.Select(ConvertMachineToInternalModel)
.Where(m => m != null)
.ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.ClrMamePro.ClrMamePro"/> to <cref="Models.Metadata.Header"/>
/// </summary>
private static Models.Metadata.Header ConvertHeaderToInternalModel(Models.ClrMamePro.ClrMamePro item)
{
var header = new Models.Metadata.Header
{
[Models.Metadata.Header.NameKey] = item.Name,
[Models.Metadata.Header.DescriptionKey] = item.Description,
[Models.Metadata.Header.RootDirKey] = item.RootDir,
[Models.Metadata.Header.CategoryKey] = item.Category,
[Models.Metadata.Header.VersionKey] = item.Version,
[Models.Metadata.Header.DateKey] = item.Date,
[Models.Metadata.Header.AuthorKey] = item.Author,
[Models.Metadata.Header.HomepageKey] = item.Homepage,
[Models.Metadata.Header.UrlKey] = item.Url,
[Models.Metadata.Header.CommentKey] = item.Comment,
[Models.Metadata.Header.HeaderKey] = item.Header,
[Models.Metadata.Header.TypeKey] = item.Type,
[Models.Metadata.Header.ForceMergingKey] = item.ForceMerging,
[Models.Metadata.Header.ForceZippingKey] = item.ForceZipping,
[Models.Metadata.Header.ForcePackingKey] = item.ForcePacking,
};
return header;
}
/// <summary>
/// Convert from <cref="Models.ClrMamePro.GameBase"/> to <cref="Models.Metadata.Machine"/>
/// </summary>
private static Models.Metadata.Machine? ConvertMachineToInternalModel(GameBase? item)
{
if (item == null)
return null;
var machine = new Models.Metadata.Machine
{
[Models.Metadata.Machine.NameKey] = item.Name,
[Models.Metadata.Machine.DescriptionKey] = item.Description,
[Models.Metadata.Machine.YearKey] = item.Year,
[Models.Metadata.Machine.ManufacturerKey] = item.Manufacturer,
[Models.Metadata.Machine.CategoryKey] = item.Category,
[Models.Metadata.Machine.CloneOfKey] = item.CloneOf,
[Models.Metadata.Machine.RomOfKey] = item.RomOf,
[Models.Metadata.Machine.SampleOfKey] = item.SampleOf,
};
if (item.Release != null && item.Release.Any())
{
machine[Models.Metadata.Machine.ReleaseKey] = item.Release
.Where(r => r != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.BiosSet != null && item.BiosSet.Any())
{
machine[Models.Metadata.Machine.BiosSetKey] = item.BiosSet
.Where(b => b != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Rom != null && item.Rom.Any())
{
machine[Models.Metadata.Machine.RomKey] = item.Rom
.Where(r => r != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Disk != null && item.Disk.Any())
{
machine[Models.Metadata.Machine.DiskKey] = item.Disk
.Where(d => d != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Media != null && item.Media.Any())
{
machine[Models.Metadata.Machine.MediaKey] = item.Media
.Where(m => m != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Sample != null && item.Sample.Any())
{
machine[Models.Metadata.Machine.SampleKey] = item.Sample
.Where(s => s != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Archive != null && item.Archive.Any())
{
machine[Models.Metadata.Machine.ArchiveKey] = item.Archive
.Where(a => a != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Chip != null && item.Chip.Any())
{
machine[Models.Metadata.Machine.ChipKey] = item.Chip
.Where(c => c != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Video != null)
{
machine[Models.Metadata.Machine.VideoKey] = item.Video
.Where(v => v != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Sound != null)
machine[Models.Metadata.Machine.SoundKey] = ConvertToInternalModel(item.Sound);
if (item.Input != null)
machine[Models.Metadata.Machine.InputKey] = ConvertToInternalModel(item.Input);
if (item.DipSwitch != null && item.DipSwitch.Any())
{
machine[Models.Metadata.Machine.DipSwitchKey] = item.DipSwitch
.Where(d => d != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Driver != null)
machine[Models.Metadata.Machine.DriverKey] = ConvertToInternalModel(item.Driver);
return machine;
}
/// <summary>
/// Convert from <cref="Models.ClrMamePro.Archive"/> to <cref="Models.Metadata.Archive"/>
/// </summary>
private static Models.Metadata.Archive ConvertToInternalModel(Archive item)
{
var archive = new Models.Metadata.Archive
{
[Models.Metadata.Archive.NameKey] = item.Name,
};
return archive;
}
/// <summary>
/// Convert from <cref="Models.ClrMamePro.BiosSet"/> to <cref="Models.Metadata.BiosSet"/>
/// </summary>
private static Models.Metadata.BiosSet ConvertToInternalModel(BiosSet item)
{
var biosset = new Models.Metadata.BiosSet
{
[Models.Metadata.BiosSet.NameKey] = item.Name,
[Models.Metadata.BiosSet.DescriptionKey] = item.Description,
[Models.Metadata.BiosSet.DefaultKey] = item.Default,
};
return biosset;
}
/// <summary>
/// Convert from <cref="Models.ClrMamePro.Chip"/> to <cref="Models.Metadata.Chip"/>
/// </summary>
private static Models.Metadata.Chip ConvertToInternalModel(Chip item)
{
var chip = new Models.Metadata.Chip
{
[Models.Metadata.Chip.ChipTypeKey] = item.Type,
[Models.Metadata.Chip.NameKey] = item.Name,
[Models.Metadata.Chip.FlagsKey] = item.Flags,
[Models.Metadata.Chip.ClockKey] = item.Clock,
};
return chip;
}
/// <summary>
/// Convert from <cref="Models.ClrMamePro.DipSwitch"/> to <cref="Models.Metadata.DipSwitch"/>
/// </summary>
private static Models.Metadata.DipSwitch ConvertToInternalModel(DipSwitch item)
{
var dipswitch = new Models.Metadata.DipSwitch
{
[Models.Metadata.DipSwitch.NameKey] = item.Name,
[Models.Metadata.DipSwitch.EntryKey] = item.Entry,
[Models.Metadata.DipSwitch.DefaultKey] = item.Default,
};
return dipswitch;
}
/// <summary>
/// Convert from <cref="Models.ClrMamePro.Disk"/> to <cref="Models.Metadata.Disk"/>
/// </summary>
private static Models.Metadata.Disk ConvertToInternalModel(Disk item)
{
var disk = new Models.Metadata.Disk
{
[Models.Metadata.Disk.NameKey] = item.Name,
[Models.Metadata.Disk.MD5Key] = item.MD5,
[Models.Metadata.Disk.SHA1Key] = item.SHA1,
[Models.Metadata.Disk.MergeKey] = item.Merge,
[Models.Metadata.Disk.StatusKey] = item.Status,
[Models.Metadata.Disk.FlagsKey] = item.Flags,
};
return disk;
}
/// <summary>
/// Convert from <cref="Models.ClrMamePro.Driver"/> to <cref="Models.Metadata.Driver"/>
/// </summary>
private static Models.Metadata.Driver ConvertToInternalModel(Driver item)
{
var driver = new Models.Metadata.Driver
{
[Models.Metadata.Driver.StatusKey] = item.Status,
[Models.Metadata.Driver.ColorKey] = item.Color,
[Models.Metadata.Driver.SoundKey] = item.Sound,
[Models.Metadata.Driver.PaletteSizeKey] = item.PaletteSize,
[Models.Metadata.Driver.BlitKey] = item.Blit,
};
return driver;
}
/// <summary>
/// Convert from <cref="Models.ClrMamePro.Input"/> to <cref="Models.Metadata.Input"/>
/// </summary>
private static Models.Metadata.Input ConvertToInternalModel(Input item)
{
var input = new Models.Metadata.Input
{
[Models.Metadata.Input.PlayersKey] = item.Players,
[Models.Metadata.Input.ControlKey] = item.Control,
[Models.Metadata.Input.ButtonsKey] = item.Buttons,
[Models.Metadata.Input.CoinsKey] = item.Coins,
[Models.Metadata.Input.TiltKey] = item.Tilt,
[Models.Metadata.Input.ServiceKey] = item.Service,
};
return input;
}
/// <summary>
/// Convert from <cref="Models.ClrMamePro.Media"/> to <cref="Models.Metadata.Media"/>
/// </summary>
private static Models.Metadata.Media ConvertToInternalModel(Media item)
{
var media = new Models.Metadata.Media
{
[Models.Metadata.Media.NameKey] = item.Name,
[Models.Metadata.Media.MD5Key] = item.MD5,
[Models.Metadata.Media.SHA1Key] = item.SHA1,
[Models.Metadata.Media.SHA256Key] = item.SHA256,
[Models.Metadata.Media.SpamSumKey] = item.SpamSum,
};
return media;
}
/// <summary>
/// Convert from <cref="Models.ClrMamePro.Release"/> to <cref="Models.Metadata.Release"/>
/// </summary>
private static Models.Metadata.Release ConvertToInternalModel(Release item)
{
var release = new Models.Metadata.Release
{
[Models.Metadata.Release.NameKey] = item.Name,
[Models.Metadata.Release.RegionKey] = item.Region,
[Models.Metadata.Release.LanguageKey] = item.Language,
[Models.Metadata.Release.DateKey] = item.Date,
[Models.Metadata.Release.DefaultKey] = item.Default,
};
return release;
}
/// <summary>
/// Convert from <cref="Models.ClrMamePro.Rom"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
private static Models.Metadata.Rom ConvertToInternalModel(Rom item)
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.NameKey] = item.Name,
[Models.Metadata.Rom.SizeKey] = item.Size,
[Models.Metadata.Rom.CRCKey] = item.CRC,
[Models.Metadata.Rom.MD5Key] = item.MD5,
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
[Models.Metadata.Rom.SHA256Key] = item.SHA256,
[Models.Metadata.Rom.SHA384Key] = item.SHA384,
[Models.Metadata.Rom.SHA512Key] = item.SHA512,
[Models.Metadata.Rom.SpamSumKey] = item.SpamSum,
[Models.Metadata.Rom.xxHash364Key] = item.xxHash364,
[Models.Metadata.Rom.xxHash3128Key] = item.xxHash3128,
[Models.Metadata.Rom.MergeKey] = item.Merge,
[Models.Metadata.Rom.StatusKey] = item.Status,
[Models.Metadata.Rom.RegionKey] = item.Region,
[Models.Metadata.Rom.FlagsKey] = item.Flags,
[Models.Metadata.Rom.OffsetKey] = item.Offs,
[Models.Metadata.Rom.SerialKey] = item.Serial,
[Models.Metadata.Rom.HeaderKey] = item.Header,
[Models.Metadata.Rom.DateKey] = item.Date,
[Models.Metadata.Rom.InvertedKey] = item.Inverted,
[Models.Metadata.Rom.MIAKey] = item.MIA,
};
return rom;
}
/// <summary>
/// Convert from <cref="Models.ClrMamePro.Sample"/> to <cref="Models.Metadata.Sample"/>
/// </summary>
private static Models.Metadata.Sample ConvertToInternalModel(Sample item)
{
var sample = new Models.Metadata.Sample
{
[Models.Metadata.Sample.NameKey] = item.Name,
};
return sample;
}
/// <summary>
/// Convert from <cref="Models.ClrMamePro.Sound"/> to <cref="Models.Metadata.Sound"/>
/// </summary>
private static Models.Metadata.Sound ConvertToInternalModel(Sound item)
{
var sound = new Models.Metadata.Sound
{
[Models.Metadata.Sound.ChannelsKey] = item.Channels,
};
return sound;
}
/// <summary>
/// Convert from <cref="Models.ClrMamePro.Video"/> to <cref="Models.Metadata.Video"/>
/// </summary>
private static Models.Metadata.Video ConvertToInternalModel(Video item)
{
var video = new Models.Metadata.Video
{
[Models.Metadata.Video.ScreenKey] = item.Screen,
[Models.Metadata.Video.OrientationKey] = item.Orientation,
[Models.Metadata.Video.WidthKey] = item.X,
[Models.Metadata.Video.HeightKey] = item.Y,
[Models.Metadata.Video.AspectXKey] = item.AspectX,
[Models.Metadata.Video.AspectYKey] = item.AspectY,
[Models.Metadata.Video.RefreshKey] = item.Freq,
};
return video;
}
}
}

View File

@@ -1,88 +0,0 @@
using System.Linq;
using SabreTools.Models.DosCenter;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class DosCenter : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public MetadataFile? Deserialize(Models.Metadata.MetadataFile? obj)
{
if (obj == null)
return null;
var metadataFile = new MetadataFile();
var header = obj.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
if (header != null)
metadataFile.DosCenter = ConvertHeaderFromInternalModel(header);
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Any())
{
metadataFile.Game = machines
.Where(m => m != null)
.Select(ConvertMachineFromInternalModel)
.ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Header"/> to <cref="Models.DosCenter.DosCenter"/>
/// </summary>
private static Models.DosCenter.DosCenter ConvertHeaderFromInternalModel(Models.Metadata.Header item)
{
var dosCenter = new Models.DosCenter.DosCenter
{
Name = item.ReadString(Models.Metadata.Header.NameKey),
Description = item.ReadString(Models.Metadata.Header.DescriptionKey),
Version = item.ReadString(Models.Metadata.Header.VersionKey),
Date = item.ReadString(Models.Metadata.Header.DateKey),
Author = item.ReadString(Models.Metadata.Header.AuthorKey),
Homepage = item.ReadString(Models.Metadata.Header.HomepageKey),
Comment = item.ReadString(Models.Metadata.Header.CommentKey),
};
return dosCenter;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Machine"/> to <cref="Models.DosCenter.Game"/>
/// </summary>
private static Game ConvertMachineFromInternalModel(Models.Metadata.Machine item)
{
var game = new Game
{
Name = item.ReadString(Models.Metadata.Machine.NameKey),
};
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
if (roms != null && roms.Any())
{
game.File = roms
.Where(r => r != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
return game;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.DosCenter.File"/>
/// </summary>
private static Models.DosCenter.File ConvertFromInternalModel(Models.Metadata.Rom item)
{
var file = new Models.DosCenter.File
{
Name = item.ReadString(Models.Metadata.Rom.NameKey),
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
CRC = item.ReadString(Models.Metadata.Rom.CRCKey),
Date = item.ReadString(Models.Metadata.Rom.DateKey),
};
return file;
}
}
}

View File

@@ -1,85 +0,0 @@
using System.Linq;
using SabreTools.Models.DosCenter;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class DosCenter : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{
if (obj == null)
return null;
var metadataFile = new Models.Metadata.MetadataFile();
if (obj?.DosCenter != null)
metadataFile[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj.DosCenter);
if (obj?.Game != null && obj.Game.Any())
{
metadataFile[Models.Metadata.MetadataFile.MachineKey] = obj.Game
.Where(g => g != null)
.Select(ConvertMachineToInternalModel)
.ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.DosCenter.DosCenter"/> to <cref="Models.Metadata.Header"/>
/// </summary>
private static Models.Metadata.Header ConvertHeaderToInternalModel(Models.DosCenter.DosCenter item)
{
var header = new Models.Metadata.Header
{
[Models.Metadata.Header.NameKey] = item.Name,
[Models.Metadata.Header.DescriptionKey] = item.Description,
[Models.Metadata.Header.VersionKey] = item.Version,
[Models.Metadata.Header.DateKey] = item.Date,
[Models.Metadata.Header.AuthorKey] = item.Author,
[Models.Metadata.Header.HomepageKey] = item.Homepage,
[Models.Metadata.Header.CommentKey] = item.Comment,
};
return header;
}
/// <summary>
/// Convert from <cref="Models.DosCenter.Game"/> to <cref="Models.Metadata.Machine"/>
/// </summary>
private static Models.Metadata.Machine ConvertMachineToInternalModel(Game item)
{
var machine = new Models.Metadata.Machine
{
[Models.Metadata.Machine.NameKey] = item.Name,
};
if (item.File != null && item.File.Any())
{
machine[Models.Metadata.Machine.RomKey] = item.File
.Where(f => f != null)
.Select(ConvertToInternalModel)
.ToArray();
}
return machine;
}
/// <summary>
/// Convert from <cref="Models.DosCenter.File"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
private static Models.Metadata.Rom ConvertToInternalModel(Models.DosCenter.File item)
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.NameKey] = item.Name,
[Models.Metadata.Rom.SizeKey] = item.Size,
[Models.Metadata.Rom.CRCKey] = item.CRC,
[Models.Metadata.Rom.DateKey] = item.Date,
};
return rom;
}
}
}

View File

@@ -1,62 +0,0 @@
using System;
using System.Linq;
using SabreTools.Models.EverdriveSMDB;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class EverdriveSMDB : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public MetadataFile? Deserialize(Models.Metadata.MetadataFile? obj)
{
if (obj == null)
return null;
var metadataFile = new MetadataFile();
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Any())
{
metadataFile.Row = machines
.Where(m => m != null)
.SelectMany(ConvertMachineFromInternalModel)
.ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Machine"/> to an array of <cref="Models.EverdriveSMDB.Row"/>
/// </summary>
private static Row[] ConvertMachineFromInternalModel(Models.Metadata.Machine item)
{
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
if (roms == null || !roms.Any())
return [];
return roms
.Where(r => r != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.EverdriveSMDB.Row"/>
/// </summary>
private static Row ConvertFromInternalModel(Models.Metadata.Rom item)
{
var row = new Row
{
SHA256 = item.ReadString(Models.Metadata.Rom.SHA256Key),
Name = item.ReadString(Models.Metadata.Rom.NameKey),
SHA1 = item.ReadString(Models.Metadata.Rom.SHA1Key),
MD5 = item.ReadString(Models.Metadata.Rom.MD5Key),
CRC32 = item.ReadString(Models.Metadata.Rom.CRCKey),
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
};
return row;
}
}
}

View File

@@ -1,72 +0,0 @@
using System.Linq;
using SabreTools.Models.EverdriveSMDB;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class EverdriveSMDB : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{
if (obj == null)
return null;
var metadataFile = new Models.Metadata.MetadataFile
{
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(),
};
if (obj?.Row != null && obj.Row.Any())
{
metadataFile[Models.Metadata.MetadataFile.MachineKey] = obj.Row
.Where(r => r != null)
.Select(ConvertMachineToInternalModel)
.ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.EverdriveSMDB.MetadataFile"/> to <cref=Models.Metadata."Header"/>
/// </summary>
private static Models.Metadata.Header ConvertHeaderToInternalModel()
{
var header = new Models.Metadata.Header
{
[Models.Metadata.Header.NameKey] = "Everdrive SMDB",
};
return header;
}
/// <summary>
/// Convert from <cref="Models.EverdriveSMDB.Row"/> to <cref="Models.Metadata.Machine"/>
/// </summary>
private static Models.Metadata.Machine ConvertMachineToInternalModel(Row item)
{
var machine = new Models.Metadata.Machine
{
[Models.Metadata.Machine.RomKey] = ConvertToInternalModel(item),
};
return machine;
}
/// <summary>
/// Convert from <cref="Models.EverdriveSMDB.Row"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
private static Models.Metadata.Rom ConvertToInternalModel(Row item)
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.SHA256Key] = item.SHA256,
[Models.Metadata.Rom.NameKey] = item.Name,
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
[Models.Metadata.Rom.MD5Key] = item.MD5,
[Models.Metadata.Rom.CRCKey] = item.CRC32,
[Models.Metadata.Rom.SizeKey] = item.Size,
};
return rom;
}
}
}

View File

@@ -1,240 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using SabreTools.Models.Hashfile;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class Hashfile : IModelSerializer<Models.Hashfile.Hashfile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.Hashfile.Hashfile? Deserialize(Models.Metadata.MetadataFile? obj) => Deserialize(obj, Hash.CRC);
/// <inheritdoc/>
public Models.Hashfile.Hashfile? Deserialize(Models.Metadata.MetadataFile? obj, Hash hash)
{
if (obj == null)
return null;
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
if (machines == null || !machines.Any())
return null;
var hashfiles = machines
.Where(m => m != null)
.Select(machine => ConvertMachineFromInternalModel(machine, hash));
var sfvs = new List<SFV>();
var md5s = new List<MD5>();
var sha1s = new List<SHA1>();
var sha256s = new List<SHA256>();
var sha384s = new List<SHA384>();
var sha512s = new List<SHA512>();
var spamsums = new List<SpamSum>();
foreach (var hashfile in hashfiles)
{
if (hashfile.SFV != null && hashfile.SFV.Any())
sfvs.AddRange(hashfile.SFV);
if (hashfile.MD5 != null && hashfile.MD5.Any())
md5s.AddRange(hashfile.MD5);
if (hashfile.SHA1 != null && hashfile.SHA1.Any())
sha1s.AddRange(hashfile.SHA1);
if (hashfile.SHA256 != null && hashfile.SHA256.Any())
sha256s.AddRange(hashfile.SHA256);
if (hashfile.SHA384 != null && hashfile.SHA384.Any())
sha384s.AddRange(hashfile.SHA384);
if (hashfile.SHA512 != null && hashfile.SHA512.Any())
sha512s.AddRange(hashfile.SHA512);
if (hashfile.SpamSum != null && hashfile.SpamSum.Any())
spamsums.AddRange(hashfile.SpamSum);
}
var hashfileItem = new Models.Hashfile.Hashfile();
if (sfvs.Any())
hashfileItem.SFV = sfvs.ToArray();
if (md5s.Any())
hashfileItem.MD5 = md5s.ToArray();
if (sha1s.Any())
hashfileItem.SHA1 = sha1s.ToArray();
if (sha256s.Any())
hashfileItem.SHA256 = sha256s.ToArray();
if (sha384s.Any())
hashfileItem.SHA384 = sha384s.ToArray();
if (sha512s.Any())
hashfileItem.SHA512 = sha512s.ToArray();
if (spamsums.Any())
hashfileItem.SpamSum = spamsums.ToArray();
return hashfileItem;
}
/// <summary>
/// Convert from <cref="Models.Metadata.MetadataFile"/> to an array of <cref="Models.Hashfile.Hashfile"/>
/// </summary>
public static Models.Hashfile.Hashfile[]? ConvertArrayFromInternalModel(Models.Metadata.MetadataFile? item, Hash hash)
{
if (item == null)
return null;
var machines = item.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Any())
{
return machines
.Where(m => m != null)
.Select(machine => ConvertMachineFromInternalModel(machine, hash))
.ToArray();
}
return null;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Machine"/> to <cref="Models.Hashfile.Hashfile"/>
/// </summary>
private static Models.Hashfile.Hashfile ConvertMachineFromInternalModel(Models.Metadata.Machine item, Hash hash)
{
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
if (roms == null)
return new Models.Hashfile.Hashfile();
return new Models.Hashfile.Hashfile
{
SFV = hash == Hash.CRC
? roms
.Where(r => r != null)
.Select(ConvertToSFV)
.ToArray()
: null,
MD5 = hash == Hash.MD5
? roms
.Where(r => r != null)
.Select(ConvertToMD5)
.ToArray()
: null,
SHA1 = hash == Hash.SHA1
? roms
.Where(r => r != null)
.Select(ConvertToSHA1)
.ToArray()
: null,
SHA256 = hash == Hash.SHA256
? roms
.Where(r => r != null)
.Select(ConvertToSHA256)
.ToArray()
: null,
SHA384 = hash == Hash.SHA384
? roms
.Where(r => r != null)
.Select(ConvertToSHA384)
.ToArray()
: null,
SHA512 = hash == Hash.SHA512
? roms
.Where(r => r != null)
.Select(ConvertToSHA512)
.ToArray()
: null,
SpamSum = hash == Hash.SpamSum
? roms
.Where(r => r != null)
.Select(ConvertToSpamSum)
.ToArray()
: null,
};
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Hashfile.MD5"/>
/// </summary>
private static MD5 ConvertToMD5(Models.Metadata.Rom item)
{
var md5 = new MD5
{
Hash = item.ReadString(Models.Metadata.Rom.MD5Key),
File = item.ReadString(Models.Metadata.Rom.NameKey),
};
return md5;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Hashfile.SFV"/>
/// </summary>
private static SFV ConvertToSFV(Models.Metadata.Rom item)
{
var sfv = new SFV
{
File = item.ReadString(Models.Metadata.Rom.NameKey),
Hash = item.ReadString(Models.Metadata.Rom.CRCKey),
};
return sfv;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Hashfile.SHA1"/>
/// </summary>
private static SHA1 ConvertToSHA1(Models.Metadata.Rom item)
{
var sha1 = new SHA1
{
Hash = item.ReadString(Models.Metadata.Rom.SHA1Key),
File = item.ReadString(Models.Metadata.Rom.NameKey),
};
return sha1;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Hashfile.SHA256"/>
/// </summary>
private static SHA256 ConvertToSHA256(Models.Metadata.Rom item)
{
var sha256 = new SHA256
{
Hash = item.ReadString(Models.Metadata.Rom.SHA256Key),
File = item.ReadString(Models.Metadata.Rom.NameKey),
};
return sha256;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Hashfile.SHA384"/>
/// </summary>
private static SHA384 ConvertToSHA384(Models.Metadata.Rom item)
{
var sha384 = new SHA384
{
Hash = item.ReadString(Models.Metadata.Rom.SHA384Key),
File = item.ReadString(Models.Metadata.Rom.NameKey),
};
return sha384;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Hashfile.SHA512"/>
/// </summary>
private static SHA512 ConvertToSHA512(Models.Metadata.Rom item)
{
var sha512 = new SHA512
{
Hash = item.ReadString(Models.Metadata.Rom.SHA512Key),
File = item.ReadString(Models.Metadata.Rom.NameKey),
};
return sha512;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Hashfile.SpamSum"/>
/// </summary>
private static SpamSum ConvertToSpamSum(Models.Metadata.Rom item)
{
var spamsum = new SpamSum
{
Hash = item.ReadString(Models.Metadata.Rom.SpamSumKey),
File = item.ReadString(Models.Metadata.Rom.NameKey),
};
return spamsum;
}
}
}

View File

@@ -1,154 +0,0 @@
using System.Linq;
using SabreTools.Models.Hashfile;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class Hashfile : IModelSerializer<Models.Hashfile.Hashfile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.Metadata.MetadataFile? Serialize(Models.Hashfile.Hashfile? obj)
{
if (obj == null)
return null;
var metadataFile = new Models.Metadata.MetadataFile
{
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(),
};
var machine = ConvertMachineToInternalModel(obj);
metadataFile[Models.Metadata.MetadataFile.MachineKey] = new Models.Metadata.Machine[] { machine };
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.Hashfile.Hashfile"/> to <cref="Models.Metadata.Header"/>
/// </summary>
private static Models.Metadata.Header ConvertHeaderToInternalModel()
{
var header = new Models.Metadata.Header
{
[Models.Metadata.Header.NameKey] = "Hashfile",
};
return header;
}
/// <summary>
/// Convert from <cref="Models.Hashfile.Hashfile"/> to <cref="Models.Metadata.Machine"/>
/// </summary>
private static Models.Metadata.Machine ConvertMachineToInternalModel(Models.Hashfile.Hashfile item)
{
var machine = new Models.Metadata.Machine();
if (item.SFV != null && item.SFV.Any())
machine[Models.Metadata.Machine.RomKey] = item.SFV.Select(ConvertToInternalModel).ToArray();
else if (item.MD5 != null && item.MD5.Any())
machine[Models.Metadata.Machine.RomKey] = item.MD5.Select(ConvertToInternalModel).ToArray();
else if (item.SHA1 != null && item.SHA1.Any())
machine[Models.Metadata.Machine.RomKey] = item.SHA1.Select(ConvertToInternalModel).ToArray();
else if (item.SHA256 != null && item.SHA256.Any())
machine[Models.Metadata.Machine.RomKey] = item.SHA256.Select(ConvertToInternalModel).ToArray();
else if (item.SHA384 != null && item.SHA384.Any())
machine[Models.Metadata.Machine.RomKey] = item.SHA384.Select(ConvertToInternalModel).ToArray();
else if (item.SHA512 != null && item.SHA512.Any())
machine[Models.Metadata.Machine.RomKey] = item.SHA512.Select(ConvertToInternalModel).ToArray();
else if (item.SpamSum != null && item.SpamSum.Any())
machine[Models.Metadata.Machine.RomKey] = item.SpamSum.Select(ConvertToInternalModel).ToArray();
return machine;
}
/// <summary>
/// Convert from <cref="Models.Hashfile.MD5"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
private static Models.Metadata.Rom ConvertToInternalModel(MD5 item)
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.MD5Key] = item.Hash,
[Models.Metadata.Rom.NameKey] = item.File,
};
return rom;
}
/// <summary>
/// Convert from <cref="Models.Hashfile.SFV"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
private static Models.Metadata.Rom ConvertToInternalModel(SFV item)
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.NameKey] = item.File,
[Models.Metadata.Rom.CRCKey] = item.Hash,
};
return rom;
}
/// <summary>
/// Convert from <cref="Models.Hashfile.SHA1"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
private static Models.Metadata.Rom ConvertToInternalModel(SHA1 item)
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.SHA1Key] = item.Hash,
[Models.Metadata.Rom.NameKey] = item.File,
};
return rom;
}
/// <summary>
/// Convert from <cref="Models.Hashfile.SHA256"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
private static Models.Metadata.Rom ConvertToInternalModel(SHA256 item)
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.SHA256Key] = item.Hash,
[Models.Metadata.Rom.NameKey] = item.File,
};
return rom;
}
/// <summary>
/// Convert from <cref="Models.Hashfile.SHA384"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
private static Models.Metadata.Rom ConvertToInternalModel(SHA384 item)
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.SHA384Key] = item.Hash,
[Models.Metadata.Rom.NameKey] = item.File,
};
return rom;
}
/// <summary>
/// Convert from <cref="Models.Hashfile.SHA512"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
private static Models.Metadata.Rom ConvertToInternalModel(SHA512 item)
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.SHA512Key] = item.Hash,
[Models.Metadata.Rom.NameKey] = item.File,
};
return rom;
}
/// <summary>
/// Convert from <cref="Models.Hashfile.SpamSum"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
private static Models.Metadata.Rom ConvertToInternalModel(SpamSum item)
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.SpamSumKey] = item.Hash,
[Models.Metadata.Rom.NameKey] = item.File,
};
return rom;
}
}
}

View File

@@ -1,98 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using SabreTools.Models.Listrom;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class Listrom : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public MetadataFile? Deserialize(Models.Metadata.MetadataFile? obj)
{
if (obj == null)
return null;
var metadataFile = new MetadataFile();
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Any())
{
metadataFile.Set = machines
.Where(m => m != null)
.Select(ConvertMachineFromInternalModel)
.ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Machine"/> to <cref="Models.Listrom.Set"/>
/// </summary>
private static Set ConvertMachineFromInternalModel(Models.Metadata.Machine item)
{
var set = new Set();
if (item.ReadString(Models.Metadata.Machine.IsDeviceKey) == "yes")
set.Device = item.ReadString(Models.Metadata.Machine.NameKey);
else
set.Driver = item.ReadString(Models.Metadata.Machine.NameKey);
var rowItems = new List<Row>();
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
if (roms != null)
{
rowItems.AddRange(roms.Where(r => r != null).Select(ConvertFromInternalModel));
}
var disks = item.Read<Models.Metadata.Disk[]>(Models.Metadata.Machine.DiskKey);
if (disks != null)
rowItems.AddRange(disks.Where(d => d != null).Select(ConvertFromInternalModel));
set.Row = rowItems.ToArray();
return set;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Disk"/> to <cref="Models.Listrom.Row"/>
/// </summary>
private static Row ConvertFromInternalModel(Models.Metadata.Disk item)
{
var row = new Row
{
Name = item.ReadString(Models.Metadata.Disk.NameKey),
MD5 = item.ReadString(Models.Metadata.Disk.MD5Key),
SHA1 = item.ReadString(Models.Metadata.Disk.SHA1Key),
};
if (item[Models.Metadata.Disk.StatusKey] as string == "nodump")
row.NoGoodDumpKnown = true;
else if (item[Models.Metadata.Disk.StatusKey] as string == "baddump")
row.Bad = true;
return row;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Listrom.Row"/>
/// </summary>
private static Row ConvertFromInternalModel(Models.Metadata.Rom item)
{
var row = new Row
{
Name = item.ReadString(Models.Metadata.Rom.NameKey),
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
CRC = item.ReadString(Models.Metadata.Rom.CRCKey),
SHA1 = item.ReadString(Models.Metadata.Rom.SHA1Key),
};
if (item[Models.Metadata.Rom.StatusKey] as string == "nodump")
row.NoGoodDumpKnown = true;
else if (item[Models.Metadata.Rom.StatusKey] as string == "baddump")
row.Bad = true;
return row;
}
}
}

View File

@@ -1,115 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using SabreTools.Models.Listrom;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class Listrom : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{
if (obj == null)
return null;
var metadataFile = new Models.Metadata.MetadataFile
{
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(),
};
if (obj?.Set != null && obj.Set.Any())
{
metadataFile[Models.Metadata.MetadataFile.MachineKey] = obj.Set
.Where(s => s != null)
.Select(ConvertMachineToInternalModel)
.ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.Listrom.MetadataFile"/> to <cref="Header"/>
/// </summary>
private static Models.Metadata.Header ConvertHeaderToInternalModel()
{
var header = new Models.Metadata.Header
{
[Models.Metadata.Header.NameKey] = "MAME Listrom",
};
return header;
}
/// <summary>
/// Convert from <cref="Models.Listrom.Set"/> to <cref="Models.Metadata.Machine"/>
/// </summary>
private static Models.Metadata.Machine ConvertMachineToInternalModel(Set item)
{
var machine = new Models.Metadata.Machine();
if (!string.IsNullOrEmpty(item.Device))
{
machine[Models.Metadata.Machine.NameKey] = item.Device;
machine[Models.Metadata.Machine.IsDeviceKey] = "yes";
}
else
{
machine[Models.Metadata.Machine.NameKey] = item.Driver;
}
if (item.Row != null && item.Row.Any())
{
var datItems = new List<Models.Metadata.DatItem>();
foreach (var file in item.Row)
{
datItems.Add(ConvertToInternalModel(file));
}
machine[Models.Metadata.Machine.DiskKey] = datItems.Where(i => i.ReadString(Models.Metadata.DatItem.TypeKey) == "disk")?.ToArray();
machine[Models.Metadata.Machine.RomKey] = datItems.Where(i => i.ReadString(Models.Metadata.DatItem.TypeKey) == "rom")?.ToArray();
}
return machine;
}
/// <summary>
/// Convert from <cref="Models.Listrom.Row"/> to <cref="Models.Metadata.DatItem"/>
/// </summary>
private static Models.Metadata.DatItem ConvertToInternalModel(Row item)
{
if (item.Size == null)
{
var disk = new Models.Metadata.Disk
{
[Models.Metadata.Disk.NameKey] = item.Name,
[Models.Metadata.Disk.MD5Key] = item.MD5,
[Models.Metadata.Disk.SHA1Key] = item.SHA1,
};
if (item.NoGoodDumpKnown)
disk[Models.Metadata.Disk.StatusKey] = "nodump";
else if (item.Bad)
disk[Models.Metadata.Disk.StatusKey] = "baddump";
return disk;
}
else
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.NameKey] = item.Name,
[Models.Metadata.Rom.SizeKey] = item.Size,
[Models.Metadata.Rom.CRCKey] = item.CRC,
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
};
if (item.NoGoodDumpKnown)
rom[Models.Metadata.Rom.StatusKey] = "nodump";
else if (item.Bad)
rom[Models.Metadata.Rom.StatusKey] = "baddump";
return rom;
}
}
}
}

View File

@@ -1,823 +0,0 @@
using System.Linq;
using SabreTools.Models.Listxml;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class Listxml : IModelSerializer<Mame, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Mame? Deserialize(Models.Metadata.MetadataFile? obj)
{
if (obj == null)
return null;
var header = obj.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
var mame = header != null ? ConvertMameFromInternalModel(header) : new Mame();
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Any())
{
mame.Game = machines
.Where(m => m != null)
.Select(ConvertMachineFromInternalModel)
.ToArray();
}
return mame;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Models.Metadata.MetadataFile"/> to <cref="Models.Listxml.Mame"/>
/// </summary>
public static Mame? ConvertMameFromInternalModel(Models.Metadata.MetadataFile? item)
{
if (item == null)
return null;
var header = item.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
var mame = header != null ? ConvertMameFromInternalModel(header) : new Mame();
var machines = item.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Any())
{
mame.Game = machines
.Where(m => m != null)
.Select(ConvertMachineFromInternalModel)
.ToArray();
}
return mame;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Models.Metadata.Header"/> to <cref="Models.Listxml.Mame"/>
/// </summary>
private static Mame ConvertMameFromInternalModel(Models.Metadata.Header item)
{
var mame = new Mame
{
Build = item.ReadString(Models.Metadata.Header.BuildKey),
Debug = item.ReadString(Models.Metadata.Header.DebugKey),
MameConfig = item.ReadString(Models.Metadata.Header.MameConfigKey),
};
return mame;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Models.Metadata.Machine"/> to <cref="Models.Listxml.GameBase"/>
/// </summary>
internal static GameBase ConvertMachineFromInternalModel(Models.Metadata.Machine item)
{
var machine = new Machine
{
Name = item.ReadString(Models.Metadata.Machine.NameKey),
SourceFile = item.ReadString(Models.Metadata.Machine.SourceFileKey),
IsBios = item.ReadString(Models.Metadata.Machine.IsBiosKey),
IsDevice = item.ReadString(Models.Metadata.Machine.IsDeviceKey),
IsMechanical = item.ReadString(Models.Metadata.Machine.IsMechanicalKey),
Runnable = item.ReadString(Models.Metadata.Machine.RunnableKey),
CloneOf = item.ReadString(Models.Metadata.Machine.CloneOfKey),
RomOf = item.ReadString(Models.Metadata.Machine.RomOfKey),
SampleOf = item.ReadString(Models.Metadata.Machine.SampleOfKey),
Description = item.ReadString(Models.Metadata.Machine.DescriptionKey),
Year = item.ReadString(Models.Metadata.Machine.YearKey),
Manufacturer = item.ReadString(Models.Metadata.Machine.ManufacturerKey),
History = item.ReadString(Models.Metadata.Machine.HistoryKey),
};
var biosSets = item.Read<Models.Metadata.BiosSet[]>(Models.Metadata.Machine.BiosSetKey);
if (biosSets != null && biosSets.Any())
{
machine.BiosSet = biosSets
.Where(b => b != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
if (roms != null && roms.Any())
{
machine.Rom = roms
.Where(r => r != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var disks = item.Read<Models.Metadata.Disk[]>(Models.Metadata.Machine.DiskKey);
if (disks != null && disks.Any())
{
machine.Disk = disks
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var deviceRefs = item.Read<Models.Metadata.DeviceRef[]>(Models.Metadata.Machine.DeviceRefKey);
if (deviceRefs != null && deviceRefs.Any())
{
machine.DeviceRef = deviceRefs
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var samples = item.Read<Models.Metadata.Sample[]>(Models.Metadata.Machine.SampleKey);
if (samples != null && samples.Any())
{
machine.Sample = samples
.Where(s => s != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var chips = item.Read<Models.Metadata.Chip[]>(Models.Metadata.Machine.ChipKey);
if (chips != null && chips.Any())
{
machine.Chip = chips
.Where(c => c != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var displays = item.Read<Models.Metadata.Display[]>(Models.Metadata.Machine.DisplayKey);
if (displays != null && displays.Any())
{
machine.Display = displays
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var videos = item.Read<Models.Metadata.Video[]>(Models.Metadata.Machine.VideoKey);
if (videos != null && videos.Any())
{
machine.Video = videos
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var sound = item.Read<Models.Metadata.Sound>(Models.Metadata.Machine.SoundKey);
if (sound != null)
machine.Sound = ConvertFromInternalModel(sound);
var input = item.Read<Models.Metadata.Input>(Models.Metadata.Machine.InputKey);
if (input != null)
machine.Input = ConvertFromInternalModel(input);
var dipSwitches = item.Read<Models.Metadata.DipSwitch[]>(Models.Metadata.Machine.DipSwitchKey);
if (dipSwitches != null && dipSwitches.Any())
{
machine.DipSwitch = dipSwitches
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var configurations = item.Read<Models.Metadata.Configuration[]>(Models.Metadata.Machine.ConfigurationKey);
if (configurations != null && configurations.Any())
{
machine.Configuration = configurations
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var ports = item.Read<Models.Metadata.Port[]>(Models.Metadata.Machine.PortKey);
if (ports != null && ports.Any())
{
machine.Port = ports
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var adjusters = item.Read<Models.Metadata.Adjuster[]>(Models.Metadata.Machine.AdjusterKey);
if (adjusters != null && adjusters.Any())
{
machine.Adjuster = adjusters
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var driver = item.Read<Models.Metadata.Driver>(Models.Metadata.Machine.DriverKey);
if (driver != null)
machine.Driver = ConvertFromInternalModel(driver);
var features = item.Read<Models.Metadata.Feature[]>(Models.Metadata.Machine.FeatureKey);
if (features != null && features.Any())
{
machine.Feature = features
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var devices = item.Read<Models.Metadata.Device[]>(Models.Metadata.Machine.DeviceKey);
if (devices != null && devices.Any())
{
machine.Device = devices
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var slots = item.Read<Models.Metadata.Slot[]>(Models.Metadata.Machine.SlotKey);
if (slots != null && slots.Any())
{
machine.Slot = slots
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var softwareLists = item.Read<Models.Metadata.SoftwareList[]>(Models.Metadata.Machine.SoftwareListKey);
if (softwareLists != null && softwareLists.Any())
{
machine.SoftwareList = softwareLists
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var ramOptions = item.Read<Models.Metadata.RamOption[]>(Models.Metadata.Machine.RamOptionKey);
if (ramOptions != null && ramOptions.Any())
{
machine.RamOption = ramOptions
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
return machine;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Models.Metadata.Adjuster"/> to <cref="Models.Listxml.Adjuster"/>
/// </summary>
private static Adjuster ConvertFromInternalModel(Models.Metadata.Adjuster item)
{
var adjuster = new Adjuster
{
Name = item.ReadString(Models.Metadata.Adjuster.NameKey),
Default = item.ReadString(Models.Metadata.Adjuster.DefaultKey),
};
var condition = item.Read<Models.Metadata.Condition>(Models.Metadata.Adjuster.ConditionKey);
if (condition != null)
adjuster.Condition = ConvertFromInternalModel(condition);
return adjuster;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Models.Metadata.Analog"/> to <cref="Models.Listxml.Analog"/>
/// </summary>
private static Analog ConvertFromInternalModel(Models.Metadata.Analog item)
{
var analog = new Analog
{
Mask = item.ReadString(Models.Metadata.Analog.MaskKey),
};
return analog;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Models.Metadata.BiosSet"/> to <cref="Models.Listxml.BiosSet"/>
/// </summary>
private static BiosSet ConvertFromInternalModel(Models.Metadata.BiosSet item)
{
var biosset = new BiosSet
{
Name = item.ReadString(Models.Metadata.BiosSet.NameKey),
Description = item.ReadString(Models.Metadata.BiosSet.DescriptionKey),
Default = item.ReadString(Models.Metadata.BiosSet.DefaultKey),
};
return biosset;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Models.Metadata.Chip"/> to <cref="Models.Listxml.Chip"/>
/// </summary>
private static Chip ConvertFromInternalModel(Models.Metadata.Chip item)
{
var chip = new Chip
{
Name = item.ReadString(Models.Metadata.Chip.NameKey),
Tag = item.ReadString(Models.Metadata.Chip.TagKey),
Type = item.ReadString(Models.Metadata.Chip.TypeKey),
SoundOnly = item.ReadString(Models.Metadata.Chip.SoundOnlyKey),
Clock = item.ReadString(Models.Metadata.Chip.ClockKey),
};
return chip;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Models.Metadata.Condition"/> to <cref="Models.Listxml.Condition"/>
/// </summary>
private static Condition ConvertFromInternalModel(Models.Metadata.Condition item)
{
var condition = new Condition
{
Tag = item.ReadString(Models.Metadata.Condition.TagKey),
Mask = item.ReadString(Models.Metadata.Condition.MaskKey),
Relation = item.ReadString(Models.Metadata.Condition.RelationKey),
Value = item.ReadString(Models.Metadata.Condition.ValueKey),
};
return condition;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Models.Metadata.Configuration"/> to <cref="Models.Listxml.Configuration"/>
/// </summary>
private static Configuration ConvertFromInternalModel(Models.Metadata.Configuration item)
{
var configuration = new Configuration
{
Name = item.ReadString(Models.Metadata.Configuration.NameKey),
Tag = item.ReadString(Models.Metadata.Configuration.TagKey),
Mask = item.ReadString(Models.Metadata.Configuration.MaskKey),
};
var condition = item.Read<Models.Metadata.Condition>(Models.Metadata.Configuration.ConditionKey);
if (condition != null)
configuration.Condition = ConvertFromInternalModel(condition);
var confLocations = item.Read<Models.Metadata.ConfLocation[]>(Models.Metadata.Configuration.ConfLocationKey);
if (confLocations != null && confLocations.Any())
{
configuration.ConfLocation = confLocations
.Where(c => c != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var confSettings = item.Read<Models.Metadata.ConfSetting[]>(Models.Metadata.Configuration.ConfSettingKey);
if (confSettings != null && confSettings.Any())
{
configuration.ConfSetting = confSettings
.Where(c => c != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
return configuration;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Models.Metadata.ConfLocation"/> to <cref="Models.Listxml.ConfLocation"/>
/// </summary>
private static ConfLocation ConvertFromInternalModel(Models.Metadata.ConfLocation item)
{
var confLocation = new ConfLocation
{
Name = item.ReadString(Models.Metadata.ConfLocation.NameKey),
Number = item.ReadString(Models.Metadata.ConfLocation.NumberKey),
Inverted = item.ReadString(Models.Metadata.ConfLocation.InvertedKey),
};
return confLocation;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Models.Metadata.ConfSetting"/> to <cref="Models.Listxml.ConfSetting"/>
/// </summary>
private static ConfSetting ConvertFromInternalModel(Models.Metadata.ConfSetting item)
{
var confSetting = new ConfSetting
{
Name = item.ReadString(Models.Metadata.ConfSetting.NameKey),
Value = item.ReadString(Models.Metadata.ConfSetting.ValueKey),
Default = item.ReadString(Models.Metadata.ConfSetting.DefaultKey),
};
var condition = item.Read<Models.Metadata.Condition>(Models.Metadata.ConfSetting.ConditionKey);
if (condition != null)
confSetting.Condition = ConvertFromInternalModel(condition);
return confSetting;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Models.Metadata.Control"/> to <cref="Models.Listxml.Control"/>
/// </summary>
private static Control ConvertFromInternalModel(Models.Metadata.Control item)
{
var control = new Control
{
Type = item.ReadString(Models.Metadata.Control.TypeKey),
Player = item.ReadString(Models.Metadata.Control.PlayerKey),
Buttons = item.ReadString(Models.Metadata.Control.ButtonsKey),
ReqButtons = item.ReadString(Models.Metadata.Control.ReqButtonsKey),
Minimum = item.ReadString(Models.Metadata.Control.MinimumKey),
Maximum = item.ReadString(Models.Metadata.Control.MaximumKey),
Sensitivity = item.ReadString(Models.Metadata.Control.SensitivityKey),
KeyDelta = item.ReadString(Models.Metadata.Control.KeyDeltaKey),
Reverse = item.ReadString(Models.Metadata.Control.ReverseKey),
Ways = item.ReadString(Models.Metadata.Control.WaysKey),
Ways2 = item.ReadString(Models.Metadata.Control.Ways2Key),
Ways3 = item.ReadString(Models.Metadata.Control.Ways3Key),
};
return control;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Models.Metadata.Device"/> to <cref="Models.Listxml.Device"/>
/// </summary>
private static Device ConvertFromInternalModel(Models.Metadata.Device item)
{
var device = new Device
{
Type = item.ReadString(Models.Metadata.Device.TypeKey),
Tag = item.ReadString(Models.Metadata.Device.TagKey),
FixedImage = item.ReadString(Models.Metadata.Device.FixedImageKey),
Mandatory = item.ReadString(Models.Metadata.Device.MandatoryKey),
Interface = item.ReadString(Models.Metadata.Device.InterfaceKey),
};
var instance = item.Read<Models.Metadata.Instance>(Models.Metadata.Device.InstanceKey);
if (instance != null)
device.Instance = ConvertFromInternalModel(instance);
var extensions = item.Read<Models.Metadata.Extension[]>(Models.Metadata.Device.ExtensionKey);
if (extensions != null && extensions.Any())
{
device.Extension = extensions
.Where(e => e != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
return device;
}
/// <summary>
/// Convert from <cref="Models.Metadata.DeviceRef"/> to <cref="Models.Listxml.DeviceRef"/>
/// </summary>
private static DeviceRef ConvertFromInternalModel(Models.Metadata.DeviceRef item)
{
var deviceRef = new DeviceRef
{
Name = item.ReadString(Models.Metadata.DeviceRef.NameKey),
};
return deviceRef;
}
/// <summary>
/// Convert from <cref="Models.Metadata.DipLocation"/> to <cref="Models.Listxml.DipLocation"/>
/// </summary>
private static DipLocation ConvertFromInternalModel(Models.Metadata.DipLocation item)
{
var dipLocation = new DipLocation
{
Name = item.ReadString(Models.Metadata.DipLocation.NameKey),
Number = item.ReadString(Models.Metadata.DipLocation.NumberKey),
Inverted = item.ReadString(Models.Metadata.DipLocation.InvertedKey),
};
return dipLocation;
}
/// <summary>
/// Convert from <cref="Models.Metadata.DipSwitch"/> to <cref="Models.Listxml.DipSwitch"/>
/// </summary>
private static DipSwitch ConvertFromInternalModel(Models.Metadata.DipSwitch item)
{
var dipSwitch = new DipSwitch
{
Name = item.ReadString(Models.Metadata.DipSwitch.NameKey),
Tag = item.ReadString(Models.Metadata.DipSwitch.TagKey),
Mask = item.ReadString(Models.Metadata.DipSwitch.MaskKey),
};
var condition = item.Read<Models.Metadata.Condition>(Models.Metadata.DipSwitch.ConditionKey);
if (condition != null)
dipSwitch.Condition = ConvertFromInternalModel(condition);
var dipLocations = item.Read<Models.Metadata.DipLocation[]>(Models.Metadata.DipSwitch.DipLocationKey);
if (dipLocations != null && dipLocations.Any())
{
dipSwitch.DipLocation = dipLocations
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var dipValues = item.Read<Models.Metadata.DipValue[]>(Models.Metadata.DipSwitch.DipValueKey);
if (dipValues != null && dipValues.Any())
{
dipSwitch.DipValue = dipValues
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
return dipSwitch;
}
/// <summary>
/// Convert from <cref="Models.Metadata.DipValue"/> to <cref="Models.Listxml.DipValue"/>
/// </summary>
private static DipValue ConvertFromInternalModel(Models.Metadata.DipValue item)
{
var dipValue = new DipValue
{
Name = item.ReadString(Models.Metadata.DipValue.NameKey),
Value = item.ReadString(Models.Metadata.DipValue.ValueKey),
Default = item.ReadString(Models.Metadata.DipValue.DefaultKey),
};
var condition = item.Read<Models.Metadata.Condition>(Models.Metadata.DipValue.ConditionKey);
if (condition != null)
dipValue.Condition = ConvertFromInternalModel(condition);
return dipValue;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Disk"/> to <cref="Models.Listxml.Disk"/>
/// </summary>
private static Disk ConvertFromInternalModel(Models.Metadata.Disk item)
{
var disk = new Disk
{
Name = item.ReadString(Models.Metadata.Disk.NameKey),
MD5 = item.ReadString(Models.Metadata.Disk.MD5Key),
SHA1 = item.ReadString(Models.Metadata.Disk.SHA1Key),
Merge = item.ReadString(Models.Metadata.Disk.MergeKey),
Region = item.ReadString(Models.Metadata.Disk.RegionKey),
Index = item.ReadString(Models.Metadata.Disk.IndexKey),
Writable = item.ReadString(Models.Metadata.Disk.WritableKey),
Status = item.ReadString(Models.Metadata.Disk.StatusKey),
Optional = item.ReadString(Models.Metadata.Disk.OptionalKey),
};
return disk;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Display"/> to <cref="Models.Listxml.Display"/>
/// </summary>
private static Display ConvertFromInternalModel(Models.Metadata.Display item)
{
var display = new Display
{
Tag = item.ReadString(Models.Metadata.Display.TagKey),
Type = item.ReadString(Models.Metadata.Display.TypeKey),
Rotate = item.ReadString(Models.Metadata.Display.RotateKey),
FlipX = item.ReadString(Models.Metadata.Display.FlipXKey),
Width = item.ReadString(Models.Metadata.Display.WidthKey),
Height = item.ReadString(Models.Metadata.Display.HeightKey),
Refresh = item.ReadString(Models.Metadata.Display.RefreshKey),
PixClock = item.ReadString(Models.Metadata.Display.PixClockKey),
HTotal = item.ReadString(Models.Metadata.Display.HTotalKey),
HBEnd = item.ReadString(Models.Metadata.Display.HBEndKey),
HBStart = item.ReadString(Models.Metadata.Display.HBStartKey),
VTotal = item.ReadString(Models.Metadata.Display.VTotalKey),
VBEnd = item.ReadString(Models.Metadata.Display.VBEndKey),
VBStart = item.ReadString(Models.Metadata.Display.VBStartKey),
};
return display;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Driver"/> to <cref="Models.Listxml.Driver"/>
/// </summary>
private static Driver ConvertFromInternalModel(Models.Metadata.Driver item)
{
var driver = new Driver
{
Status = item.ReadString(Models.Metadata.Driver.StatusKey),
Color = item.ReadString(Models.Metadata.Driver.ColorKey),
Sound = item.ReadString(Models.Metadata.Driver.SoundKey),
PaletteSize = item.ReadString(Models.Metadata.Driver.PaletteSizeKey),
Emulation = item.ReadString(Models.Metadata.Driver.EmulationKey),
Cocktail = item.ReadString(Models.Metadata.Driver.CocktailKey),
SaveState = item.ReadString(Models.Metadata.Driver.SaveStateKey),
RequiresArtwork = item.ReadString(Models.Metadata.Driver.RequiresArtworkKey),
Unofficial = item.ReadString(Models.Metadata.Driver.UnofficialKey),
NoSoundHardware = item.ReadString(Models.Metadata.Driver.NoSoundHardwareKey),
Incomplete = item.ReadString(Models.Metadata.Driver.IncompleteKey),
};
return driver;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Extension"/> to <cref="Models.Listxml.Extension"/>
/// </summary>
private static Extension ConvertFromInternalModel(Models.Metadata.Extension item)
{
var extension = new Extension
{
Name = item.ReadString(Models.Metadata.Extension.NameKey),
};
return extension;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Feature"/> to <cref="Models.Listxml.Feature"/>
/// </summary>
private static Feature ConvertFromInternalModel(Models.Metadata.Feature item)
{
var feature = new Feature
{
Type = item.ReadString(Models.Metadata.Feature.TypeKey),
Status = item.ReadString(Models.Metadata.Feature.StatusKey),
Overall = item.ReadString(Models.Metadata.Feature.OverallKey),
};
return feature;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Input"/> to <cref="Models.Listxml.Input"/>
/// </summary>
private static Input ConvertFromInternalModel(Models.Metadata.Input item)
{
var input = new Input
{
Service = item.ReadString(Models.Metadata.Input.ServiceKey),
Tilt = item.ReadString(Models.Metadata.Input.TiltKey),
Players = item.ReadString(Models.Metadata.Input.PlayersKey),
ControlAttr = item.ReadString(Models.Metadata.Input.ControlKey),
Buttons = item.ReadString(Models.Metadata.Input.ButtonsKey),
Coins = item.ReadString(Models.Metadata.Input.CoinsKey),
};
var controls = item.Read<Models.Metadata.Control[]>(Models.Metadata.Input.ControlKey);
if (controls != null && controls.Any())
{
input.Control = controls
.Where(c => c != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
return input;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Instance"/> to <cref="Models.Listxml.Instance"/>
/// </summary>
private static Instance ConvertFromInternalModel(Models.Metadata.Instance item)
{
var instance = new Instance
{
Name = item.ReadString(Models.Metadata.Instance.NameKey),
BriefName = item.ReadString(Models.Metadata.Instance.BriefNameKey),
};
return instance;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Port"/> to <cref="Models.Listxml.Port"/>
/// </summary>
private static Port ConvertFromInternalModel(Models.Metadata.Port item)
{
var port = new Port
{
Tag = item.ReadString(Models.Metadata.Port.TagKey),
};
var analogs = item.Read<Models.Metadata.Analog[]>(Models.Metadata.Port.AnalogKey);
if (analogs != null && analogs.Any())
{
port.Analog = analogs
.Where(a => a != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
return port;
}
/// <summary>
/// Convert from <cref="Models.Metadata.RamOption"/> to <cref="Models.Listxml.RamOption"/>
/// </summary>
private static RamOption ConvertFromInternalModel(Models.Metadata.RamOption item)
{
var ramOption = new RamOption
{
Name = item.ReadString(Models.Metadata.RamOption.NameKey),
Default = item.ReadString(Models.Metadata.RamOption.DefaultKey),
Content = item.ReadString(Models.Metadata.RamOption.ContentKey),
};
return ramOption;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Listxml.Rom"/>
/// </summary>
private static Rom ConvertFromInternalModel(Models.Metadata.Rom item)
{
var rom = new Rom
{
Name = item.ReadString(Models.Metadata.Rom.NameKey),
Bios = item.ReadString(Models.Metadata.Rom.BiosKey),
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
CRC = item.ReadString(Models.Metadata.Rom.CRCKey),
SHA1 = item.ReadString(Models.Metadata.Rom.SHA1Key),
Merge = item.ReadString(Models.Metadata.Rom.MergeKey),
Region = item.ReadString(Models.Metadata.Rom.RegionKey),
Offset = item.ReadString(Models.Metadata.Rom.OffsetKey),
Status = item.ReadString(Models.Metadata.Rom.StatusKey),
Optional = item.ReadString(Models.Metadata.Rom.OptionalKey),
Dispose = item.ReadString(Models.Metadata.Rom.DisposeKey),
SoundOnly = item.ReadString(Models.Metadata.Rom.SoundOnlyKey),
};
return rom;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Sample"/> to <cref="Models.Listxml.Sample"/>
/// </summary>
private static Sample ConvertFromInternalModel(Models.Metadata.Sample item)
{
var sample = new Sample
{
Name = item.ReadString(Models.Metadata.Sample.NameKey),
};
return sample;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Slot"/> to <cref="Models.Listxml.Slot"/>
/// </summary>
private static Slot ConvertFromInternalModel(Models.Metadata.Slot item)
{
var slot = new Slot
{
Name = item.ReadString(Models.Metadata.Slot.NameKey),
};
var slotOptions = item.Read<Models.Metadata.SlotOption[]>(Models.Metadata.Slot.SlotOptionKey);
if (slotOptions != null && slotOptions.Any())
{
slot.SlotOption = slotOptions
.Where(s => s != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
return slot;
}
/// <summary>
/// Convert from <cref="Models.Metadata.SlotOption"/> to <cref="Models.Listxml.SlotOption"/>
/// </summary>
private static SlotOption ConvertFromInternalModel(Models.Metadata.SlotOption item)
{
var slotOption = new SlotOption
{
Name = item.ReadString(Models.Metadata.SlotOption.NameKey),
DevName = item.ReadString(Models.Metadata.SlotOption.DevNameKey),
Default = item.ReadString(Models.Metadata.SlotOption.DefaultKey),
};
return slotOption;
}
/// <summary>
/// Convert from <cref="Models.Metadata.SoftwareList"/> to <cref="Models.Listxml.SoftwareList"/>
/// </summary>
private static Models.Listxml.SoftwareList ConvertFromInternalModel(Models.Metadata.SoftwareList item)
{
var softwareList = new Models.Listxml.SoftwareList
{
Tag = item.ReadString(Models.Metadata.SoftwareList.TagKey),
Name = item.ReadString(Models.Metadata.SoftwareList.NameKey),
Status = item.ReadString(Models.Metadata.SoftwareList.StatusKey),
Filter = item.ReadString(Models.Metadata.SoftwareList.FilterKey),
};
return softwareList;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Sound"/> to <cref="Models.Listxml.Sound"/>
/// </summary>
private static Sound ConvertFromInternalModel(Models.Metadata.Sound item)
{
var sound = new Sound
{
Channels = item.ReadString(Models.Metadata.Sound.ChannelsKey),
};
return sound;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Video"/> to <cref="Models.Listxml.Video"/>
/// </summary>
private static Video ConvertFromInternalModel(Models.Metadata.Video item)
{
var video = new Video
{
Screen = item.ReadString(Models.Metadata.Video.ScreenKey),
Orientation = item.ReadString(Models.Metadata.Video.OrientationKey),
Width = item.ReadString(Models.Metadata.Video.WidthKey),
Height = item.ReadString(Models.Metadata.Video.HeightKey),
AspectX = item.ReadString(Models.Metadata.Video.AspectXKey),
AspectY = item.ReadString(Models.Metadata.Video.AspectYKey),
Refresh = item.ReadString(Models.Metadata.Video.RefreshKey),
};
return video;
}
}
}

View File

@@ -1,766 +0,0 @@
using System.Linq;
using SabreTools.Models.Listxml;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class Listxml : IModelSerializer<Mame, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.Metadata.MetadataFile? Serialize(Mame? item)
{
if (item == null)
return null;
var metadataFile = new Models.Metadata.MetadataFile
{
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
};
if (item?.Game != null && item.Game.Any())
{
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.Game
.Where(g => g != null)
.Select(ConvertMachineToInternalModel)
.ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Mame"/> to <cref="Models.Metadata.Header"/>
/// </summary>
private static Models.Metadata.Header ConvertHeaderToInternalModel(Mame item)
{
var header = new Models.Metadata.Header
{
[Models.Metadata.Header.BuildKey] = item.Build,
[Models.Metadata.Header.DebugKey] = item.Debug,
[Models.Metadata.Header.MameConfigKey] = item.MameConfig,
};
return header;
}
/// <summary>
/// Convert from <cref="Models.Listxml.GameBase"/> to <cref="Models.Metadata.Machine"/>
/// </summary>
internal static Models.Metadata.Machine ConvertMachineToInternalModel(GameBase item)
{
var machine = new Models.Metadata.Machine
{
[Models.Metadata.Machine.NameKey] = item.Name,
[Models.Metadata.Machine.SourceFileKey] = item.SourceFile,
[Models.Metadata.Machine.IsBiosKey] = item.IsBios,
[Models.Metadata.Machine.IsDeviceKey] = item.IsDevice,
[Models.Metadata.Machine.IsMechanicalKey] = item.IsMechanical,
[Models.Metadata.Machine.RunnableKey] = item.Runnable,
[Models.Metadata.Machine.CloneOfKey] = item.CloneOf,
[Models.Metadata.Machine.RomOfKey] = item.RomOf,
[Models.Metadata.Machine.SampleOfKey] = item.SampleOf,
[Models.Metadata.Machine.DescriptionKey] = item.Description,
[Models.Metadata.Machine.YearKey] = item.Year,
[Models.Metadata.Machine.ManufacturerKey] = item.Manufacturer,
[Models.Metadata.Machine.HistoryKey] = item.History,
};
if (item.BiosSet != null && item.BiosSet.Any())
{
machine[Models.Metadata.Machine.BiosSetKey] = item.BiosSet
.Where(b => b != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Rom != null && item.Rom.Any())
{
machine[Models.Metadata.Machine.RomKey] = item.Rom
.Where(r => r != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Disk != null && item.Disk.Any())
{
machine[Models.Metadata.Machine.DiskKey] = item.Disk
.Where(d => d != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.DeviceRef != null && item.DeviceRef.Any())
{
machine[Models.Metadata.Machine.DeviceRefKey] = item.DeviceRef
.Where(d => d != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Sample != null && item.Sample.Any())
{
machine[Models.Metadata.Machine.SampleKey] = item.Sample
.Where(s => s != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Chip != null && item.Chip.Any())
{
machine[Models.Metadata.Machine.ChipKey] = item.Chip
.Where(c => c != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Display != null && item.Display.Any())
{
machine[Models.Metadata.Machine.DisplayKey] = item.Display
.Where(d => d != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Video != null && item.Video.Any())
{
machine[Models.Metadata.Machine.VideoKey] = item.Video
.Where(v => v != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Sound != null)
machine[Models.Metadata.Machine.SoundKey] = ConvertToInternalModel(item.Sound);
if (item.Input != null)
machine[Models.Metadata.Machine.InputKey] = ConvertToInternalModel(item.Input);
if (item.DipSwitch != null && item.DipSwitch.Any())
{
machine[Models.Metadata.Machine.DipSwitchKey] = item.DipSwitch
.Where(d => d != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Configuration != null && item.Configuration.Any())
{
machine[Models.Metadata.Machine.ConfigurationKey] = item.Configuration
.Where(c => c != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Port != null && item.Port.Any())
{
machine[Models.Metadata.Machine.PortKey] = item.Port
.Where(p => p != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Adjuster != null && item.Adjuster.Any())
{
machine[Models.Metadata.Machine.AdjusterKey] = item.Adjuster
.Where(a => a != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Driver != null)
machine[Models.Metadata.Machine.DriverKey] = ConvertToInternalModel(item.Driver);
if (item.Feature != null && item.Feature.Any())
{
machine[Models.Metadata.Machine.FeatureKey] = item.Feature
.Where(f => f != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Device != null && item.Device.Any())
{
machine[Models.Metadata.Machine.DeviceKey] = item.Device
.Where(d => d != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.Slot != null && item.Slot.Any())
{
machine[Models.Metadata.Machine.SlotKey] = item.Slot
.Where(s => s != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.SoftwareList != null && item.SoftwareList.Any())
{
machine[Models.Metadata.Machine.SoftwareListKey] = item.SoftwareList
.Where(s => s != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.RamOption != null && item.RamOption.Any())
{
machine[Models.Metadata.Machine.RamOptionKey] = item.RamOption
.Where(r => r != null)
.Select(ConvertToInternalModel)
.ToArray();
}
return machine;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Adjuster"/> to <cref="Models.Metadata.Adjuster"/>
/// </summary>
private static Models.Metadata.Adjuster ConvertToInternalModel(Adjuster item)
{
var adjuster = new Models.Metadata.Adjuster
{
[Models.Metadata.Adjuster.NameKey] = item.Name,
[Models.Metadata.Adjuster.DefaultKey] = item.Default,
};
if (item.Condition != null)
adjuster[Models.Metadata.Adjuster.ConditionKey] = ConvertToInternalModel(item.Condition);
return adjuster;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Analog"/> to <cref="Models.Metadata.Analog"/>
/// </summary>
private static Models.Metadata.Analog ConvertToInternalModel(Analog item)
{
var analog = new Models.Metadata.Analog
{
[Models.Metadata.Analog.MaskKey] = item.Mask,
};
return analog;
}
/// <summary>
/// Convert from <cref="Models.Listxml.BiosSet"/> to <cref="Models.Metadata.BiosSet"/>
/// </summary>
private static Models.Metadata.BiosSet ConvertToInternalModel(BiosSet item)
{
var biosset = new Models.Metadata.BiosSet
{
[Models.Metadata.BiosSet.NameKey] = item.Name,
[Models.Metadata.BiosSet.DescriptionKey] = item.Description,
[Models.Metadata.BiosSet.DefaultKey] = item.Default,
};
return biosset;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Chip"/> to <cref="Models.Metadata.Chip"/>
/// </summary>
private static Models.Metadata.Chip ConvertToInternalModel(Chip item)
{
var chip = new Models.Metadata.Chip
{
[Models.Metadata.Chip.NameKey] = item.Name,
[Models.Metadata.Chip.TagKey] = item.Tag,
[Models.Metadata.Chip.TypeKey] = item.Type,
[Models.Metadata.Chip.SoundOnlyKey] = item.SoundOnly,
[Models.Metadata.Chip.ClockKey] = item.Clock,
};
return chip;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Condition"/> to <cref="Models.Metadata.Condition"/>
/// </summary>
private static Models.Metadata.Condition ConvertToInternalModel(Condition item)
{
var condition = new Models.Metadata.Condition
{
[Models.Metadata.Condition.TagKey] = item.Tag,
[Models.Metadata.Condition.MaskKey] = item.Mask,
[Models.Metadata.Condition.RelationKey] = item.Relation,
[Models.Metadata.Condition.ValueKey] = item.Value,
};
return condition;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Configuration"/> to <cref="Models.Metadata.Configuration"/>
/// </summary>
private static Models.Metadata.Configuration ConvertToInternalModel(Configuration item)
{
var configuration = new Models.Metadata.Configuration
{
[Models.Metadata.Configuration.NameKey] = item.Name,
[Models.Metadata.Configuration.TagKey] = item.Tag,
[Models.Metadata.Configuration.MaskKey] = item.Mask,
};
if (item.Condition != null)
configuration[Models.Metadata.Configuration.ConditionKey] = ConvertToInternalModel(item.Condition);
if (item.ConfLocation != null && item.ConfLocation.Any())
{
configuration[Models.Metadata.Configuration.ConfLocationKey] = item.ConfLocation
.Where(c => c != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.ConfSetting != null && item.ConfSetting.Any())
{
configuration[Models.Metadata.Configuration.ConfSettingKey] = item.ConfSetting
.Where(c => c != null)
.Select(ConvertToInternalModel)
.ToArray();
}
return configuration;
}
/// <summary>
/// Convert from <cref="Models.Listxml.ConfLocation"/> to <cref="Models.Metadata.ConfLocation"/>
/// </summary>
private static Models.Metadata.ConfLocation ConvertToInternalModel(ConfLocation item)
{
var confLocation = new Models.Metadata.ConfLocation
{
[Models.Metadata.ConfLocation.NameKey] = item.Name,
[Models.Metadata.ConfLocation.NumberKey] = item.Number,
[Models.Metadata.ConfLocation.InvertedKey] = item.Inverted,
};
return confLocation;
}
/// <summary>
/// Convert from <cref="Models.Listxml.ConfSetting"/> to <cref="Models.Metadata.ConfSetting"/>
/// </summary>
private static Models.Metadata.ConfSetting ConvertToInternalModel(ConfSetting item)
{
var confSetting = new Models.Metadata.ConfSetting
{
[Models.Metadata.ConfSetting.NameKey] = item.Name,
[Models.Metadata.ConfSetting.ValueKey] = item.Value,
[Models.Metadata.ConfSetting.DefaultKey] = item.Default,
};
if (item.Condition != null)
confSetting[Models.Metadata.ConfSetting.ConditionKey] = ConvertToInternalModel(item.Condition);
return confSetting;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Control"/> to <cref="Models.Metadata.Control"/>
/// </summary>
private static Models.Metadata.Control ConvertToInternalModel(Control item)
{
var control = new Models.Metadata.Control
{
[Models.Metadata.Control.TypeKey] = item.Type,
[Models.Metadata.Control.PlayerKey] = item.Player,
[Models.Metadata.Control.ButtonsKey] = item.Buttons,
[Models.Metadata.Control.ReqButtonsKey] = item.ReqButtons,
[Models.Metadata.Control.MinimumKey] = item.Minimum,
[Models.Metadata.Control.MaximumKey] = item.Maximum,
[Models.Metadata.Control.SensitivityKey] = item.Sensitivity,
[Models.Metadata.Control.KeyDeltaKey] = item.KeyDelta,
[Models.Metadata.Control.ReverseKey] = item.Reverse,
[Models.Metadata.Control.WaysKey] = item.Ways,
[Models.Metadata.Control.Ways2Key] = item.Ways2,
[Models.Metadata.Control.Ways3Key] = item.Ways3,
};
return control;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Device"/> to <cref="Models.Metadata.Device"/>
/// </summary>
private static Models.Metadata.Device ConvertToInternalModel(Device item)
{
var device = new Models.Metadata.Device
{
[Models.Metadata.Device.TypeKey] = item.Type,
[Models.Metadata.Device.TagKey] = item.Tag,
[Models.Metadata.Device.FixedImageKey] = item.FixedImage,
[Models.Metadata.Device.MandatoryKey] = item.Mandatory,
[Models.Metadata.Device.InterfaceKey] = item.Interface,
};
if (item.Instance != null)
device[Models.Metadata.Device.InstanceKey] = ConvertToInternalModel(item.Instance);
if (item.Extension != null && item.Extension.Any())
{
device[Models.Metadata.Device.ExtensionKey] = item.Extension
.Where(e => e != null)
.Select(ConvertToInternalModel)
.ToArray();
}
return device;
}
/// <summary>
/// Convert from <cref="Models.Listxml.DeviceRef"/> to <cref="Models.Metadata.DeviceRef"/>
/// </summary>
private static Models.Metadata.DeviceRef ConvertToInternalModel(DeviceRef item)
{
var deviceRef = new Models.Metadata.DeviceRef
{
[Models.Metadata.DeviceRef.NameKey] = item.Name,
};
return deviceRef;
}
/// <summary>
/// Convert from <cref="Models.Listxml.DipLocation"/> to <cref="Models.Metadata.DipLocation"/>
/// </summary>
private static Models.Metadata.DipLocation ConvertToInternalModel(DipLocation item)
{
var dipLocation = new Models.Metadata.DipLocation
{
[Models.Metadata.DipLocation.NameKey] = item.Name,
[Models.Metadata.DipLocation.NumberKey] = item.Number,
[Models.Metadata.DipLocation.InvertedKey] = item.Inverted,
};
return dipLocation;
}
/// <summary>
/// Convert from <cref="Models.Listxml.DipSwitch"/> to <cref="Models.Metadata.DipSwitch"/>
/// </summary>
private static Models.Metadata.DipSwitch ConvertToInternalModel(DipSwitch item)
{
var dipSwitch = new Models.Metadata.DipSwitch
{
[Models.Metadata.DipSwitch.NameKey] = item.Name,
[Models.Metadata.DipSwitch.TagKey] = item.Tag,
[Models.Metadata.DipSwitch.MaskKey] = item.Mask,
};
if (item.Condition != null)
dipSwitch[Models.Metadata.DipSwitch.ConditionKey] = ConvertToInternalModel(item.Condition);
if (item.DipLocation != null && item.DipLocation.Any())
{
dipSwitch[Models.Metadata.DipSwitch.DipLocationKey] = item.DipLocation
.Where(d => d != null)
.Select(ConvertToInternalModel)
.ToArray();
}
if (item.DipValue != null && item.DipValue.Any())
{
dipSwitch[Models.Metadata.DipSwitch.DipValueKey] = item.DipValue
.Where(d => d != null)
.Select(ConvertToInternalModel)
.ToArray();
}
return dipSwitch;
}
/// <summary>
/// Convert from <cref="Models.Listxml.DipValue"/> to <cref="Models.Metadata.DipValue"/>
/// </summary>
private static Models.Metadata.DipValue ConvertToInternalModel(DipValue item)
{
var dipValue = new Models.Metadata.DipValue
{
[Models.Metadata.DipValue.NameKey] = item.Name,
[Models.Metadata.DipValue.ValueKey] = item.Value,
[Models.Metadata.DipValue.DefaultKey] = item.Default,
};
if (item.Condition != null)
dipValue[Models.Metadata.DipValue.ConditionKey] = ConvertToInternalModel(item.Condition);
return dipValue;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Disk"/> to <cref="Models.Metadata.Disk"/>
/// </summary>
private static Models.Metadata.Disk ConvertToInternalModel(Disk item)
{
var disk = new Models.Metadata.Disk
{
[Models.Metadata.Disk.NameKey] = item.Name,
[Models.Metadata.Disk.MD5Key] = item.MD5,
[Models.Metadata.Disk.SHA1Key] = item.SHA1,
[Models.Metadata.Disk.MergeKey] = item.Merge,
[Models.Metadata.Disk.RegionKey] = item.Region,
[Models.Metadata.Disk.IndexKey] = item.Index,
[Models.Metadata.Disk.WritableKey] = item.Writable,
[Models.Metadata.Disk.StatusKey] = item.Status,
[Models.Metadata.Disk.OptionalKey] = item.Optional,
};
return disk;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Display"/> to <cref="Models.Metadata.Display"/>
/// </summary>
private static Models.Metadata.Display ConvertToInternalModel(Display item)
{
var display = new Models.Metadata.Display
{
[Models.Metadata.Display.TagKey] = item.Tag,
[Models.Metadata.Display.TypeKey] = item.Type,
[Models.Metadata.Display.RotateKey] = item.Rotate,
[Models.Metadata.Display.FlipXKey] = item.FlipX,
[Models.Metadata.Display.WidthKey] = item.Width,
[Models.Metadata.Display.HeightKey] = item.Height,
[Models.Metadata.Display.RefreshKey] = item.Refresh,
[Models.Metadata.Display.PixClockKey] = item.PixClock,
[Models.Metadata.Display.HTotalKey] = item.HTotal,
[Models.Metadata.Display.HBEndKey] = item.HBEnd,
[Models.Metadata.Display.HBStartKey] = item.HBStart,
[Models.Metadata.Display.VTotalKey] = item.VTotal,
[Models.Metadata.Display.VBEndKey] = item.VBEnd,
[Models.Metadata.Display.VBStartKey] = item.VBStart,
};
return display;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Driver"/> to <cref="Models.Metadata.Driver"/>
/// </summary>
private static Models.Metadata.Driver ConvertToInternalModel(Driver item)
{
var driver = new Models.Metadata.Driver
{
[Models.Metadata.Driver.StatusKey] = item.Status,
[Models.Metadata.Driver.ColorKey] = item.Color,
[Models.Metadata.Driver.SoundKey] = item.Sound,
[Models.Metadata.Driver.PaletteSizeKey] = item.PaletteSize,
[Models.Metadata.Driver.EmulationKey] = item.Emulation,
[Models.Metadata.Driver.CocktailKey] = item.Cocktail,
[Models.Metadata.Driver.SaveStateKey] = item.SaveState,
[Models.Metadata.Driver.RequiresArtworkKey] = item.RequiresArtwork,
[Models.Metadata.Driver.UnofficialKey] = item.Unofficial,
[Models.Metadata.Driver.NoSoundHardwareKey] = item.NoSoundHardware,
[Models.Metadata.Driver.IncompleteKey] = item.Incomplete,
};
return driver;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Extension"/> to <cref="Models.Metadata.Extension"/>
/// </summary>
private static Models.Metadata.Extension ConvertToInternalModel(Extension item)
{
var extension = new Models.Metadata.Extension
{
[Models.Metadata.Extension.NameKey] = item.Name,
};
return extension;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Feature"/> to <cref="Models.Metadata.Feature"/>
/// </summary>
private static Models.Metadata.Feature ConvertToInternalModel(Feature item)
{
var feature = new Models.Metadata.Feature
{
[Models.Metadata.Feature.TypeKey] = item.Type,
[Models.Metadata.Feature.StatusKey] = item.Status,
[Models.Metadata.Feature.OverallKey] = item.Overall,
};
return feature;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Input"/> to <cref="Models.Metadata.Input"/>
/// </summary>
private static Models.Metadata.Input ConvertToInternalModel(Input item)
{
var input = new Models.Metadata.Input
{
[Models.Metadata.Input.ServiceKey] = item.Service,
[Models.Metadata.Input.TiltKey] = item.Tilt,
[Models.Metadata.Input.PlayersKey] = item.Players,
[Models.Metadata.Input.ControlKey] = item.ControlAttr,
[Models.Metadata.Input.ButtonsKey] = item.Buttons,
[Models.Metadata.Input.CoinsKey] = item.Coins,
};
if (item.Control != null && item.Control.Any())
{
input[Models.Metadata.Input.ControlKey] = item.Control
.Where(c => c != null)
.Select(ConvertToInternalModel)
.ToArray();
}
return input;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Instance"/> to <cref="Models.Metadata.Instance"/>
/// </summary>
private static Models.Metadata.Instance ConvertToInternalModel(Instance item)
{
var instance = new Models.Metadata.Instance
{
[Models.Metadata.Instance.NameKey] = item.Name,
[Models.Metadata.Instance.BriefNameKey] = item.BriefName,
};
return instance;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Port"/> to <cref="Models.Metadata.Port"/>
/// </summary>
private static Models.Metadata.Port ConvertToInternalModel(Port item)
{
var port = new Models.Metadata.Port
{
[Models.Metadata.Port.TagKey] = item.Tag,
};
if (item.Analog != null && item.Analog.Any())
{
port[Models.Metadata.Port.AnalogKey] = item.Analog
.Where(a => a != null)
.Select(ConvertToInternalModel)
.ToArray();
}
return port;
}
/// <summary>
/// Convert from <cref="Models.Listxml.RamOption"/> to <cref="Models.Metadata.RamOption"/>
/// </summary>
private static Models.Metadata.RamOption ConvertToInternalModel(RamOption item)
{
var ramOption = new Models.Metadata.RamOption
{
[Models.Metadata.RamOption.NameKey] = item.Name,
[Models.Metadata.RamOption.DefaultKey] = item.Default,
[Models.Metadata.RamOption.ContentKey] = item.Content,
};
return ramOption;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Rom"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
private static Models.Metadata.Rom ConvertToInternalModel(Rom item)
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.NameKey] = item.Name,
[Models.Metadata.Rom.BiosKey] = item.Bios,
[Models.Metadata.Rom.SizeKey] = item.Size,
[Models.Metadata.Rom.CRCKey] = item.CRC,
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
[Models.Metadata.Rom.MergeKey] = item.Merge,
[Models.Metadata.Rom.RegionKey] = item.Region,
[Models.Metadata.Rom.OffsetKey] = item.Offset,
[Models.Metadata.Rom.StatusKey] = item.Status,
[Models.Metadata.Rom.OptionalKey] = item.Optional,
[Models.Metadata.Rom.DisposeKey] = item.Dispose,
[Models.Metadata.Rom.SoundOnlyKey] = item.SoundOnly,
};
return rom;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Sample"/> to <cref="Models.Metadata.Sample"/>
/// </summary>
private static Models.Metadata.Sample ConvertToInternalModel(Sample item)
{
var sample = new Models.Metadata.Sample
{
[Models.Metadata.Sample.NameKey] = item.Name,
};
return sample;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Slot"/> to <cref="Models.Metadata.Slot"/>
/// </summary>
private static Models.Metadata.Slot ConvertToInternalModel(Slot item)
{
var slot = new Models.Metadata.Slot
{
[Models.Metadata.Slot.NameKey] = item.Name,
};
if (item.SlotOption != null && item.SlotOption.Any())
{
slot[Models.Metadata.Slot.SlotOptionKey] = item.SlotOption
.Where(s => s != null)
.Select(ConvertToInternalModel)
.ToArray();
}
return slot;
}
/// <summary>
/// Convert from <cref="Models.Listxml.SlotOption"/> to <cref="Models.Metadata.SlotOption"/>
/// </summary>
private static Models.Metadata.SlotOption ConvertToInternalModel(SlotOption item)
{
var slotOption = new Models.Metadata.SlotOption
{
[Models.Metadata.SlotOption.NameKey] = item.Name,
[Models.Metadata.SlotOption.DevNameKey] = item.DevName,
[Models.Metadata.SlotOption.DefaultKey] = item.Default,
};
return slotOption;
}
/// <summary>
/// Convert from <cref="Models.Listxml.SoftwareList"/> to <cref="Models.Metadata.SoftwareList"/>
/// </summary>
private static Models.Metadata.SoftwareList ConvertToInternalModel(Models.Listxml.SoftwareList item)
{
var softwareList = new Models.Metadata.SoftwareList
{
[Models.Metadata.SoftwareList.TagKey] = item.Tag,
[Models.Metadata.SoftwareList.NameKey] = item.Name,
[Models.Metadata.SoftwareList.StatusKey] = item.Status,
[Models.Metadata.SoftwareList.FilterKey] = item.Filter,
};
return softwareList;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Sound"/> to <cref="Models.Metadata.Sound"/>
/// </summary>
private static Models.Metadata.Sound ConvertToInternalModel(Sound item)
{
var sound = new Models.Metadata.Sound
{
[Models.Metadata.Sound.ChannelsKey] = item.Channels,
};
return sound;
}
/// <summary>
/// Convert from <cref="Models.Listxml.Video"/> to <cref="Models.Metadata.Video"/>
/// </summary>
private static Models.Metadata.Video ConvertToInternalModel(Video item)
{
var video = new Models.Metadata.Video
{
[Models.Metadata.Video.ScreenKey] = item.Screen,
[Models.Metadata.Video.OrientationKey] = item.Orientation,
[Models.Metadata.Video.WidthKey] = item.Width,
[Models.Metadata.Video.HeightKey] = item.Height,
[Models.Metadata.Video.AspectXKey] = item.AspectX,
[Models.Metadata.Video.AspectYKey] = item.AspectY,
[Models.Metadata.Video.RefreshKey] = item.Refresh,
};
return video;
}
}
}

View File

@@ -1,382 +0,0 @@
using System.Linq;
using SabreTools.Models.Logiqx;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class Logiqx : IModelSerializer<Datafile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Datafile? Deserialize(Models.Metadata.MetadataFile? obj) => Deserialize(obj, false);
/// <inheritdoc/>
public Datafile? Deserialize(Models.Metadata.MetadataFile? obj, bool game)
{
if (obj == null)
return null;
var datafile = new Datafile
{
Build = obj.ReadString(Models.Metadata.Header.BuildKey),
Debug = obj.ReadString(Models.Metadata.Header.DebugKey),
SchemaLocation = obj.ReadString(Models.Metadata.Header.SchemaLocationKey),
};
var header = obj.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
if (header != null)
datafile.Header = ConvertHeaderFromInternalModel(header);
// TODO: Handle Dir items - Currently need to be generated from the machines
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Any())
{
datafile.Game = machines
.Where(m => m != null)
.Select(machine => ConvertMachineFromInternalModel(machine, game))
.ToArray();
}
return datafile;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Header"/> to <cref="Models.Logiqx.Header"/>
/// </summary>
private static Header ConvertHeaderFromInternalModel(Models.Metadata.Header item)
{
var header = new Header
{
Id = item.ReadString(Models.Metadata.Header.IdKey),
Name = item.ReadString(Models.Metadata.Header.NameKey),
Description = item.ReadString(Models.Metadata.Header.DescriptionKey),
RootDir = item.ReadString(Models.Metadata.Header.RootDirKey),
Category = item.ReadString(Models.Metadata.Header.CategoryKey),
Version = item.ReadString(Models.Metadata.Header.VersionKey),
Date = item.ReadString(Models.Metadata.Header.DateKey),
Author = item.ReadString(Models.Metadata.Header.AuthorKey),
Email = item.ReadString(Models.Metadata.Header.EmailKey),
Homepage = item.ReadString(Models.Metadata.Header.HomepageKey),
Url = item.ReadString(Models.Metadata.Header.UrlKey),
Comment = item.ReadString(Models.Metadata.Header.CommentKey),
Type = item.ReadString(Models.Metadata.Header.TypeKey),
};
if (item.ContainsKey(Models.Metadata.Header.HeaderKey)
|| item.ContainsKey(Models.Metadata.Header.ForceMergingKey)
|| item.ContainsKey(Models.Metadata.Header.ForceNodumpKey)
|| item.ContainsKey(Models.Metadata.Header.ForcePackingKey))
{
header.ClrMamePro = new Models.Logiqx.ClrMamePro
{
Header = item.ReadString(Models.Metadata.Header.HeaderKey),
ForceMerging = item.ReadString(Models.Metadata.Header.ForceMergingKey),
ForceNodump = item.ReadString(Models.Metadata.Header.ForceNodumpKey),
ForcePacking = item.ReadString(Models.Metadata.Header.ForcePackingKey),
};
}
if (item.ContainsKey(Models.Metadata.Header.PluginKey)
|| item.ContainsKey(Models.Metadata.Header.RomModeKey)
|| item.ContainsKey(Models.Metadata.Header.BiosModeKey)
|| item.ContainsKey(Models.Metadata.Header.SampleModeKey)
|| item.ContainsKey(Models.Metadata.Header.LockRomModeKey)
|| item.ContainsKey(Models.Metadata.Header.LockBiosModeKey)
|| item.ContainsKey(Models.Metadata.Header.LockSampleModeKey))
{
header.RomCenter = new Models.Logiqx.RomCenter
{
Plugin = item.ReadString(Models.Metadata.Header.PluginKey),
RomMode = item.ReadString(Models.Metadata.Header.RomModeKey),
BiosMode = item.ReadString(Models.Metadata.Header.BiosModeKey),
SampleMode = item.ReadString(Models.Metadata.Header.SampleModeKey),
LockRomMode = item.ReadString(Models.Metadata.Header.LockRomModeKey),
LockBiosMode = item.ReadString(Models.Metadata.Header.LockBiosModeKey),
LockSampleMode = item.ReadString(Models.Metadata.Header.LockSampleModeKey),
};
}
return header;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Machine"/> to <cref="Models.Logiqx.GameBase"/>
/// </summary>
private static GameBase ConvertMachineFromInternalModel(Models.Metadata.Machine item, bool game = false)
{
GameBase gameBase = game ? new Game() : new Machine();
gameBase.Name = item.ReadString(Models.Metadata.Machine.NameKey);
gameBase.SourceFile = item.ReadString(Models.Metadata.Machine.SourceFileKey);
gameBase.IsBios = item.ReadString(Models.Metadata.Machine.IsBiosKey);
gameBase.IsDevice = item.ReadString(Models.Metadata.Machine.IsDeviceKey);
gameBase.IsMechanical = item.ReadString(Models.Metadata.Machine.IsMechanicalKey);
gameBase.CloneOf = item.ReadString(Models.Metadata.Machine.CloneOfKey);
gameBase.RomOf = item.ReadString(Models.Metadata.Machine.RomOfKey);
gameBase.SampleOf = item.ReadString(Models.Metadata.Machine.SampleOfKey);
gameBase.Board = item.ReadString(Models.Metadata.Machine.BoardKey);
gameBase.RebuildTo = item.ReadString(Models.Metadata.Machine.RebuildToKey);
gameBase.Id = item.ReadString(Models.Metadata.Machine.IdKey);
gameBase.CloneOfId = item.ReadString(Models.Metadata.Machine.CloneOfIdKey);
gameBase.Runnable = item.ReadString(Models.Metadata.Machine.RunnableKey);
gameBase.Comment = item.ReadStringArray(Models.Metadata.Machine.CommentKey);
gameBase.Description = item.ReadString(Models.Metadata.Machine.DescriptionKey);
gameBase.Year = item.ReadString(Models.Metadata.Machine.YearKey);
gameBase.Manufacturer = item.ReadString(Models.Metadata.Machine.ManufacturerKey);
gameBase.Publisher = item.ReadString(Models.Metadata.Machine.PublisherKey);
gameBase.Category = item.ReadStringArray(Models.Metadata.Machine.CategoryKey);
var trurip = item.Read<Trurip>(Models.Metadata.Machine.TruripKey);
if (trurip != null)
gameBase.Trurip = trurip;
var releases = item.Read<Models.Metadata.Release[]>(Models.Metadata.Machine.ReleaseKey);
if (releases != null && releases.Any())
{
gameBase.Release = releases
.Where(r => r != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var biosSets = item.Read<Models.Metadata.BiosSet[]>(Models.Metadata.Machine.BiosSetKey);
if (biosSets != null && biosSets.Any())
{
gameBase.BiosSet = biosSets
.Where(b => b != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
if (roms != null && roms.Any())
{
gameBase.Rom = roms
.Where(r => r != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var disks = item.Read<Models.Metadata.Disk[]>(Models.Metadata.Machine.DiskKey);
if (disks != null && disks.Any())
{
gameBase.Disk = disks
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var medias = item.Read<Models.Metadata.Media[]>(Models.Metadata.Machine.MediaKey);
if (medias != null && medias.Any())
{
gameBase.Media = medias
.Where(m => m != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var deviceRefs = item.Read<Models.Metadata.DeviceRef[]>(Models.Metadata.Machine.DeviceRefKey);
if (deviceRefs != null && deviceRefs.Any())
{
gameBase.DeviceRef = deviceRefs
.Where(m => m != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var samples = item.Read<Models.Metadata.Sample[]>(Models.Metadata.Machine.SampleKey);
if (samples != null && samples.Any())
{
gameBase.Sample = samples
.Where(m => m != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var archives = item.Read<Models.Metadata.Archive[]>(Models.Metadata.Machine.ArchiveKey);
if (archives != null && archives.Any())
{
gameBase.Archive = archives
.Where(m => m != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var driver = item.Read<Models.Metadata.Driver>(Models.Metadata.Machine.DriverKey);
if (driver != null)
gameBase.Driver = ConvertFromInternalModel(driver);
var softwareLists = item.Read<Models.Metadata.SoftwareList[]>(Models.Metadata.Machine.SoftwareListKey);
if (softwareLists != null && softwareLists.Any())
{
gameBase.SoftwareList = softwareLists
.Where(m => m != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
return gameBase;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Archive"/> to <cref="Models.Logiqx.Archive"/>
/// </summary>
private static Archive ConvertFromInternalModel(Models.Metadata.Archive item)
{
var archive = new Archive
{
Name = item.ReadString(Models.Metadata.Archive.NameKey),
};
return archive;
}
/// <summary>
/// Convert from <cref="Models.Metadata.BiosSet"/> to <cref="Models.Logiqx.BiosSet"/>
/// </summary>
private static BiosSet ConvertFromInternalModel(Models.Metadata.BiosSet item)
{
var biosset = new BiosSet
{
Name = item.ReadString(Models.Metadata.BiosSet.NameKey),
Description = item.ReadString(Models.Metadata.BiosSet.DescriptionKey),
Default = item.ReadString(Models.Metadata.BiosSet.DefaultKey),
};
return biosset;
}
/// <summary>
/// Convert from <cref="Models.Metadata.DeviceRef"/> to <cref="Models.Logiqx.DeviceRef"/>
/// </summary>
private static DeviceRef ConvertFromInternalModel(Models.Metadata.DeviceRef item)
{
var deviceRef = new DeviceRef
{
Name = item.ReadString(Models.Metadata.DipSwitch.NameKey),
};
return deviceRef;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Disk"/> to <cref="Models.Logiqx.Disk"/>
/// </summary>
private static Disk ConvertFromInternalModel(Models.Metadata.Disk item)
{
var disk = new Disk
{
Name = item.ReadString(Models.Metadata.Disk.NameKey),
MD5 = item.ReadString(Models.Metadata.Disk.MD5Key),
SHA1 = item.ReadString(Models.Metadata.Disk.SHA1Key),
Merge = item.ReadString(Models.Metadata.Disk.MergeKey),
Status = item.ReadString(Models.Metadata.Disk.StatusKey),
Region = item.ReadString(Models.Metadata.Disk.RegionKey),
};
return disk;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Driver"/> to <cref="Models.Logiqx.Driver"/>
/// </summary>
private static Driver ConvertFromInternalModel(Models.Metadata.Driver item)
{
var driver = new Driver
{
Status = item.ReadString(Models.Metadata.Driver.StatusKey),
Emulation = item.ReadString(Models.Metadata.Driver.EmulationKey),
Cocktail = item.ReadString(Models.Metadata.Driver.CocktailKey),
SaveState = item.ReadString(Models.Metadata.Driver.SaveStateKey),
RequiresArtwork = item.ReadString(Models.Metadata.Driver.RequiresArtworkKey),
Unofficial = item.ReadString(Models.Metadata.Driver.UnofficialKey),
NoSoundHardware = item.ReadString(Models.Metadata.Driver.NoSoundHardwareKey),
Incomplete = item.ReadString(Models.Metadata.Driver.IncompleteKey),
};
return driver;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Media"/> to <cref="Models.Logiqx.Media"/>
/// </summary>
private static Media ConvertFromInternalModel(Models.Metadata.Media item)
{
var media = new Media
{
Name = item.ReadString(Models.Metadata.Media.NameKey),
MD5 = item.ReadString(Models.Metadata.Media.MD5Key),
SHA1 = item.ReadString(Models.Metadata.Media.SHA1Key),
SHA256 = item.ReadString(Models.Metadata.Media.SHA256Key),
SpamSum = item.ReadString(Models.Metadata.Media.SpamSumKey),
};
return media;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Release"/> to <cref="Models.Logiqx.Release"/>
/// </summary>
private static Release ConvertFromInternalModel(Models.Metadata.Release item)
{
var release = new Release
{
Name = item.ReadString(Models.Metadata.Release.NameKey),
Region = item.ReadString(Models.Metadata.Release.RegionKey),
Language = item.ReadString(Models.Metadata.Release.LanguageKey),
Date = item.ReadString(Models.Metadata.Release.DateKey),
Default = item.ReadString(Models.Metadata.Release.DefaultKey),
};
return release;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.Logiqx.Rom"/>
/// </summary>
private static Rom ConvertFromInternalModel(Models.Metadata.Rom item)
{
var rom = new Rom
{
Name = item.ReadString(Models.Metadata.Rom.NameKey),
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
CRC = item.ReadString(Models.Metadata.Rom.CRCKey),
MD5 = item.ReadString(Models.Metadata.Rom.MD5Key),
SHA1 = item.ReadString(Models.Metadata.Rom.SHA1Key),
SHA256 = item.ReadString(Models.Metadata.Rom.SHA256Key),
SHA384 = item.ReadString(Models.Metadata.Rom.SHA384Key),
SHA512 = item.ReadString(Models.Metadata.Rom.SHA512Key),
SpamSum = item.ReadString(Models.Metadata.Rom.SpamSumKey),
xxHash364 = item.ReadString(Models.Metadata.Rom.xxHash364Key),
xxHash3128 = item.ReadString(Models.Metadata.Rom.xxHash3128Key),
Merge = item.ReadString(Models.Metadata.Rom.MergeKey),
Status = item.ReadString(Models.Metadata.Rom.StatusKey),
Serial = item.ReadString(Models.Metadata.Rom.SerialKey),
Header = item.ReadString(Models.Metadata.Rom.HeaderKey),
Date = item.ReadString(Models.Metadata.Rom.DateKey),
Inverted = item.ReadString(Models.Metadata.Rom.InvertedKey),
MIA = item.ReadString(Models.Metadata.Rom.MIAKey),
};
return rom;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Sample"/> to <cref="Models.Logiqx.Sample"/>
/// </summary>
private static Sample ConvertFromInternalModel(Models.Metadata.Sample item)
{
var sample = new Sample
{
Name = item.ReadString(Models.Metadata.Sample.NameKey),
};
return sample;
}
/// <summary>
/// Convert from <cref="Models.Metadata.SoftwareList"/> to <cref="Models.Logiqx.SoftwareList"/>
/// </summary>
private static Models.Logiqx.SoftwareList ConvertFromInternalModel(Models.Metadata.SoftwareList item)
{
var softwareList = new Models.Logiqx.SoftwareList
{
Tag = item.ReadString(Models.Metadata.SoftwareList.TagKey),
Name = item.ReadString(Models.Metadata.SoftwareList.NameKey),
Status = item.ReadString(Models.Metadata.SoftwareList.StatusKey),
Filter = item.ReadString(Models.Metadata.SoftwareList.FilterKey),
};
return softwareList;
}
}
}

View File

@@ -1,344 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SabreTools.Models.Logiqx;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class Logiqx : IModelSerializer<Datafile, Models.Metadata.MetadataFile>
{
public Models.Metadata.MetadataFile? Serialize(Datafile? item)
{
if (item == null)
return null;
var metadataFile = new Models.Metadata.MetadataFile
{
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
};
var machines = new List<Models.Metadata.Machine>();
if (item.Game != null && item.Game.Any())
{
machines.AddRange(item.Game
.Where(g => g != null)
.Select(ConvertMachineToInternalModel));
}
if (item.Dir != null && item.Dir.Any())
{
machines.AddRange(item.Dir
.Where(d => d != null)
.SelectMany(ConvertDirToInternalModel));
}
if (machines.Any())
metadataFile[Models.Metadata.MetadataFile.MachineKey] = machines.ToArray();
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.Logiqx.Datafile"/> to <cref="Models.Metadata.Header"/>
/// </summary>
private static Models.Metadata.Header ConvertHeaderToInternalModel(Datafile item)
{
var header = item.Header != null ? ConvertHeaderToInternalModel(item.Header) : new Models.Metadata.Header();
header[Models.Metadata.Header.BuildKey] = item.Build;
header[Models.Metadata.Header.DebugKey] = item.Debug;
header[Models.Metadata.Header.SchemaLocationKey] = item.SchemaLocation;
return header;
}
/// <summary>
/// Convert from <cref="Models.Logiqx.Header"/> to <cref="Models.Metadata.Header"/>
/// </summary>
private static Models.Metadata.Header ConvertHeaderToInternalModel(Header item)
{
var header = new Models.Metadata.Header
{
[Models.Metadata.Header.IdKey] = item.Id,
[Models.Metadata.Header.NameKey] = item.Name,
[Models.Metadata.Header.DescriptionKey] = item.Description,
[Models.Metadata.Header.RootDirKey] = item.RootDir,
[Models.Metadata.Header.CategoryKey] = item.Category,
[Models.Metadata.Header.VersionKey] = item.Version,
[Models.Metadata.Header.DateKey] = item.Date,
[Models.Metadata.Header.AuthorKey] = item.Author,
[Models.Metadata.Header.EmailKey] = item.Email,
[Models.Metadata.Header.HomepageKey] = item.Homepage,
[Models.Metadata.Header.UrlKey] = item.Url,
[Models.Metadata.Header.CommentKey] = item.Comment,
[Models.Metadata.Header.TypeKey] = item.Type,
};
if (item.ClrMamePro != null)
{
header[Models.Metadata.Header.HeaderKey] = item.ClrMamePro.Header;
header[Models.Metadata.Header.ForceMergingKey] = item.ClrMamePro.ForceMerging;
header[Models.Metadata.Header.ForceNodumpKey] = item.ClrMamePro.ForceNodump;
header[Models.Metadata.Header.ForcePackingKey] = item.ClrMamePro.ForcePacking;
}
if (item.RomCenter != null)
{
header[Models.Metadata.Header.PluginKey] = item.RomCenter.Plugin;
header[Models.Metadata.Header.RomModeKey] = item.RomCenter.RomMode;
header[Models.Metadata.Header.BiosModeKey] = item.RomCenter.BiosMode;
header[Models.Metadata.Header.SampleModeKey] = item.RomCenter.SampleMode;
header[Models.Metadata.Header.LockRomModeKey] = item.RomCenter.LockRomMode;
header[Models.Metadata.Header.LockBiosModeKey] = item.RomCenter.LockBiosMode;
header[Models.Metadata.Header.LockSampleModeKey] = item.RomCenter.LockSampleMode;
}
return header;
}
/// <summary>
/// Convert from <cref="Models.Logiqx.Dir"/> to an array of <cref="Models.Metadata.Machine"/>
/// </summary>
private static Models.Metadata.Machine[] ConvertDirToInternalModel(Dir item)
{
if (item.Game == null || !item.Game.Any())
return [];
return item.Game
.Where(g => g != null)
.Select(game =>
{
var machine = ConvertMachineToInternalModel(game);
machine[Models.Metadata.Machine.DirNameKey] = item.Name;
return machine;
})
.ToArray();
}
/// <summary>
/// Convert from <cref="Models.Logiqx.GameBase"/> to <cref="Models.Metadata.Machine"/>
/// </summary>
private static Models.Metadata.Machine ConvertMachineToInternalModel(GameBase item)
{
var machine = new Models.Metadata.Machine
{
[Models.Metadata.Machine.NameKey] = item.Name,
[Models.Metadata.Machine.SourceFileKey] = item.SourceFile,
[Models.Metadata.Machine.IsBiosKey] = item.IsBios,
[Models.Metadata.Machine.IsDeviceKey] = item.IsDevice,
[Models.Metadata.Machine.IsMechanicalKey] = item.IsMechanical,
[Models.Metadata.Machine.CloneOfKey] = item.CloneOf,
[Models.Metadata.Machine.RomOfKey] = item.RomOf,
[Models.Metadata.Machine.SampleOfKey] = item.SampleOf,
[Models.Metadata.Machine.BoardKey] = item.Board,
[Models.Metadata.Machine.RebuildToKey] = item.RebuildTo,
[Models.Metadata.Machine.IdKey] = item.Id,
[Models.Metadata.Machine.CloneOfIdKey] = item.CloneOfId,
[Models.Metadata.Machine.RunnableKey] = item.Runnable,
[Models.Metadata.Machine.CommentKey] = item.Comment,
[Models.Metadata.Machine.DescriptionKey] = item.Description,
[Models.Metadata.Machine.YearKey] = item.Year,
[Models.Metadata.Machine.ManufacturerKey] = item.Manufacturer,
[Models.Metadata.Machine.PublisherKey] = item.Publisher,
[Models.Metadata.Machine.CategoryKey] = item.Category,
[Models.Metadata.Machine.TruripKey] = item.Trurip,
};
if (item.Release != null && item.Release.Any())
machine[Models.Metadata.Machine.ReleaseKey] = item.Release.Select(ConvertToInternalModel).ToArray();
if (item.BiosSet != null && item.BiosSet.Any())
machine[Models.Metadata.Machine.BiosSetKey] = item.BiosSet.Select(ConvertToInternalModel).ToArray();
if (item.Rom != null && item.Rom.Any())
machine[Models.Metadata.Machine.RomKey] = item.Rom.Select(ConvertToInternalModel).ToArray();
if (item.Disk != null && item.Disk.Any())
machine[Models.Metadata.Machine.DiskKey] = item.Disk.Select(ConvertToInternalModel).ToArray();
if (item.Media != null && item.Media.Any())
machine[Models.Metadata.Machine.MediaKey] = item.Media.Select(ConvertToInternalModel).ToArray();
if (item.DeviceRef != null && item.DeviceRef.Any())
machine[Models.Metadata.Machine.DeviceRefKey] = item.DeviceRef.Select(ConvertToInternalModel).ToArray();
if (item.Sample != null && item.Sample.Any())
machine[Models.Metadata.Machine.SampleKey] = item.Sample.Select(ConvertToInternalModel).ToArray();
if (item.Archive != null && item.Archive.Any())
machine[Models.Metadata.Machine.ArchiveKey] = item.Archive.Select(ConvertToInternalModel).ToArray();
if (item.Driver != null)
machine[Models.Metadata.Machine.DriverKey] = ConvertToInternalModel(item.Driver);
if (item.SoftwareList != null && item.SoftwareList.Any())
machine[Models.Metadata.Machine.SoftwareListKey] = item.SoftwareList.Select(ConvertToInternalModel).ToArray();
return machine;
}
/// <summary>
/// Convert from <cref="Models.Logiqx.Archive"/> to <cref="Models.Metadata.Archive"/>
/// </summary>
private static Models.Metadata.Archive ConvertToInternalModel(Archive item)
{
var archive = new Models.Metadata.Archive
{
[Models.Metadata.Archive.NameKey] = item.Name,
};
return archive;
}
/// <summary>
/// Convert from <cref="Models.Logiqx.BiosSet"/> to <cref="Models.Metadata.BiosSet"/>
/// </summary>
private static Models.Metadata.BiosSet ConvertToInternalModel(BiosSet item)
{
var biosset = new Models.Metadata.BiosSet
{
[Models.Metadata.BiosSet.NameKey] = item.Name,
[Models.Metadata.BiosSet.DescriptionKey] = item.Description,
[Models.Metadata.BiosSet.DefaultKey] = item.Default,
};
return biosset;
}
/// <summary>
/// Convert from <cref="Models.Logiqx.DeviceRef"/> to <cref="Models.Metadata.DeviceRef"/>
/// </summary>
private static Models.Metadata.DeviceRef ConvertToInternalModel(DeviceRef item)
{
var deviceRef = new Models.Metadata.DeviceRef
{
[Models.Metadata.DeviceRef.NameKey] = item.Name,
};
return deviceRef;
}
/// <summary>
/// Convert from <cref="Models.Logiqx.Disk"/> to <cref="Models.Metadata.Disk"/>
/// </summary>
private static Models.Metadata.Disk ConvertToInternalModel(Disk item)
{
var disk = new Models.Metadata.Disk
{
[Models.Metadata.Disk.NameKey] = item.Name,
[Models.Metadata.Disk.MD5Key] = item.MD5,
[Models.Metadata.Disk.SHA1Key] = item.SHA1,
[Models.Metadata.Disk.MergeKey] = item.Merge,
[Models.Metadata.Disk.StatusKey] = item.Status,
[Models.Metadata.Disk.RegionKey] = item.Region,
};
return disk;
}
/// <summary>
/// Convert from <cref="Models.Logiqx.Driver"/> to <cref="Models.Metadata.Driver"/>
/// </summary>
private static Models.Metadata.Driver ConvertToInternalModel(Driver item)
{
var driver = new Models.Metadata.Driver
{
[Models.Metadata.Driver.StatusKey] = item.Status,
[Models.Metadata.Driver.EmulationKey] = item.Emulation,
[Models.Metadata.Driver.CocktailKey] = item.Cocktail,
[Models.Metadata.Driver.SaveStateKey] = item.SaveState,
[Models.Metadata.Driver.RequiresArtworkKey] = item.RequiresArtwork,
[Models.Metadata.Driver.UnofficialKey] = item.Unofficial,
[Models.Metadata.Driver.NoSoundHardwareKey] = item.NoSoundHardware,
[Models.Metadata.Driver.IncompleteKey] = item.Incomplete,
};
return driver;
}
/// <summary>
/// Convert from <cref="Models.Logiqx.Media"/> to <cref="Models.Metadata.Media"/>
/// </summary>
private static Models.Metadata.Media ConvertToInternalModel(Media item)
{
var media = new Models.Metadata.Media
{
[Models.Metadata.Media.NameKey] = item.Name,
[Models.Metadata.Media.MD5Key] = item.MD5,
[Models.Metadata.Media.SHA1Key] = item.SHA1,
[Models.Metadata.Media.SHA256Key] = item.SHA256,
[Models.Metadata.Media.SpamSumKey] = item.SpamSum,
};
return media;
}
/// <summary>
/// Convert from <cref="Models.Logiqx.Release"/> to <cref="Models.Metadata.Release"/>
/// </summary>
private static Models.Metadata.Release ConvertToInternalModel(Release item)
{
var release = new Models.Metadata.Release
{
[Models.Metadata.Release.NameKey] = item.Name,
[Models.Metadata.Release.RegionKey] = item.Region,
[Models.Metadata.Release.LanguageKey] = item.Language,
[Models.Metadata.Release.DateKey] = item.Date,
[Models.Metadata.Release.DefaultKey] = item.Default,
};
return release;
}
/// <summary>
/// Convert from <cref="Models.Logiqx.Rom"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
private static Models.Metadata.Rom ConvertToInternalModel(Rom item)
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.NameKey] = item.Name,
[Models.Metadata.Rom.SizeKey] = item.Size,
[Models.Metadata.Rom.CRCKey] = item.CRC,
[Models.Metadata.Rom.MD5Key] = item.MD5,
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
[Models.Metadata.Rom.SHA256Key] = item.SHA256,
[Models.Metadata.Rom.SHA384Key] = item.SHA384,
[Models.Metadata.Rom.SHA512Key] = item.SHA512,
[Models.Metadata.Rom.SpamSumKey] = item.SpamSum,
[Models.Metadata.Rom.xxHash364Key] = item.xxHash364,
[Models.Metadata.Rom.xxHash3128Key] = item.xxHash3128,
[Models.Metadata.Rom.MergeKey] = item.Merge,
[Models.Metadata.Rom.StatusKey] = item.Status,
[Models.Metadata.Rom.SerialKey] = item.Serial,
[Models.Metadata.Rom.HeaderKey] = item.Header,
[Models.Metadata.Rom.DateKey] = item.Date,
[Models.Metadata.Rom.InvertedKey] = item.Inverted,
[Models.Metadata.Rom.MIAKey] = item.MIA,
};
return rom;
}
/// <summary>
/// Convert from <cref="Models.Logiqx.Sample"/> to <cref="Models.Metadata.Sample"/>
/// </summary>
private static Models.Metadata.Sample ConvertToInternalModel(Sample item)
{
var sample = new Models.Metadata.Sample
{
[Models.Metadata.Sample.NameKey] = item.Name,
};
return sample;
}
/// <summary>
/// Convert from <cref="Models.Logiqx.SoftwareList"/> to <cref="Models.Metadata.SoftwareList"/>
/// </summary>
private static Models.Metadata.SoftwareList ConvertToInternalModel(Models.Logiqx.SoftwareList item)
{
var softwareList = new Models.Metadata.SoftwareList
{
[Models.Metadata.SoftwareList.TagKey] = item.Tag,
[Models.Metadata.SoftwareList.NameKey] = item.Name,
[Models.Metadata.SoftwareList.StatusKey] = item.Status,
[Models.Metadata.SoftwareList.FilterKey] = item.Filter,
};
return softwareList;
}
}
}

View File

@@ -1,41 +0,0 @@
using System.Linq;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class M1 : IModelSerializer<Models.Listxml.M1, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.Listxml.M1? Deserialize(Models.Metadata.MetadataFile? obj)
{
if (obj == null)
return null;
var header = obj.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
var m1 = header != null ? ConvertM1FromInternalModel(header) : new Models.Listxml.M1();
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Any())
{
m1.Game = machines
.Where(m => m != null)
.Select(Listxml.ConvertMachineFromInternalModel)
.ToArray();
}
return m1;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Models.Metadata.Header"/> to <cref="Models.Listxml.M1"/>
/// </summary>
private static Models.Listxml.M1 ConvertM1FromInternalModel(Models.Metadata.Header item)
{
var m1 = new Models.Listxml.M1
{
Version = item.ReadString(Models.Metadata.Header.VersionKey),
};
return m1;
}
}
}

View File

@@ -1,42 +0,0 @@
using System.Linq;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class M1 : IModelSerializer<Models.Listxml.M1, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.Metadata.MetadataFile? Serialize(Models.Listxml.M1? item)
{
if (item == null)
return null;
var metadataFile = new Models.Metadata.MetadataFile
{
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
};
if (item?.Game != null && item.Game.Any())
{
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.Game
.Where(g => g != null)
.Select(Listxml.ConvertMachineToInternalModel)
.ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.Listxml.M1"/> to <cref="Models.Metadata.Header"/>
/// </summary>
private static Models.Metadata.Header ConvertHeaderToInternalModel(Models.Listxml.M1 item)
{
var header = new Models.Metadata.Header
{
[Models.Metadata.Header.VersionKey] = item.Version,
};
return header;
}
}
}

View File

@@ -1,134 +0,0 @@
using System.Linq;
using SabreTools.Models.OfflineList;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class OfflineList : IModelSerializer<Dat, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Dat? Deserialize(Models.Metadata.MetadataFile? obj)
{
if (obj == null)
return null;
var header = obj.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
var dat = header != null ? ConvertHeaderFromInternalModel(header) : new Dat();
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Any())
{
dat.Games = new Games
{
Game = machines
.Where(m => m != null)
.Select(ConvertMachineFromInternalModel)
.ToArray()
};
}
return dat;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Header"/> to <cref="Models.OfflineList.Dat"/>
/// </summary>
private static Dat ConvertHeaderFromInternalModel(Models.Metadata.Header item)
{
var dat = new Dat
{
NoNamespaceSchemaLocation = item.ReadString(Models.Metadata.Header.SchemaLocationKey),
};
if (item.ContainsKey(Models.Metadata.Header.NameKey)
|| item.ContainsKey(Models.Metadata.Header.ImFolderKey)
|| item.ContainsKey(Models.Metadata.Header.DatVersionKey)
|| item.ContainsKey(Models.Metadata.Header.SystemKey)
|| item.ContainsKey(Models.Metadata.Header.ScreenshotsWidthKey)
|| item.ContainsKey(Models.Metadata.Header.ScreenshotsHeightKey)
|| item.ContainsKey(Models.Metadata.Header.InfosKey)
|| item.ContainsKey(Models.Metadata.Header.CanOpenKey)
|| item.ContainsKey(Models.Metadata.Header.NewDatKey)
|| item.ContainsKey(Models.Metadata.Header.SearchKey)
|| item.ContainsKey(Models.Metadata.Header.RomTitleKey))
{
dat.Configuration = new Configuration
{
DatName = item.ReadString(Models.Metadata.Header.NameKey),
ImFolder = item.ReadString(Models.Metadata.Header.ImFolderKey),
DatVersion = item.ReadString(Models.Metadata.Header.DatVersionKey),
System = item.ReadString(Models.Metadata.Header.SystemKey),
ScreenshotsWidth = item.ReadString(Models.Metadata.Header.ScreenshotsWidthKey),
ScreenshotsHeight = item.ReadString(Models.Metadata.Header.ScreenshotsHeightKey),
Infos = item.Read<Infos>(Models.Metadata.Header.InfosKey),
CanOpen = item.Read<CanOpen>(Models.Metadata.Header.CanOpenKey),
NewDat = item.Read<NewDat>(Models.Metadata.Header.NewDatKey),
Search = item.Read<Search>(Models.Metadata.Header.SearchKey),
RomTitle = item.ReadString(Models.Metadata.Header.RomTitleKey),
};
}
if (item.ContainsKey(Models.Metadata.Header.ImagesKey))
{
dat.GUI = new GUI
{
Images = item.Read<Images>(Models.Metadata.Header.ImagesKey),
};
}
return dat;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Machine"/> to <cref="Models.OfflineList.Game"/>
/// </summary>
private static Game ConvertMachineFromInternalModel(Models.Metadata.Machine item)
{
var game = new Game
{
ImageNumber = item.ReadString(Models.Metadata.Machine.ImageNumberKey),
ReleaseNumber = item.ReadString(Models.Metadata.Machine.ReleaseNumberKey),
Title = item.ReadString(Models.Metadata.Machine.NameKey),
SaveType = item.ReadString(Models.Metadata.Machine.SaveTypeKey),
Publisher = item.ReadString(Models.Metadata.Machine.PublisherKey),
Location = item.ReadString(Models.Metadata.Machine.LocationKey),
SourceRom = item.ReadString(Models.Metadata.Machine.SourceRomKey),
Language = item.ReadString(Models.Metadata.Machine.LanguageKey),
Im1CRC = item.ReadString(Models.Metadata.Machine.Im1CRCKey),
Im2CRC = item.ReadString(Models.Metadata.Machine.Im2CRCKey),
Comment = item.ReadString(Models.Metadata.Machine.CommentKey),
DuplicateID = item.ReadString(Models.Metadata.Machine.DuplicateIDKey),
};
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
if (roms != null && roms.Any())
{
game.RomSize = roms
.Select(rom => rom.ReadString(Models.Metadata.Rom.SizeKey))
.FirstOrDefault(s => s != null);
var romCRCs = roms
.Where(r => r != null)
.Select(ConvertFromInternalModel)
.ToArray();
game.Files = new Models.OfflineList.Files { RomCRC = romCRCs };
}
return game;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.OfflineList.FileRomCRC"/>
/// </summary>
private static FileRomCRC ConvertFromInternalModel(Models.Metadata.Rom item)
{
var fileRomCRC = new FileRomCRC
{
Extension = item.ReadString(Models.Metadata.Rom.ExtensionKey),
Content = item.ReadString(Models.Metadata.Rom.CRCKey),
};
return fileRomCRC;
}
}
}

View File

@@ -1,114 +0,0 @@
using System.Linq;
using SabreTools.Models.OfflineList;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class OfflineList : IModelSerializer<Dat, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.Metadata.MetadataFile? Serialize(Dat? item)
{
if (item == null)
return null;
var metadataFile = new Models.Metadata.MetadataFile
{
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
};
if (item?.Games?.Game != null && item.Games.Game.Any())
{
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.Games.Game
.Where(g => g != null)
.Select(ConvertMachineToInternalModel)
.ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.OfflineList.Dat"/> to <cref="Models.Metadata.Header"/>
/// </summary>
private static Models.Metadata.Header ConvertHeaderToInternalModel(Dat item)
{
var header = new Models.Metadata.Header
{
[Models.Metadata.Header.SchemaLocationKey] = item.NoNamespaceSchemaLocation,
};
if (item.Configuration != null)
{
header[Models.Metadata.Header.NameKey] = item.Configuration.DatName;
header[Models.Metadata.Header.ImFolderKey] = item.Configuration.ImFolder;
header[Models.Metadata.Header.DatVersionKey] = item.Configuration.DatVersion;
header[Models.Metadata.Header.SystemKey] = item.Configuration.System;
header[Models.Metadata.Header.ScreenshotsWidthKey] = item.Configuration.ScreenshotsWidth;
header[Models.Metadata.Header.ScreenshotsHeightKey] = item.Configuration.ScreenshotsHeight;
header[Models.Metadata.Header.InfosKey] = item.Configuration.Infos;
header[Models.Metadata.Header.CanOpenKey] = item.Configuration.CanOpen;
header[Models.Metadata.Header.NewDatKey] = item.Configuration.NewDat;
header[Models.Metadata.Header.SearchKey] = item.Configuration.Search;
header[Models.Metadata.Header.RomTitleKey] = item.Configuration.RomTitle;
}
if (item.GUI != null)
{
header[Models.Metadata.Header.ImagesKey] = item.GUI.Images;
}
return header;
}
/// <summary>
/// Convert from <cref="Models.OfflineList.Game"/> to <cref="Models.Metadata.Machine"/>
/// </summary>
private static Models.Metadata.Machine ConvertMachineToInternalModel(Game item)
{
var machine = new Models.Metadata.Machine
{
[Models.Metadata.Machine.ImageNumberKey] = item.ImageNumber,
[Models.Metadata.Machine.ReleaseNumberKey] = item.ReleaseNumber,
[Models.Metadata.Machine.NameKey] = item.Title,
[Models.Metadata.Machine.SaveTypeKey] = item.SaveType,
[Models.Metadata.Machine.PublisherKey] = item.Publisher,
[Models.Metadata.Machine.LocationKey] = item.Location,
[Models.Metadata.Machine.SourceRomKey] = item.SourceRom,
[Models.Metadata.Machine.LanguageKey] = item.Language,
[Models.Metadata.Machine.Im1CRCKey] = item.Im1CRC,
[Models.Metadata.Machine.Im2CRCKey] = item.Im2CRC,
[Models.Metadata.Machine.CommentKey] = item.Comment,
[Models.Metadata.Machine.DuplicateIDKey] = item.DuplicateID,
};
if (item.Files?.RomCRC != null && item.Files.RomCRC.Any())
{
machine[Models.Metadata.Machine.RomKey] = item.Files.RomCRC
.Where(r => r != null)
.Select(romCRC =>
{
var rom = ConvertToInternalModel(romCRC);
rom[Models.Metadata.Rom.SizeKey] = item.RomSize;
return rom;
})
.ToArray();
}
return machine;
}
/// <summary>
/// Convert from <cref="Models.OfflineList.FileRomCRC"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
private static Models.Metadata.Rom ConvertToInternalModel(FileRomCRC item)
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.ExtensionKey] = item.Extension,
[Models.Metadata.Rom.CRCKey] = item.Content,
};
return rom;
}
}
}

View File

@@ -1,153 +0,0 @@
using System.Linq;
using SabreTools.Models.OpenMSX;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class OpenMSX : IModelSerializer<SoftwareDb, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public SoftwareDb? Deserialize(Models.Metadata.MetadataFile? obj)
{
if (obj == null)
return null;
var header = obj.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
var softwareDb = header != null ? ConvertHeaderFromInternalModel(header) : new SoftwareDb();
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Any())
{
softwareDb.Software = machines
.Where(m => m != null)
.Select(ConvertMachineFromInternalModel)
.ToArray();
}
return softwareDb;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Header"/> to <cref="Models.OpenMSX.SoftwareDb"/>
/// </summary>
private static SoftwareDb ConvertHeaderFromInternalModel(Models.Metadata.Header item)
{
var softwareDb = new SoftwareDb
{
Timestamp = item.ReadString(Models.Metadata.Header.TimestampKey),
};
return softwareDb;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Machine"/> to <cref="Models.OpenMSX.Software"/>
/// </summary>
private static Software ConvertMachineFromInternalModel(Models.Metadata.Machine item)
{
var game = new Software
{
Title = item.ReadString(Models.Metadata.Machine.NameKey),
GenMSXID = item.ReadString(Models.Metadata.Machine.GenMSXIDKey),
System = item.ReadString(Models.Metadata.Machine.SystemKey),
Company = item.ReadString(Models.Metadata.Machine.CompanyKey),
Year = item.ReadString(Models.Metadata.Machine.YearKey),
Country = item.ReadString(Models.Metadata.Machine.CountryKey),
};
var dumps = item.Read<Models.Metadata.Dump[]>(Models.Metadata.Machine.DumpKey);
if (dumps != null && dumps.Any())
{
game.Dump = dumps
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
return game;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Dump"/> to <cref="Models.OpenMSX.Dump"/>
/// </summary>
private static Dump ConvertFromInternalModel(Models.Metadata.Dump item)
{
var dump = new Dump();
var original = item.Read<Models.Metadata.Original>(Models.Metadata.Dump.OriginalKey);
if (original != null)
dump.Original = ConvertFromInternalModel(original);
var rom = item.Read<Models.Metadata.Rom>(Models.Metadata.Dump.RomKey);
if (rom != null)
dump.Rom = ConvertRomFromInternalModel(rom);
var megaRom = item.Read<Models.Metadata.Rom>(Models.Metadata.Dump.MegaRomKey);
if (megaRom != null)
dump.Rom = ConvertMegaRomFromInternalModel(megaRom);
var sccPlusCart = item.Read<Models.Metadata.Rom>(Models.Metadata.Dump.SCCPlusCartKey);
if (sccPlusCart != null)
dump.Rom = ConvertSCCPlusCartFromInternalModel(sccPlusCart);
return dump;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.OpenMSX.MegaRom"/>
/// </summary>
private static MegaRom ConvertMegaRomFromInternalModel(Models.Metadata.Rom item)
{
var megaRom = new MegaRom
{
Start = item.ReadString(Models.Metadata.Rom.StartKey),
Type = item.ReadString(Models.Metadata.Rom.TypeKey),
Hash = item.ReadString(Models.Metadata.Rom.SHA1Key),
Remark = item.ReadString(Models.Metadata.Rom.RemarkKey),
};
return megaRom;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Original"/> to <cref="Models.OpenMSX.Original"/>
/// </summary>
private static Original ConvertFromInternalModel(Models.Metadata.Original item)
{
var original = new Original
{
Value = item.ReadString(Models.Metadata.Original.ValueKey),
Content = item.ReadString(Models.Metadata.Original.ContentKey),
};
return original;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.OpenMSX.Rom"/>
/// </summary>
private static Rom ConvertRomFromInternalModel(Models.Metadata.Rom item)
{
var rom = new Rom
{
Start = item.ReadString(Models.Metadata.Rom.StartKey),
Type = item.ReadString(Models.Metadata.Rom.TypeKey),
Hash = item.ReadString(Models.Metadata.Rom.SHA1Key),
Remark = item.ReadString(Models.Metadata.Rom.RemarkKey),
};
return rom;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.OpenMSX.SCCPlusCart"/>
/// </summary>
private static SCCPlusCart ConvertSCCPlusCartFromInternalModel(Models.Metadata.Rom item)
{
var sccPlusCart = new SCCPlusCart
{
Start = item.ReadString(Models.Metadata.Rom.StartKey),
Type = item.ReadString(Models.Metadata.Rom.TypeKey),
Hash = item.ReadString(Models.Metadata.Rom.SHA1Key),
Remark = item.ReadString(Models.Metadata.Rom.RemarkKey),
};
return sccPlusCart;
}
}
}

View File

@@ -1,128 +0,0 @@
using System.Linq;
using SabreTools.Models.OpenMSX;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class OpenMSX : IModelSerializer<SoftwareDb, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.Metadata.MetadataFile? Serialize(SoftwareDb? item)
{
if (item == null)
return null;
var metadataFile = new Models.Metadata.MetadataFile
{
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
};
if (item?.Software != null && item.Software.Any())
{
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.Software
.Where(s => s != null)
.Select(ConvertMachineToInternalModel)
.ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.OpenMSX.SoftwareDb"/> to <cref="Models.Metadata.Header"/>
/// </summary>
public static Models.Metadata.Header ConvertHeaderToInternalModel(SoftwareDb item)
{
var header = new Models.Metadata.Header
{
[Models.Metadata.Header.TimestampKey] = item.Timestamp,
};
return header;
}
/// <summary>
/// Convert from <cref="Models.OpenMSX.Software"/> to <cref="Models.Metadata.Machine"/>
/// </summary>
public static Models.Metadata.Machine ConvertMachineToInternalModel(Software item)
{
var machine = new Models.Metadata.Machine
{
[Models.Metadata.Machine.NameKey] = item.Title,
[Models.Metadata.Machine.GenMSXIDKey] = item.GenMSXID,
[Models.Metadata.Machine.SystemKey] = item.System,
[Models.Metadata.Machine.CompanyKey] = item.Company,
[Models.Metadata.Machine.YearKey] = item.Year,
[Models.Metadata.Machine.CountryKey] = item.Country,
};
if (item.Dump != null && item.Dump.Any())
{
machine[Models.Metadata.Machine.DumpKey] = item.Dump
.Where(d => d != null)
.Select(ConvertToInternalModel)
.ToArray();
}
return machine;
}
/// <summary>
/// Convert from <cref="Models.OpenMSX.Dump"/> to <cref="Models.Metadata.Dump"/>
/// </summary>
public static Models.Metadata.Dump ConvertToInternalModel(Dump item)
{
var dump = new Models.Metadata.Dump();
if (item.Original != null)
dump[Models.Metadata.Dump.OriginalKey] = ConvertToInternalModel(item.Original);
if (item.Rom != null)
{
switch (item.Rom)
{
case Rom rom:
dump[Models.Metadata.Dump.RomKey] = ConvertToInternalModel(rom);
break;
case MegaRom megaRom:
dump[Models.Metadata.Dump.MegaRomKey] = ConvertToInternalModel(megaRom);
break;
case SCCPlusCart sccPlusCart:
dump[Models.Metadata.Dump.SCCPlusCartKey] = ConvertToInternalModel(sccPlusCart);
break;
}
}
return dump;
}
/// <summary>
/// Convert from <cref="Models.OpenMSX.Original"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
public static Models.Metadata.Original ConvertToInternalModel(Original item)
{
var original = new Models.Metadata.Original
{
[Models.Metadata.Original.ValueKey] = item.Value,
[Models.Metadata.Original.ContentKey] = item.Content,
};
return original;
}
/// <summary>
/// Convert from <cref="Models.OpenMSX.RomBase"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
public static Models.Metadata.Rom ConvertToInternalModel(RomBase item)
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.StartKey] = item.Start,
[Models.Metadata.Rom.TypeKey] = item.Type,
[Models.Metadata.Rom.SHA1Key] = item.Hash,
[Models.Metadata.Rom.RemarkKey] = item.Remark,
};
return rom;
}
}
}

View File

@@ -1,122 +0,0 @@
using System;
using System.Linq;
using SabreTools.Models.RomCenter;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class RomCenter : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public MetadataFile? Deserialize(Models.Metadata.MetadataFile? obj)
{
if (obj == null)
return null;
var header = obj.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
var metadataFile = header != null ? ConvertHeaderFromInternalModel(header) : new MetadataFile();
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Any())
{
metadataFile.Games = new Games
{
Rom = machines
.Where(m => m != null)
.SelectMany(ConvertMachineFromInternalModel)
.ToArray()
};
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Header"/> to <cref="Models.RomCenter.MetadataFile"/>
/// </summary>
private static MetadataFile ConvertHeaderFromInternalModel(Models.Metadata.Header item)
{
var metadataFile = new MetadataFile();
if (item.ContainsKey(Models.Metadata.Header.AuthorKey)
|| item.ContainsKey(Models.Metadata.Header.VersionKey)
|| item.ContainsKey(Models.Metadata.Header.EmailKey)
|| item.ContainsKey(Models.Metadata.Header.HomepageKey)
|| item.ContainsKey(Models.Metadata.Header.UrlKey)
|| item.ContainsKey(Models.Metadata.Header.DateKey)
|| item.ContainsKey(Models.Metadata.Header.CommentKey))
{
metadataFile.Credits = new Credits
{
Author = item.ReadString(Models.Metadata.Header.AuthorKey),
Version = item.ReadString(Models.Metadata.Header.VersionKey),
Email = item.ReadString(Models.Metadata.Header.EmailKey),
Homepage = item.ReadString(Models.Metadata.Header.HomepageKey),
Url = item.ReadString(Models.Metadata.Header.UrlKey),
Date = item.ReadString(Models.Metadata.Header.DateKey),
Comment = item.ReadString(Models.Metadata.Header.CommentKey),
};
}
if (item.ContainsKey(Models.Metadata.Header.DatVersionKey)
|| item.ContainsKey(Models.Metadata.Header.PluginKey)
|| item.ContainsKey(Models.Metadata.Header.ForceMergingKey))
{
metadataFile.Dat = new Dat
{
Version = item.ReadString(Models.Metadata.Header.DatVersionKey),
Plugin = item.ReadString(Models.Metadata.Header.PluginKey),
Split = item.ReadString(Models.Metadata.Header.ForceMergingKey) == "split" ? "yes" : "no",
Merge = item.ReadString(Models.Metadata.Header.ForceMergingKey) == "merge" ? "yes" : "no",
};
}
if (item.ContainsKey(Models.Metadata.Header.RefNameKey)
|| item.ContainsKey(Models.Metadata.Header.EmulatorVersionKey))
{
metadataFile.Emulator = new Emulator
{
RefName = item.ReadString(Models.Metadata.Header.RefNameKey),
Version = item.ReadString(Models.Metadata.Header.EmulatorVersionKey),
};
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Machine"/> to an array of <cref="Models.RomCenter.Rom"/>
/// </summary>
private static Rom[] ConvertMachineFromInternalModel(Models.Metadata.Machine item)
{
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
if (roms == null)
return [];
return roms
.Where(r => r != null)
.Select(rom => ConvertFromInternalModel(rom, item))
.ToArray();
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.RomCenter.Rom"/>
/// </summary>
private static Rom ConvertFromInternalModel(Models.Metadata.Rom item, Models.Metadata.Machine parent)
{
var row = new Rom
{
RomName = item.ReadString(Models.Metadata.Rom.NameKey),
RomCRC = item.ReadString(Models.Metadata.Rom.CRCKey),
RomSize = item.ReadString(Models.Metadata.Rom.SizeKey),
MergeName = item.ReadString(Models.Metadata.Rom.MergeKey),
ParentName = parent.ReadString(Models.Metadata.Machine.RomOfKey),
//ParentDescription = parent.ReadString(Models.Metadata.Machine.ParentDescriptionKey), // This is unmappable
GameName = parent.ReadString(Models.Metadata.Machine.NameKey),
GameDescription = parent.ReadString(Models.Metadata.Machine.DescriptionKey),
};
return row;
}
}
}

View File

@@ -1,100 +0,0 @@
using System.Linq;
using SabreTools.Models.RomCenter;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class RomCenter : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{
if (obj == null)
return null;
var metadataFile = new Models.Metadata.MetadataFile
{
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj),
};
if (obj?.Games?.Rom != null && obj.Games.Rom.Any())
{
metadataFile[Models.Metadata.MetadataFile.MachineKey] = obj.Games.Rom
.Where(r => r != null)
.Select(ConvertMachineToInternalModel).ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.RomCenter.MetadataFile"/> to <cref="Models.Metadata.Header"/>
/// </summary>
private static Models.Metadata.Header ConvertHeaderToInternalModel(MetadataFile item)
{
var header = new Models.Metadata.Header();
if (item.Credits != null)
{
header[Models.Metadata.Header.AuthorKey] = item.Credits.Author;
header[Models.Metadata.Header.VersionKey] = item.Credits.Version;
header[Models.Metadata.Header.EmailKey] = item.Credits.Email;
header[Models.Metadata.Header.HomepageKey] = item.Credits.Homepage;
header[Models.Metadata.Header.UrlKey] = item.Credits.Url;
header[Models.Metadata.Header.DateKey] = item.Credits.Date;
header[Models.Metadata.Header.CommentKey] = item.Credits.Comment;
}
if (item.Dat != null)
{
header[Models.Metadata.Header.DatVersionKey] = item.Dat.Version;
header[Models.Metadata.Header.PluginKey] = item.Dat.Plugin;
if (item.Dat.Split == "yes" || item.Dat.Split == "1")
header[Models.Metadata.Header.ForceMergingKey] = "split";
else if (item.Dat.Merge == "yes" || item.Dat.Merge == "1")
header[Models.Metadata.Header.ForceMergingKey] = "merge";
}
if (item.Emulator != null)
{
header[Models.Metadata.Header.RefNameKey] = item.Emulator.RefName;
header[Models.Metadata.Header.EmulatorVersionKey] = item.Emulator.Version;
}
return header;
}
/// <summary>
/// Convert from <cref="Models.RomCenter.Game"/> to <cref="Models.Metadata.Machine"/>
/// </summary>
private static Models.Metadata.Machine ConvertMachineToInternalModel(Rom item)
{
var machine = new Models.Metadata.Machine
{
[Models.Metadata.Machine.RomOfKey] = item.ParentName,
//[Models.Metadata.Machine.ParentDescriptionKey] = item.ParentDescription, // This is unmappable
[Models.Metadata.Machine.NameKey] = item.GameName,
[Models.Metadata.Machine.DescriptionKey] = item.GameDescription,
[Models.Metadata.Machine.RomKey] = new Models.Metadata.Rom[] { ConvertToInternalModel(item) },
};
return machine;
}
/// <summary>
/// Convert from <cref="Models.RomCenter.Rom"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
private static Models.Metadata.Rom ConvertToInternalModel(Rom item)
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.NameKey] = item.RomName,
[Models.Metadata.Rom.CRCKey] = item.RomCRC,
[Models.Metadata.Rom.SizeKey] = item.RomSize,
[Models.Metadata.Rom.MergeKey] = item.MergeName,
};
return rom;
}
}
}

View File

@@ -1,138 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using SabreTools.Models.SeparatedValue;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class SeparatedValue : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public MetadataFile? Deserialize(Models.Metadata.MetadataFile? obj)
{
if (obj == null)
return null;
var header = obj.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
var metadataFile = header != null ? ConvertHeaderFromInternalModel(header) : new MetadataFile();
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Any())
{
metadataFile.Row = machines
.Where(m => m != null)
.SelectMany(ConvertMachineFromInternalModel)
.ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Header"/> to <cref="Models.SeparatedValue.MetadataFile"/>
/// </summary>
private static MetadataFile ConvertHeaderFromInternalModel(Models.Metadata.Header item)
{
var metadataFile = new MetadataFile
{
Header = item.ReadStringArray(Models.Metadata.Header.HeaderKey),
};
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Machine"/> to an array of <cref="Models.SeparatedValue.Row"/>
/// </summary>
private static Row[] ConvertMachineFromInternalModel(Models.Metadata.Machine item)
{
var rowItems = new List<Row>();
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.Machine.RomKey);
if (roms != null && roms.Any())
{
rowItems.AddRange(roms
.Where(r => r != null)
.Select(rom => ConvertFromInternalModel(rom, item)));
}
var disks = item.Read<Models.Metadata.Disk[]>(Models.Metadata.Machine.DiskKey);
if (disks != null && disks.Any())
{
rowItems.AddRange(disks
.Where(d => d != null)
.Select(disk => ConvertFromInternalModel(disk, item)));
}
var media = item.Read<Models.Metadata.Media[]>(Models.Metadata.Machine.MediaKey);
if (media != null && media.Any())
{
rowItems.AddRange(media
.Where(m => m != null)
.Select(medium => ConvertFromInternalModel(medium, item)));
}
return rowItems.ToArray();
}
/// <summary>
/// Convert from <cref="Models.Metadata.Disk"/> to <cref="Models.SeparatedValue.Row"/>
/// </summary>
private static Row ConvertFromInternalModel(Models.Metadata.Disk item, Models.Metadata.Machine parent)
{
var row = new Row
{
GameName = parent.ReadString(Models.Metadata.Machine.NameKey),
Description = parent.ReadString(Models.Metadata.Machine.DescriptionKey),
Type = "disk",
DiskName = item.ReadString(Models.Metadata.Disk.NameKey),
MD5 = item.ReadString(Models.Metadata.Disk.MD5Key),
SHA1 = item.ReadString(Models.Metadata.Disk.SHA1Key),
Status = item.ReadString(Models.Metadata.Disk.StatusKey),
};
return row;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Media"/> to <cref="Models.SeparatedValue.Row"/>
/// </summary>
private static Row ConvertFromInternalModel(Models.Metadata.Media item, Models.Metadata.Machine parent)
{
var row = new Row
{
GameName = parent.ReadString(Models.Metadata.Machine.NameKey),
Description = parent.ReadString(Models.Metadata.Machine.DescriptionKey),
Type = "media",
DiskName = item.ReadString(Models.Metadata.Media.NameKey),
MD5 = item.ReadString(Models.Metadata.Media.MD5Key),
SHA1 = item.ReadString(Models.Metadata.Media.SHA1Key),
SHA256 = item.ReadString(Models.Metadata.Media.SHA256Key),
SpamSum = item.ReadString(Models.Metadata.Media.SpamSumKey),
};
return row;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.SeparatedValue.Row"/>
/// </summary>
private static Row ConvertFromInternalModel(Models.Metadata.Rom item, Models.Metadata.Machine parent)
{
var row = new Row
{
GameName = parent?.ReadString(Models.Metadata.Machine.NameKey),
Description = parent?.ReadString(Models.Metadata.Machine.DescriptionKey),
Type = "rom",
RomName = item.ReadString(Models.Metadata.Rom.NameKey),
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
CRC = item.ReadString(Models.Metadata.Rom.CRCKey),
MD5 = item.ReadString(Models.Metadata.Rom.MD5Key),
SHA1 = item.ReadString(Models.Metadata.Rom.SHA1Key),
SHA256 = item.ReadString(Models.Metadata.Rom.SHA256Key),
SHA384 = item.ReadString(Models.Metadata.Rom.SHA384Key),
SHA512 = item.ReadString(Models.Metadata.Rom.SHA512Key),
SpamSum = item.ReadString(Models.Metadata.Rom.SpamSumKey),
Status = item.ReadString(Models.Metadata.Rom.StatusKey),
};
return row;
}
}
}

View File

@@ -1,116 +0,0 @@
using System.Linq;
using SabreTools.Models.SeparatedValue;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class SeparatedValue : IModelSerializer<MetadataFile, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{
if (obj == null)
return null;
var metadataFile = new Models.Metadata.MetadataFile
{
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj),
};
if (obj?.Row != null && obj.Row.Any())
metadataFile[Models.Metadata.MetadataFile.MachineKey] = obj.Row.Select(ConvertMachineToInternalModel).ToArray();
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.SeparatedValue.MetadataFile"/> to <cref="Models.Metadata.Header"/>
/// </summary>
private static Models.Metadata.Header ConvertHeaderToInternalModel(MetadataFile item)
{
var header = new Models.Metadata.Header
{
[Models.Metadata.Header.HeaderKey] = item.Header,
};
if (item.Row != null && item.Row.Any())
{
var first = item.Row[0];
//header[Models.Metadata.Header.FileNameKey] = first.FileName; // Not possible to map
header[Models.Metadata.Header.NameKey] = first.FileName;
header[Models.Metadata.Header.DescriptionKey] = first.Description;
}
return header;
}
/// <summary>
/// Convert from <cref="Models.SeparatedValue.Row"/> to <cref="Models.Metadata.Machine"/>
/// </summary>
private static Models.Metadata.Machine ConvertMachineToInternalModel(Row item)
{
var machine = new Models.Metadata.Machine
{
[Models.Metadata.Machine.NameKey] = item.GameName,
[Models.Metadata.Machine.DescriptionKey] = item.GameDescription,
};
var datItem = ConvertToInternalModel(item);
switch (datItem)
{
case Models.Metadata.Disk disk:
machine[Models.Metadata.Machine.DiskKey] = new Models.Metadata.Disk[] { disk };
break;
case Models.Metadata.Media media:
machine[Models.Metadata.Machine.MediaKey] = new Models.Metadata.Media[] { media };
break;
case Models.Metadata.Rom rom:
machine[Models.Metadata.Machine.RomKey] = new Models.Metadata.Rom[] { rom };
break;
}
return machine;
}
/// <summary>
/// Convert from <cref="Models.SeparatedValue.Row"/> to <cref="Models.Metadata.DatItem"/>
/// </summary>
private static Models.Metadata.DatItem? ConvertToInternalModel(Row item)
{
return item.Type switch
{
"disk" => new Models.Metadata.Disk
{
[Models.Metadata.Disk.NameKey] = item.DiskName,
[Models.Metadata.Disk.MD5Key] = item.MD5,
[Models.Metadata.Disk.SHA1Key] = item.SHA1,
[Models.Metadata.Disk.StatusKey] = item.Status,
},
"media" => new Models.Metadata.Media
{
[Models.Metadata.Media.NameKey] = item.DiskName,
[Models.Metadata.Media.MD5Key] = item.MD5,
[Models.Metadata.Media.SHA1Key] = item.SHA1,
[Models.Metadata.Media.SHA256Key] = item.SHA256,
[Models.Metadata.Media.SpamSumKey] = item.SpamSum,
},
"rom" => new Models.Metadata.Rom
{
[Models.Metadata.Rom.NameKey] = item.RomName,
[Models.Metadata.Rom.SizeKey] = item.Size,
[Models.Metadata.Rom.CRCKey] = item.CRC,
[Models.Metadata.Rom.MD5Key] = item.MD5,
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
[Models.Metadata.Rom.SHA256Key] = item.SHA256,
[Models.Metadata.Rom.SHA384Key] = item.SHA384,
[Models.Metadata.Rom.SHA512Key] = item.SHA512,
[Models.Metadata.Rom.SpamSumKey] = item.SpamSum,
[Models.Metadata.Rom.StatusKey] = item.Status,
},
_ => null,
};
}
}
}

View File

@@ -1,300 +0,0 @@
using System.Linq;
using SabreTools.Models.SoftwareList;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class SoftwareList : IModelSerializer<Models.SoftwareList.SoftwareList, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.SoftwareList.SoftwareList? Deserialize(Models.Metadata.MetadataFile? obj)
{
if (obj == null)
return null;
var header = obj.Read<Models.Metadata.Header>(Models.Metadata.MetadataFile.HeaderKey);
var metadataFile = header != null ? ConvertHeaderFromInternalModel(header) : new Models.SoftwareList.SoftwareList();
var machines = obj.Read<Models.Metadata.Machine[]>(Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Any())
{
metadataFile.Software = machines
.Where(m => m != null)
.Select(ConvertMachineFromInternalModel)
.ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Header"/> to <cref="Models.SoftwareList.SoftwareList"/>
/// </summary>
private static Models.SoftwareList.SoftwareList ConvertHeaderFromInternalModel(Models.Metadata.Header item)
{
var softwareList = new Models.SoftwareList.SoftwareList
{
Name = item.ReadString(Models.Metadata.Header.NameKey),
Description = item.ReadString(Models.Metadata.Header.DescriptionKey),
Notes = item.ReadString(Models.Metadata.Header.NotesKey),
};
return softwareList;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Machine"/> to <cref="Models.SoftwareList.Software"/>
/// </summary>
private static Software ConvertMachineFromInternalModel(Models.Metadata.Machine item)
{
var software = new Software
{
Name = item.ReadString(Models.Metadata.Machine.NameKey),
CloneOf = item.ReadString(Models.Metadata.Machine.CloneOfKey),
Supported = item.ReadString(Models.Metadata.Machine.SupportedKey),
Description = item.ReadString(Models.Metadata.Machine.DescriptionKey),
Year = item.ReadString(Models.Metadata.Machine.YearKey),
Publisher = item.ReadString(Models.Metadata.Machine.PublisherKey),
Notes = item.ReadString(Models.Metadata.Machine.NotesKey),
};
var infos = item.Read<Models.Metadata.Info[]>(Models.Metadata.Machine.InfoKey);
if (infos != null && infos.Any())
{
software.Info = infos
.Where(i => i != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var sharedFeats = item.Read<Models.Metadata.SharedFeat[]>(Models.Metadata.Machine.SharedFeatKey);
if (sharedFeats != null && sharedFeats.Any())
{
software.SharedFeat = sharedFeats
.Where(s => s != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var parts = item.Read<Models.Metadata.Part[]>(Models.Metadata.Machine.PartKey);
if (parts != null && parts.Any())
{
software.Part = parts
.Where(p => p != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
return software;
}
/// <summary>
/// Convert from <cref="Models.Metadata.DataArea"/> to <cref="Models.SoftwareList.DataArea"/>
/// </summary>
private static DataArea ConvertFromInternalModel(Models.Metadata.DataArea item)
{
var dataArea = new DataArea
{
Name = item.ReadString(Models.Metadata.DataArea.NameKey),
Size = item.ReadString(Models.Metadata.DataArea.SizeKey),
Width = item.ReadString(Models.Metadata.DataArea.WidthKey),
Endianness = item.ReadString(Models.Metadata.DataArea.EndiannessKey),
};
var roms = item.Read<Models.Metadata.Rom[]>(Models.Metadata.DataArea.RomKey);
if (roms != null && roms.Any())
{
dataArea.Rom = roms
.Where(r => r != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
return dataArea;
}
/// <summary>
/// Convert from <cref="Models.Metadata.DipSwitch"/> to <cref="Models.SoftwareList.DipSwitch"/>
/// </summary>
private static DipSwitch ConvertFromInternalModel(Models.Metadata.DipSwitch item)
{
var dipSwitch = new DipSwitch
{
Name = item.ReadString(Models.Metadata.DipSwitch.NameKey),
Tag = item.ReadString(Models.Metadata.DipSwitch.TagKey),
Mask = item.ReadString(Models.Metadata.DipSwitch.MaskKey),
};
var dipValues = item.Read<Models.Metadata.DipValue[]>(Models.Metadata.DipSwitch.DipValueKey);
if (dipValues != null && dipValues.Any())
{
dipSwitch.DipValue = dipValues
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
return dipSwitch;
}
/// <summary>
/// Convert from <cref="Models.Metadata.DipValue"/> to <cref="Models.SoftwareList.DipValue"/>
/// </summary>
private static DipValue ConvertFromInternalModel(Models.Metadata.DipValue item)
{
var dipValue = new DipValue
{
Name = item.ReadString(Models.Metadata.DipValue.NameKey),
Value = item.ReadString(Models.Metadata.DipValue.ValueKey),
Default = item.ReadString(Models.Metadata.DipValue.DefaultKey),
};
return dipValue;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Disk"/> to <cref="Models.SoftwareList.Disk"/>
/// </summary>
private static Disk ConvertFromInternalModel(Models.Metadata.Disk item)
{
var disk = new Disk
{
Name = item.ReadString(Models.Metadata.Disk.NameKey),
MD5 = item.ReadString(Models.Metadata.Disk.MD5Key),
SHA1 = item.ReadString(Models.Metadata.Disk.SHA1Key),
Status = item.ReadString(Models.Metadata.Disk.StatusKey),
Writeable = item.ReadString(Models.Metadata.Disk.WritableKey),
};
return disk;
}
/// <summary>
/// Convert from <cref="Models.Metadata.DiskArea"/> to <cref="Models.SoftwareList.DiskArea"/>
/// </summary>
private static DiskArea ConvertFromInternalModel(Models.Metadata.DiskArea item)
{
var diskArea = new DiskArea
{
Name = item.ReadString(Models.Metadata.DiskArea.NameKey),
};
var disks = item.Read<Models.Metadata.Disk[]>(Models.Metadata.DiskArea.DiskKey);
if (disks != null && disks.Any())
{
diskArea.Disk = disks
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
return diskArea;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Feature"/> to <cref="Models.SoftwareList.Feature"/>
/// </summary>
private static Feature ConvertFromInternalModel(Models.Metadata.Feature item)
{
var feature = new Feature
{
Name = item.ReadString(Models.Metadata.Feature.NameKey),
Value = item.ReadString(Models.Metadata.Feature.ValueKey),
};
return feature;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Info"/> to <cref="Models.SoftwareList.Info"/>
/// </summary>
private static Info ConvertFromInternalModel(Models.Metadata.Info item)
{
var info = new Info
{
Name = item.ReadString(Models.Metadata.Info.NameKey),
Value = item.ReadString(Models.Metadata.Info.ValueKey),
};
return info;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Part"/> to <cref="Models.SoftwareList.Part"/>
/// </summary>
private static Part ConvertFromInternalModel(Models.Metadata.Part item)
{
var part = new Part
{
Name = item.ReadString(Models.Metadata.Part.NameKey),
Interface = item.ReadString(Models.Metadata.Part.InterfaceKey),
};
var features = item.Read<Models.Metadata.Feature[]>(Models.Metadata.Part.FeatureKey);
if (features != null && features.Any())
{
part.Feature = features
.Where(f => f != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var dataAreas = item.Read<Models.Metadata.DataArea[]>(Models.Metadata.Part.DataAreaKey);
if (dataAreas != null && dataAreas.Any())
{
part.DataArea = dataAreas
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var diskAreas = item.Read<Models.Metadata.DiskArea[]>(Models.Metadata.Part.DiskAreaKey);
if (diskAreas != null && diskAreas.Any())
{
part.DiskArea = diskAreas
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
var dipSwitches = item.Read<Models.Metadata.DipSwitch[]>(Models.Metadata.Part.DipSwitchKey);
if (dipSwitches != null && dipSwitches.Any())
{
part.DipSwitch = dipSwitches
.Where(d => d != null)
.Select(ConvertFromInternalModel)
.ToArray();
}
return part;
}
/// <summary>
/// Convert from <cref="Models.Metadata.Rom"/> to <cref="Models.SoftwareList.Rom"/>
/// </summary>
private static Rom ConvertFromInternalModel(Models.Metadata.Rom item)
{
var rom = new Rom
{
Name = item.ReadString(Models.Metadata.Rom.NameKey),
Size = item.ReadString(Models.Metadata.Rom.SizeKey),
Length = item.ReadString(Models.Metadata.Rom.LengthKey),
CRC = item.ReadString(Models.Metadata.Rom.CRCKey),
SHA1 = item.ReadString(Models.Metadata.Rom.SHA1Key),
Offset = item.ReadString(Models.Metadata.Rom.OffsetKey),
Value = item.ReadString(Models.Metadata.Rom.ValueKey),
Status = item.ReadString(Models.Metadata.Rom.StatusKey),
LoadFlag = item.ReadString(Models.Metadata.Rom.LoadFlagKey),
};
return rom;
}
/// <summary>
/// Convert from <cref="Models.Metadata.SharedFeat"/> to <cref="Models.SoftwareList.SharedFeat"/>
/// </summary>
private static SharedFeat ConvertFromInternalModel(Models.Metadata.SharedFeat item)
{
var sharedFeat = new SharedFeat
{
Name = item.ReadString(Models.Metadata.SharedFeat.NameKey),
Value = item.ReadString(Models.Metadata.SharedFeat.ValueKey),
};
return sharedFeat;
}
}
}

View File

@@ -1,241 +0,0 @@
using System.Linq;
using SabreTools.Models.SoftwareList;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
public partial class SoftwareList : IModelSerializer<Models.SoftwareList.SoftwareList, Models.Metadata.MetadataFile>
{
/// <inheritdoc/>
public Models.Metadata.MetadataFile? Serialize(Models.SoftwareList.SoftwareList? item)
{
if (item == null)
return null;
var metadataFile = new Models.Metadata.MetadataFile
{
[Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
};
if (item?.Software != null && item.Software.Any())
{
metadataFile[Models.Metadata.MetadataFile.MachineKey] = item.Software
.Where(s => s != null)
.Select(ConvertMachineToInternalModel)
.ToArray();
}
return metadataFile;
}
/// <summary>
/// Convert from <cref="Models.SoftwareList.SoftwareList"/> to <cref="Models.Metadata.Header"/>
/// </summary>
private static Models.Metadata.Header ConvertHeaderToInternalModel(Models.SoftwareList.SoftwareList item)
{
var header = new Models.Metadata.Header
{
[Models.Metadata.Header.NameKey] = item.Name,
[Models.Metadata.Header.DescriptionKey] = item.Description,
[Models.Metadata.Header.NotesKey] = item.Notes,
};
return header;
}
/// <summary>
/// Convert from <cref="Models.SoftwareList.Software"/> to <cref="Models.Metadata.Machine"/>
/// </summary>
private static Models.Metadata.Machine ConvertMachineToInternalModel(Software item)
{
var machine = new Models.Metadata.Machine
{
[Models.Metadata.Machine.NameKey] = item.Name,
[Models.Metadata.Machine.CloneOfKey] = item.CloneOf,
[Models.Metadata.Machine.SupportedKey] = item.Supported,
[Models.Metadata.Machine.DescriptionKey] = item.Description,
[Models.Metadata.Machine.YearKey] = item.Year,
[Models.Metadata.Machine.PublisherKey] = item.Publisher,
[Models.Metadata.Machine.NotesKey] = item.Notes,
};
if (item.Info != null && item.Info.Any())
machine[Models.Metadata.Machine.InfoKey] = item.Info.Select(ConvertToInternalModel).ToArray();
if (item.SharedFeat != null && item.SharedFeat.Any())
machine[Models.Metadata.Machine.SharedFeatKey] = item.SharedFeat.Select(ConvertToInternalModel).ToArray();
if (item.Part != null && item.Part.Any())
machine[Models.Metadata.Machine.PartKey] = item.Part.Select(ConvertToInternalModel).ToArray();
return machine;
}
/// <summary>
/// Convert from <cref="Models.SoftwareList.DataArea"/> to <cref="Models.Metadata.DataArea"/>
/// </summary>
private static Models.Metadata.DataArea ConvertToInternalModel(DataArea item)
{
var dataArea = new Models.Metadata.DataArea
{
[Models.Metadata.DataArea.NameKey] = item.Name,
[Models.Metadata.DataArea.SizeKey] = item.Size,
[Models.Metadata.DataArea.WidthKey] = item.Width,
[Models.Metadata.DataArea.EndiannessKey] = item.Endianness,
};
if (item.Rom != null && item.Rom.Any())
dataArea[Models.Metadata.DataArea.RomKey] = item.Rom.Select(ConvertToInternalModel).ToArray();
return dataArea;
}
/// <summary>
/// Convert from <cref="Models.SoftwareList.DipSwitch"/> to <cref="Models.Metadata.DipSwitch"/>
/// </summary>
private static Models.Metadata.DipSwitch ConvertToInternalModel(DipSwitch item)
{
var dipSwitch = new Models.Metadata.DipSwitch
{
[Models.Metadata.DipSwitch.NameKey] = item.Name,
[Models.Metadata.DipSwitch.TagKey] = item.Tag,
[Models.Metadata.DipSwitch.MaskKey] = item.Mask,
};
if (item.DipValue != null && item.DipValue.Any())
dipSwitch[Models.Metadata.DipSwitch.DipValueKey] = item.DipValue.Select(ConvertToInternalModel).ToArray();
return dipSwitch;
}
/// <summary>
/// Convert from <cref="Models.SoftwareList.DipValue"/> to <cref="Models.Metadata.DipValue"/>
/// </summary>
private static Models.Metadata.DipValue ConvertToInternalModel(DipValue item)
{
var dipValue = new Models.Metadata.DipValue
{
[Models.Metadata.DipValue.NameKey] = item.Name,
[Models.Metadata.DipValue.ValueKey] = item.Value,
[Models.Metadata.DipValue.DefaultKey] = item.Default,
};
return dipValue;
}
/// <summary>
/// Convert from <cref="Models.SoftwareList.Disk"/> to <cref="Models.Metadata.Disk"/>
/// </summary>
private static Models.Metadata.Disk ConvertToInternalModel(Disk item)
{
var disk = new Models.Metadata.Disk
{
[Models.Metadata.Disk.NameKey] = item.Name,
[Models.Metadata.Disk.MD5Key] = item.MD5,
[Models.Metadata.Disk.SHA1Key] = item.SHA1,
[Models.Metadata.Disk.StatusKey] = item.Status,
[Models.Metadata.Disk.WritableKey] = item.Writeable,
};
return disk;
}
/// <summary>
/// Convert from <cref="Models.SoftwareList.DiskArea"/> to <cref="Models.Metadata.DiskArea"/>
/// </summary>
private static Models.Metadata.DiskArea ConvertToInternalModel(DiskArea item)
{
var diskArea = new Models.Metadata.DiskArea
{
[Models.Metadata.DiskArea.NameKey] = item.Name,
};
if (item.Disk != null && item.Disk.Any())
diskArea[Models.Metadata.DiskArea.DiskKey] = item.Disk.Select(ConvertToInternalModel).ToArray();
return diskArea;
}
/// <summary>
/// Convert from <cref="Models.SoftwareList.Feature"/> to <cref="Models.Metadata.Feature"/>
/// </summary>
private static Models.Metadata.Feature ConvertToInternalModel(Feature item)
{
var feature = new Models.Metadata.Feature
{
[Models.Metadata.Feature.NameKey] = item.Name,
[Models.Metadata.Feature.ValueKey] = item.Value,
};
return feature;
}
/// <summary>
/// Convert from <cref="Models.SoftwareList.Info"/> to <cref="Models.Metadata.Info"/>
/// </summary>
private static Models.Metadata.Info ConvertToInternalModel(Info item)
{
var info = new Models.Metadata.Info
{
[Models.Metadata.Info.NameKey] = item.Name,
[Models.Metadata.Info.ValueKey] = item.Value,
};
return info;
}
/// <summary>
/// Convert from <cref="Models.SoftwareList.Part"/> to <cref="Models.Metadata.Part"/>
/// </summary>
private static Models.Metadata.Part ConvertToInternalModel(Part item)
{
var part = new Models.Metadata.Part
{
[Models.Metadata.Part.NameKey] = item.Name,
[Models.Metadata.Part.InterfaceKey] = item.Interface,
};
if (item.Feature != null && item.Feature.Any())
part[Models.Metadata.Part.FeatureKey] = item.Feature.Select(ConvertToInternalModel).ToArray();
if (item.DataArea != null && item.DataArea.Any())
part[Models.Metadata.Part.DataAreaKey] = item.DataArea.Select(ConvertToInternalModel).ToArray();
if (item.DiskArea != null && item.DiskArea.Any())
part[Models.Metadata.Part.DiskAreaKey] = item.DiskArea.Select(ConvertToInternalModel).ToArray();
if (item.DipSwitch != null && item.DipSwitch.Any())
part[Models.Metadata.Part.DipSwitchKey] = item.DipSwitch.Select(ConvertToInternalModel).ToArray();
return part;
}
/// <summary>
/// Convert from <cref="Models.SoftwareList.Rom"/> to <cref="Models.Metadata.Rom"/>
/// </summary>
private static Models.Metadata.Rom ConvertToInternalModel(Rom item)
{
var rom = new Models.Metadata.Rom
{
[Models.Metadata.Rom.NameKey] = item.Name,
[Models.Metadata.Rom.SizeKey] = item.Size,
[Models.Metadata.Rom.LengthKey] = item.Length,
[Models.Metadata.Rom.CRCKey] = item.CRC,
[Models.Metadata.Rom.SHA1Key] = item.SHA1,
[Models.Metadata.Rom.OffsetKey] = item.Offset,
[Models.Metadata.Rom.ValueKey] = item.Value,
[Models.Metadata.Rom.StatusKey] = item.Status,
[Models.Metadata.Rom.LoadFlagKey] = item.LoadFlag,
};
return rom;
}
/// <summary>
/// Convert from <cref="Models.SoftwareList.SharedFeat"/> to <cref="Models.Metadata.SharedFeat"/>
/// </summary>
private static Models.Metadata.SharedFeat ConvertToInternalModel(SharedFeat item)
{
var sharedFeat = new Models.Metadata.SharedFeat
{
[Models.Metadata.SharedFeat.NameKey] = item.Name,
[Models.Metadata.SharedFeat.ValueKey] = item.Value,
};
return sharedFeat;
}
}
}

View File

@@ -1,13 +0,0 @@
namespace SabreTools.Serialization
{
public enum Hash
{
CRC,
MD5,
SHA1,
SHA256,
SHA384,
SHA512,
SpamSum,
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,56 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net20;net35;net40;net452;net462;net472;net48;netcoreapp3.1;net5.0;net6.0;net7.0;net8.0;net9.0;net10.0</TargetFrameworks>
<OutputType>Exe</OutputType>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>3.0.1</Version>
</PropertyGroup>
<!-- Support All Frameworks -->
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net2`)) OR $(TargetFramework.StartsWith(`net3`)) OR $(TargetFramework.StartsWith(`net4`))">
<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith(`netcoreapp`)) OR $(TargetFramework.StartsWith(`net5`))">
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith(`net6`)) OR $(TargetFramework.StartsWith(`net7`)) OR $(TargetFramework.StartsWith(`net8`)) OR $(TargetFramework.StartsWith(`net9`)) OR $(TargetFramework.StartsWith(`net10`))">
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;linux-x64;linux-arm64;osx-x64;osx-arm64</RuntimeIdentifiers>
</PropertyGroup>
<PropertyGroup Condition="$(RuntimeIdentifier.StartsWith(`osx-arm`))">
<TargetFrameworks>net6.0;net7.0;net8.0;net9.0;net10.0</TargetFrameworks>
</PropertyGroup>
<!-- These are needed for dealing with native Windows DLLs -->
<ItemGroup Condition="'$(RuntimeIdentifier)'=='win-x86'">
<ContentWithTargetPath Include="..\runtimes\win-x86\native\StormLib.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
<TargetPath>StormLib.dll</TargetPath>
</ContentWithTargetPath>
</ItemGroup>
<ItemGroup Condition="'$(RuntimeIdentifier)'=='win-x64'">
<ContentWithTargetPath Include="..\runtimes\win-x64\native\StormLib.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
<TargetPath>StormLib.dll</TargetPath>
</ContentWithTargetPath>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SabreTools.Wrappers\SabreTools.Wrappers.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.CommandLine" Version="[1.4.0]" />
<PackageReference Include="SabreTools.IO" Version="[2.1.0]" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="10.0.8" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,194 @@
using System;
using System.IO;
using SabreTools.CommandLine;
using SabreTools.CommandLine.Inputs;
using SabreTools.IO.Extensions;
using SabreTools.Numerics.Extensions;
using SabreTools.Wrappers;
namespace ExtractionTool.Features
{
internal sealed class MainFeature : Feature
{
#region Feature Definition
public const string DisplayName = "main";
/// <remarks>Flags are unused</remarks>
private static readonly string[] _flags = [];
/// <remarks>Description is unused</remarks>
private const string _description = "";
#endregion
#region Inputs
private const string _debugName = "debug";
internal readonly FlagInput DebugInput = new(_debugName, ["-d", "--debug"], "Enable debug mode");
private const string _outputPathName = "output-path";
internal readonly StringInput OutputPathInput = new(_outputPathName, ["-o", "--outdir"], "Set output path for extraction (required)");
#endregion
#region Properties
/// <summary>
/// Enable debug output for relevant operations
/// </summary>
public bool Debug { get; private set; }
/// <summary>
/// Output path for archive extraction
/// </summary>
public string OutputPath { get; private set; } = string.Empty;
#endregion
public MainFeature()
: base(DisplayName, _flags, _description)
{
RequiresInputs = true;
Add(DebugInput);
Add(OutputPathInput);
}
/// <inheritdoc/>
public override bool Execute()
{
// Get the options from the arguments
Debug = GetBoolean(_debugName);
OutputPath = GetString(_outputPathName) ?? string.Empty;
// Validate the output path
if (!ValidateExtractionPath())
return false;
// Loop through the input paths
for (int i = 0; i < Inputs.Count; i++)
{
string arg = Inputs[i];
ExtractPath(arg);
}
return true;
}
/// <inheritdoc/>
public override bool VerifyInputs() => Inputs.Count > 0;
/// <summary>
/// Wrapper to extract data for a single path
/// </summary>
/// <param name="path">File or directory path</param>
private void ExtractPath(string path)
{
// Normalize by getting the full path
path = Path.GetFullPath(path);
Console.WriteLine($"Checking possible path: {path}");
// Check if the file or directory exists
if (File.Exists(path))
{
ExtractFile(path);
}
else if (Directory.Exists(path))
{
foreach (string file in path.SafeEnumerateFiles("*", SearchOption.AllDirectories))
{
ExtractFile(file);
}
}
else
{
Console.WriteLine($"{path} does not exist, skipping...");
}
}
/// <summary>
/// Print information for a single file, if possible
/// </summary>
/// <param name="path">File path</param>
private void ExtractFile(string file)
{
try
{
Console.WriteLine($"Attempting to extract all files from {file}");
using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
// Read the first 32 bytes
byte[] magic = stream.PeekBytes(32);
// Get the file type
string extension = Path.GetExtension(file).TrimStart('.');
WrapperType ft = WrapperFactory.GetFileType(magic ?? [], extension);
// Print out the file format
Console.WriteLine($"File format found: {ft}");
// Setup the wrapper to extract
var wrapper = WrapperFactory.CreateWrapper(ft, stream);
// If we don't have a wrapper
if (wrapper is null)
{
Console.WriteLine($"Either {ft} is not supported or something went wrong during parsing!");
Console.WriteLine();
return;
}
// If the wrapper is not extractable
if (wrapper is not IExtractable extractable)
{
Console.WriteLine($"{ft} is not supported for extraction!");
Console.WriteLine();
return;
}
// Print the preamble
Console.WriteLine($"Attempting to extract from '{wrapper.Description()}'");
Console.WriteLine();
// Attempt the extraction
Directory.CreateDirectory(OutputPath);
extractable.Extract(OutputPath, Debug);
}
catch (Exception ex)
{
Console.WriteLine(Debug ? ex : "[Exception opening file, please try again]");
Console.WriteLine();
}
}
/// <summary>
/// Validate the extraction path
/// </summary>
private bool ValidateExtractionPath()
{
// Null or empty output path
if (string.IsNullOrEmpty(OutputPath))
{
Console.WriteLine("Output directory required for extraction!");
Console.WriteLine();
return false;
}
// Malformed output path or invalid location
try
{
OutputPath = Path.GetFullPath(OutputPath);
Directory.CreateDirectory(OutputPath);
}
catch
{
Console.WriteLine("Output directory could not be created!");
Console.WriteLine();
return false;
}
return true;
}
}
}

79
ExtractionTool/Program.cs Normal file
View File

@@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using ExtractionTool.Features;
using SabreTools.CommandLine;
using SabreTools.CommandLine.Features;
namespace ExtractionTool
{
public static class Program
{
public static void Main(string[] args)
{
#if NET462_OR_GREATER || NETCOREAPP
// Register the codepages
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
#endif
// Create the command set
var mainFeature = new MainFeature();
var commandSet = CreateCommands(mainFeature);
// If we have no args, show the help and quit
if (args is null || args.Length == 0)
{
commandSet.OutputAllHelp();
return;
}
// Cache the first argument and starting index
string featureName = args[0];
// Try processing the standalone arguments
var topLevel = commandSet.GetTopLevel(featureName);
switch (topLevel)
{
// Standalone Options
case Help help: help.ProcessArgs(args, 0, commandSet); return;
// Default Behavior
default:
if (!mainFeature.ProcessArgs(args, 0))
{
commandSet.OutputAllHelp();
return;
}
else if (!mainFeature.VerifyInputs())
{
Console.Error.WriteLine("At least one input is required");
commandSet.OutputAllHelp();
return;
}
mainFeature.Execute();
break;
}
}
/// <summary>
/// Create the command set for the program
/// </summary>
private static CommandSet CreateCommands(MainFeature mainFeature)
{
List<string> header = [
"Extraction Tool",
string.Empty,
"ExtractionTool <options> file|directory ...",
string.Empty,
];
var commandSet = new CommandSet(header);
commandSet.Add(new Help(["-?", "-h", "--help"]));
commandSet.Add(mainFeature.DebugInput);
commandSet.Add(mainFeature.OutputPathInput);
return commandSet;
}
}
}

View File

@@ -1,7 +0,0 @@
namespace SabreTools.Serialization.Files
{
public partial class ArchiveDotOrg : XmlFile<Models.ArchiveDotOrg.Files>
{
// All serialization logic is in the base class
}
}

View File

@@ -1,7 +0,0 @@
namespace SabreTools.Serialization.Files
{
public partial class ArchiveDotOrg : XmlFile<Models.ArchiveDotOrg.Files>
{
// All serialization logic is in the base class
}
}

View File

@@ -1,17 +0,0 @@
using SabreTools.Models.AttractMode;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class AttractMode : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
public MetadataFile? Deserialize(string? path)
{
using (var stream = PathProcessor.OpenStream(path))
{
return new Streams.AttractMode().Deserialize(stream);
}
}
}
}

View File

@@ -1,24 +0,0 @@
using System.IO;
using SabreTools.Models.AttractMode;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class AttractMode : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
public bool Serialize(MetadataFile? obj, string? path)
{
if (string.IsNullOrEmpty(path))
return false;
using var stream = new Streams.AttractMode().Serialize(obj);
if (stream == null)
return false;
using var fs = File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -1,20 +0,0 @@
using SabreTools.Models.ClrMamePro;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class ClrMamePro : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
public MetadataFile? Deserialize(string? path) => Deserialize(path, true);
/// <inheritdoc/>
public MetadataFile? Deserialize(string? path, bool quotes)
{
using (var stream = PathProcessor.OpenStream(path))
{
return new Streams.ClrMamePro().Deserialize(stream, quotes);
}
}
}
}

View File

@@ -1,27 +0,0 @@
using System.IO;
using SabreTools.Models.ClrMamePro;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class ClrMamePro : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
public bool Serialize(MetadataFile? obj, string? path) => Serialize(obj, path, true);
/// <inheritdoc cref="Serialize(MetadataFile, string)"/>
public bool Serialize(MetadataFile? obj, string? path, bool quotes)
{
if (string.IsNullOrEmpty(path))
return false;
using var stream = new Streams.ClrMamePro().Serialize(obj, quotes);
if (stream == null)
return false;
using var fs = File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -1,23 +0,0 @@
using System.IO;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class CueSheet : IFileSerializer<Models.CueSheets.CueSheet>
{
/// <inheritdoc/>
public bool Serialize(Models.CueSheets.CueSheet? obj, string? path)
{
if (string.IsNullOrEmpty(path))
return false;
using var stream = new Streams.CueSheet().Serialize(obj);
if (stream == null)
return false;
using var fs = File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -1,17 +0,0 @@
using SabreTools.Models.DosCenter;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class DosCenter : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
public MetadataFile? Deserialize(string? path)
{
using (var stream = PathProcessor.OpenStream(path))
{
return new Streams.DosCenter().Deserialize(stream);
}
}
}
}

View File

@@ -1,23 +0,0 @@
using SabreTools.Models.DosCenter;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class DosCenter : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
public bool Serialize(MetadataFile? obj, string? path)
{
if (string.IsNullOrEmpty(path))
return false;
using var stream = new Streams.DosCenter().Serialize(obj);
if (stream == null)
return false;
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -1,17 +0,0 @@
using SabreTools.Models.EverdriveSMDB;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class EverdriveSMDB : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
public MetadataFile? Deserialize(string? path)
{
using (var stream = PathProcessor.OpenStream(path))
{
return new Streams.EverdriveSMDB().Deserialize(stream);
}
}
}
}

View File

@@ -1,23 +0,0 @@
using SabreTools.Models.EverdriveSMDB;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class EverdriveSMDB : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
public bool Serialize(MetadataFile? obj, string? path)
{
if (string.IsNullOrEmpty(path))
return false;
using var stream = new Streams.EverdriveSMDB().Serialize(obj);
if (stream == null)
return false;
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -1,19 +0,0 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class Hashfile : IFileSerializer<Models.Hashfile.Hashfile>
{
/// <inheritdoc/>
public Models.Hashfile.Hashfile? Deserialize(string? path) => Deserialize(path, Hash.CRC);
/// <inheritdoc/>
public Models.Hashfile.Hashfile? Deserialize(string? path, Hash hash)
{
using (var stream = PathProcessor.OpenStream(path))
{
return new Streams.Hashfile().Deserialize(stream, hash);
}
}
}
}

View File

@@ -1,25 +0,0 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class Hashfile : IFileSerializer<Models.Hashfile.Hashfile>
{
/// <inheritdoc/>
public bool Serialize(Models.Hashfile.Hashfile? obj, string? path) => Serialize(obj, path, Hash.CRC);
/// <inheritdoc/>
public bool Serialize(Models.Hashfile.Hashfile? obj, string? path, Hash hash)
{
if (string.IsNullOrEmpty(path))
return false;
using var stream = new Streams.Hashfile().Serialize(obj, hash);
if (stream == null)
return false;
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -1,16 +0,0 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class IRD : IFileSerializer<Models.IRD.File>
{
/// <inheritdoc/>
public Models.IRD.File? Deserialize(string? path)
{
using (var stream = PathProcessor.OpenStream(path))
{
return new Streams.IRD().Deserialize(stream);
}
}
}
}

View File

@@ -1,22 +0,0 @@
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class IRD : IFileSerializer<Models.IRD.File>
{
/// <inheritdoc/>
public bool Serialize(Models.IRD.File? obj, string? path)
{
if (string.IsNullOrEmpty(path))
return false;
using var stream = new Streams.IRD().Serialize(obj);
if (stream == null)
return false;
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -1,17 +0,0 @@
using SabreTools.Models.Listrom;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class Listrom : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
public MetadataFile? Deserialize(string? path)
{
using (var stream = PathProcessor.OpenStream(path))
{
return new Streams.Listrom().Deserialize(stream);
}
}
}
}

View File

@@ -1,23 +0,0 @@
using SabreTools.Models.Listrom;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class Listrom : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
public bool Serialize(MetadataFile? obj, string? path)
{
if (string.IsNullOrEmpty(path))
return false;
using var stream = new Streams.Listrom().Serialize(obj);
if (stream == null)
return false;
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -1,7 +0,0 @@
namespace SabreTools.Serialization.Files
{
public partial class Listxml : XmlFile<Models.Listxml.Mame>
{
// All serialization logic is in the base class
}
}

View File

@@ -1,7 +0,0 @@
namespace SabreTools.Serialization.Files
{
public partial class Listxml : XmlFile<Models.Listxml.Mame>
{
// All serialization logic is in the base class
}
}

View File

@@ -1,7 +0,0 @@
namespace SabreTools.Serialization.Files
{
public partial class Logiqx : XmlFile<Models.Logiqx.Datafile>
{
// All serialization logic is in the base class
}
}

View File

@@ -1,11 +0,0 @@
using SabreTools.Models.Logiqx;
namespace SabreTools.Serialization.Files
{
public partial class Logiqx : XmlFile<Datafile>
{
/// <inheritdoc cref="Serialize(Datafile, string, string?, string?, string?, string?)" />
public bool SerializeToFileWithDocType(Datafile obj, string path)
=> Serialize(obj, path, Serialization.Logiqx.DocTypeName, Serialization.Logiqx.DocTypePubId, Serialization.Logiqx.DocTypeSysId, Serialization.Logiqx.DocTypeSysId);
}
}

View File

@@ -1,7 +0,0 @@
namespace SabreTools.Serialization.Files
{
public partial class M1 : XmlFile<Models.Listxml.M1>
{
// All serialization logic is in the base class
}
}

View File

@@ -1,7 +0,0 @@
namespace SabreTools.Serialization.Files
{
public partial class M1 : XmlFile<Models.Listxml.M1>
{
// All serialization logic is in the base class
}
}

View File

@@ -1,7 +0,0 @@
namespace SabreTools.Serialization.Files
{
public partial class OfflineList : XmlFile<Models.OfflineList.Dat>
{
// All serialization logic is in the base class
}
}

View File

@@ -1,7 +0,0 @@
namespace SabreTools.Serialization.Files
{
public partial class OfflineList : XmlFile<Models.OfflineList.Dat>
{
// All serialization logic is in the base class
}
}

View File

@@ -1,7 +0,0 @@
namespace SabreTools.Serialization.Files
{
public partial class OpenMSX : XmlFile<Models.OpenMSX.SoftwareDb>
{
// All serialization logic is in the base class
}
}

View File

@@ -1,11 +0,0 @@
using SabreTools.Models.OpenMSX;
namespace SabreTools.Serialization.Files
{
public partial class OpenMSX : XmlFile<SoftwareDb>
{
/// <inheritdoc cref="Serialize(SoftwareDb, string, string?, string?, string?, string?)" />
public bool SerializeToFileWithDocType(SoftwareDb obj, string path)
=> Serialize(obj, path, Serialization.OpenMSX.DocTypeName, Serialization.OpenMSX.DocTypePubId, Serialization.OpenMSX.DocTypeSysId, Serialization.OpenMSX.DocTypeSysId);
}
}

View File

@@ -1,17 +0,0 @@
using SabreTools.Models.PIC;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class PIC : IFileSerializer<DiscInformation>
{
/// <inheritdoc/>
public DiscInformation? Deserialize(string? path)
{
using (var stream = PathProcessor.OpenStream(path))
{
return new Streams.PIC().Deserialize(stream);
}
}
}
}

View File

@@ -1,23 +0,0 @@
using SabreTools.Models.PIC;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class PIC : IFileSerializer<DiscInformation>
{
/// <inheritdoc/>
public bool Serialize(DiscInformation? obj, string? path)
{
if (string.IsNullOrEmpty(path))
return false;
using var stream = new Streams.PIC().Serialize(obj);
if (stream == null)
return false;
using var fs = System.IO.File.OpenWrite(path);
stream.CopyTo(fs);
return true;
}
}
}

View File

@@ -1,17 +0,0 @@
using SabreTools.Models.RomCenter;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.Files
{
public partial class RomCenter : IFileSerializer<MetadataFile>
{
/// <inheritdoc/>
public MetadataFile? Deserialize(string? path)
{
using (var stream = PathProcessor.OpenStream(path))
{
return new Streams.RomCenter().Deserialize(stream);
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More