Compare commits

...

971 Commits
1.4.3 ... 2.2.1

Author SHA1 Message Date
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
1704 changed files with 150499 additions and 23028 deletions

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

View File

@@ -1,43 +0,0 @@
name: Nuget Pack
on:
push:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
- name: Pack
run: dotnet pack
- name: Upload build
uses: actions/upload-artifact@v4
with:
name: 'Nuget Package'
path: 'SabreTools.Serialization/bin/Release/*.nupkg'
- name: Upload to rolling
uses: ncipollo/release-action@v1.14.0
with:
allowUpdates: True
artifacts: 'SabreTools.Serialization/bin/Release/*.nupkg'
body: 'Last built commit: ${{ github.sha }}'
name: 'Rolling Release'
prerelease: True
replacesArtifacts: True
tag: "rolling"
updateOnlyUnreleased: True

View File

@@ -3,15 +3,21 @@ name: Build PR
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Build
run: dotnet build
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

328
.gitignore vendored
View File

@@ -1,15 +1,7 @@
*.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
*.suo
@@ -17,6 +9,9 @@ nupkg/
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
@@ -24,15 +19,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

@@ -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>2.2.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="..\SabreTools.Serialization\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="..\SabreTools.Serialization\runtimes\win-x64\native\StormLib.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
<TargetPath>StormLib.dll</TargetPath>
</ContentWithTargetPath>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SabreTools.Serialization\SabreTools.Serialization.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.CommandLine" Version="[1.4.0]" />
<PackageReference Include="SabreTools.IO" Version="[1.9.0]" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="10.0.0" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,340 @@
using System;
using System.IO;
using SabreTools.CommandLine;
using SabreTools.CommandLine.Inputs;
using SabreTools.IO.Extensions;
using SabreTools.Serialization;
using SabreTools.Serialization.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)
{
Console.WriteLine($"Attempting to extract all files from {file}");
using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
// Get the extension for certain checks
string extension = Path.GetExtension(file).ToLower().TrimStart('.');
// Get the first 16 bytes for matching
byte[] magic = new byte[16];
try
{
int read = stream.Read(magic, 0, 16);
stream.SeekIfPossible(0, SeekOrigin.Begin);
}
catch (Exception ex)
{
if (Debug) Console.Error.WriteLine(ex);
return;
}
// Get the file type
WrapperType ft = WrapperFactory.GetFileType(magic, extension);
var wrapper = WrapperFactory.CreateWrapper(ft, stream);
// Create the output directory
Directory.CreateDirectory(OutputPath);
// Print the preamble
Console.WriteLine($"Attempting to extract from '{wrapper?.Description() ?? "UNKNOWN"}'");
Console.WriteLine();
switch (wrapper)
{
// 7-zip
case SevenZip sz:
sz.Extract(OutputPath, Debug);
break;
// BFPK archive
case BFPK bfpk:
bfpk.Extract(OutputPath, Debug);
break;
// BSP
case BSP bsp:
bsp.Extract(OutputPath, Debug);
break;
// bzip2
case BZip2 bzip2:
bzip2.Extract(OutputPath, Debug);
break;
// CD-ROM bin file
case CDROM cdrom:
cdrom.Extract(OutputPath, Debug);
break;
// CFB
case CFB cfb:
cfb.Extract(OutputPath, Debug);
break;
// GCF
case GCF gcf:
gcf.Extract(OutputPath, Debug);
break;
// gzip
case GZip gzip:
gzip.Extract(OutputPath, Debug);
break;
// InstallShield Archive V3 (Z)
case InstallShieldArchiveV3 isv3:
isv3.Extract(OutputPath, Debug);
break;
// IS-CAB archive
case InstallShieldCabinet iscab:
iscab.Extract(OutputPath, Debug);
break;
// ISO 9660 volume
case ISO9660 iso9660:
iso9660.Extract(OutputPath, Debug);
break;
// LZ-compressed file, KWAJ variant
case LZKWAJ kwaj:
kwaj.Extract(OutputPath, Debug);
break;
// LZ-compressed file, QBasic variant
case LZQBasic qbasic:
qbasic.Extract(OutputPath, Debug);
break;
// LZ-compressed file, SZDD variant
case LZSZDD szdd:
szdd.Extract(OutputPath, Debug);
break;
// Microsoft Cabinet archive
case MicrosoftCabinet mscab:
mscab.Extract(OutputPath, Debug);
break;
// MoPaQ (MPQ) archive
case MoPaQ mpq:
mpq.Extract(OutputPath, Debug);
break;
// New Executable
case NewExecutable nex:
nex.Extract(OutputPath, Debug);
break;
// PAK
case PAK pak:
pak.Extract(OutputPath, Debug);
break;
// PFF
case PFF pff:
pff.Extract(OutputPath, Debug);
break;
// PKZIP
case PKZIP pkzip:
pkzip.Extract(OutputPath, Debug);
break;
// Portable Executable
case PortableExecutable pex:
pex.Extract(OutputPath, Debug);
break;
// Quantum
case Quantum quantum:
quantum.Extract(OutputPath, Debug);
break;
// RAR
case RAR rar:
rar.Extract(OutputPath, Debug);
break;
// SGA
case SGA sga:
sga.Extract(OutputPath, Debug);
break;
// Tape Archive
case TapeArchive tar:
tar.Extract(OutputPath, Debug);
break;
// VBSP
case VBSP vbsp:
vbsp.Extract(OutputPath, Debug);
break;
// VPK
case VPK vpk:
vpk.Extract(OutputPath, Debug);
break;
// WAD3
case WAD3 wad:
wad.Extract(OutputPath, Debug);
break;
// xz
case XZ xz:
xz.Extract(OutputPath, Debug);
break;
// XZP
case XZP xzp:
xzp.Extract(OutputPath, Debug);
break;
// ZSTD
case ZSTD zstd:
zstd.Extract(OutputPath, Debug);
break;
// Everything else
default:
Console.WriteLine("Not a supported extractable file format, skipping...");
Console.WriteLine();
break;
}
}
/// <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 == 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

@@ -0,0 +1,278 @@
using System;
using System.IO;
using System.Text;
using SabreTools.CommandLine;
using SabreTools.CommandLine.Inputs;
using SabreTools.Hashing;
using SabreTools.IO.Extensions;
using SabreTools.Serialization;
using SabreTools.Serialization.Wrappers;
namespace InfoPrint.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 _fileOnlyName = "file-only";
internal readonly FlagInput FileOnlyInput = new(_fileOnlyName, ["-f", "--file"], "Print to file only");
private const string _hashName = "hash";
internal readonly FlagInput HashInput = new(_hashName, ["-c", "--hash"], "Output file hashes");
#if NETCOREAPP
private const string _jsonName = "json";
internal readonly FlagInput JsonInput = new(_jsonName, ["-j", "--json"], "Print info as JSON");
#endif
#endregion
/// <summary>
/// Enable debug output for relevant operations
/// </summary>
public bool Debug { get; private set; }
/// <summary>
/// Output information to file only, skip printing to console
/// </summary>
public bool FileOnly { get; private set; }
/// <summary>
/// Print external file hashes
/// </summary>
public bool Hash { get; private set; }
#if NETCOREAPP
/// <summary>
/// Enable JSON output
/// </summary>
public bool Json { get; private set; }
#endif
public MainFeature()
: base(DisplayName, _flags, _description)
{
RequiresInputs = true;
Add(DebugInput);
Add(HashInput);
Add(FileOnlyInput);
#if NETCOREAPP
Add(JsonInput);
#endif
}
/// <inheritdoc/>
public override bool Execute()
{
// Get the options from the arguments
Debug = GetBoolean(_debugName);
Hash = GetBoolean(_hashName);
FileOnly = GetBoolean(_fileOnlyName);
#if NETCOREAPP
Json = GetBoolean(_jsonName);
#endif
// Loop through the input paths
for (int i = 0; i < Inputs.Count; i++)
{
string arg = Inputs[i];
PrintPathInfo(arg);
}
return true;
}
/// <inheritdoc/>
public override bool VerifyInputs() => Inputs.Count > 0;
/// <summary>
/// Wrapper to print information for a single path
/// </summary>
/// <param name="path">File or directory path</param>
private void PrintPathInfo(string path)
{
Console.WriteLine($"Checking possible path: {path}");
// Check if the file or directory exists
if (File.Exists(path))
{
PrintFileInfo(path);
}
else if (Directory.Exists(path))
{
foreach (string file in path.SafeEnumerateFiles("*", SearchOption.AllDirectories))
{
PrintFileInfo(file);
}
}
else
{
Console.WriteLine($"{path} does not exist, skipping...");
}
}
/// <summary>
/// Print information for a single file, if possible
/// </summary>
/// <param name="file">File path</param>
private void PrintFileInfo(string file)
{
Console.WriteLine($"Attempting to print info for {file}");
// Get the base info output name
string filenameBase = $"info-{DateTime.Now:yyyy-MM-dd_HHmmss.ffff}";
// If we have the hash flag
if (Hash)
{
var hashBuilder = PrintHashInfo(file);
if (hashBuilder != null)
{
// Create the output data
string hashData = hashBuilder.ToString();
// Write the output data
using var hsw = new StreamWriter(File.OpenWrite($"{filenameBase}.hashes"));
hsw.WriteLine(hashData);
hsw.Flush();
}
}
try
{
using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
// Read the first 8 bytes
byte[] magic = stream.PeekBytes(8);
// 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 print
var wrapper = WrapperFactory.CreateWrapper(ft, stream);
// If we don't have a wrapper
if (wrapper == null)
{
Console.WriteLine($"Either {ft} is not supported or something went wrong during parsing!");
Console.WriteLine();
return;
}
#if NETCOREAPP
// If we have the JSON flag
if (Json)
{
// Create the output data
string serializedData = wrapper.ExportJSON();
// Write the output data
using var jsw = new StreamWriter(File.OpenWrite($"{filenameBase}.json"));
jsw.WriteLine(serializedData);
jsw.Flush();
}
#endif
// Create the output data
var builder = wrapper.ExportStringBuilder();
if (builder == null)
{
Console.WriteLine("No item information could be generated");
return;
}
// Only print to console if enabled
if (!FileOnly)
Console.WriteLine(builder);
using var sw = new StreamWriter(File.OpenWrite($"{filenameBase}.txt"));
sw.WriteLine(file);
sw.WriteLine();
sw.WriteLine(builder.ToString());
sw.Flush();
}
catch (Exception ex)
{
Console.WriteLine(Debug ? ex : "[Exception opening file, please try again]");
Console.WriteLine();
}
}
/// <summary>
/// Print hash information for a single file, if possible
/// </summary>
/// <param name="file">File path</param>
/// <returns>StringBuilder representing the hash information, if possible</returns>
private StringBuilder? PrintHashInfo(string file)
{
// Ignore missing files
if (!File.Exists(file))
return null;
Console.WriteLine($"Attempting to hash {file}, this may take a while...");
try
{
// Get all file hashes for flexibility
var hashes = HashTool.GetFileHashes(file);
if (hashes == null)
{
if (Debug) Console.WriteLine($"Hashes for {file} could not be retrieved");
return null;
}
// Output subset of available hashes
var builder = new StringBuilder();
if (hashes.TryGetValue(HashType.CRC16, out string? crc16) && crc16 != null)
builder.AppendLine($"CRC-16 checksum: {crc16}");
if (hashes.TryGetValue(HashType.CRC32, out string? crc32) && crc32 != null)
builder.AppendLine($"CRC-32 checksum: {crc32}");
if (hashes.TryGetValue(HashType.MD2, out string? md2) && md2 != null)
builder.AppendLine($"MD2 hash: {md2}");
if (hashes.TryGetValue(HashType.MD4, out string? md4) && md4 != null)
builder.AppendLine($"MD4 hash: {md4}");
if (hashes.TryGetValue(HashType.MD5, out string? md5) && md5 != null)
builder.AppendLine($"MD5 hash: {md5}");
if (hashes.TryGetValue(HashType.RIPEMD128, out string? ripemd128) && ripemd128 != null)
builder.AppendLine($"RIPEMD-128 hash: {ripemd128}");
if (hashes.TryGetValue(HashType.RIPEMD160, out string? ripemd160) && ripemd160 != null)
builder.AppendLine($"RIPEMD-160 hash: {ripemd160}");
if (hashes.TryGetValue(HashType.SHA1, out string? sha1) && sha1 != null)
builder.AppendLine($"SHA-1 hash: {sha1}");
if (hashes.TryGetValue(HashType.SHA256, out string? sha256) && sha256 != null)
builder.AppendLine($"SHA-256 hash: {sha256}");
if (hashes.TryGetValue(HashType.SHA384, out string? sha384) && sha384 != null)
builder.AppendLine($"SHA-384 hash: {sha384}");
if (hashes.TryGetValue(HashType.SHA512, out string? sha512) && sha512 != null)
builder.AppendLine($"SHA-512 hash: {sha512}");
return builder;
}
catch (Exception ex)
{
Console.WriteLine(Debug ? ex : "[Exception opening file, please try again]");
return null;
}
}
}
}

View File

@@ -0,0 +1,40 @@
<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>2.2.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>
<ItemGroup>
<ProjectReference Include="..\SabreTools.Serialization\SabreTools.Serialization.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.CommandLine" Version="[1.4.0]" />
<PackageReference Include="SabreTools.Hashing" Version="[1.6.0]" />
<PackageReference Include="SabreTools.IO" Version="[1.9.0]" />
</ItemGroup>
</Project>

78
InfoPrint/Program.cs Normal file
View File

@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using InfoPrint.Features;
using SabreTools.CommandLine;
using SabreTools.CommandLine.Features;
namespace InfoPrint
{
public static class Program
{
public static void Main(string[] args)
{
// Create the command set
var mainFeature = new MainFeature();
var commandSet = CreateCommands(mainFeature);
// If we have no args, show the help and quit
if (args == 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 = [
"Information Printing Program",
string.Empty,
"InfoPrint <options> file|directory ...",
string.Empty,
];
var commandSet = new CommandSet(header);
commandSet.Add(new Help(["-?", "-h", "--help"]));
commandSet.Add(mainFeature.DebugInput);
commandSet.Add(mainFeature.HashInput);
commandSet.Add(mainFeature.FileOnlyInput);
#if NETCOREAPP
commandSet.Add(mainFeature.JsonInput);
#endif
return commandSet;
}
}
}

7
LICENSE Normal file
View File

@@ -0,0 +1,7 @@
Copyright (c) 2018-2025 Matt Nadareski
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

116
README.MD
View File

@@ -1,29 +1,121 @@
# SabreTools.Serialization
[![Build and Test](https://github.com/SabreTools/SabreTools.Serialization/actions/workflows/build_and_test.yml/badge.svg)](https://github.com/SabreTools/SabreTools.Serialization/actions/workflows/build_and_test.yml)
This library comprises of serializers that both read and write from files and streams to the dedicated models as well as convert to and from the common internal models. This library is partially used by the current parsing and writing code but none of the internal model serialization is used.
Find the link to the Nuget package [here](https://www.nuget.org/packages/SabreTools.Serialization).
## `SabreTools.Serialization.Bytes`
The following non-project libraries (or ports thereof) are used for file handling:
This namespace comprises of deserializers that take byte arrays to convert into models.
- [GrindCore.SharpCompress](https://github.com/Nanook/GrindCore.SharpCompress) - Common archive format extraction
- [StormLibSharp](https://github.com/robpaveza/stormlibsharp) - MoPaQ extraction [Unused in non-Windows builds due to Windows-specific libraries]
## `SabreTools.Serialization.CrossModel`
The following projects have influenced this library:
This namespace comprises of serializers and deserializers that convert models to other common ones. This is mainly used for metadata files converting to and from a common, `Dictionary`-based model.
- [libmspack](https://github.com/kyz/libmspack) - Documentation around the MS-CAB format and associated compression methods.
- [Unshield](https://github.com/twogood/unshield/) - InstallShield CAB extraction tool that influenced internal handling
## `SabreTools.Serialization.Files`
## Releases
This namespace comprises of serializers and deserializers that can convert to and from files on disk. Most of the serializers are symmetric, but this is not guaranteed. Unimplemented methods will throw `NotImplementedException`.
For the most recent stable build, download the latest release here: [Releases Page](https://github.com/SabreTools/SabreTools.Serialization/releases)
## `SabreTools.Serialization.Streams`
For the latest WIP build here: [Rolling Release](https://github.com/SabreTools/SabreTools.Serialization/releases/tag/rolling)
This namespace comprises of serializers and deserializers that can convert to and from any type of stream. Most of the serializers are symmetric, but this is not guaranteed. Unimplemented methods will throw `NotImplementedException`.
## InfoPrint
## `SabreTools.Serialization.Strings`
**InfoPrint** is a reference implementation for the deserialization and printing features of the library, packaged as a standalone executable for all supported platforms. It will attempt to detect and display information about many supported file types, optionally both hashing the file and outputting the information to a JSON file (.NET Core 3.1 and above only).
This namespace comprises of serializers and deserializers that can convert to and from strings. Most of the serializers are symmetric, but this is not guaranteed. Unimplemented methods will throw `NotImplementedException`.
```text
InfoPrint <options> file|directory ...
## `SabreTools.Serialization.Wrappers`
Options:
-?, -h, --help Display this help text
-d, --debug Enable debug mode
-c, --hash Output file hashes
-f, --file Print to file only
-j, --json Print info as JSON
```
This namespace comrpises of wrapping classes that include keeping a reference to the source of each serializable model. Some of the wrappers may also include what are referred to as "extension properties", which are generated properties derived from either parts of the model or the underlying source.
## ExtractionTool
**ExtractionTool** is a reference implementation for the extraction features of the library, packaged as a standalone executable for all supported platforms. It will attempt to detect and extract many supported file types. See the table below for supported extraction functionality.
```text
ExtractionTool <options> file|directory ...
Options:
-?, -h, --help Display this help text
-d, --debug Enable debug mode
-o, --outdir [PATH] Set output path for extraction (required)
```
| Format Name | Notes |
| --- | --- |
| 7-zip archive | .NET Framework 4.6.2 and greater |
| BFPK custom archive format | |
| bzip2 archive | .NET Framework 4.6.2 and greater |
| Compound File Binary (CFB) | Only CFB common pieces extractable |
| gzip archive | |
| Half-Life Game Cache File (GCF) | |
| Half-Life Level (BSP) | |
| Half-Life Package File (PAK) | |
| Half-Life Texture Package File (WAD3) | |
| Half-Life 2 Level (VBSP) | |
| InstallShield Archive V3 (Z) | |
| InstallShield CAB | |
| Microsoft cabinet file | Does not support LZX or Quantum compression |
| Microsoft LZ-compressed files | KWAJ, QBasic, and SZDD variants |
| MoPaQ game data archive (MPQ) | Windows only |
| New Exectuable | Embedded archives and executables in the overlay and Wise installer |
| NovaLogic Game Archive Format (PFF) | |
| PKZIP and derived files (ZIP, etc.) | .NET Framework 4.6.2 and greater |
| Portable Executable | Embedded archives and executables in the resources and overlay, CExe-packed data, SFX archives (7-zip, PKZIP, and RAR), and Wise installer |
| Quantum archive (Q) | Currently not working |
| RAR archive (RAR) | .NET Framework 4.6.2 and greater |
| SGA game archive | |
| Tape archive (TAR) | |
| Valve Package File (VPK) | |
| XBox Package File (XZP) | |
| xz archive (XZ) | .NET Framework 4.6.2 and greater |
## Interfaces
Below is a table representing the various conversion interfaces that are implemented within this library.
| Interface Name | Source Type | Destination Type |
| --- | --- | --- |
| `SabreTools.Serialization.Interfaces.IByteReader<TModel>` | `byte[]?` | `TModel` |
| `SabreTools.Serialization.Interfaces.IByteWriter<TModel>` | `TModel` | `byte[]?` |
| `SabreTools.Serialization.Interfaces.ICrossModel<TSource, TDest>` | `TSource`/`TDest` | `TDest`/`TSource` |
| `SabreTools.Serialization.Interfaces.IFileReader<TModel>` | `string?` path | `TModel` |
| `SabreTools.Serialization.Interfaces.IFileWriter<TModel>` | `TModel` | `string?` path |
| `SabreTools.Serialization.Interfaces.IStreamReader<TModel>` | `Stream?` | `TModel` |
| `SabreTools.Serialization.Interfaces.IStreamWriter<TModel>` | `TModel` | `Stream?` |
| `SabreTools.Serialization.Interfaces.IStringReader<TModel>` | `string?` representation | `TModel` |
| `SabreTools.Serialization.Interfaces.IStringWriter<TModel>` | `TModel` | `string?` representation |
Below is a table representing the various non-conversion interfaces that are implemented within this library.
| Interface Name | Purpose |
| --- | --- |
| `SabreTools.Serialization.Wrappers.IExtractable` | Marks a wrapper as able to be extracted |
| `SabreTools.Serialization.Wrappers.IPrintable` | Marks a wrapper as able to print model information |
| `SabreTools.Serialization.Wrappers.IWrapper` | Represents an item with a description and JSON serializable state, allowing for extensions |
| `SabreTools.Serialization.Wrappers.IWrapper<TModel>` | Wraps a model with source data, allowing for extensions |
## Namespaces
Below is a table of all namespaces within the library and what they represent
| Namespace | Description |
| --- | --- |
| `SabreTools.Data.Attributes` | Common attributes for data marking and manipulation |
| `SabreTools.Data.Extensions` | Extension methods related to models |
| `SabreTools.Data.Models` | Models representing different file and structure types |
| `SabreTools.Data.ObjectIdentifier` | Object Identifier (OID) parsing |
| `SabreTools.Serialization.CrossModel` | Convert between models; mainly used for metadata files converting to and from a common, `Dictionary`-based model |
| `SabreTools.Serialization.Interfaces` | Interfaces used commonly throughout the library |
| `SabreTools.Serialization.Readers` | Convert from external sources to models |
| `SabreTools.Serialization.Wrappers` | Classes that wrap serialization and models to allow for including extension properties |
| `SabreTools.Serialization.Writers` | Convert from models to external sources |

View File

@@ -0,0 +1,174 @@
using SabreTools.Serialization.CrossModel;
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class ArchiveDotOrgTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new ArchiveDotOrg();
// Build the data
Data.Models.ArchiveDotOrg.Files files = Build();
// Serialize to generic model
SabreTools.Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(files);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.ArchiveDotOrg.Files? newFiles = serializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newFiles);
Assert.NotNull(newFiles.File);
var newFile = Assert.Single(newFiles.File);
Validate(newFile);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.ArchiveDotOrg.Files Build()
{
var file = new Data.Models.ArchiveDotOrg.File
{
Name = "XXXXXX",
Source = "XXXXXX",
BitTorrentMagnetHash = "XXXXXX",
LastModifiedTime = "XXXXXX",
Size = "XXXXXX",
MD5 = "XXXXXX",
CRC32 = "XXXXXX",
SHA1 = "XXXXXX",
FileCount = "XXXXXX",
Format = "XXXXXX",
Original = "XXXXXX",
Summation = "XXXXXX",
MatrixNumber = "XXXXXX",
CollectionCatalogNumber = "XXXXXX",
Publisher = "XXXXXX",
Comment = "XXXXXX",
ASRDetectedLang = "XXXXXX",
ASRDetectedLangConf = "XXXXXX",
ASRTranscribedLang = "XXXXXX",
WhisperASRModuleVersion = "XXXXXX",
WhisperModelHash = "XXXXXX",
WhisperModelName = "XXXXXX",
WhisperVersion = "XXXXXX",
ClothCoverDetectionModuleVersion = "XXXXXX",
hOCRCharToWordhOCRVersion = "XXXXXX",
hOCRCharToWordModuleVersion = "XXXXXX",
hOCRFtsTexthOCRVersion = "XXXXXX",
hOCRFtsTextModuleVersion = "XXXXXX",
hOCRPageIndexhOCRVersion = "XXXXXX",
hOCRPageIndexModuleVersion = "XXXXXX",
TesseractOCR = "XXXXXX",
TesseractOCRConverted = "XXXXXX",
TesseractOCRDetectedLang = "XXXXXX",
TesseractOCRDetectedLangConf = "XXXXXX",
TesseractOCRDetectedScript = "XXXXXX",
TesseractOCRDetectedScriptConf = "XXXXXX",
TesseractOCRModuleVersion = "XXXXXX",
TesseractOCRParameters = "XXXXXX",
PDFModuleVersion = "XXXXXX",
WordConfidenceInterval0To10 = "XXXXXX",
WordConfidenceInterval11To20 = "XXXXXX",
WordConfidenceInterval21To30 = "XXXXXX",
WordConfidenceInterval31To40 = "XXXXXX",
WordConfidenceInterval41To50 = "XXXXXX",
WordConfidenceInterval51To60 = "XXXXXX",
WordConfidenceInterval61To70 = "XXXXXX",
WordConfidenceInterval71To80 = "XXXXXX",
WordConfidenceInterval81To90 = "XXXXXX",
WordConfidenceInterval91To100 = "XXXXXX",
Album = "XXXXXX",
Artist = "XXXXXX",
Bitrate = "XXXXXX",
Creator = "XXXXXX",
Height = "XXXXXX",
Length = "XXXXXX",
PreviewImage = "XXXXXX",
Rotation = "XXXXXX",
Title = "XXXXXX",
Track = "XXXXXX",
Width = "XXXXXX",
};
return new Data.Models.ArchiveDotOrg.Files
{
File = [file]
};
}
/// <summary>
/// Validate a File
/// </summary>
private static void Validate(Data.Models.ArchiveDotOrg.File? file)
{
Assert.NotNull(file);
Assert.Equal("XXXXXX", file.Name);
Assert.Equal("XXXXXX", file.Source);
Assert.Equal("XXXXXX", file.BitTorrentMagnetHash);
Assert.Equal("XXXXXX", file.LastModifiedTime);
Assert.Equal("XXXXXX", file.Size);
Assert.Equal("XXXXXX", file.MD5);
Assert.Equal("XXXXXX", file.CRC32);
Assert.Equal("XXXXXX", file.SHA1);
Assert.Equal("XXXXXX", file.FileCount);
Assert.Equal("XXXXXX", file.Format);
Assert.Equal("XXXXXX", file.Original);
Assert.Equal("XXXXXX", file.Summation);
Assert.Equal("XXXXXX", file.MatrixNumber);
Assert.Equal("XXXXXX", file.CollectionCatalogNumber);
Assert.Equal("XXXXXX", file.Publisher);
Assert.Equal("XXXXXX", file.Comment);
Assert.Equal("XXXXXX", file.ASRDetectedLang);
Assert.Equal("XXXXXX", file.ASRDetectedLangConf);
Assert.Equal("XXXXXX", file.ASRTranscribedLang);
Assert.Equal("XXXXXX", file.WhisperASRModuleVersion);
Assert.Equal("XXXXXX", file.WhisperModelHash);
Assert.Equal("XXXXXX", file.WhisperModelName);
Assert.Equal("XXXXXX", file.WhisperVersion);
Assert.Equal("XXXXXX", file.ClothCoverDetectionModuleVersion);
Assert.Equal("XXXXXX", file.hOCRCharToWordhOCRVersion);
Assert.Equal("XXXXXX", file.hOCRCharToWordModuleVersion);
Assert.Equal("XXXXXX", file.hOCRFtsTexthOCRVersion);
Assert.Equal("XXXXXX", file.hOCRFtsTextModuleVersion);
Assert.Equal("XXXXXX", file.hOCRPageIndexhOCRVersion);
Assert.Equal("XXXXXX", file.hOCRPageIndexModuleVersion);
Assert.Equal("XXXXXX", file.TesseractOCR);
Assert.Equal("XXXXXX", file.TesseractOCRConverted);
Assert.Equal("XXXXXX", file.TesseractOCRDetectedLang);
Assert.Equal("XXXXXX", file.TesseractOCRDetectedLangConf);
Assert.Equal("XXXXXX", file.TesseractOCRDetectedScript);
Assert.Equal("XXXXXX", file.TesseractOCRDetectedScriptConf);
Assert.Equal("XXXXXX", file.TesseractOCRModuleVersion);
Assert.Equal("XXXXXX", file.TesseractOCRParameters);
Assert.Equal("XXXXXX", file.PDFModuleVersion);
Assert.Equal("XXXXXX", file.WordConfidenceInterval0To10);
Assert.Equal("XXXXXX", file.WordConfidenceInterval11To20);
Assert.Equal("XXXXXX", file.WordConfidenceInterval21To30);
Assert.Equal("XXXXXX", file.WordConfidenceInterval31To40);
Assert.Equal("XXXXXX", file.WordConfidenceInterval41To50);
Assert.Equal("XXXXXX", file.WordConfidenceInterval51To60);
Assert.Equal("XXXXXX", file.WordConfidenceInterval61To70);
Assert.Equal("XXXXXX", file.WordConfidenceInterval71To80);
Assert.Equal("XXXXXX", file.WordConfidenceInterval81To90);
Assert.Equal("XXXXXX", file.WordConfidenceInterval91To100);
Assert.Equal("XXXXXX", file.Album);
Assert.Equal("XXXXXX", file.Artist);
Assert.Equal("XXXXXX", file.Bitrate);
Assert.Equal("XXXXXX", file.Creator);
Assert.Equal("XXXXXX", file.Height);
Assert.Equal("XXXXXX", file.Length);
Assert.Equal("XXXXXX", file.PreviewImage);
Assert.Equal("XXXXXX", file.Rotation);
Assert.Equal("XXXXXX", file.Title);
Assert.Equal("XXXXXX", file.Track);
Assert.Equal("XXXXXX", file.Width);
}
}
}

View File

@@ -0,0 +1,112 @@
using SabreTools.Serialization.CrossModel;
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class AttractModeTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new AttractMode();
// Build the data
Data.Models.AttractMode.MetadataFile mf = Build();
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(mf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.AttractMode.MetadataFile? newMf = serializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newMf);
Validate(newMf.Header);
Assert.NotNull(newMf.Row);
var newRow = Assert.Single(newMf.Row);
Validate(newRow);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.AttractMode.MetadataFile Build()
{
string[] header = ["header"];
var row = new Data.Models.AttractMode.Row
{
Name = "XXXXXX",
Title = "XXXXXX",
Emulator = "XXXXXX",
CloneOf = "XXXXXX",
Year = "XXXXXX",
Manufacturer = "XXXXXX",
Category = "XXXXXX",
Players = "XXXXXX",
Rotation = "XXXXXX",
Control = "XXXXXX",
Status = "XXXXXX",
DisplayCount = "XXXXXX",
DisplayType = "XXXXXX",
AltRomname = "XXXXXX",
AltTitle = "XXXXXX",
Extra = "XXXXXX",
Buttons = "XXXXXX",
Favorite = "XXXXXX",
Tags = "XXXXXX",
PlayedCount = "XXXXXX",
PlayedTime = "XXXXXX",
FileIsAvailable = "XXXXXX",
};
return new Data.Models.AttractMode.MetadataFile
{
Header = header,
Row = [row],
};
}
/// <summary>
/// Validate a header
/// </summary>
private static void Validate(string[]? header)
{
Assert.NotNull(header);
string column = Assert.Single(header);
Assert.Equal("header", column);
}
/// <summary>
/// Validate a Row
/// </summary>
private static void Validate(Data.Models.AttractMode.Row? row)
{
Assert.NotNull(row);
Assert.Equal("XXXXXX", row.Name);
Assert.Equal("XXXXXX", row.Title);
Assert.Equal("XXXXXX", row.Emulator);
Assert.Equal("XXXXXX", row.CloneOf);
Assert.Equal("XXXXXX", row.Year);
Assert.Equal("XXXXXX", row.Manufacturer);
Assert.Equal("XXXXXX", row.Category);
Assert.Equal("XXXXXX", row.Players);
Assert.Equal("XXXXXX", row.Rotation);
Assert.Equal("XXXXXX", row.Control);
Assert.Equal("XXXXXX", row.Status);
Assert.Equal("XXXXXX", row.DisplayCount);
Assert.Equal("XXXXXX", row.DisplayType);
Assert.Equal("XXXXXX", row.AltRomname);
Assert.Equal("XXXXXX", row.AltTitle);
Assert.Equal("XXXXXX", row.Extra);
Assert.Equal("XXXXXX", row.Buttons);
Assert.Equal("XXXXXX", row.Favorite);
Assert.Equal("XXXXXX", row.Tags);
Assert.Equal("XXXXXX", row.PlayedCount);
Assert.Equal("XXXXXX", row.PlayedTime);
Assert.Equal("XXXXXX", row.FileIsAvailable);
}
}
}

View File

@@ -0,0 +1,501 @@
using SabreTools.Serialization.CrossModel;
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class ClrMameProTests
{
[Fact]
public void RoundTripGameTest()
{
// Get the cross-model serializer
var serializer = new ClrMamePro();
// Build the data
Data.Models.ClrMamePro.MetadataFile mf = Build(game: true);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(mf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.ClrMamePro.MetadataFile? newMf = serializer.Deserialize(metadata, game: true);
// Validate the data
Assert.NotNull(newMf);
Validate(newMf.ClrMamePro);
Assert.NotNull(newMf.Game);
var newGame = Assert.Single(newMf.Game);
Validate(newGame);
}
[Fact]
public void RoundTripMachineTest()
{
// Get the cross-model serializer
var serializer = new ClrMamePro();
// Build the data
Data.Models.ClrMamePro.MetadataFile mf = Build(game: false);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(mf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.ClrMamePro.MetadataFile? newMf = serializer.Deserialize(metadata, game: false);
// Validate the data
Assert.NotNull(newMf);
Validate(newMf.ClrMamePro);
Assert.NotNull(newMf.Game);
var newGame = Assert.Single(newMf.Game);
Validate(newGame);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.ClrMamePro.MetadataFile Build(bool game)
{
var cmp = new Data.Models.ClrMamePro.ClrMamePro
{
Name = "XXXXXX",
Description = "XXXXXX",
RootDir = "XXXXXX",
Category = "XXXXXX",
Version = "XXXXXX",
Date = "XXXXXX",
Author = "XXXXXX",
Homepage = "XXXXXX",
Url = "XXXXXX",
Comment = "XXXXXX",
Header = "XXXXXX",
Type = "XXXXXX",
ForceMerging = "XXXXXX",
ForceZipping = "XXXXXX",
ForcePacking = "XXXXXX",
};
var release = new Data.Models.ClrMamePro.Release
{
Name = "XXXXXX",
Region = "XXXXXX",
Language = "XXXXXX",
Date = "XXXXXX",
Default = "XXXXXX",
};
var biosset = new Data.Models.ClrMamePro.BiosSet
{
Name = "XXXXXX",
Description = "XXXXXX",
Default = "XXXXXX",
};
var rom = new Data.Models.ClrMamePro.Rom
{
Name = "XXXXXX",
Size = "XXXXXX",
CRC = "XXXXXX",
MD2 = "XXXXXX",
MD4 = "XXXXXX",
MD5 = "XXXXXX",
RIPEMD128 = "XXXXXX",
RIPEMD160 = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Status = "XXXXXX",
Flags = "XXXXXX",
Date = "XXXXXX",
SHA256 = "XXXXXX",
SHA384 = "XXXXXX",
SHA512 = "XXXXXX",
SpamSum = "XXXXXX",
xxHash364 = "XXXXXX",
xxHash3128 = "XXXXXX",
Region = "XXXXXX",
Offs = "XXXXXX",
Serial = "XXXXXX",
Header = "XXXXXX",
Inverted = "XXXXXX",
MIA = "XXXXXX",
};
var disk = new Data.Models.ClrMamePro.Disk
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Status = "XXXXXX",
Flags = "XXXXXX",
};
var sample = new Data.Models.ClrMamePro.Sample
{
Name = "XXXXXX",
};
var archive = new Data.Models.ClrMamePro.Archive
{
Name = "XXXXXX",
};
var media = new Data.Models.ClrMamePro.Media
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
SHA256 = "XXXXXX",
SpamSum = "XXXXXX",
};
var chip = new Data.Models.ClrMamePro.Chip
{
Type = "XXXXXX",
Name = "XXXXXX",
Flags = "XXXXXX",
Clock = "XXXXXX",
};
var video = new Data.Models.ClrMamePro.Video
{
Screen = "XXXXXX",
Orientation = "XXXXXX",
X = "XXXXXX",
Y = "XXXXXX",
AspectX = "XXXXXX",
AspectY = "XXXXXX",
Freq = "XXXXXX",
};
var sound = new Data.Models.ClrMamePro.Sound
{
Channels = "XXXXXX",
};
var input = new Data.Models.ClrMamePro.Input
{
Players = "XXXXXX",
Control = "XXXXXX",
Buttons = "XXXXXX",
Coins = "XXXXXX",
Tilt = "XXXXXX",
Service = "XXXXXX",
};
var dipswitch = new Data.Models.ClrMamePro.DipSwitch
{
Name = "XXXXXX",
Entry = ["XXXXXX"],
Default = "XXXXXX",
};
var driver = new Data.Models.ClrMamePro.Driver
{
Status = "XXXXXX",
Color = "XXXXXX",
Sound = "XXXXXX",
PaletteSize = "XXXXXX",
Blit = "XXXXXX",
};
// TODO: This omits Set, should that have a separate case?
Data.Models.ClrMamePro.GameBase gameBase = game
? new Data.Models.ClrMamePro.Game()
: new Data.Models.ClrMamePro.Machine();
gameBase.Name = "XXXXXX";
gameBase.Description = "XXXXXX";
gameBase.Year = "XXXXXX";
gameBase.Manufacturer = "XXXXXX";
gameBase.Category = "XXXXXX";
gameBase.CloneOf = "XXXXXX";
gameBase.RomOf = "XXXXXX";
gameBase.SampleOf = "XXXXXX";
gameBase.Release = [release];
gameBase.BiosSet = [biosset];
gameBase.Rom = [rom];
gameBase.Disk = [disk];
gameBase.Sample = [sample];
gameBase.Archive = [archive];
gameBase.Media = [media];
gameBase.Chip = [chip];
gameBase.Video = [video];
gameBase.Sound = sound;
gameBase.Input = input;
gameBase.DipSwitch = [dipswitch];
gameBase.Driver = driver;
return new Data.Models.ClrMamePro.MetadataFile
{
ClrMamePro = cmp,
Game = [gameBase],
};
}
/// <summary>
/// Validate a ClrMamePro
/// </summary>
private static void Validate(Data.Models.ClrMamePro.ClrMamePro? cmp)
{
Assert.NotNull(cmp);
Assert.Equal("XXXXXX", cmp.Name);
Assert.Equal("XXXXXX", cmp.Description);
Assert.Equal("XXXXXX", cmp.RootDir);
Assert.Equal("XXXXXX", cmp.Category);
Assert.Equal("XXXXXX", cmp.Version);
Assert.Equal("XXXXXX", cmp.Date);
Assert.Equal("XXXXXX", cmp.Author);
Assert.Equal("XXXXXX", cmp.Homepage);
Assert.Equal("XXXXXX", cmp.Url);
Assert.Equal("XXXXXX", cmp.Comment);
Assert.Equal("XXXXXX", cmp.Header);
Assert.Equal("XXXXXX", cmp.Type);
Assert.Equal("XXXXXX", cmp.ForceMerging);
Assert.Equal("XXXXXX", cmp.ForceZipping);
Assert.Equal("XXXXXX", cmp.ForcePacking);
}
/// <summary>
/// Validate a GameBase
/// </summary>
private static void Validate(Data.Models.ClrMamePro.GameBase? gb)
{
Assert.NotNull(gb);
Assert.Equal("XXXXXX", gb.Name);
Assert.Equal("XXXXXX", gb.Description);
Assert.Equal("XXXXXX", gb.Year);
Assert.Equal("XXXXXX", gb.Manufacturer);
Assert.Equal("XXXXXX", gb.Category);
Assert.Equal("XXXXXX", gb.CloneOf);
Assert.Equal("XXXXXX", gb.RomOf);
Assert.Equal("XXXXXX", gb.SampleOf);
Assert.NotNull(gb.Release);
var release = Assert.Single(gb.Release);
Validate(release);
Assert.NotNull(gb.BiosSet);
var biosset = Assert.Single(gb.BiosSet);
Validate(biosset);
Assert.NotNull(gb.Rom);
var rom = Assert.Single(gb.Rom);
Validate(rom);
Assert.NotNull(gb.Disk);
var disk = Assert.Single(gb.Disk);
Validate(disk);
Assert.NotNull(gb.Sample);
var sample = Assert.Single(gb.Sample);
Validate(sample);
Assert.NotNull(gb.Archive);
var archive = Assert.Single(gb.Archive);
Validate(archive);
Assert.NotNull(gb.Media);
var media = Assert.Single(gb.Media);
Validate(media);
Assert.NotNull(gb.Chip);
var chip = Assert.Single(gb.Chip);
Validate(chip);
Assert.NotNull(gb.Video);
var video = Assert.Single(gb.Video);
Validate(video);
Validate(gb.Sound);
Validate(gb.Input);
Assert.NotNull(gb.DipSwitch);
var dipswitch = Assert.Single(gb.DipSwitch);
Validate(dipswitch);
Validate(gb.Driver);
}
/// <summary>
/// Validate a Release
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Release? release)
{
Assert.NotNull(release);
Assert.Equal("XXXXXX", release.Name);
Assert.Equal("XXXXXX", release.Region);
Assert.Equal("XXXXXX", release.Language);
Assert.Equal("XXXXXX", release.Date);
Assert.Equal("XXXXXX", release.Default);
}
/// <summary>
/// Validate a BiosSet
/// </summary>
private static void Validate(Data.Models.ClrMamePro.BiosSet? biosset)
{
Assert.NotNull(biosset);
Assert.Equal("XXXXXX", biosset.Name);
Assert.Equal("XXXXXX", biosset.Description);
Assert.Equal("XXXXXX", biosset.Default);
}
/// <summary>
/// Validate a Rom
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Rom? rom)
{
Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.Name);
Assert.Equal("XXXXXX", rom.Size);
Assert.Equal("XXXXXX", rom.CRC);
Assert.Equal("XXXXXX", rom.MD2);
Assert.Equal("XXXXXX", rom.MD4);
Assert.Equal("XXXXXX", rom.MD5);
Assert.Equal("XXXXXX", rom.RIPEMD128);
Assert.Equal("XXXXXX", rom.RIPEMD160);
Assert.Equal("XXXXXX", rom.SHA1);
Assert.Equal("XXXXXX", rom.Merge);
Assert.Equal("XXXXXX", rom.Status);
Assert.Equal("XXXXXX", rom.Flags);
Assert.Equal("XXXXXX", rom.Date);
Assert.Equal("XXXXXX", rom.SHA256);
Assert.Equal("XXXXXX", rom.SHA384);
Assert.Equal("XXXXXX", rom.SHA512);
Assert.Equal("XXXXXX", rom.SpamSum);
Assert.Equal("XXXXXX", rom.xxHash364);
Assert.Equal("XXXXXX", rom.xxHash3128);
Assert.Equal("XXXXXX", rom.Region);
Assert.Equal("XXXXXX", rom.Offs);
Assert.Equal("XXXXXX", rom.Serial);
Assert.Equal("XXXXXX", rom.Header);
Assert.Equal("XXXXXX", rom.Inverted);
Assert.Equal("XXXXXX", rom.MIA);
}
/// <summary>
/// Validate a Disk
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Disk? disk)
{
Assert.NotNull(disk);
Assert.Equal("XXXXXX", disk.Name);
Assert.Equal("XXXXXX", disk.MD5);
Assert.Equal("XXXXXX", disk.SHA1);
Assert.Equal("XXXXXX", disk.Merge);
Assert.Equal("XXXXXX", disk.Status);
Assert.Equal("XXXXXX", disk.Flags);
}
/// <summary>
/// Validate a Sample
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Sample? sample)
{
Assert.NotNull(sample);
Assert.Equal("XXXXXX", sample.Name);
}
/// <summary>
/// Validate a Archive
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Archive? archive)
{
Assert.NotNull(archive);
Assert.Equal("XXXXXX", archive.Name);
}
/// <summary>
/// Validate a Media
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Media? media)
{
Assert.NotNull(media);
Assert.Equal("XXXXXX", media.Name);
Assert.Equal("XXXXXX", media.MD5);
Assert.Equal("XXXXXX", media.SHA1);
Assert.Equal("XXXXXX", media.SHA256);
Assert.Equal("XXXXXX", media.SpamSum);
}
/// <summary>
/// Validate a Chip
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Chip? chip)
{
Assert.NotNull(chip);
Assert.Equal("XXXXXX", chip.Type);
Assert.Equal("XXXXXX", chip.Name);
Assert.Equal("XXXXXX", chip.Flags);
Assert.Equal("XXXXXX", chip.Clock);
}
/// <summary>
/// Validate a Video
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Video? video)
{
Assert.NotNull(video);
Assert.Equal("XXXXXX", video.Screen);
Assert.Equal("XXXXXX", video.Orientation);
Assert.Equal("XXXXXX", video.X);
Assert.Equal("XXXXXX", video.Y);
Assert.Equal("XXXXXX", video.AspectX);
Assert.Equal("XXXXXX", video.AspectY);
Assert.Equal("XXXXXX", video.Freq);
}
/// <summary>
/// Validate a Sound
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Sound? sound)
{
Assert.NotNull(sound);
Assert.Equal("XXXXXX", sound.Channels);
}
/// <summary>
/// Validate a Input
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Input? input)
{
Assert.NotNull(input);
Assert.Equal("XXXXXX", input.Players);
Assert.Equal("XXXXXX", input.Control);
Assert.Equal("XXXXXX", input.Buttons);
Assert.Equal("XXXXXX", input.Coins);
Assert.Equal("XXXXXX", input.Tilt);
Assert.Equal("XXXXXX", input.Service);
}
/// <summary>
/// Validate a DipSwitch
/// </summary>
private static void Validate(Data.Models.ClrMamePro.DipSwitch? dipswitch)
{
Assert.NotNull(dipswitch);
Assert.Equal("XXXXXX", dipswitch.Name);
Assert.NotNull(dipswitch.Entry);
string entry = Assert.Single(dipswitch.Entry);
Assert.Equal("XXXXXX", entry);
Assert.Equal("XXXXXX", dipswitch.Default);
}
/// <summary>
/// Validate a Driver
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Driver? driver)
{
Assert.NotNull(driver);
Assert.Equal("XXXXXX", driver.Status);
Assert.Equal("XXXXXX", driver.Color);
Assert.Equal("XXXXXX", driver.Sound);
Assert.Equal("XXXXXX", driver.PaletteSize);
Assert.Equal("XXXXXX", driver.Blit);
}
}
}

View File

@@ -0,0 +1,111 @@
using SabreTools.Serialization.CrossModel;
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class DosCenterTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new DosCenter();
// Build the data
Data.Models.DosCenter.MetadataFile mf = Build();
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(mf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.DosCenter.MetadataFile? newMf = serializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newMf);
Validate(newMf.DosCenter);
Assert.NotNull(newMf.Game);
var newGame = Assert.Single(newMf.Game);
Validate(newGame);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.DosCenter.MetadataFile Build()
{
var dc = new Data.Models.DosCenter.DosCenter
{
Name = "XXXXXX",
Description = "XXXXXX",
Version = "XXXXXX",
Date = "XXXXXX",
Author = "XXXXXX",
Homepage = "XXXXXX",
Comment = "XXXXXX",
};
var file = new Data.Models.DosCenter.File
{
Name = "XXXXXX",
Size = "XXXXXX",
CRC = "XXXXXX",
SHA1 = "XXXXXX",
Date = "XXXXXX",
};
var game = new Data.Models.DosCenter.Game
{
Name = "XXXXXX",
File = [file],
};
return new Data.Models.DosCenter.MetadataFile
{
DosCenter = dc,
Game = [game],
};
}
/// <summary>
/// Validate a DosCenter
/// </summary>
private static void Validate(Data.Models.DosCenter.DosCenter? cmp)
{
Assert.NotNull(cmp);
Assert.Equal("XXXXXX", cmp.Name);
Assert.Equal("XXXXXX", cmp.Description);
Assert.Equal("XXXXXX", cmp.Version);
Assert.Equal("XXXXXX", cmp.Date);
Assert.Equal("XXXXXX", cmp.Author);
Assert.Equal("XXXXXX", cmp.Homepage);
Assert.Equal("XXXXXX", cmp.Comment);
}
/// <summary>
/// Validate a Game
/// </summary>
private static void Validate(Data.Models.DosCenter.Game? game)
{
Assert.NotNull(game);
Assert.Equal("XXXXXX", game.Name);
Assert.NotNull(game.File);
var file = Assert.Single(game.File);
Validate(file);
}
/// <summary>
/// Validate a File
/// </summary>
private static void Validate(Data.Models.DosCenter.File? rom)
{
Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.Name);
Assert.Equal("XXXXXX", rom.Size);
Assert.Equal("XXXXXX", rom.CRC);
Assert.Equal("XXXXXX", rom.SHA1);
Assert.Equal("XXXXXX", rom.Date);
}
}
}

View File

@@ -0,0 +1,66 @@
using SabreTools.Serialization.CrossModel;
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class EverdriveSMDBTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new EverdriveSMDB();
// Build the data
Data.Models.EverdriveSMDB.MetadataFile mf = Build();
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(mf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.EverdriveSMDB.MetadataFile? newMf = serializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newMf);
Assert.NotNull(newMf.Row);
var newRow = Assert.Single(newMf.Row);
Validate(newRow);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.EverdriveSMDB.MetadataFile Build()
{
var row = new Data.Models.EverdriveSMDB.Row
{
SHA256 = "XXXXXX",
Name = "XXXXXX",
SHA1 = "XXXXXX",
MD5 = "XXXXXX",
CRC32 = "XXXXXX",
Size = "XXXXXX",
};
return new Data.Models.EverdriveSMDB.MetadataFile
{
Row = [row],
};
}
/// <summary>
/// Validate a Row
/// </summary>
private static void Validate(Data.Models.EverdriveSMDB.Row? row)
{
Assert.NotNull(row);
Assert.Equal("XXXXXX", row.SHA256);
Assert.Equal("XXXXXX", row.Name);
Assert.Equal("XXXXXX", row.SHA1);
Assert.Equal("XXXXXX", row.MD5);
Assert.Equal("XXXXXX", row.CRC32);
Assert.Equal("XXXXXX", row.Size);
}
}
}

View File

@@ -0,0 +1,327 @@
using System;
using SabreTools.Hashing;
using SabreTools.Serialization.CrossModel;
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class HashfileTests
{
[Fact]
public void RoundTripSFVTest()
{
// Get the cross-model serializer
var serializer = new Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.CRC32);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = serializer.Deserialize(metadata, HashType.CRC32);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.SFV);
var newSfv = Assert.Single(newHf.SFV);
Validate(newSfv);
}
[Fact]
public void RoundTripMD2Test()
{
// Get the cross-model serializer
var serializer = new Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.MD2);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = serializer.Deserialize(metadata, HashType.MD2);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.MD2);
var newMd2 = Assert.Single(newHf.MD2);
Validate(newMd2);
}
[Fact]
public void RoundTripMD4Test()
{
// Get the cross-model serializer
var serializer = new Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.MD4);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = serializer.Deserialize(metadata, HashType.MD4);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.MD4);
var newMd4 = Assert.Single(newHf.MD4);
Validate(newMd4);
}
[Fact]
public void RoundTripMD5Test()
{
// Get the cross-model serializer
var serializer = new Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.MD5);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = serializer.Deserialize(metadata, HashType.MD5);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.MD5);
var newMd5 = Assert.Single(newHf.MD5);
Validate(newMd5);
}
[Fact]
public void RoundTripSHA1Test()
{
// Get the cross-model serializer
var serializer = new Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.SHA1);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = serializer.Deserialize(metadata, HashType.SHA1);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.SHA1);
var newSha1 = Assert.Single(newHf.SHA1);
Validate(newSha1);
}
[Fact]
public void RoundTripSHA256Test()
{
// Get the cross-model serializer
var serializer = new Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.SHA256);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = serializer.Deserialize(metadata, HashType.SHA256);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.SHA256);
var newSha256 = Assert.Single(newHf.SHA256);
Validate(newSha256);
}
[Fact]
public void RoundTripSHA384Test()
{
// Get the cross-model serializer
var serializer = new Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.SHA384);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = serializer.Deserialize(metadata, HashType.SHA384);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.SHA384);
var newSha384 = Assert.Single(newHf.SHA384);
Validate(newSha384);
}
[Fact]
public void RoundTripSHA512Test()
{
// Get the cross-model serializer
var serializer = new Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.SHA512);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = serializer.Deserialize(metadata, HashType.SHA512);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.SHA512);
var newSha512 = Assert.Single(newHf.SHA512);
Validate(newSha512);
}
[Fact]
public void RoundTripSpamSumTest()
{
// Get the cross-model serializer
var serializer = new Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.SpamSum);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = serializer.Deserialize(metadata, HashType.SpamSum);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.SpamSum);
var newSpamsum = Assert.Single(newHf.SpamSum);
Validate(newSpamsum);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.Hashfile.Hashfile Build(HashType hashType)
{
return hashType switch
{
HashType.CRC32 => new Data.Models.Hashfile.Hashfile { SFV = [new Data.Models.Hashfile.SFV { File = "XXXXXX", Hash = "XXXXXX" }] },
HashType.MD2 => new Data.Models.Hashfile.Hashfile { MD2 = [new Data.Models.Hashfile.MD2 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.MD4 => new Data.Models.Hashfile.Hashfile { MD4 = [new Data.Models.Hashfile.MD4 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.MD5 => new Data.Models.Hashfile.Hashfile { MD5 = [new Data.Models.Hashfile.MD5 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SHA1 => new Data.Models.Hashfile.Hashfile { SHA1 = [new Data.Models.Hashfile.SHA1 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SHA256 => new Data.Models.Hashfile.Hashfile { SHA256 = [new Data.Models.Hashfile.SHA256 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SHA384 => new Data.Models.Hashfile.Hashfile { SHA384 = [new Data.Models.Hashfile.SHA384 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SHA512 => new Data.Models.Hashfile.Hashfile { SHA512 = [new Data.Models.Hashfile.SHA512 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SpamSum => new Data.Models.Hashfile.Hashfile { SpamSum = [new Data.Models.Hashfile.SpamSum { Hash = "XXXXXX", File = "XXXXXX" }] },
_ => throw new ArgumentOutOfRangeException(),
};
}
/// <summary>
/// Validate a SFV
/// </summary>
private static void Validate(Data.Models.Hashfile.SFV? sfv)
{
Assert.NotNull(sfv);
Assert.Equal("XXXXXX", sfv.File);
Assert.Equal("XXXXXX", sfv.Hash);
}
/// <summary>
/// Validate a MD2
/// </summary>
private static void Validate(Data.Models.Hashfile.MD2? md2)
{
Assert.NotNull(md2);
Assert.Equal("XXXXXX", md2.Hash);
Assert.Equal("XXXXXX", md2.File);
}
/// <summary>
/// Validate a MD4
/// </summary>
private static void Validate(Data.Models.Hashfile.MD4? md4)
{
Assert.NotNull(md4);
Assert.Equal("XXXXXX", md4.Hash);
Assert.Equal("XXXXXX", md4.File);
}
/// <summary>
/// Validate a MD5
/// </summary>
private static void Validate(Data.Models.Hashfile.MD5? md5)
{
Assert.NotNull(md5);
Assert.Equal("XXXXXX", md5.Hash);
Assert.Equal("XXXXXX", md5.File);
}
/// <summary>
/// Validate a SHA1
/// </summary>
private static void Validate(Data.Models.Hashfile.SHA1? sha1)
{
Assert.NotNull(sha1);
Assert.Equal("XXXXXX", sha1.Hash);
Assert.Equal("XXXXXX", sha1.File);
}
/// <summary>
/// Validate a SHA256
/// </summary>
private static void Validate(Data.Models.Hashfile.SHA256? sha256)
{
Assert.NotNull(sha256);
Assert.Equal("XXXXXX", sha256.Hash);
Assert.Equal("XXXXXX", sha256.File);
}
/// <summary>
/// Validate a SHA384
/// </summary>
private static void Validate(Data.Models.Hashfile.SHA384? sha384)
{
Assert.NotNull(sha384);
Assert.Equal("XXXXXX", sha384.Hash);
Assert.Equal("XXXXXX", sha384.File);
}
/// <summary>
/// Validate a SHA512
/// </summary>
private static void Validate(Data.Models.Hashfile.SHA512? sha512)
{
Assert.NotNull(sha512);
Assert.Equal("XXXXXX", sha512.Hash);
Assert.Equal("XXXXXX", sha512.File);
}
/// <summary>
/// Validate a SpamSum
/// </summary>
private static void Validate(Data.Models.Hashfile.SpamSum? spamsum)
{
Assert.NotNull(spamsum);
Assert.Equal("XXXXXX", spamsum.Hash);
Assert.Equal("XXXXXX", spamsum.File);
}
}
}

View File

@@ -0,0 +1,128 @@
using SabreTools.Serialization.CrossModel;
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class ListromTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new Listrom();
// Build the data
Data.Models.Listrom.MetadataFile mf = Build();
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(mf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Listrom.MetadataFile? newMf = serializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newMf);
Assert.NotNull(newMf.Set);
Assert.Equal(2, newMf.Set.Length);
ValidateDevice(newMf.Set[0]);
ValidateDriver(newMf.Set[1]);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.Listrom.MetadataFile Build()
{
var rom = new Data.Models.Listrom.Row
{
Name = "XXXXXX",
Size = "XXXXXX",
Bad = true,
CRC = "XXXXXX",
SHA1 = "XXXXXX",
NoGoodDumpKnown = false,
};
var disk = new Data.Models.Listrom.Row
{
Name = "XXXXXX",
Bad = false,
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
NoGoodDumpKnown = true,
};
var device = new Data.Models.Listrom.Set()
{
Device = "XXXXXX",
Row = [rom],
};
var driver = new Data.Models.Listrom.Set()
{
Driver = "XXXXXX",
Row = [disk],
};
return new Data.Models.Listrom.MetadataFile
{
Set = [device, driver],
};
}
/// <summary>
/// Validate a Set
/// </summary>
private static void ValidateDevice(Data.Models.Listrom.Set? set)
{
Assert.NotNull(set);
Assert.Equal("XXXXXX", set.Device);
Assert.NotNull(set.Row);
var row = Assert.Single(set.Row);
ValidateRom(row);
}
/// <summary>
/// Validate a Set
/// </summary>
private static void ValidateDriver(Data.Models.Listrom.Set? set)
{
Assert.NotNull(set);
Assert.Equal("XXXXXX", set.Driver);
Assert.NotNull(set.Row);
var row = Assert.Single(set.Row);
ValidateDisk(row);
}
/// <summary>
/// Validate a Row
/// </summary>
private static void ValidateRom(Data.Models.Listrom.Row? row)
{
Assert.NotNull(row);
Assert.Equal("XXXXXX", row.Name);
Assert.Equal("XXXXXX", row.Size);
Assert.True(row.Bad);
Assert.Equal("XXXXXX", row.CRC);
Assert.Equal("XXXXXX", row.SHA1);
Assert.False(row.NoGoodDumpKnown);
}
/// <summary>
/// Validate a Row
/// </summary>
private static void ValidateDisk(Data.Models.Listrom.Row? row)
{
Assert.NotNull(row);
Assert.Equal("XXXXXX", row.Name);
Assert.False(row.Bad);
Assert.Equal("XXXXXX", row.MD5);
Assert.Equal("XXXXXX", row.SHA1);
Assert.True(row.NoGoodDumpKnown);
}
}
}

View File

@@ -0,0 +1,879 @@
using SabreTools.Serialization.CrossModel;
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class ListxmlTests
{
[Fact]
public void RoundTripGameTest()
{
// Get the cross-model serializer
var serializer = new Listxml();
// Build the data
Data.Models.Listxml.Mame mame = Build(game: true);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(mame);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Listxml.Mame? newMame = serializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newMame);
Assert.Equal("XXXXXX", newMame.Build);
Assert.Equal("XXXXXX", newMame.Debug);
Assert.Equal("XXXXXX", newMame.MameConfig);
Assert.NotNull(newMame.Game);
var newGame = Assert.Single(newMame.Game);
Validate(newGame);
}
[Fact]
public void RoundTripMachineTest()
{
// Get the cross-model serializer
var serializer = new Listxml();
// Build the data
Data.Models.Listxml.Mame mame = Build(game: false);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(mame);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Listxml.Mame? newMame = serializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newMame);
Assert.Equal("XXXXXX", newMame.Build);
Assert.Equal("XXXXXX", newMame.Debug);
Assert.Equal("XXXXXX", newMame.MameConfig);
Assert.NotNull(newMame.Game);
var newGame = Assert.Single(newMame.Game);
Validate(newGame);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.Listxml.Mame Build(bool game)
{
var biosset = new Data.Models.Listxml.BiosSet
{
Name = "XXXXXX",
Description = "XXXXXX",
Default = "XXXXXX",
};
var rom = new Data.Models.Listxml.Rom
{
Name = "XXXXXX",
Bios = "XXXXXX",
Size = "XXXXXX",
CRC = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Region = "XXXXXX",
Offset = "XXXXXX",
Status = "XXXXXX",
Optional = "XXXXXX",
Dispose = "XXXXXX",
SoundOnly = "XXXXXX",
};
var disk = new Data.Models.Listxml.Disk
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Region = "XXXXXX",
Index = "XXXXXX",
Writable = "XXXXXX",
Status = "XXXXXX",
Optional = "XXXXXX",
};
var deviceref = new Data.Models.Listxml.DeviceRef
{
Name = "XXXXXX",
};
var sample = new Data.Models.Listxml.Sample
{
Name = "XXXXXX",
};
var chip = new Data.Models.Listxml.Chip
{
Name = "XXXXXX",
Tag = "XXXXXX",
Type = "XXXXXX",
SoundOnly = "XXXXXX",
Clock = "XXXXXX",
};
var display = new Data.Models.Listxml.Display
{
Tag = "XXXXXX",
Type = "XXXXXX",
Rotate = "XXXXXX",
FlipX = "XXXXXX",
Width = "XXXXXX",
Height = "XXXXXX",
Refresh = "XXXXXX",
PixClock = "XXXXXX",
HTotal = "XXXXXX",
HBEnd = "XXXXXX",
HBStart = "XXXXXX",
VTotal = "XXXXXX",
VBEnd = "XXXXXX",
VBStart = "XXXXXX",
};
var video = new Data.Models.Listxml.Video
{
Screen = "XXXXXX",
Orientation = "XXXXXX",
Width = "XXXXXX",
Height = "XXXXXX",
AspectX = "XXXXXX",
AspectY = "XXXXXX",
Refresh = "XXXXXX",
};
var sound = new Data.Models.Listxml.Sound
{
Channels = "XXXXXX",
};
var control = new Data.Models.Listxml.Control
{
Type = "XXXXXX",
Player = "XXXXXX",
Buttons = "XXXXXX",
ReqButtons = "XXXXXX",
Minimum = "XXXXXX",
Maximum = "XXXXXX",
Sensitivity = "XXXXXX",
KeyDelta = "XXXXXX",
Reverse = "XXXXXX",
Ways = "XXXXXX",
Ways2 = "XXXXXX",
Ways3 = "XXXXXX",
};
var input = new Data.Models.Listxml.Input
{
Service = "XXXXXX",
Tilt = "XXXXXX",
Players = "XXXXXX",
//ControlAttr = "XXXXXX", // Mututally exclusive with input.Control
Buttons = "XXXXXX",
Coins = "XXXXXX",
Control = [control],
};
var condition = new Data.Models.Listxml.Condition
{
Tag = "XXXXXX",
Mask = "XXXXXX",
Relation = "XXXXXX",
Value = "XXXXXX",
};
var diplocation = new Data.Models.Listxml.DipLocation
{
Name = "XXXXXX",
Number = "XXXXXX",
Inverted = "XXXXXX",
};
var dipvalue = new Data.Models.Listxml.DipValue
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var dipswitch = new Data.Models.Listxml.DipSwitch
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
Condition = condition,
DipLocation = [diplocation],
DipValue = [dipvalue],
};
var conflocation = new Data.Models.Listxml.ConfLocation
{
Name = "XXXXXX",
Number = "XXXXXX",
Inverted = "XXXXXX",
};
var confsetting = new Data.Models.Listxml.ConfSetting
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var configuration = new Data.Models.Listxml.Configuration
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
Condition = condition,
ConfLocation = [conflocation],
ConfSetting = [confsetting],
};
var analog = new Data.Models.Listxml.Analog
{
Mask = "XXXXXX",
};
var port = new Data.Models.Listxml.Port
{
Tag = "XXXXXX",
Analog = [analog],
};
var adjuster = new Data.Models.Listxml.Adjuster
{
Name = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var driver = new Data.Models.Listxml.Driver
{
Status = "XXXXXX",
Color = "XXXXXX",
Sound = "XXXXXX",
PaletteSize = "XXXXXX",
Emulation = "XXXXXX",
Cocktail = "XXXXXX",
SaveState = "XXXXXX",
RequiresArtwork = "XXXXXX",
Unofficial = "XXXXXX",
NoSoundHardware = "XXXXXX",
Incomplete = "XXXXXX",
};
var feature = new Data.Models.Listxml.Feature
{
Type = "XXXXXX",
Status = "XXXXXX",
Overall = "XXXXXX",
};
var instance = new Data.Models.Listxml.Instance
{
Name = "XXXXXX",
BriefName = "XXXXXX",
};
var extension = new Data.Models.Listxml.Extension
{
Name = "XXXXXX",
};
var device = new Data.Models.Listxml.Device
{
Type = "XXXXXX",
Tag = "XXXXXX",
FixedImage = "XXXXXX",
Mandatory = "XXXXXX",
Interface = "XXXXXX",
Instance = instance,
Extension = [extension],
};
var slotOption = new Data.Models.Listxml.SlotOption
{
Name = "XXXXXX",
DevName = "XXXXXX",
Default = "XXXXXX",
};
var slot = new Data.Models.Listxml.Slot
{
Name = "XXXXXX",
SlotOption = [slotOption],
};
var softwarelist = new Data.Models.Listxml.SoftwareList
{
Tag = "XXXXXX",
Name = "XXXXXX",
Status = "XXXXXX",
Filter = "XXXXXX",
};
var ramoption = new Data.Models.Listxml.RamOption
{
Name = "XXXXXX",
Default = "XXXXXX",
Content = "XXXXXX",
};
Data.Models.Listxml.GameBase gameBase = game
? new Data.Models.Listxml.Game()
: new Data.Models.Listxml.Machine();
gameBase.Name = "XXXXXX";
gameBase.SourceFile = "XXXXXX";
gameBase.IsBios = "XXXXXX";
gameBase.IsDevice = "XXXXXX";
gameBase.IsMechanical = "XXXXXX";
gameBase.Runnable = "XXXXXX";
gameBase.CloneOf = "XXXXXX";
gameBase.RomOf = "XXXXXX";
gameBase.SampleOf = "XXXXXX";
gameBase.Description = "XXXXXX";
gameBase.Year = "XXXXXX";
gameBase.Manufacturer = "XXXXXX";
gameBase.History = "XXXXXX";
gameBase.BiosSet = [biosset];
gameBase.Rom = [rom];
gameBase.Disk = [disk];
gameBase.DeviceRef = [deviceref];
gameBase.Sample = [sample];
gameBase.Chip = [chip];
gameBase.Display = [display];
gameBase.Video = [video];
gameBase.Sound = sound;
gameBase.Input = input;
gameBase.DipSwitch = [dipswitch];
gameBase.Configuration = [configuration];
gameBase.Port = [port];
gameBase.Adjuster = [adjuster];
gameBase.Driver = driver;
gameBase.Feature = [feature];
gameBase.Device = [device];
gameBase.Slot = [slot];
gameBase.SoftwareList = [softwarelist];
gameBase.RamOption = [ramoption];
return new Data.Models.Listxml.Mame
{
Build = "XXXXXX",
Debug = "XXXXXX",
MameConfig = "XXXXXX",
Game = [gameBase],
};
}
/// <summary>
/// Validate a GameBase
/// </summary>
private static void Validate(Data.Models.Listxml.GameBase? gb)
{
Assert.NotNull(gb);
Assert.Equal("XXXXXX", gb.Name);
Assert.Equal("XXXXXX", gb.SourceFile);
Assert.Equal("XXXXXX", gb.IsBios);
Assert.Equal("XXXXXX", gb.IsDevice);
Assert.Equal("XXXXXX", gb.IsMechanical);
Assert.Equal("XXXXXX", gb.Runnable);
Assert.Equal("XXXXXX", gb.CloneOf);
Assert.Equal("XXXXXX", gb.RomOf);
Assert.Equal("XXXXXX", gb.SampleOf);
Assert.Equal("XXXXXX", gb.Description);
Assert.Equal("XXXXXX", gb.Year);
Assert.Equal("XXXXXX", gb.Manufacturer);
Assert.Equal("XXXXXX", gb.History);
Assert.NotNull(gb.BiosSet);
var biosset = Assert.Single(gb.BiosSet);
Validate(biosset);
Assert.NotNull(gb.Rom);
var rom = Assert.Single(gb.Rom);
Validate(rom);
Assert.NotNull(gb.Disk);
var disk = Assert.Single(gb.Disk);
Validate(disk);
Assert.NotNull(gb.DeviceRef);
var deviceref = Assert.Single(gb.DeviceRef);
Validate(deviceref);
Assert.NotNull(gb.Sample);
var sample = Assert.Single(gb.Sample);
Validate(sample);
Assert.NotNull(gb.Chip);
var chip = Assert.Single(gb.Chip);
Validate(chip);
Assert.NotNull(gb.Display);
var display = Assert.Single(gb.Display);
Validate(display);
Assert.NotNull(gb.Video);
var video = Assert.Single(gb.Video);
Validate(video);
Validate(gb.Sound);
Validate(gb.Input);
Assert.NotNull(gb.DipSwitch);
var dipswitch = Assert.Single(gb.DipSwitch);
Validate(dipswitch);
Assert.NotNull(gb.Configuration);
var configuration = Assert.Single(gb.Configuration);
Validate(configuration);
Assert.NotNull(gb.Port);
var port = Assert.Single(gb.Port);
Validate(port);
Assert.NotNull(gb.Adjuster);
var adjuster = Assert.Single(gb.Adjuster);
Validate(adjuster);
Validate(gb.Driver);
Assert.NotNull(gb.Feature);
var feature = Assert.Single(gb.Feature);
Validate(feature);
Assert.NotNull(gb.Device);
var device = Assert.Single(gb.Device);
Validate(device);
Assert.NotNull(gb.Slot);
var slot = Assert.Single(gb.Slot);
Validate(slot);
Assert.NotNull(gb.SoftwareList);
var softwarelist = Assert.Single(gb.SoftwareList);
Validate(softwarelist);
Assert.NotNull(gb.RamOption);
var ramoption = Assert.Single(gb.RamOption);
Validate(ramoption);
}
/// <summary>
/// Validate a BiosSet
/// </summary>
private static void Validate(Data.Models.Listxml.BiosSet? biosset)
{
Assert.NotNull(biosset);
Assert.Equal("XXXXXX", biosset.Name);
Assert.Equal("XXXXXX", biosset.Description);
Assert.Equal("XXXXXX", biosset.Default);
}
/// <summary>
/// Validate a Rom
/// </summary>
private static void Validate(Data.Models.Listxml.Rom? rom)
{
Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.Name);
Assert.Equal("XXXXXX", rom.Bios);
Assert.Equal("XXXXXX", rom.Size);
Assert.Equal("XXXXXX", rom.CRC);
Assert.Equal("XXXXXX", rom.SHA1);
Assert.Equal("XXXXXX", rom.Merge);
Assert.Equal("XXXXXX", rom.Region);
Assert.Equal("XXXXXX", rom.Offset);
Assert.Equal("XXXXXX", rom.Status);
Assert.Equal("XXXXXX", rom.Optional);
Assert.Equal("XXXXXX", rom.Dispose);
Assert.Equal("XXXXXX", rom.SoundOnly);
}
/// <summary>
/// Validate a Disk
/// </summary>
private static void Validate(Data.Models.Listxml.Disk? disk)
{
Assert.NotNull(disk);
Assert.Equal("XXXXXX", disk.Name);
Assert.Equal("XXXXXX", disk.MD5);
Assert.Equal("XXXXXX", disk.SHA1);
Assert.Equal("XXXXXX", disk.Merge);
Assert.Equal("XXXXXX", disk.Region);
Assert.Equal("XXXXXX", disk.Index);
Assert.Equal("XXXXXX", disk.Writable);
Assert.Equal("XXXXXX", disk.Status);
Assert.Equal("XXXXXX", disk.Optional);
}
/// <summary>
/// Validate a DeviceRef
/// </summary>
private static void Validate(Data.Models.Listxml.DeviceRef? deviceref)
{
Assert.NotNull(deviceref);
Assert.Equal("XXXXXX", deviceref.Name);
}
/// <summary>
/// Validate a Sample
/// </summary>
private static void Validate(Data.Models.Listxml.Sample? sample)
{
Assert.NotNull(sample);
Assert.Equal("XXXXXX", sample.Name);
}
/// <summary>
/// Validate a Chip
/// </summary>
private static void Validate(Data.Models.Listxml.Chip? chip)
{
Assert.NotNull(chip);
Assert.Equal("XXXXXX", chip.Name);
Assert.Equal("XXXXXX", chip.Tag);
Assert.Equal("XXXXXX", chip.Type);
Assert.Equal("XXXXXX", chip.SoundOnly);
Assert.Equal("XXXXXX", chip.Clock);
}
/// <summary>
/// Validate a Display
/// </summary>
private static void Validate(Data.Models.Listxml.Display? display)
{
Assert.NotNull(display);
Assert.Equal("XXXXXX", display.Tag);
Assert.Equal("XXXXXX", display.Type);
Assert.Equal("XXXXXX", display.Rotate);
Assert.Equal("XXXXXX", display.FlipX);
Assert.Equal("XXXXXX", display.Width);
Assert.Equal("XXXXXX", display.Height);
Assert.Equal("XXXXXX", display.Refresh);
Assert.Equal("XXXXXX", display.PixClock);
Assert.Equal("XXXXXX", display.HTotal);
Assert.Equal("XXXXXX", display.HBEnd);
Assert.Equal("XXXXXX", display.HBStart);
Assert.Equal("XXXXXX", display.VTotal);
Assert.Equal("XXXXXX", display.VBEnd);
Assert.Equal("XXXXXX", display.VBStart);
}
/// <summary>
/// Validate a Video
/// </summary>
private static void Validate(Data.Models.Listxml.Video? video)
{
Assert.NotNull(video);
Assert.Equal("XXXXXX", video.Screen);
Assert.Equal("XXXXXX", video.Orientation);
Assert.Equal("XXXXXX", video.Width);
Assert.Equal("XXXXXX", video.Height);
Assert.Equal("XXXXXX", video.AspectX);
Assert.Equal("XXXXXX", video.AspectY);
Assert.Equal("XXXXXX", video.Refresh);
}
/// <summary>
/// Validate a Sound
/// </summary>
private static void Validate(Data.Models.Listxml.Sound? sound)
{
Assert.NotNull(sound);
Assert.Equal("XXXXXX", sound.Channels);
}
/// <summary>
/// Validate a Input
/// </summary>
private static void Validate(Data.Models.Listxml.Input? input)
{
Assert.NotNull(input);
Assert.Equal("XXXXXX", input.Service);
Assert.Equal("XXXXXX", input.Tilt);
Assert.Equal("XXXXXX", input.Players);
//Assert.Equal("XXXXXX", input.ControlAttr); // Mututally exclusive with input.Control
Assert.Equal("XXXXXX", input.Buttons);
Assert.Equal("XXXXXX", input.Coins);
Assert.NotNull(input.Control);
var control = Assert.Single(input.Control);
Validate(control);
}
/// <summary>
/// Validate a Control
/// </summary>
private static void Validate(Data.Models.Listxml.Control? control)
{
Assert.NotNull(control);
Assert.Equal("XXXXXX", control.Type);
Assert.Equal("XXXXXX", control.Player);
Assert.Equal("XXXXXX", control.Buttons);
Assert.Equal("XXXXXX", control.ReqButtons);
Assert.Equal("XXXXXX", control.Minimum);
Assert.Equal("XXXXXX", control.Maximum);
Assert.Equal("XXXXXX", control.Sensitivity);
Assert.Equal("XXXXXX", control.KeyDelta);
Assert.Equal("XXXXXX", control.Reverse);
Assert.Equal("XXXXXX", control.Ways);
Assert.Equal("XXXXXX", control.Ways2);
Assert.Equal("XXXXXX", control.Ways3);
}
/// <summary>
/// Validate a DipSwitch
/// </summary>
private static void Validate(Data.Models.Listxml.DipSwitch? dipswitch)
{
Assert.NotNull(dipswitch);
Assert.Equal("XXXXXX", dipswitch.Name);
Assert.Equal("XXXXXX", dipswitch.Tag);
Assert.Equal("XXXXXX", dipswitch.Mask);
Validate(dipswitch.Condition);
Assert.NotNull(dipswitch.DipLocation);
var diplocation = Assert.Single(dipswitch.DipLocation);
Validate(diplocation);
Assert.NotNull(dipswitch.DipValue);
var dipvalue = Assert.Single(dipswitch.DipValue);
Validate(dipvalue);
}
/// <summary>
/// Validate a Condition
/// </summary>
private static void Validate(Data.Models.Listxml.Condition? condition)
{
Assert.NotNull(condition);
Assert.Equal("XXXXXX", condition.Tag);
Assert.Equal("XXXXXX", condition.Mask);
Assert.Equal("XXXXXX", condition.Relation);
Assert.Equal("XXXXXX", condition.Value);
}
/// <summary>
/// Validate a DipLocation
/// </summary>
private static void Validate(Data.Models.Listxml.DipLocation? diplocation)
{
Assert.NotNull(diplocation);
Assert.Equal("XXXXXX", diplocation.Name);
Assert.Equal("XXXXXX", diplocation.Number);
Assert.Equal("XXXXXX", diplocation.Inverted);
}
/// <summary>
/// Validate a DipValue
/// </summary>
private static void Validate(Data.Models.Listxml.DipValue? dipvalue)
{
Assert.NotNull(dipvalue);
Assert.Equal("XXXXXX", dipvalue.Name);
Assert.Equal("XXXXXX", dipvalue.Value);
Assert.Equal("XXXXXX", dipvalue.Default);
Validate(dipvalue.Condition);
}
/// <summary>
/// Validate a Configuration
/// </summary>
private static void Validate(Data.Models.Listxml.Configuration? configuration)
{
Assert.NotNull(configuration);
Assert.Equal("XXXXXX", configuration.Name);
Assert.Equal("XXXXXX", configuration.Tag);
Assert.Equal("XXXXXX", configuration.Mask);
Validate(configuration.Condition);
Assert.NotNull(configuration.ConfLocation);
var conflocation = Assert.Single(configuration.ConfLocation);
Validate(conflocation);
Assert.NotNull(configuration.ConfSetting);
var confsetting = Assert.Single(configuration.ConfSetting);
Validate(confsetting);
}
/// <summary>
/// Validate a ConfLocation
/// </summary>
private static void Validate(Data.Models.Listxml.ConfLocation? conflocation)
{
Assert.NotNull(conflocation);
Assert.Equal("XXXXXX", conflocation.Name);
Assert.Equal("XXXXXX", conflocation.Number);
Assert.Equal("XXXXXX", conflocation.Inverted);
}
/// <summary>
/// Validate a ConfSetting
/// </summary>
private static void Validate(Data.Models.Listxml.ConfSetting? confsetting)
{
Assert.NotNull(confsetting);
Assert.Equal("XXXXXX", confsetting.Name);
Assert.Equal("XXXXXX", confsetting.Value);
Assert.Equal("XXXXXX", confsetting.Default);
Validate(confsetting.Condition);
}
/// <summary>
/// Validate a Port
/// </summary>
private static void Validate(Data.Models.Listxml.Port? port)
{
Assert.NotNull(port);
Assert.Equal("XXXXXX", port.Tag);
Assert.NotNull(port.Analog);
var analog = Assert.Single(port.Analog);
Validate(analog);
}
/// <summary>
/// Validate a Analog
/// </summary>
private static void Validate(Data.Models.Listxml.Analog? analog)
{
Assert.NotNull(analog);
Assert.Equal("XXXXXX", analog.Mask);
}
/// <summary>
/// Validate a Adjuster
/// </summary>
private static void Validate(Data.Models.Listxml.Adjuster? adjuster)
{
Assert.NotNull(adjuster);
Assert.Equal("XXXXXX", adjuster.Name);
Assert.Equal("XXXXXX", adjuster.Default);
Validate(adjuster.Condition);
}
/// <summary>
/// Validate a Driver
/// </summary>
private static void Validate(Data.Models.Listxml.Driver? driver)
{
Assert.NotNull(driver);
Assert.Equal("XXXXXX", driver.Status);
Assert.Equal("XXXXXX", driver.Color);
Assert.Equal("XXXXXX", driver.Sound);
Assert.Equal("XXXXXX", driver.PaletteSize);
Assert.Equal("XXXXXX", driver.Emulation);
Assert.Equal("XXXXXX", driver.Cocktail);
Assert.Equal("XXXXXX", driver.SaveState);
Assert.Equal("XXXXXX", driver.RequiresArtwork);
Assert.Equal("XXXXXX", driver.Unofficial);
Assert.Equal("XXXXXX", driver.NoSoundHardware);
Assert.Equal("XXXXXX", driver.Incomplete);
}
/// <summary>
/// Validate a Feature
/// </summary>
private static void Validate(Data.Models.Listxml.Feature? feature)
{
Assert.NotNull(feature);
Assert.Equal("XXXXXX", feature.Type);
Assert.Equal("XXXXXX", feature.Status);
Assert.Equal("XXXXXX", feature.Overall);
}
/// <summary>
/// Validate a Device
/// </summary>
private static void Validate(Data.Models.Listxml.Device? device)
{
Assert.NotNull(device);
Assert.Equal("XXXXXX", device.Type);
Assert.Equal("XXXXXX", device.Tag);
Assert.Equal("XXXXXX", device.FixedImage);
Assert.Equal("XXXXXX", device.Mandatory);
Assert.Equal("XXXXXX", device.Interface);
Validate(device.Instance);
Assert.NotNull(device.Extension);
var extension = Assert.Single(device.Extension);
Validate(extension);
}
/// <summary>
/// Validate a Instance
/// </summary>
private static void Validate(Data.Models.Listxml.Instance? instance)
{
Assert.NotNull(instance);
Assert.Equal("XXXXXX", instance.Name);
Assert.Equal("XXXXXX", instance.BriefName);
}
/// <summary>
/// Validate a Extension
/// </summary>
private static void Validate(Data.Models.Listxml.Extension? extension)
{
Assert.NotNull(extension);
Assert.Equal("XXXXXX", extension.Name);
}
/// <summary>
/// Validate a Slot
/// </summary>
private static void Validate(Data.Models.Listxml.Slot? slot)
{
Assert.NotNull(slot);
Assert.Equal("XXXXXX", slot.Name);
Assert.NotNull(slot.SlotOption);
var slotoption = Assert.Single(slot.SlotOption);
Validate(slotoption);
}
/// <summary>
/// Validate a SlotOption
/// </summary>
private static void Validate(Data.Models.Listxml.SlotOption? slotoption)
{
Assert.NotNull(slotoption);
Assert.Equal("XXXXXX", slotoption.Name);
Assert.Equal("XXXXXX", slotoption.DevName);
Assert.Equal("XXXXXX", slotoption.Default);
}
/// <summary>
/// Validate a SoftwareList
/// </summary>
private static void Validate(Data.Models.Listxml.SoftwareList? softwarelist)
{
Assert.NotNull(softwarelist);
Assert.Equal("XXXXXX", softwarelist.Tag);
Assert.Equal("XXXXXX", softwarelist.Name);
Assert.Equal("XXXXXX", softwarelist.Status);
Assert.Equal("XXXXXX", softwarelist.Filter);
}
/// <summary>
/// Validate a RamOption
/// </summary>
private static void Validate(Data.Models.Listxml.RamOption? ramoption)
{
Assert.NotNull(ramoption);
Assert.Equal("XXXXXX", ramoption.Name);
Assert.Equal("XXXXXX", ramoption.Default);
Assert.Equal("XXXXXX", ramoption.Content);
}
}
}

View File

@@ -0,0 +1,571 @@
using SabreTools.Serialization.CrossModel;
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class LogiqxTests
{
[Fact]
public void RoundTripGameTest()
{
// Get the cross-model serializer
var serializer = new Logiqx();
// Build the data
Data.Models.Logiqx.Datafile df = Build(game: true);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(df);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Logiqx.Datafile? newDf = serializer.Deserialize(metadata, game: true);
// Validate the data
Assert.NotNull(newDf);
Assert.Equal("XXXXXX", newDf.Build);
Assert.Equal("XXXXXX", newDf.Debug);
Assert.Equal("XXXXXX", newDf.SchemaLocation);
Validate(newDf.Header);
Assert.NotNull(newDf.Game);
Assert.Equal(2, newDf.Game.Length);
Validate(newDf.Game[0], nested: false);
Validate(newDf.Game[1], nested: true);
// TODO: Unsupported for round-trip
Assert.Null(newDf.Dir);
}
[Fact]
public void RoundTripMachineTest()
{
// Get the cross-model serializer
var serializer = new Logiqx();
// Build the data
Data.Models.Logiqx.Datafile df = Build(game: false);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(df);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Logiqx.Datafile? newDf = serializer.Deserialize(metadata, game: false);
// Validate the data
Assert.NotNull(newDf);
Assert.Equal("XXXXXX", newDf.Build);
Assert.Equal("XXXXXX", newDf.Debug);
Assert.Equal("XXXXXX", newDf.SchemaLocation);
Validate(newDf.Header);
Assert.NotNull(newDf.Game);
Assert.Equal(2, newDf.Game.Length);
Validate(newDf.Game[0], nested: false);
Validate(newDf.Game[1], nested: true);
// TODO: Unsupported for round-trip
Assert.Null(newDf.Dir);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.Logiqx.Datafile Build(bool game)
{
var clrmamepro = new Data.Models.Logiqx.ClrMamePro
{
Header = "XXXXXX",
ForceMerging = "XXXXXX",
ForceNodump = "XXXXXX",
ForcePacking = "XXXXXX",
};
var romcenter = new Data.Models.Logiqx.RomCenter
{
Plugin = "XXXXXX",
RomMode = "XXXXXX",
BiosMode = "XXXXXX",
SampleMode = "XXXXXX",
LockRomMode = "XXXXXX",
LockBiosMode = "XXXXXX",
LockSampleMode = "XXXXXX",
};
var header = new Data.Models.Logiqx.Header
{
Id = "XXXXXX",
Name = "XXXXXX",
Description = "XXXXXX",
RootDir = "XXXXXX",
Category = "XXXXXX",
Version = "XXXXXX",
Date = "XXXXXX",
Author = "XXXXXX",
Email = "XXXXXX",
Homepage = "XXXXXX",
Url = "XXXXXX",
Comment = "XXXXXX",
Type = "XXXXXX",
ClrMamePro = clrmamepro,
RomCenter = romcenter,
};
var trurip = new Data.Models.Logiqx.Trurip
{
TitleID = "XXXXXX",
Publisher = "XXXXXX",
Developer = "XXXXXX",
Year = "XXXXXX",
Genre = "XXXXXX",
Subgenre = "XXXXXX",
Ratings = "XXXXXX",
Score = "XXXXXX",
Players = "XXXXXX",
Enabled = "XXXXXX",
CRC = "XXXXXX",
Source = "XXXXXX",
CloneOf = "XXXXXX",
RelatedTo = "XXXXXX",
};
var release = new Data.Models.Logiqx.Release
{
Name = "XXXXXX",
Region = "XXXXXX",
Language = "XXXXXX",
Date = "XXXXXX",
Default = "XXXXXX",
};
var biosset = new Data.Models.Logiqx.BiosSet
{
Name = "XXXXXX",
Description = "XXXXXX",
Default = "XXXXXX",
};
var rom = new Data.Models.Logiqx.Rom
{
Name = "XXXXXX",
Size = "XXXXXX",
CRC = "XXXXXX",
MD2 = "XXXXXX",
MD4 = "XXXXXX",
MD5 = "XXXXXX",
RIPEMD128 = "XXXXXX",
RIPEMD160 = "XXXXXX",
SHA1 = "XXXXXX",
SHA256 = "XXXXXX",
SHA384 = "XXXXXX",
SHA512 = "XXXXXX",
SpamSum = "XXXXXX",
xxHash364 = "XXXXXX",
xxHash3128 = "XXXXXX",
Merge = "XXXXXX",
Status = "XXXXXX",
Serial = "XXXXXX",
Header = "XXXXXX",
Date = "XXXXXX",
Inverted = "XXXXXX",
MIA = "XXXXXX",
};
var disk = new Data.Models.Logiqx.Disk
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Status = "XXXXXX",
Region = "XXXXXX",
};
var media = new Data.Models.Logiqx.Media
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
SHA256 = "XXXXXX",
SpamSum = "XXXXXX",
};
var deviceRef = new Data.Models.Logiqx.DeviceRef
{
Name = "XXXXXX",
};
var sample = new Data.Models.Logiqx.Sample
{
Name = "XXXXXX",
};
var archive = new Data.Models.Logiqx.Archive
{
Name = "XXXXXX",
};
var driver = new Data.Models.Logiqx.Driver
{
Status = "XXXXXX",
Emulation = "XXXXXX",
Cocktail = "XXXXXX",
SaveState = "XXXXXX",
RequiresArtwork = "XXXXXX",
Unofficial = "XXXXXX",
NoSoundHardware = "XXXXXX",
Incomplete = "XXXXXX",
};
var softwarelist = new Data.Models.Logiqx.SoftwareList
{
Tag = "XXXXXX",
Name = "XXXXXX",
Status = "XXXXXX",
Filter = "XXXXXX",
};
Data.Models.Logiqx.GameBase gameBase = game
? new Data.Models.Logiqx.Game()
: new Data.Models.Logiqx.Machine();
gameBase.Name = "XXXXXX";
gameBase.SourceFile = "XXXXXX";
gameBase.IsBios = "XXXXXX";
gameBase.IsDevice = "XXXXXX";
gameBase.IsMechanical = "XXXXXX";
gameBase.CloneOf = "XXXXXX";
gameBase.RomOf = "XXXXXX";
gameBase.SampleOf = "XXXXXX";
gameBase.Board = "XXXXXX";
gameBase.RebuildTo = "XXXXXX";
gameBase.Id = "XXXXXX";
gameBase.CloneOfId = "XXXXXX";
gameBase.Runnable = "XXXXXX";
gameBase.Comment = ["XXXXXX"];
gameBase.Description = "XXXXXX";
gameBase.Year = "XXXXXX";
gameBase.Manufacturer = "XXXXXX";
gameBase.Publisher = "XXXXXX";
gameBase.Category = ["XXXXXX"];
gameBase.Trurip = trurip;
gameBase.Release = [release];
gameBase.BiosSet = [biosset];
gameBase.Rom = [rom];
gameBase.Disk = [disk];
gameBase.Media = [media];
gameBase.DeviceRef = [deviceRef];
gameBase.Sample = [sample];
gameBase.Archive = [archive];
gameBase.Driver = driver;
gameBase.SoftwareList = [softwarelist];
var subdir = new Data.Models.Logiqx.Dir
{
Name = "XXXXXX",
Game = [gameBase],
};
var dir = new Data.Models.Logiqx.Dir
{
Name = "XXXXXX",
Subdir = [subdir],
};
return new Data.Models.Logiqx.Datafile
{
Build = "XXXXXX",
Debug = "XXXXXX",
SchemaLocation = "XXXXXX",
Header = header,
Game = [gameBase],
Dir = [dir],
};
}
/// <summary>
/// Validate a Header
/// </summary>
private static void Validate(Data.Models.Logiqx.Header? header)
{
Assert.NotNull(header);
Assert.Equal("XXXXXX", header.Id);
Assert.Equal("XXXXXX", header.Name);
Assert.Equal("XXXXXX", header.Description);
Assert.Equal("XXXXXX", header.RootDir);
Assert.Equal("XXXXXX", header.Category);
Assert.Equal("XXXXXX", header.Version);
Assert.Equal("XXXXXX", header.Date);
Assert.Equal("XXXXXX", header.Author);
Assert.Equal("XXXXXX", header.Email);
Assert.Equal("XXXXXX", header.Homepage);
Assert.Equal("XXXXXX", header.Url);
Assert.Equal("XXXXXX", header.Comment);
Assert.Equal("XXXXXX", header.Type);
Validate(header.ClrMamePro);
Validate(header.RomCenter);
}
/// <summary>
/// Validate a ClrMamePro
/// </summary>
private static void Validate(Data.Models.Logiqx.ClrMamePro? cmp)
{
Assert.NotNull(cmp);
Assert.Equal("XXXXXX", cmp.Header);
Assert.Equal("XXXXXX", cmp.ForceMerging);
Assert.Equal("XXXXXX", cmp.ForceNodump);
Assert.Equal("XXXXXX", cmp.ForcePacking);
}
/// <summary>
/// Validate a RomCenter
/// </summary>
private static void Validate(Data.Models.Logiqx.RomCenter? rc)
{
Assert.NotNull(rc);
Assert.Equal("XXXXXX", rc.Plugin);
Assert.Equal("XXXXXX", rc.RomMode);
Assert.Equal("XXXXXX", rc.BiosMode);
Assert.Equal("XXXXXX", rc.SampleMode);
Assert.Equal("XXXXXX", rc.LockRomMode);
Assert.Equal("XXXXXX", rc.LockBiosMode);
Assert.Equal("XXXXXX", rc.LockSampleMode);
}
/// <summary>
/// Validate a GameBase
/// </summary>
private static void Validate(Data.Models.Logiqx.GameBase? gb, bool nested)
{
Assert.NotNull(gb);
if (nested)
Assert.Equal("XXXXXX\\XXXXXX\\XXXXXX", gb.Name);
else
Assert.Equal("XXXXXX", gb.Name);
Assert.Equal("XXXXXX", gb.SourceFile);
Assert.Equal("XXXXXX", gb.IsBios);
Assert.Equal("XXXXXX", gb.IsDevice);
Assert.Equal("XXXXXX", gb.IsMechanical);
Assert.Equal("XXXXXX", gb.CloneOf);
Assert.Equal("XXXXXX", gb.RomOf);
Assert.Equal("XXXXXX", gb.SampleOf);
Assert.Equal("XXXXXX", gb.Board);
Assert.Equal("XXXXXX", gb.RebuildTo);
Assert.Equal("XXXXXX", gb.Id);
Assert.Equal("XXXXXX", gb.CloneOfId);
Assert.Equal("XXXXXX", gb.Runnable);
Assert.NotNull(gb.Comment);
string comment = Assert.Single(gb.Comment);
Assert.Equal("XXXXXX", comment);
Assert.Equal("XXXXXX", gb.Description);
Assert.Equal("XXXXXX", gb.Year);
Assert.Equal("XXXXXX", gb.Manufacturer);
Assert.Equal("XXXXXX", gb.Publisher);
Assert.NotNull(gb.Category);
string category = Assert.Single(gb.Category);
Assert.Equal("XXXXXX", category);
Validate(gb.Trurip);
Assert.NotNull(gb.Release);
var release = Assert.Single(gb.Release);
Validate(release);
Assert.NotNull(gb.BiosSet);
var biosset = Assert.Single(gb.BiosSet);
Validate(biosset);
Assert.NotNull(gb.Rom);
var rom = Assert.Single(gb.Rom);
Validate(rom);
Assert.NotNull(gb.Disk);
var disk = Assert.Single(gb.Disk);
Validate(disk);
Assert.NotNull(gb.Media);
var media = Assert.Single(gb.Media);
Validate(media);
Assert.NotNull(gb.DeviceRef);
var deviceref = Assert.Single(gb.DeviceRef);
Validate(deviceref);
Assert.NotNull(gb.Sample);
var sample = Assert.Single(gb.Sample);
Validate(sample);
Assert.NotNull(gb.Archive);
var archive = Assert.Single(gb.Archive);
Validate(archive);
Validate(gb.Driver);
Assert.NotNull(gb.SoftwareList);
var softwarelist = Assert.Single(gb.SoftwareList);
Validate(softwarelist);
}
/// <summary>
/// Validate a Trurip
/// </summary>
private static void Validate(Data.Models.Logiqx.Trurip? trurip)
{
Assert.NotNull(trurip);
Assert.Equal("XXXXXX", trurip.TitleID);
Assert.Equal("XXXXXX", trurip.Publisher);
Assert.Equal("XXXXXX", trurip.Developer);
Assert.Equal("XXXXXX", trurip.Year);
Assert.Equal("XXXXXX", trurip.Genre);
Assert.Equal("XXXXXX", trurip.Subgenre);
Assert.Equal("XXXXXX", trurip.Ratings);
Assert.Equal("XXXXXX", trurip.Score);
Assert.Equal("XXXXXX", trurip.Players);
Assert.Equal("XXXXXX", trurip.Enabled);
Assert.Equal("XXXXXX", trurip.CRC);
Assert.Equal("XXXXXX", trurip.Source);
Assert.Equal("XXXXXX", trurip.CloneOf);
Assert.Equal("XXXXXX", trurip.RelatedTo);
}
/// <summary>
/// Validate a Release
/// </summary>
private static void Validate(Data.Models.Logiqx.Release? release)
{
Assert.NotNull(release);
Assert.Equal("XXXXXX", release.Name);
Assert.Equal("XXXXXX", release.Region);
Assert.Equal("XXXXXX", release.Language);
Assert.Equal("XXXXXX", release.Date);
Assert.Equal("XXXXXX", release.Default);
}
/// <summary>
/// Validate a BiosSet
/// </summary>
private static void Validate(Data.Models.Logiqx.BiosSet? biosset)
{
Assert.NotNull(biosset);
Assert.Equal("XXXXXX", biosset.Name);
Assert.Equal("XXXXXX", biosset.Description);
Assert.Equal("XXXXXX", biosset.Default);
}
/// <summary>
/// Validate a Rom
/// </summary>
private static void Validate(Data.Models.Logiqx.Rom? rom)
{
Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.Name);
Assert.Equal("XXXXXX", rom.Size);
Assert.Equal("XXXXXX", rom.CRC);
Assert.Equal("XXXXXX", rom.MD2);
Assert.Equal("XXXXXX", rom.MD4);
Assert.Equal("XXXXXX", rom.MD5);
Assert.Equal("XXXXXX", rom.RIPEMD128);
Assert.Equal("XXXXXX", rom.RIPEMD160);
Assert.Equal("XXXXXX", rom.SHA1);
Assert.Equal("XXXXXX", rom.SHA256);
Assert.Equal("XXXXXX", rom.SHA384);
Assert.Equal("XXXXXX", rom.SHA512);
Assert.Equal("XXXXXX", rom.SpamSum);
Assert.Equal("XXXXXX", rom.xxHash364);
Assert.Equal("XXXXXX", rom.xxHash3128);
Assert.Equal("XXXXXX", rom.Merge);
Assert.Equal("XXXXXX", rom.Status);
Assert.Equal("XXXXXX", rom.Serial);
Assert.Equal("XXXXXX", rom.Header);
Assert.Equal("XXXXXX", rom.Date);
Assert.Equal("XXXXXX", rom.Inverted);
Assert.Equal("XXXXXX", rom.MIA);
}
/// <summary>
/// Validate a Disk
/// </summary>
private static void Validate(Data.Models.Logiqx.Disk? disk)
{
Assert.NotNull(disk);
Assert.Equal("XXXXXX", disk.Name);
Assert.Equal("XXXXXX", disk.MD5);
Assert.Equal("XXXXXX", disk.SHA1);
Assert.Equal("XXXXXX", disk.Merge);
Assert.Equal("XXXXXX", disk.Status);
Assert.Equal("XXXXXX", disk.Region);
}
/// <summary>
/// Validate a Media
/// </summary>
private static void Validate(Data.Models.Logiqx.Media? media)
{
Assert.NotNull(media);
Assert.Equal("XXXXXX", media.Name);
Assert.Equal("XXXXXX", media.MD5);
Assert.Equal("XXXXXX", media.SHA1);
Assert.Equal("XXXXXX", media.SHA256);
Assert.Equal("XXXXXX", media.SpamSum);
}
/// <summary>
/// Validate a DeviceRef
/// </summary>
private static void Validate(Data.Models.Logiqx.DeviceRef? deviceref)
{
Assert.NotNull(deviceref);
Assert.Equal("XXXXXX", deviceref.Name);
}
/// <summary>
/// Validate a Sample
/// </summary>
private static void Validate(Data.Models.Logiqx.Sample? sample)
{
Assert.NotNull(sample);
Assert.Equal("XXXXXX", sample.Name);
}
/// <summary>
/// Validate a Archive
/// </summary>
private static void Validate(Data.Models.Logiqx.Archive? archive)
{
Assert.NotNull(archive);
Assert.Equal("XXXXXX", archive.Name);
}
/// <summary>
/// Validate a Driver
/// </summary>
private static void Validate(Data.Models.Logiqx.Driver? driver)
{
Assert.NotNull(driver);
Assert.Equal("XXXXXX", driver.Status);
Assert.Equal("XXXXXX", driver.Emulation);
Assert.Equal("XXXXXX", driver.Cocktail);
Assert.Equal("XXXXXX", driver.SaveState);
Assert.Equal("XXXXXX", driver.RequiresArtwork);
Assert.Equal("XXXXXX", driver.Unofficial);
Assert.Equal("XXXXXX", driver.NoSoundHardware);
Assert.Equal("XXXXXX", driver.Incomplete);
}
/// <summary>
/// Validate a SoftwareList
/// </summary>
private static void Validate(Data.Models.Logiqx.SoftwareList? softwarelist)
{
Assert.NotNull(softwarelist);
Assert.Equal("XXXXXX", softwarelist.Tag);
Assert.Equal("XXXXXX", softwarelist.Name);
Assert.Equal("XXXXXX", softwarelist.Status);
Assert.Equal("XXXXXX", softwarelist.Filter);
}
}
}

View File

@@ -0,0 +1,873 @@
using SabreTools.Serialization.CrossModel;
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class M1Tests
{
[Fact]
public void RoundTripGameTest()
{
// Get the cross-model serializer
var serializer = new M1();
// Build the data
Data.Models.Listxml.M1 m1 = Build(game: true);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(m1);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Listxml.M1? newM1 = serializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newM1);
Assert.Equal("XXXXXX", newM1.Version);
Assert.NotNull(newM1.Game);
var newGame = Assert.Single(newM1.Game);
Validate(newGame);
}
[Fact]
public void RoundTripMachineTest()
{
// Get the cross-model serializer
var serializer = new M1();
// Build the data
Data.Models.Listxml.M1 m1 = Build(game: false);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(m1);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Listxml.M1? newM1 = serializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newM1);
Assert.Equal("XXXXXX", newM1.Version);
Assert.NotNull(newM1.Game);
var newGame = Assert.Single(newM1.Game);
Validate(newGame);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.Listxml.M1 Build(bool game)
{
var biosset = new Data.Models.Listxml.BiosSet
{
Name = "XXXXXX",
Description = "XXXXXX",
Default = "XXXXXX",
};
var rom = new Data.Models.Listxml.Rom
{
Name = "XXXXXX",
Bios = "XXXXXX",
Size = "XXXXXX",
CRC = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Region = "XXXXXX",
Offset = "XXXXXX",
Status = "XXXXXX",
Optional = "XXXXXX",
Dispose = "XXXXXX",
SoundOnly = "XXXXXX",
};
var disk = new Data.Models.Listxml.Disk
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Region = "XXXXXX",
Index = "XXXXXX",
Writable = "XXXXXX",
Status = "XXXXXX",
Optional = "XXXXXX",
};
var deviceref = new Data.Models.Listxml.DeviceRef
{
Name = "XXXXXX",
};
var sample = new Data.Models.Listxml.Sample
{
Name = "XXXXXX",
};
var chip = new Data.Models.Listxml.Chip
{
Name = "XXXXXX",
Tag = "XXXXXX",
Type = "XXXXXX",
SoundOnly = "XXXXXX",
Clock = "XXXXXX",
};
var display = new Data.Models.Listxml.Display
{
Tag = "XXXXXX",
Type = "XXXXXX",
Rotate = "XXXXXX",
FlipX = "XXXXXX",
Width = "XXXXXX",
Height = "XXXXXX",
Refresh = "XXXXXX",
PixClock = "XXXXXX",
HTotal = "XXXXXX",
HBEnd = "XXXXXX",
HBStart = "XXXXXX",
VTotal = "XXXXXX",
VBEnd = "XXXXXX",
VBStart = "XXXXXX",
};
var video = new Data.Models.Listxml.Video
{
Screen = "XXXXXX",
Orientation = "XXXXXX",
Width = "XXXXXX",
Height = "XXXXXX",
AspectX = "XXXXXX",
AspectY = "XXXXXX",
Refresh = "XXXXXX",
};
var sound = new Data.Models.Listxml.Sound
{
Channels = "XXXXXX",
};
var control = new Data.Models.Listxml.Control
{
Type = "XXXXXX",
Player = "XXXXXX",
Buttons = "XXXXXX",
ReqButtons = "XXXXXX",
Minimum = "XXXXXX",
Maximum = "XXXXXX",
Sensitivity = "XXXXXX",
KeyDelta = "XXXXXX",
Reverse = "XXXXXX",
Ways = "XXXXXX",
Ways2 = "XXXXXX",
Ways3 = "XXXXXX",
};
var input = new Data.Models.Listxml.Input
{
Service = "XXXXXX",
Tilt = "XXXXXX",
Players = "XXXXXX",
//ControlAttr = "XXXXXX", // Mututally exclusive with input.Control
Buttons = "XXXXXX",
Coins = "XXXXXX",
Control = [control],
};
var condition = new Data.Models.Listxml.Condition
{
Tag = "XXXXXX",
Mask = "XXXXXX",
Relation = "XXXXXX",
Value = "XXXXXX",
};
var diplocation = new Data.Models.Listxml.DipLocation
{
Name = "XXXXXX",
Number = "XXXXXX",
Inverted = "XXXXXX",
};
var dipvalue = new Data.Models.Listxml.DipValue
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var dipswitch = new Data.Models.Listxml.DipSwitch
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
Condition = condition,
DipLocation = [diplocation],
DipValue = [dipvalue],
};
var conflocation = new Data.Models.Listxml.ConfLocation
{
Name = "XXXXXX",
Number = "XXXXXX",
Inverted = "XXXXXX",
};
var confsetting = new Data.Models.Listxml.ConfSetting
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var configuration = new Data.Models.Listxml.Configuration
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
Condition = condition,
ConfLocation = [conflocation],
ConfSetting = [confsetting],
};
var analog = new Data.Models.Listxml.Analog
{
Mask = "XXXXXX",
};
var port = new Data.Models.Listxml.Port
{
Tag = "XXXXXX",
Analog = [analog],
};
var adjuster = new Data.Models.Listxml.Adjuster
{
Name = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var driver = new Data.Models.Listxml.Driver
{
Status = "XXXXXX",
Color = "XXXXXX",
Sound = "XXXXXX",
PaletteSize = "XXXXXX",
Emulation = "XXXXXX",
Cocktail = "XXXXXX",
SaveState = "XXXXXX",
RequiresArtwork = "XXXXXX",
Unofficial = "XXXXXX",
NoSoundHardware = "XXXXXX",
Incomplete = "XXXXXX",
};
var feature = new Data.Models.Listxml.Feature
{
Type = "XXXXXX",
Status = "XXXXXX",
Overall = "XXXXXX",
};
var instance = new Data.Models.Listxml.Instance
{
Name = "XXXXXX",
BriefName = "XXXXXX",
};
var extension = new Data.Models.Listxml.Extension
{
Name = "XXXXXX",
};
var device = new Data.Models.Listxml.Device
{
Type = "XXXXXX",
Tag = "XXXXXX",
FixedImage = "XXXXXX",
Mandatory = "XXXXXX",
Interface = "XXXXXX",
Instance = instance,
Extension = [extension],
};
var slotOption = new Data.Models.Listxml.SlotOption
{
Name = "XXXXXX",
DevName = "XXXXXX",
Default = "XXXXXX",
};
var slot = new Data.Models.Listxml.Slot
{
Name = "XXXXXX",
SlotOption = [slotOption],
};
var softwarelist = new Data.Models.Listxml.SoftwareList
{
Tag = "XXXXXX",
Name = "XXXXXX",
Status = "XXXXXX",
Filter = "XXXXXX",
};
var ramoption = new Data.Models.Listxml.RamOption
{
Name = "XXXXXX",
Default = "XXXXXX",
Content = "XXXXXX",
};
Data.Models.Listxml.GameBase gameBase = game
? new Data.Models.Listxml.Game()
: new Data.Models.Listxml.Machine();
gameBase.Name = "XXXXXX";
gameBase.SourceFile = "XXXXXX";
gameBase.IsBios = "XXXXXX";
gameBase.IsDevice = "XXXXXX";
gameBase.IsMechanical = "XXXXXX";
gameBase.Runnable = "XXXXXX";
gameBase.CloneOf = "XXXXXX";
gameBase.RomOf = "XXXXXX";
gameBase.SampleOf = "XXXXXX";
gameBase.Description = "XXXXXX";
gameBase.Year = "XXXXXX";
gameBase.Manufacturer = "XXXXXX";
gameBase.History = "XXXXXX";
gameBase.BiosSet = [biosset];
gameBase.Rom = [rom];
gameBase.Disk = [disk];
gameBase.DeviceRef = [deviceref];
gameBase.Sample = [sample];
gameBase.Chip = [chip];
gameBase.Display = [display];
gameBase.Video = [video];
gameBase.Sound = sound;
gameBase.Input = input;
gameBase.DipSwitch = [dipswitch];
gameBase.Configuration = [configuration];
gameBase.Port = [port];
gameBase.Adjuster = [adjuster];
gameBase.Driver = driver;
gameBase.Feature = [feature];
gameBase.Device = [device];
gameBase.Slot = [slot];
gameBase.SoftwareList = [softwarelist];
gameBase.RamOption = [ramoption];
return new Data.Models.Listxml.M1
{
Version = "XXXXXX",
Game = [gameBase],
};
}
/// <summary>
/// Validate a GameBase
/// </summary>
private static void Validate(Data.Models.Listxml.GameBase? gb)
{
Assert.NotNull(gb);
Assert.Equal("XXXXXX", gb.Name);
Assert.Equal("XXXXXX", gb.SourceFile);
Assert.Equal("XXXXXX", gb.IsBios);
Assert.Equal("XXXXXX", gb.IsDevice);
Assert.Equal("XXXXXX", gb.IsMechanical);
Assert.Equal("XXXXXX", gb.Runnable);
Assert.Equal("XXXXXX", gb.CloneOf);
Assert.Equal("XXXXXX", gb.RomOf);
Assert.Equal("XXXXXX", gb.SampleOf);
Assert.Equal("XXXXXX", gb.Description);
Assert.Equal("XXXXXX", gb.Year);
Assert.Equal("XXXXXX", gb.Manufacturer);
Assert.Equal("XXXXXX", gb.History);
Assert.NotNull(gb.BiosSet);
var biosset = Assert.Single(gb.BiosSet);
Validate(biosset);
Assert.NotNull(gb.Rom);
var rom = Assert.Single(gb.Rom);
Validate(rom);
Assert.NotNull(gb.Disk);
var disk = Assert.Single(gb.Disk);
Validate(disk);
Assert.NotNull(gb.DeviceRef);
var deviceref = Assert.Single(gb.DeviceRef);
Validate(deviceref);
Assert.NotNull(gb.Sample);
var sample = Assert.Single(gb.Sample);
Validate(sample);
Assert.NotNull(gb.Chip);
var chip = Assert.Single(gb.Chip);
Validate(chip);
Assert.NotNull(gb.Display);
var display = Assert.Single(gb.Display);
Validate(display);
Assert.NotNull(gb.Video);
var video = Assert.Single(gb.Video);
Validate(video);
Validate(gb.Sound);
Validate(gb.Input);
Assert.NotNull(gb.DipSwitch);
var dipswitch = Assert.Single(gb.DipSwitch);
Validate(dipswitch);
Assert.NotNull(gb.Configuration);
var configuration = Assert.Single(gb.Configuration);
Validate(configuration);
Assert.NotNull(gb.Port);
var port = Assert.Single(gb.Port);
Validate(port);
Assert.NotNull(gb.Adjuster);
var adjuster = Assert.Single(gb.Adjuster);
Validate(adjuster);
Validate(gb.Driver);
Assert.NotNull(gb.Feature);
var feature = Assert.Single(gb.Feature);
Validate(feature);
Assert.NotNull(gb.Device);
var device = Assert.Single(gb.Device);
Validate(device);
Assert.NotNull(gb.Slot);
var slot = Assert.Single(gb.Slot);
Validate(slot);
Assert.NotNull(gb.SoftwareList);
var softwarelist = Assert.Single(gb.SoftwareList);
Validate(softwarelist);
Assert.NotNull(gb.RamOption);
var ramoption = Assert.Single(gb.RamOption);
Validate(ramoption);
}
/// <summary>
/// Validate a BiosSet
/// </summary>
private static void Validate(Data.Models.Listxml.BiosSet? biosset)
{
Assert.NotNull(biosset);
Assert.Equal("XXXXXX", biosset.Name);
Assert.Equal("XXXXXX", biosset.Description);
Assert.Equal("XXXXXX", biosset.Default);
}
/// <summary>
/// Validate a Rom
/// </summary>
private static void Validate(Data.Models.Listxml.Rom? rom)
{
Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.Name);
Assert.Equal("XXXXXX", rom.Bios);
Assert.Equal("XXXXXX", rom.Size);
Assert.Equal("XXXXXX", rom.CRC);
Assert.Equal("XXXXXX", rom.SHA1);
Assert.Equal("XXXXXX", rom.Merge);
Assert.Equal("XXXXXX", rom.Region);
Assert.Equal("XXXXXX", rom.Offset);
Assert.Equal("XXXXXX", rom.Status);
Assert.Equal("XXXXXX", rom.Optional);
Assert.Equal("XXXXXX", rom.Dispose);
Assert.Equal("XXXXXX", rom.SoundOnly);
}
/// <summary>
/// Validate a Disk
/// </summary>
private static void Validate(Data.Models.Listxml.Disk? disk)
{
Assert.NotNull(disk);
Assert.Equal("XXXXXX", disk.Name);
Assert.Equal("XXXXXX", disk.MD5);
Assert.Equal("XXXXXX", disk.SHA1);
Assert.Equal("XXXXXX", disk.Merge);
Assert.Equal("XXXXXX", disk.Region);
Assert.Equal("XXXXXX", disk.Index);
Assert.Equal("XXXXXX", disk.Writable);
Assert.Equal("XXXXXX", disk.Status);
Assert.Equal("XXXXXX", disk.Optional);
}
/// <summary>
/// Validate a DeviceRef
/// </summary>
private static void Validate(Data.Models.Listxml.DeviceRef? deviceref)
{
Assert.NotNull(deviceref);
Assert.Equal("XXXXXX", deviceref.Name);
}
/// <summary>
/// Validate a Sample
/// </summary>
private static void Validate(Data.Models.Listxml.Sample? sample)
{
Assert.NotNull(sample);
Assert.Equal("XXXXXX", sample.Name);
}
/// <summary>
/// Validate a Chip
/// </summary>
private static void Validate(Data.Models.Listxml.Chip? chip)
{
Assert.NotNull(chip);
Assert.Equal("XXXXXX", chip.Name);
Assert.Equal("XXXXXX", chip.Tag);
Assert.Equal("XXXXXX", chip.Type);
Assert.Equal("XXXXXX", chip.SoundOnly);
Assert.Equal("XXXXXX", chip.Clock);
}
/// <summary>
/// Validate a Display
/// </summary>
private static void Validate(Data.Models.Listxml.Display? display)
{
Assert.NotNull(display);
Assert.Equal("XXXXXX", display.Tag);
Assert.Equal("XXXXXX", display.Type);
Assert.Equal("XXXXXX", display.Rotate);
Assert.Equal("XXXXXX", display.FlipX);
Assert.Equal("XXXXXX", display.Width);
Assert.Equal("XXXXXX", display.Height);
Assert.Equal("XXXXXX", display.Refresh);
Assert.Equal("XXXXXX", display.PixClock);
Assert.Equal("XXXXXX", display.HTotal);
Assert.Equal("XXXXXX", display.HBEnd);
Assert.Equal("XXXXXX", display.HBStart);
Assert.Equal("XXXXXX", display.VTotal);
Assert.Equal("XXXXXX", display.VBEnd);
Assert.Equal("XXXXXX", display.VBStart);
}
/// <summary>
/// Validate a Video
/// </summary>
private static void Validate(Data.Models.Listxml.Video? video)
{
Assert.NotNull(video);
Assert.Equal("XXXXXX", video.Screen);
Assert.Equal("XXXXXX", video.Orientation);
Assert.Equal("XXXXXX", video.Width);
Assert.Equal("XXXXXX", video.Height);
Assert.Equal("XXXXXX", video.AspectX);
Assert.Equal("XXXXXX", video.AspectY);
Assert.Equal("XXXXXX", video.Refresh);
}
/// <summary>
/// Validate a Sound
/// </summary>
private static void Validate(Data.Models.Listxml.Sound? sound)
{
Assert.NotNull(sound);
Assert.Equal("XXXXXX", sound.Channels);
}
/// <summary>
/// Validate a Input
/// </summary>
private static void Validate(Data.Models.Listxml.Input? input)
{
Assert.NotNull(input);
Assert.Equal("XXXXXX", input.Service);
Assert.Equal("XXXXXX", input.Tilt);
Assert.Equal("XXXXXX", input.Players);
//Assert.Equal("XXXXXX", input.ControlAttr); // Mututally exclusive with input.Control
Assert.Equal("XXXXXX", input.Buttons);
Assert.Equal("XXXXXX", input.Coins);
Assert.NotNull(input.Control);
var control = Assert.Single(input.Control);
Validate(control);
}
/// <summary>
/// Validate a Control
/// </summary>
private static void Validate(Data.Models.Listxml.Control? control)
{
Assert.NotNull(control);
Assert.Equal("XXXXXX", control.Type);
Assert.Equal("XXXXXX", control.Player);
Assert.Equal("XXXXXX", control.Buttons);
Assert.Equal("XXXXXX", control.ReqButtons);
Assert.Equal("XXXXXX", control.Minimum);
Assert.Equal("XXXXXX", control.Maximum);
Assert.Equal("XXXXXX", control.Sensitivity);
Assert.Equal("XXXXXX", control.KeyDelta);
Assert.Equal("XXXXXX", control.Reverse);
Assert.Equal("XXXXXX", control.Ways);
Assert.Equal("XXXXXX", control.Ways2);
Assert.Equal("XXXXXX", control.Ways3);
}
/// <summary>
/// Validate a DipSwitch
/// </summary>
private static void Validate(Data.Models.Listxml.DipSwitch? dipswitch)
{
Assert.NotNull(dipswitch);
Assert.Equal("XXXXXX", dipswitch.Name);
Assert.Equal("XXXXXX", dipswitch.Tag);
Assert.Equal("XXXXXX", dipswitch.Mask);
Validate(dipswitch.Condition);
Assert.NotNull(dipswitch.DipLocation);
var diplocation = Assert.Single(dipswitch.DipLocation);
Validate(diplocation);
Assert.NotNull(dipswitch.DipValue);
var dipvalue = Assert.Single(dipswitch.DipValue);
Validate(dipvalue);
}
/// <summary>
/// Validate a Condition
/// </summary>
private static void Validate(Data.Models.Listxml.Condition? condition)
{
Assert.NotNull(condition);
Assert.Equal("XXXXXX", condition.Tag);
Assert.Equal("XXXXXX", condition.Mask);
Assert.Equal("XXXXXX", condition.Relation);
Assert.Equal("XXXXXX", condition.Value);
}
/// <summary>
/// Validate a DipLocation
/// </summary>
private static void Validate(Data.Models.Listxml.DipLocation? diplocation)
{
Assert.NotNull(diplocation);
Assert.Equal("XXXXXX", diplocation.Name);
Assert.Equal("XXXXXX", diplocation.Number);
Assert.Equal("XXXXXX", diplocation.Inverted);
}
/// <summary>
/// Validate a DipValue
/// </summary>
private static void Validate(Data.Models.Listxml.DipValue? dipvalue)
{
Assert.NotNull(dipvalue);
Assert.Equal("XXXXXX", dipvalue.Name);
Assert.Equal("XXXXXX", dipvalue.Value);
Assert.Equal("XXXXXX", dipvalue.Default);
Validate(dipvalue.Condition);
}
/// <summary>
/// Validate a Configuration
/// </summary>
private static void Validate(Data.Models.Listxml.Configuration? configuration)
{
Assert.NotNull(configuration);
Assert.Equal("XXXXXX", configuration.Name);
Assert.Equal("XXXXXX", configuration.Tag);
Assert.Equal("XXXXXX", configuration.Mask);
Validate(configuration.Condition);
Assert.NotNull(configuration.ConfLocation);
var conflocation = Assert.Single(configuration.ConfLocation);
Validate(conflocation);
Assert.NotNull(configuration.ConfSetting);
var confsetting = Assert.Single(configuration.ConfSetting);
Validate(confsetting);
}
/// <summary>
/// Validate a ConfLocation
/// </summary>
private static void Validate(Data.Models.Listxml.ConfLocation? conflocation)
{
Assert.NotNull(conflocation);
Assert.Equal("XXXXXX", conflocation.Name);
Assert.Equal("XXXXXX", conflocation.Number);
Assert.Equal("XXXXXX", conflocation.Inverted);
}
/// <summary>
/// Validate a ConfSetting
/// </summary>
private static void Validate(Data.Models.Listxml.ConfSetting? confsetting)
{
Assert.NotNull(confsetting);
Assert.Equal("XXXXXX", confsetting.Name);
Assert.Equal("XXXXXX", confsetting.Value);
Assert.Equal("XXXXXX", confsetting.Default);
Validate(confsetting.Condition);
}
/// <summary>
/// Validate a Port
/// </summary>
private static void Validate(Data.Models.Listxml.Port? port)
{
Assert.NotNull(port);
Assert.Equal("XXXXXX", port.Tag);
Assert.NotNull(port.Analog);
var analog = Assert.Single(port.Analog);
Validate(analog);
}
/// <summary>
/// Validate a Analog
/// </summary>
private static void Validate(Data.Models.Listxml.Analog? analog)
{
Assert.NotNull(analog);
Assert.Equal("XXXXXX", analog.Mask);
}
/// <summary>
/// Validate a Adjuster
/// </summary>
private static void Validate(Data.Models.Listxml.Adjuster? adjuster)
{
Assert.NotNull(adjuster);
Assert.Equal("XXXXXX", adjuster.Name);
Assert.Equal("XXXXXX", adjuster.Default);
Validate(adjuster.Condition);
}
/// <summary>
/// Validate a Driver
/// </summary>
private static void Validate(Data.Models.Listxml.Driver? driver)
{
Assert.NotNull(driver);
Assert.Equal("XXXXXX", driver.Status);
Assert.Equal("XXXXXX", driver.Color);
Assert.Equal("XXXXXX", driver.Sound);
Assert.Equal("XXXXXX", driver.PaletteSize);
Assert.Equal("XXXXXX", driver.Emulation);
Assert.Equal("XXXXXX", driver.Cocktail);
Assert.Equal("XXXXXX", driver.SaveState);
Assert.Equal("XXXXXX", driver.RequiresArtwork);
Assert.Equal("XXXXXX", driver.Unofficial);
Assert.Equal("XXXXXX", driver.NoSoundHardware);
Assert.Equal("XXXXXX", driver.Incomplete);
}
/// <summary>
/// Validate a Feature
/// </summary>
private static void Validate(Data.Models.Listxml.Feature? feature)
{
Assert.NotNull(feature);
Assert.Equal("XXXXXX", feature.Type);
Assert.Equal("XXXXXX", feature.Status);
Assert.Equal("XXXXXX", feature.Overall);
}
/// <summary>
/// Validate a Device
/// </summary>
private static void Validate(Data.Models.Listxml.Device? device)
{
Assert.NotNull(device);
Assert.Equal("XXXXXX", device.Type);
Assert.Equal("XXXXXX", device.Tag);
Assert.Equal("XXXXXX", device.FixedImage);
Assert.Equal("XXXXXX", device.Mandatory);
Assert.Equal("XXXXXX", device.Interface);
Validate(device.Instance);
Assert.NotNull(device.Extension);
var extension = Assert.Single(device.Extension);
Validate(extension);
}
/// <summary>
/// Validate a Instance
/// </summary>
private static void Validate(Data.Models.Listxml.Instance? instance)
{
Assert.NotNull(instance);
Assert.Equal("XXXXXX", instance.Name);
Assert.Equal("XXXXXX", instance.BriefName);
}
/// <summary>
/// Validate a Extension
/// </summary>
private static void Validate(Data.Models.Listxml.Extension? extension)
{
Assert.NotNull(extension);
Assert.Equal("XXXXXX", extension.Name);
}
/// <summary>
/// Validate a Slot
/// </summary>
private static void Validate(Data.Models.Listxml.Slot? slot)
{
Assert.NotNull(slot);
Assert.Equal("XXXXXX", slot.Name);
Assert.NotNull(slot.SlotOption);
var slotoption = Assert.Single(slot.SlotOption);
Validate(slotoption);
}
/// <summary>
/// Validate a SlotOption
/// </summary>
private static void Validate(Data.Models.Listxml.SlotOption? slotoption)
{
Assert.NotNull(slotoption);
Assert.Equal("XXXXXX", slotoption.Name);
Assert.Equal("XXXXXX", slotoption.DevName);
Assert.Equal("XXXXXX", slotoption.Default);
}
/// <summary>
/// Validate a SoftwareList
/// </summary>
private static void Validate(Data.Models.Listxml.SoftwareList? softwarelist)
{
Assert.NotNull(softwarelist);
Assert.Equal("XXXXXX", softwarelist.Tag);
Assert.Equal("XXXXXX", softwarelist.Name);
Assert.Equal("XXXXXX", softwarelist.Status);
Assert.Equal("XXXXXX", softwarelist.Filter);
}
/// <summary>
/// Validate a RamOption
/// </summary>
private static void Validate(Data.Models.Listxml.RamOption? ramoption)
{
Assert.NotNull(ramoption);
Assert.Equal("XXXXXX", ramoption.Name);
Assert.Equal("XXXXXX", ramoption.Default);
Assert.Equal("XXXXXX", ramoption.Content);
}
}
}

View File

@@ -0,0 +1,873 @@
using SabreTools.Serialization.CrossModel;
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class MessTests
{
[Fact]
public void RoundTripGameTest()
{
// Get the cross-model serializer
var serializer = new Mess();
// Build the data
Data.Models.Listxml.Mess m1 = Build(game: true);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(m1);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Listxml.Mess? newMess = serializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newMess);
Assert.Equal("XXXXXX", newMess.Version);
Assert.NotNull(newMess.Game);
var newGame = Assert.Single(newMess.Game);
Validate(newGame);
}
[Fact]
public void RoundTripMachineTest()
{
// Get the cross-model serializer
var serializer = new Mess();
// Build the data
Data.Models.Listxml.Mess m1 = Build(game: false);
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(m1);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Listxml.Mess? newMess = serializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newMess);
Assert.Equal("XXXXXX", newMess.Version);
Assert.NotNull(newMess.Game);
var newGame = Assert.Single(newMess.Game);
Validate(newGame);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.Listxml.Mess Build(bool game)
{
var biosset = new Data.Models.Listxml.BiosSet
{
Name = "XXXXXX",
Description = "XXXXXX",
Default = "XXXXXX",
};
var rom = new Data.Models.Listxml.Rom
{
Name = "XXXXXX",
Bios = "XXXXXX",
Size = "XXXXXX",
CRC = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Region = "XXXXXX",
Offset = "XXXXXX",
Status = "XXXXXX",
Optional = "XXXXXX",
Dispose = "XXXXXX",
SoundOnly = "XXXXXX",
};
var disk = new Data.Models.Listxml.Disk
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Region = "XXXXXX",
Index = "XXXXXX",
Writable = "XXXXXX",
Status = "XXXXXX",
Optional = "XXXXXX",
};
var deviceref = new Data.Models.Listxml.DeviceRef
{
Name = "XXXXXX",
};
var sample = new Data.Models.Listxml.Sample
{
Name = "XXXXXX",
};
var chip = new Data.Models.Listxml.Chip
{
Name = "XXXXXX",
Tag = "XXXXXX",
Type = "XXXXXX",
SoundOnly = "XXXXXX",
Clock = "XXXXXX",
};
var display = new Data.Models.Listxml.Display
{
Tag = "XXXXXX",
Type = "XXXXXX",
Rotate = "XXXXXX",
FlipX = "XXXXXX",
Width = "XXXXXX",
Height = "XXXXXX",
Refresh = "XXXXXX",
PixClock = "XXXXXX",
HTotal = "XXXXXX",
HBEnd = "XXXXXX",
HBStart = "XXXXXX",
VTotal = "XXXXXX",
VBEnd = "XXXXXX",
VBStart = "XXXXXX",
};
var video = new Data.Models.Listxml.Video
{
Screen = "XXXXXX",
Orientation = "XXXXXX",
Width = "XXXXXX",
Height = "XXXXXX",
AspectX = "XXXXXX",
AspectY = "XXXXXX",
Refresh = "XXXXXX",
};
var sound = new Data.Models.Listxml.Sound
{
Channels = "XXXXXX",
};
var control = new Data.Models.Listxml.Control
{
Type = "XXXXXX",
Player = "XXXXXX",
Buttons = "XXXXXX",
ReqButtons = "XXXXXX",
Minimum = "XXXXXX",
Maximum = "XXXXXX",
Sensitivity = "XXXXXX",
KeyDelta = "XXXXXX",
Reverse = "XXXXXX",
Ways = "XXXXXX",
Ways2 = "XXXXXX",
Ways3 = "XXXXXX",
};
var input = new Data.Models.Listxml.Input
{
Service = "XXXXXX",
Tilt = "XXXXXX",
Players = "XXXXXX",
//ControlAttr = "XXXXXX", // Mututally exclusive with input.Control
Buttons = "XXXXXX",
Coins = "XXXXXX",
Control = [control],
};
var condition = new Data.Models.Listxml.Condition
{
Tag = "XXXXXX",
Mask = "XXXXXX",
Relation = "XXXXXX",
Value = "XXXXXX",
};
var diplocation = new Data.Models.Listxml.DipLocation
{
Name = "XXXXXX",
Number = "XXXXXX",
Inverted = "XXXXXX",
};
var dipvalue = new Data.Models.Listxml.DipValue
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var dipswitch = new Data.Models.Listxml.DipSwitch
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
Condition = condition,
DipLocation = [diplocation],
DipValue = [dipvalue],
};
var conflocation = new Data.Models.Listxml.ConfLocation
{
Name = "XXXXXX",
Number = "XXXXXX",
Inverted = "XXXXXX",
};
var confsetting = new Data.Models.Listxml.ConfSetting
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var configuration = new Data.Models.Listxml.Configuration
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
Condition = condition,
ConfLocation = [conflocation],
ConfSetting = [confsetting],
};
var analog = new Data.Models.Listxml.Analog
{
Mask = "XXXXXX",
};
var port = new Data.Models.Listxml.Port
{
Tag = "XXXXXX",
Analog = [analog],
};
var adjuster = new Data.Models.Listxml.Adjuster
{
Name = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var driver = new Data.Models.Listxml.Driver
{
Status = "XXXXXX",
Color = "XXXXXX",
Sound = "XXXXXX",
PaletteSize = "XXXXXX",
Emulation = "XXXXXX",
Cocktail = "XXXXXX",
SaveState = "XXXXXX",
RequiresArtwork = "XXXXXX",
Unofficial = "XXXXXX",
NoSoundHardware = "XXXXXX",
Incomplete = "XXXXXX",
};
var feature = new Data.Models.Listxml.Feature
{
Type = "XXXXXX",
Status = "XXXXXX",
Overall = "XXXXXX",
};
var instance = new Data.Models.Listxml.Instance
{
Name = "XXXXXX",
BriefName = "XXXXXX",
};
var extension = new Data.Models.Listxml.Extension
{
Name = "XXXXXX",
};
var device = new Data.Models.Listxml.Device
{
Type = "XXXXXX",
Tag = "XXXXXX",
FixedImage = "XXXXXX",
Mandatory = "XXXXXX",
Interface = "XXXXXX",
Instance = instance,
Extension = [extension],
};
var slotOption = new Data.Models.Listxml.SlotOption
{
Name = "XXXXXX",
DevName = "XXXXXX",
Default = "XXXXXX",
};
var slot = new Data.Models.Listxml.Slot
{
Name = "XXXXXX",
SlotOption = [slotOption],
};
var softwarelist = new Data.Models.Listxml.SoftwareList
{
Tag = "XXXXXX",
Name = "XXXXXX",
Status = "XXXXXX",
Filter = "XXXXXX",
};
var ramoption = new Data.Models.Listxml.RamOption
{
Name = "XXXXXX",
Default = "XXXXXX",
Content = "XXXXXX",
};
Data.Models.Listxml.GameBase gameBase = game
? new Data.Models.Listxml.Game()
: new Data.Models.Listxml.Machine();
gameBase.Name = "XXXXXX";
gameBase.SourceFile = "XXXXXX";
gameBase.IsBios = "XXXXXX";
gameBase.IsDevice = "XXXXXX";
gameBase.IsMechanical = "XXXXXX";
gameBase.Runnable = "XXXXXX";
gameBase.CloneOf = "XXXXXX";
gameBase.RomOf = "XXXXXX";
gameBase.SampleOf = "XXXXXX";
gameBase.Description = "XXXXXX";
gameBase.Year = "XXXXXX";
gameBase.Manufacturer = "XXXXXX";
gameBase.History = "XXXXXX";
gameBase.BiosSet = [biosset];
gameBase.Rom = [rom];
gameBase.Disk = [disk];
gameBase.DeviceRef = [deviceref];
gameBase.Sample = [sample];
gameBase.Chip = [chip];
gameBase.Display = [display];
gameBase.Video = [video];
gameBase.Sound = sound;
gameBase.Input = input;
gameBase.DipSwitch = [dipswitch];
gameBase.Configuration = [configuration];
gameBase.Port = [port];
gameBase.Adjuster = [adjuster];
gameBase.Driver = driver;
gameBase.Feature = [feature];
gameBase.Device = [device];
gameBase.Slot = [slot];
gameBase.SoftwareList = [softwarelist];
gameBase.RamOption = [ramoption];
return new Data.Models.Listxml.Mess
{
Version = "XXXXXX",
Game = [gameBase],
};
}
/// <summary>
/// Validate a GameBase
/// </summary>
private static void Validate(Data.Models.Listxml.GameBase? gb)
{
Assert.NotNull(gb);
Assert.Equal("XXXXXX", gb.Name);
Assert.Equal("XXXXXX", gb.SourceFile);
Assert.Equal("XXXXXX", gb.IsBios);
Assert.Equal("XXXXXX", gb.IsDevice);
Assert.Equal("XXXXXX", gb.IsMechanical);
Assert.Equal("XXXXXX", gb.Runnable);
Assert.Equal("XXXXXX", gb.CloneOf);
Assert.Equal("XXXXXX", gb.RomOf);
Assert.Equal("XXXXXX", gb.SampleOf);
Assert.Equal("XXXXXX", gb.Description);
Assert.Equal("XXXXXX", gb.Year);
Assert.Equal("XXXXXX", gb.Manufacturer);
Assert.Equal("XXXXXX", gb.History);
Assert.NotNull(gb.BiosSet);
var biosset = Assert.Single(gb.BiosSet);
Validate(biosset);
Assert.NotNull(gb.Rom);
var rom = Assert.Single(gb.Rom);
Validate(rom);
Assert.NotNull(gb.Disk);
var disk = Assert.Single(gb.Disk);
Validate(disk);
Assert.NotNull(gb.DeviceRef);
var deviceref = Assert.Single(gb.DeviceRef);
Validate(deviceref);
Assert.NotNull(gb.Sample);
var sample = Assert.Single(gb.Sample);
Validate(sample);
Assert.NotNull(gb.Chip);
var chip = Assert.Single(gb.Chip);
Validate(chip);
Assert.NotNull(gb.Display);
var display = Assert.Single(gb.Display);
Validate(display);
Assert.NotNull(gb.Video);
var video = Assert.Single(gb.Video);
Validate(video);
Validate(gb.Sound);
Validate(gb.Input);
Assert.NotNull(gb.DipSwitch);
var dipswitch = Assert.Single(gb.DipSwitch);
Validate(dipswitch);
Assert.NotNull(gb.Configuration);
var configuration = Assert.Single(gb.Configuration);
Validate(configuration);
Assert.NotNull(gb.Port);
var port = Assert.Single(gb.Port);
Validate(port);
Assert.NotNull(gb.Adjuster);
var adjuster = Assert.Single(gb.Adjuster);
Validate(adjuster);
Validate(gb.Driver);
Assert.NotNull(gb.Feature);
var feature = Assert.Single(gb.Feature);
Validate(feature);
Assert.NotNull(gb.Device);
var device = Assert.Single(gb.Device);
Validate(device);
Assert.NotNull(gb.Slot);
var slot = Assert.Single(gb.Slot);
Validate(slot);
Assert.NotNull(gb.SoftwareList);
var softwarelist = Assert.Single(gb.SoftwareList);
Validate(softwarelist);
Assert.NotNull(gb.RamOption);
var ramoption = Assert.Single(gb.RamOption);
Validate(ramoption);
}
/// <summary>
/// Validate a BiosSet
/// </summary>
private static void Validate(Data.Models.Listxml.BiosSet? biosset)
{
Assert.NotNull(biosset);
Assert.Equal("XXXXXX", biosset.Name);
Assert.Equal("XXXXXX", biosset.Description);
Assert.Equal("XXXXXX", biosset.Default);
}
/// <summary>
/// Validate a Rom
/// </summary>
private static void Validate(Data.Models.Listxml.Rom? rom)
{
Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.Name);
Assert.Equal("XXXXXX", rom.Bios);
Assert.Equal("XXXXXX", rom.Size);
Assert.Equal("XXXXXX", rom.CRC);
Assert.Equal("XXXXXX", rom.SHA1);
Assert.Equal("XXXXXX", rom.Merge);
Assert.Equal("XXXXXX", rom.Region);
Assert.Equal("XXXXXX", rom.Offset);
Assert.Equal("XXXXXX", rom.Status);
Assert.Equal("XXXXXX", rom.Optional);
Assert.Equal("XXXXXX", rom.Dispose);
Assert.Equal("XXXXXX", rom.SoundOnly);
}
/// <summary>
/// Validate a Disk
/// </summary>
private static void Validate(Data.Models.Listxml.Disk? disk)
{
Assert.NotNull(disk);
Assert.Equal("XXXXXX", disk.Name);
Assert.Equal("XXXXXX", disk.MD5);
Assert.Equal("XXXXXX", disk.SHA1);
Assert.Equal("XXXXXX", disk.Merge);
Assert.Equal("XXXXXX", disk.Region);
Assert.Equal("XXXXXX", disk.Index);
Assert.Equal("XXXXXX", disk.Writable);
Assert.Equal("XXXXXX", disk.Status);
Assert.Equal("XXXXXX", disk.Optional);
}
/// <summary>
/// Validate a DeviceRef
/// </summary>
private static void Validate(Data.Models.Listxml.DeviceRef? deviceref)
{
Assert.NotNull(deviceref);
Assert.Equal("XXXXXX", deviceref.Name);
}
/// <summary>
/// Validate a Sample
/// </summary>
private static void Validate(Data.Models.Listxml.Sample? sample)
{
Assert.NotNull(sample);
Assert.Equal("XXXXXX", sample.Name);
}
/// <summary>
/// Validate a Chip
/// </summary>
private static void Validate(Data.Models.Listxml.Chip? chip)
{
Assert.NotNull(chip);
Assert.Equal("XXXXXX", chip.Name);
Assert.Equal("XXXXXX", chip.Tag);
Assert.Equal("XXXXXX", chip.Type);
Assert.Equal("XXXXXX", chip.SoundOnly);
Assert.Equal("XXXXXX", chip.Clock);
}
/// <summary>
/// Validate a Display
/// </summary>
private static void Validate(Data.Models.Listxml.Display? display)
{
Assert.NotNull(display);
Assert.Equal("XXXXXX", display.Tag);
Assert.Equal("XXXXXX", display.Type);
Assert.Equal("XXXXXX", display.Rotate);
Assert.Equal("XXXXXX", display.FlipX);
Assert.Equal("XXXXXX", display.Width);
Assert.Equal("XXXXXX", display.Height);
Assert.Equal("XXXXXX", display.Refresh);
Assert.Equal("XXXXXX", display.PixClock);
Assert.Equal("XXXXXX", display.HTotal);
Assert.Equal("XXXXXX", display.HBEnd);
Assert.Equal("XXXXXX", display.HBStart);
Assert.Equal("XXXXXX", display.VTotal);
Assert.Equal("XXXXXX", display.VBEnd);
Assert.Equal("XXXXXX", display.VBStart);
}
/// <summary>
/// Validate a Video
/// </summary>
private static void Validate(Data.Models.Listxml.Video? video)
{
Assert.NotNull(video);
Assert.Equal("XXXXXX", video.Screen);
Assert.Equal("XXXXXX", video.Orientation);
Assert.Equal("XXXXXX", video.Width);
Assert.Equal("XXXXXX", video.Height);
Assert.Equal("XXXXXX", video.AspectX);
Assert.Equal("XXXXXX", video.AspectY);
Assert.Equal("XXXXXX", video.Refresh);
}
/// <summary>
/// Validate a Sound
/// </summary>
private static void Validate(Data.Models.Listxml.Sound? sound)
{
Assert.NotNull(sound);
Assert.Equal("XXXXXX", sound.Channels);
}
/// <summary>
/// Validate a Input
/// </summary>
private static void Validate(Data.Models.Listxml.Input? input)
{
Assert.NotNull(input);
Assert.Equal("XXXXXX", input.Service);
Assert.Equal("XXXXXX", input.Tilt);
Assert.Equal("XXXXXX", input.Players);
//Assert.Equal("XXXXXX", input.ControlAttr); // Mututally exclusive with input.Control
Assert.Equal("XXXXXX", input.Buttons);
Assert.Equal("XXXXXX", input.Coins);
Assert.NotNull(input.Control);
var control = Assert.Single(input.Control);
Validate(control);
}
/// <summary>
/// Validate a Control
/// </summary>
private static void Validate(Data.Models.Listxml.Control? control)
{
Assert.NotNull(control);
Assert.Equal("XXXXXX", control.Type);
Assert.Equal("XXXXXX", control.Player);
Assert.Equal("XXXXXX", control.Buttons);
Assert.Equal("XXXXXX", control.ReqButtons);
Assert.Equal("XXXXXX", control.Minimum);
Assert.Equal("XXXXXX", control.Maximum);
Assert.Equal("XXXXXX", control.Sensitivity);
Assert.Equal("XXXXXX", control.KeyDelta);
Assert.Equal("XXXXXX", control.Reverse);
Assert.Equal("XXXXXX", control.Ways);
Assert.Equal("XXXXXX", control.Ways2);
Assert.Equal("XXXXXX", control.Ways3);
}
/// <summary>
/// Validate a DipSwitch
/// </summary>
private static void Validate(Data.Models.Listxml.DipSwitch? dipswitch)
{
Assert.NotNull(dipswitch);
Assert.Equal("XXXXXX", dipswitch.Name);
Assert.Equal("XXXXXX", dipswitch.Tag);
Assert.Equal("XXXXXX", dipswitch.Mask);
Validate(dipswitch.Condition);
Assert.NotNull(dipswitch.DipLocation);
var diplocation = Assert.Single(dipswitch.DipLocation);
Validate(diplocation);
Assert.NotNull(dipswitch.DipValue);
var dipvalue = Assert.Single(dipswitch.DipValue);
Validate(dipvalue);
}
/// <summary>
/// Validate a Condition
/// </summary>
private static void Validate(Data.Models.Listxml.Condition? condition)
{
Assert.NotNull(condition);
Assert.Equal("XXXXXX", condition.Tag);
Assert.Equal("XXXXXX", condition.Mask);
Assert.Equal("XXXXXX", condition.Relation);
Assert.Equal("XXXXXX", condition.Value);
}
/// <summary>
/// Validate a DipLocation
/// </summary>
private static void Validate(Data.Models.Listxml.DipLocation? diplocation)
{
Assert.NotNull(diplocation);
Assert.Equal("XXXXXX", diplocation.Name);
Assert.Equal("XXXXXX", diplocation.Number);
Assert.Equal("XXXXXX", diplocation.Inverted);
}
/// <summary>
/// Validate a DipValue
/// </summary>
private static void Validate(Data.Models.Listxml.DipValue? dipvalue)
{
Assert.NotNull(dipvalue);
Assert.Equal("XXXXXX", dipvalue.Name);
Assert.Equal("XXXXXX", dipvalue.Value);
Assert.Equal("XXXXXX", dipvalue.Default);
Validate(dipvalue.Condition);
}
/// <summary>
/// Validate a Configuration
/// </summary>
private static void Validate(Data.Models.Listxml.Configuration? configuration)
{
Assert.NotNull(configuration);
Assert.Equal("XXXXXX", configuration.Name);
Assert.Equal("XXXXXX", configuration.Tag);
Assert.Equal("XXXXXX", configuration.Mask);
Validate(configuration.Condition);
Assert.NotNull(configuration.ConfLocation);
var conflocation = Assert.Single(configuration.ConfLocation);
Validate(conflocation);
Assert.NotNull(configuration.ConfSetting);
var confsetting = Assert.Single(configuration.ConfSetting);
Validate(confsetting);
}
/// <summary>
/// Validate a ConfLocation
/// </summary>
private static void Validate(Data.Models.Listxml.ConfLocation? conflocation)
{
Assert.NotNull(conflocation);
Assert.Equal("XXXXXX", conflocation.Name);
Assert.Equal("XXXXXX", conflocation.Number);
Assert.Equal("XXXXXX", conflocation.Inverted);
}
/// <summary>
/// Validate a ConfSetting
/// </summary>
private static void Validate(Data.Models.Listxml.ConfSetting? confsetting)
{
Assert.NotNull(confsetting);
Assert.Equal("XXXXXX", confsetting.Name);
Assert.Equal("XXXXXX", confsetting.Value);
Assert.Equal("XXXXXX", confsetting.Default);
Validate(confsetting.Condition);
}
/// <summary>
/// Validate a Port
/// </summary>
private static void Validate(Data.Models.Listxml.Port? port)
{
Assert.NotNull(port);
Assert.Equal("XXXXXX", port.Tag);
Assert.NotNull(port.Analog);
var analog = Assert.Single(port.Analog);
Validate(analog);
}
/// <summary>
/// Validate a Analog
/// </summary>
private static void Validate(Data.Models.Listxml.Analog? analog)
{
Assert.NotNull(analog);
Assert.Equal("XXXXXX", analog.Mask);
}
/// <summary>
/// Validate a Adjuster
/// </summary>
private static void Validate(Data.Models.Listxml.Adjuster? adjuster)
{
Assert.NotNull(adjuster);
Assert.Equal("XXXXXX", adjuster.Name);
Assert.Equal("XXXXXX", adjuster.Default);
Validate(adjuster.Condition);
}
/// <summary>
/// Validate a Driver
/// </summary>
private static void Validate(Data.Models.Listxml.Driver? driver)
{
Assert.NotNull(driver);
Assert.Equal("XXXXXX", driver.Status);
Assert.Equal("XXXXXX", driver.Color);
Assert.Equal("XXXXXX", driver.Sound);
Assert.Equal("XXXXXX", driver.PaletteSize);
Assert.Equal("XXXXXX", driver.Emulation);
Assert.Equal("XXXXXX", driver.Cocktail);
Assert.Equal("XXXXXX", driver.SaveState);
Assert.Equal("XXXXXX", driver.RequiresArtwork);
Assert.Equal("XXXXXX", driver.Unofficial);
Assert.Equal("XXXXXX", driver.NoSoundHardware);
Assert.Equal("XXXXXX", driver.Incomplete);
}
/// <summary>
/// Validate a Feature
/// </summary>
private static void Validate(Data.Models.Listxml.Feature? feature)
{
Assert.NotNull(feature);
Assert.Equal("XXXXXX", feature.Type);
Assert.Equal("XXXXXX", feature.Status);
Assert.Equal("XXXXXX", feature.Overall);
}
/// <summary>
/// Validate a Device
/// </summary>
private static void Validate(Data.Models.Listxml.Device? device)
{
Assert.NotNull(device);
Assert.Equal("XXXXXX", device.Type);
Assert.Equal("XXXXXX", device.Tag);
Assert.Equal("XXXXXX", device.FixedImage);
Assert.Equal("XXXXXX", device.Mandatory);
Assert.Equal("XXXXXX", device.Interface);
Validate(device.Instance);
Assert.NotNull(device.Extension);
var extension = Assert.Single(device.Extension);
Validate(extension);
}
/// <summary>
/// Validate a Instance
/// </summary>
private static void Validate(Data.Models.Listxml.Instance? instance)
{
Assert.NotNull(instance);
Assert.Equal("XXXXXX", instance.Name);
Assert.Equal("XXXXXX", instance.BriefName);
}
/// <summary>
/// Validate a Extension
/// </summary>
private static void Validate(Data.Models.Listxml.Extension? extension)
{
Assert.NotNull(extension);
Assert.Equal("XXXXXX", extension.Name);
}
/// <summary>
/// Validate a Slot
/// </summary>
private static void Validate(Data.Models.Listxml.Slot? slot)
{
Assert.NotNull(slot);
Assert.Equal("XXXXXX", slot.Name);
Assert.NotNull(slot.SlotOption);
var slotoption = Assert.Single(slot.SlotOption);
Validate(slotoption);
}
/// <summary>
/// Validate a SlotOption
/// </summary>
private static void Validate(Data.Models.Listxml.SlotOption? slotoption)
{
Assert.NotNull(slotoption);
Assert.Equal("XXXXXX", slotoption.Name);
Assert.Equal("XXXXXX", slotoption.DevName);
Assert.Equal("XXXXXX", slotoption.Default);
}
/// <summary>
/// Validate a SoftwareList
/// </summary>
private static void Validate(Data.Models.Listxml.SoftwareList? softwarelist)
{
Assert.NotNull(softwarelist);
Assert.Equal("XXXXXX", softwarelist.Tag);
Assert.Equal("XXXXXX", softwarelist.Name);
Assert.Equal("XXXXXX", softwarelist.Status);
Assert.Equal("XXXXXX", softwarelist.Filter);
}
/// <summary>
/// Validate a RamOption
/// </summary>
private static void Validate(Data.Models.Listxml.RamOption? ramoption)
{
Assert.NotNull(ramoption);
Assert.Equal("XXXXXX", ramoption.Name);
Assert.Equal("XXXXXX", ramoption.Default);
Assert.Equal("XXXXXX", ramoption.Content);
}
}
}

View File

@@ -0,0 +1,451 @@
using SabreTools.Serialization.CrossModel;
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class OfflineListTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new OfflineList();
// Build the data
Data.Models.OfflineList.Dat dat = Build();
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(dat);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.OfflineList.Dat? newDat = serializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newDat);
Assert.Equal("XXXXXX", newDat.NoNamespaceSchemaLocation);
Validate(newDat.Configuration);
Validate(newDat.Games);
Validate(newDat.GUI);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.OfflineList.Dat Build()
{
var infos = new Data.Models.OfflineList.Infos
{
Title = new Data.Models.OfflineList.Title
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
Location = new Data.Models.OfflineList.Location
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
Publisher = new Data.Models.OfflineList.Publisher
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
SourceRom = new Data.Models.OfflineList.SourceRom
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
SaveType = new Data.Models.OfflineList.SaveType
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
RomSize = new Data.Models.OfflineList.RomSize
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
ReleaseNumber = new Data.Models.OfflineList.ReleaseNumber
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
ImageNumber = new Data.Models.OfflineList.ImageNumber
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
LanguageNumber = new Data.Models.OfflineList.LanguageNumber
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
Comment = new Data.Models.OfflineList.Comment
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
RomCRC = new Data.Models.OfflineList.RomCRC
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
Im1CRC = new Data.Models.OfflineList.Im1CRC
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
Im2CRC = new Data.Models.OfflineList.Im2CRC
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
Languages = new Data.Models.OfflineList.Languages
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
};
var canopen = new Data.Models.OfflineList.CanOpen
{
Extension = ["XXXXXX"],
};
var daturl = new Data.Models.OfflineList.DatUrl
{
FileName = "XXXXXX",
Content = "XXXXXX",
};
var newdat = new Data.Models.OfflineList.NewDat
{
DatVersionUrl = "XXXXXX",
DatUrl = daturl,
ImUrl = "XXXXXX",
};
var find = new Data.Models.OfflineList.Find
{
Operation = "XXXXXX",
Value = "XXXXXX",
Content = "XXXXXX",
};
var to = new Data.Models.OfflineList.To
{
Value = "XXXXXX",
Default = "XXXXXX",
Auto = "XXXXXX",
Find = [find],
};
var search = new Data.Models.OfflineList.Search
{
To = [to],
};
var configuration = new Data.Models.OfflineList.Configuration
{
DatName = "XXXXXX",
ImFolder = "XXXXXX",
DatVersion = "XXXXXX",
System = "XXXXXX",
ScreenshotsWidth = "XXXXXX",
ScreenshotsHeight = "XXXXXX",
Infos = infos,
CanOpen = canopen,
NewDat = newdat,
Search = search,
RomTitle = "XXXXXX",
};
var fileromcrc = new Data.Models.OfflineList.FileRomCRC
{
Extension = "XXXXXX",
Content = "XXXXXX",
};
var files = new Data.Models.OfflineList.Files
{
RomCRC = [fileromcrc],
};
var game = new Data.Models.OfflineList.Game
{
ImageNumber = "XXXXXX",
ReleaseNumber = "XXXXXX",
Title = "XXXXXX",
SaveType = "XXXXXX",
RomSize = "XXXXXX",
Publisher = "XXXXXX",
Location = "XXXXXX",
SourceRom = "XXXXXX",
Language = "XXXXXX",
Files = files,
Im1CRC = "XXXXXX",
Im2CRC = "XXXXXX",
Comment = "XXXXXX",
DuplicateID = "XXXXXX",
};
var games = new Data.Models.OfflineList.Games
{
Game = [game],
};
var image = new Data.Models.OfflineList.Image
{
X = "XXXXXX",
Y = "XXXXXX",
Width = "XXXXXX",
Height = "XXXXXX",
};
var images = new Data.Models.OfflineList.Images
{
Width = "XXXXXX",
Height = "XXXXXX",
Image = [image],
};
var gui = new Data.Models.OfflineList.GUI
{
Images = images,
};
return new Data.Models.OfflineList.Dat
{
NoNamespaceSchemaLocation = "XXXXXX",
Configuration = configuration,
Games = games,
GUI = gui,
};
}
/// <summary>
/// Validate a Configuration
/// </summary>
private static void Validate(Data.Models.OfflineList.Configuration? configuration)
{
Assert.NotNull(configuration);
Assert.Equal("XXXXXX", configuration.DatName);
Assert.Equal("XXXXXX", configuration.ImFolder);
Assert.Equal("XXXXXX", configuration.DatVersion);
Assert.Equal("XXXXXX", configuration.System);
Assert.Equal("XXXXXX", configuration.ScreenshotsWidth);
Assert.Equal("XXXXXX", configuration.ScreenshotsHeight);
Validate(configuration.Infos);
Validate(configuration.CanOpen);
Validate(configuration.NewDat);
Validate(configuration.Search);
Assert.Equal("XXXXXX", configuration.RomTitle);
}
/// <summary>
/// Validate a Infos
/// </summary>
private static void Validate(Data.Models.OfflineList.Infos? infos)
{
Assert.NotNull(infos);
Validate(infos.Title);
Validate(infos.Location);
Validate(infos.Publisher);
Validate(infos.SourceRom);
Validate(infos.SaveType);
Validate(infos.RomSize);
Validate(infos.ReleaseNumber);
Validate(infos.ImageNumber);
Validate(infos.LanguageNumber);
Validate(infos.Comment);
Validate(infos.RomCRC);
Validate(infos.Im1CRC);
Validate(infos.Im2CRC);
Validate(infos.Languages);
}
/// <summary>
/// Validate a InfoBase
/// </summary>
private static void Validate(Data.Models.OfflineList.InfoBase? info)
{
Assert.NotNull(info);
Assert.Equal("XXXXXX", info.Visible);
Assert.Equal("XXXXXX", info.InNamingOption);
Assert.Equal("XXXXXX", info.Default);
}
/// <summary>
/// Validate a CanOpen
/// </summary>
private static void Validate(Data.Models.OfflineList.CanOpen? canopen)
{
Assert.NotNull(canopen);
Assert.NotNull(canopen.Extension);
string extension = Assert.Single(canopen.Extension);
Assert.Equal("XXXXXX", extension);
}
/// <summary>
/// Validate a NewDat
/// </summary>
private static void Validate(Data.Models.OfflineList.NewDat? newdat)
{
Assert.NotNull(newdat);
Assert.Equal("XXXXXX", newdat.DatVersionUrl);
Validate(newdat.DatUrl);
Assert.Equal("XXXXXX", newdat.ImUrl);
}
/// <summary>
/// Validate a DatUrl
/// </summary>
private static void Validate(Data.Models.OfflineList.DatUrl? daturl)
{
Assert.NotNull(daturl);
Assert.Equal("XXXXXX", daturl.FileName);
Assert.Equal("XXXXXX", daturl.Content);
}
/// <summary>
/// Validate a Search
/// </summary>
private static void Validate(Data.Models.OfflineList.Search? search)
{
Assert.NotNull(search);
Assert.NotNull(search.To);
var to = Assert.Single(search.To);
Validate(to);
}
/// <summary>
/// Validate a To
/// </summary>
private static void Validate(Data.Models.OfflineList.To? to)
{
Assert.NotNull(to);
Assert.Equal("XXXXXX", to.Value);
Assert.Equal("XXXXXX", to.Default);
Assert.Equal("XXXXXX", to.Auto);
Assert.NotNull(to.Find);
var find = Assert.Single(to.Find);
Validate(find);
}
/// <summary>
/// Validate a Find
/// </summary>
private static void Validate(Data.Models.OfflineList.Find? find)
{
Assert.NotNull(find);
Assert.Equal("XXXXXX", find.Operation);
Assert.Equal("XXXXXX", find.Value);
Assert.Equal("XXXXXX", find.Content);
}
/// <summary>
/// Validate a Games
/// </summary>
private static void Validate(Data.Models.OfflineList.Games? games)
{
Assert.NotNull(games);
Assert.NotNull(games.Game);
var game = Assert.Single(games.Game);
Validate(game);
}
/// <summary>
/// Validate a Game
/// </summary>
private static void Validate(Data.Models.OfflineList.Game? game)
{
Assert.NotNull(game);
Assert.Equal("XXXXXX", game.ImageNumber);
Assert.Equal("XXXXXX", game.ReleaseNumber);
Assert.Equal("XXXXXX", game.Title);
Assert.Equal("XXXXXX", game.SaveType);
Assert.Equal("0", game.RomSize); // Converted due to filtering
Assert.Equal("XXXXXX", game.Publisher);
Assert.Equal("XXXXXX", game.Location);
Assert.Equal("XXXXXX", game.SourceRom);
Assert.Equal("XXXXXX", game.Language);
Validate(game.Files);
Assert.Equal("XXXXXX", game.Im1CRC);
Assert.Equal("XXXXXX", game.Im2CRC);
Assert.Equal("XXXXXX", game.Comment);
Assert.Equal("XXXXXX", game.DuplicateID);
}
/// <summary>
/// Validate a Files
/// </summary>
private static void Validate(Data.Models.OfflineList.Files? files)
{
Assert.NotNull(files);
Assert.NotNull(files.RomCRC);
var fileromcrc = Assert.Single(files.RomCRC);
Validate(fileromcrc);
}
/// <summary>
/// Validate a FileRomCRC
/// </summary>
private static void Validate(Data.Models.OfflineList.FileRomCRC? fileromcrc)
{
Assert.NotNull(fileromcrc);
Assert.Equal("XXXXXX", fileromcrc.Extension);
Assert.Equal("XXXXXX", fileromcrc.Content);
}
/// <summary>
/// Validate a GUI
/// </summary>
private static void Validate(Data.Models.OfflineList.GUI? gui)
{
Assert.NotNull(gui);
Validate(gui.Images);
}
/// <summary>
/// Validate a Images
/// </summary>
private static void Validate(Data.Models.OfflineList.Images? images)
{
Assert.NotNull(images);
Assert.Equal("XXXXXX", images.Width);
Assert.Equal("XXXXXX", images.Height);
Assert.NotNull(images.Image);
var image = Assert.Single(images.Image);
Validate(image);
}
/// <summary>
/// Validate a Image
/// </summary>
private static void Validate(Data.Models.OfflineList.Image? image)
{
Assert.NotNull(image);
Assert.Equal("XXXXXX", image.X);
Assert.Equal("XXXXXX", image.Y);
Assert.Equal("XXXXXX", image.Width);
Assert.Equal("XXXXXX", image.Height);
}
}
}

View File

@@ -0,0 +1,157 @@
using SabreTools.Serialization.CrossModel;
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class OpenMSXTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new OpenMSX();
// Build the data
Data.Models.OpenMSX.SoftwareDb sdb = Build();
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(sdb);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.OpenMSX.SoftwareDb? newSdb = serializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newSdb);
Assert.Equal("XXXXXX", newSdb.Timestamp);
Assert.NotNull(newSdb.Software);
var software = Assert.Single(newSdb.Software);
Validate(software);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.OpenMSX.SoftwareDb Build()
{
var original = new Data.Models.OpenMSX.Original
{
Value = "XXXXXX",
Content = "XXXXXX",
};
var rom = new Data.Models.OpenMSX.Rom
{
Start = "XXXXXX",
Type = "XXXXXX",
Hash = "XXXXXX",
Remark = "XXXXXX",
};
var dump_rom = new Data.Models.OpenMSX.Dump
{
Original = original,
Rom = rom,
};
var megarom = new Data.Models.OpenMSX.MegaRom
{
Start = "XXXXXX",
Type = "XXXXXX",
Hash = "XXXXXX",
Remark = "XXXXXX",
};
var dump_megarom = new Data.Models.OpenMSX.Dump
{
Original = original,
Rom = megarom,
};
var sccpluscart = new Data.Models.OpenMSX.SCCPlusCart
{
Start = "XXXXXX",
Type = "XXXXXX",
Hash = "XXXXXX",
Remark = "XXXXXX",
};
var dump_sccpluscart = new Data.Models.OpenMSX.Dump
{
Original = original,
Rom = sccpluscart,
};
var software = new Data.Models.OpenMSX.Software
{
Title = "XXXXXX",
GenMSXID = "XXXXXX",
System = "XXXXXX",
Company = "XXXXXX",
Year = "XXXXXX",
Country = "XXXXXX",
Dump = [dump_rom, dump_megarom, dump_sccpluscart],
};
return new Data.Models.OpenMSX.SoftwareDb
{
Timestamp = "XXXXXX",
Software = [software],
};
}
/// <summary>
/// Validate a Software
/// </summary>
private static void Validate(Data.Models.OpenMSX.Software? software)
{
Assert.NotNull(software);
Assert.Equal("XXXXXX", software.Title);
Assert.Equal("XXXXXX", software.GenMSXID);
Assert.Equal("XXXXXX", software.System);
Assert.Equal("XXXXXX", software.Company);
Assert.Equal("XXXXXX", software.Year);
Assert.Equal("XXXXXX", software.Country);
Assert.NotNull(software.Dump);
Assert.Equal(3, software.Dump.Length);
foreach (var dump in software.Dump)
{
Validate(dump);
}
}
/// <summary>
/// Validate a Dump
/// </summary>
private static void Validate(Data.Models.OpenMSX.Dump? dump)
{
Assert.NotNull(dump);
Validate(dump.Original);
Validate(dump.Rom);
}
/// <summary>
/// Validate a Original
/// </summary>
private static void Validate(Data.Models.OpenMSX.Original? original)
{
Assert.NotNull(original);
Assert.Equal("XXXXXX", original.Value);
Assert.Equal("XXXXXX", original.Content);
}
/// <summary>
/// Validate a RomBase
/// </summary>
private static void Validate(Data.Models.OpenMSX.RomBase? rombase)
{
Assert.NotNull(rombase);
Assert.Equal("XXXXXX", rombase.Start);
Assert.Equal("XXXXXX", rombase.Type);
Assert.Equal("XXXXXX", rombase.Hash);
Assert.Equal("XXXXXX", rombase.Remark);
}
}
}

View File

@@ -0,0 +1,154 @@
using SabreTools.Serialization.CrossModel;
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class RomCenterTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new RomCenter();
// Build the data
Data.Models.RomCenter.MetadataFile mf = Build();
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(mf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.RomCenter.MetadataFile? newMf = serializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newMf);
Validate(newMf.Credits);
Validate(newMf.Dat);
Validate(newMf.Emulator);
Validate(newMf.Games);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.RomCenter.MetadataFile Build()
{
var credits = new Data.Models.RomCenter.Credits
{
Author = "XXXXXX",
Version = "XXXXXX",
Email = "XXXXXX",
Homepage = "XXXXXX",
Url = "XXXXXX",
Date = "XXXXXX",
Comment = "XXXXXX",
};
var dat = new Data.Models.RomCenter.Dat
{
Version = "XXXXXX",
Plugin = "XXXXXX",
Split = "XXXXXX",
Merge = "XXXXXX",
};
var emulator = new Data.Models.RomCenter.Emulator
{
RefName = "XXXXXX",
Version = "XXXXXX",
};
var rom = new Data.Models.RomCenter.Rom
{
ParentName = "XXXXXX",
ParentDescription = "XXXXXX",
GameName = "XXXXXX",
GameDescription = "XXXXXX",
RomName = "XXXXXX",
RomCRC = "XXXXXX",
RomSize = "XXXXXX",
RomOf = "XXXXXX",
MergeName = "XXXXXX",
};
var games = new Data.Models.RomCenter.Games
{
Rom = [rom],
};
return new Data.Models.RomCenter.MetadataFile
{
Credits = credits,
Dat = dat,
Emulator = emulator,
Games = games,
};
}
/// <summary>
/// Validate a Credits
/// </summary>
private static void Validate(Data.Models.RomCenter.Credits? credits)
{
Assert.NotNull(credits);
Assert.Equal("XXXXXX", credits.Author);
Assert.Equal("XXXXXX", credits.Version);
Assert.Equal("XXXXXX", credits.Email);
Assert.Equal("XXXXXX", credits.Homepage);
Assert.Equal("XXXXXX", credits.Url);
Assert.Equal("XXXXXX", credits.Date);
Assert.Equal("XXXXXX", credits.Comment);
}
/// <summary>
/// Validate a Dat
/// </summary>
private static void Validate(Data.Models.RomCenter.Dat? dat)
{
Assert.NotNull(dat);
Assert.Equal("XXXXXX", dat.Version);
Assert.Equal("XXXXXX", dat.Plugin);
Assert.Equal("no", dat.Split); // Converted due to filtering
Assert.Equal("no", dat.Merge); // Converted due to filtering
}
/// <summary>
/// Validate a Emulator
/// </summary>
private static void Validate(Data.Models.RomCenter.Emulator? emulator)
{
Assert.NotNull(emulator);
Assert.Equal("XXXXXX", emulator.RefName);
Assert.Equal("XXXXXX", emulator.Version);
}
/// <summary>
/// Validate a Games
/// </summary>
private static void Validate(Data.Models.RomCenter.Games? games)
{
Assert.NotNull(games);
Assert.NotNull(games.Rom);
var rom = Assert.Single(games.Rom);
Validate(rom);
}
/// <summary>
/// Validate a Rom
/// </summary>
private static void Validate(Data.Models.RomCenter.Rom? rom)
{
Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.ParentName);
Assert.Null(rom.ParentDescription); // This is unmappable
Assert.Equal("XXXXXX", rom.GameName);
Assert.Equal("XXXXXX", rom.GameDescription);
Assert.Equal("XXXXXX", rom.RomName);
Assert.Equal("XXXXXX", rom.RomCRC);
Assert.Equal("XXXXXX", rom.RomSize);
Assert.Equal("XXXXXX", rom.RomOf);
Assert.Equal("XXXXXX", rom.MergeName);
}
}
}

View File

@@ -0,0 +1,183 @@
using SabreTools.Serialization.CrossModel;
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class SeparatedValueTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new SeparatedValue();
// Build the data
Data.Models.SeparatedValue.MetadataFile mf = Build();
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(mf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.SeparatedValue.MetadataFile? newMf = serializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newMf);
Validate(newMf.Header);
Assert.NotNull(newMf.Row);
Assert.Equal(3, newMf.Row.Length);
ValidateDisk(newMf.Row[0]);
ValidateMedia(newMf.Row[1]);
ValidateRom(newMf.Row[2]);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.SeparatedValue.MetadataFile Build()
{
string[] header = ["header"];
var disk = new Data.Models.SeparatedValue.Row
{
FileName = "XXXXXX",
InternalName = "XXXXXX",
Description = "XXXXXX",
GameName = "XXXXXX",
GameDescription = "XXXXXX",
Type = "disk",
DiskName = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Status = "XXXXXX",
};
var media = new Data.Models.SeparatedValue.Row
{
FileName = "XXXXXX",
InternalName = "XXXXXX",
Description = "XXXXXX",
GameName = "XXXXXX",
GameDescription = "XXXXXX",
Type = "media",
DiskName = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
SHA256 = "XXXXXX",
SpamSum = "XXXXXX",
};
var rom = new Data.Models.SeparatedValue.Row
{
FileName = "XXXXXX",
InternalName = "XXXXXX",
Description = "XXXXXX",
GameName = "XXXXXX",
GameDescription = "XXXXXX",
Type = "rom",
RomName = "XXXXXX",
Size = "XXXXXX",
CRC = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
SHA256 = "XXXXXX",
SHA384 = "XXXXXX",
SHA512 = "XXXXXX",
SpamSum = "XXXXXX",
Status = "XXXXXX",
};
return new Data.Models.SeparatedValue.MetadataFile
{
Header = header,
Row = [disk, media, rom],
};
}
/// <summary>
/// Validate a header
/// </summary>
private static void Validate(string[]? header)
{
Assert.NotNull(header);
string column = Assert.Single(header);
Assert.Equal("header", column);
}
/// <summary>
/// Validate a Row
/// </summary>
private static void ValidateDisk(Data.Models.SeparatedValue.Row? row)
{
Assert.NotNull(row);
Assert.Equal("XXXXXX", row.FileName);
Assert.Equal("XXXXXX", row.InternalName);
Assert.Equal("XXXXXX", row.Description);
Assert.Equal("XXXXXX", row.GameName);
Assert.Equal("XXXXXX", row.GameDescription);
Assert.Equal("disk", row.Type);
Assert.Null(row.RomName);
Assert.Equal("XXXXXX", row.DiskName);
Assert.Null(row.Size);
Assert.Null(row.CRC);
Assert.Equal("XXXXXX", row.MD5);
Assert.Equal("XXXXXX", row.SHA1);
Assert.Null(row.SHA256);
Assert.Null(row.SHA384);
Assert.Null(row.SHA512);
Assert.Null(row.SpamSum);
Assert.Equal("XXXXXX", row.Status);
}
/// <summary>
/// Validate a Row
/// </summary>
private static void ValidateMedia(Data.Models.SeparatedValue.Row? row)
{
Assert.NotNull(row);
Assert.Equal("XXXXXX", row.FileName);
Assert.Equal("XXXXXX", row.InternalName);
Assert.Equal("XXXXXX", row.Description);
Assert.Equal("XXXXXX", row.GameName);
Assert.Equal("XXXXXX", row.GameDescription);
Assert.Equal("media", row.Type);
Assert.Null(row.RomName);
Assert.Equal("XXXXXX", row.DiskName);
Assert.Null(row.Size);
Assert.Null(row.CRC);
Assert.Equal("XXXXXX", row.MD5);
Assert.Equal("XXXXXX", row.SHA1);
Assert.Equal("XXXXXX", row.SHA256);
Assert.Null(row.SHA384);
Assert.Null(row.SHA512);
Assert.Equal("XXXXXX", row.SpamSum);
Assert.Null(row.Status);
}
/// <summary>
/// Validate a Row
/// </summary>
private static void ValidateRom(Data.Models.SeparatedValue.Row? row)
{
Assert.NotNull(row);
Assert.Equal("XXXXXX", row.FileName);
Assert.Equal("XXXXXX", row.InternalName);
Assert.Equal("XXXXXX", row.Description);
Assert.Equal("XXXXXX", row.GameName);
Assert.Equal("XXXXXX", row.GameDescription);
Assert.Equal("rom", row.Type);
Assert.Equal("XXXXXX", row.RomName);
Assert.Null(row.DiskName);
Assert.Equal("XXXXXX", row.Size);
Assert.Equal("XXXXXX", row.CRC);
Assert.Equal("XXXXXX", row.MD5);
Assert.Equal("XXXXXX", row.SHA1);
Assert.Equal("XXXXXX", row.SHA256);
Assert.Equal("XXXXXX", row.SHA384);
Assert.Equal("XXXXXX", row.SHA512);
Assert.Equal("XXXXXX", row.SpamSum);
Assert.Equal("XXXXXX", row.Status);
}
}
}

View File

@@ -0,0 +1,311 @@
using SabreTools.Serialization.CrossModel;
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class SoftwareListTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new SoftwareList();
// Build the data
Data.Models.SoftwareList.SoftwareList sl = Build();
// Serialize to generic model
Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(sl);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.SoftwareList.SoftwareList? newSl = serializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newSl);
Assert.Equal("XXXXXX", newSl.Name);
Assert.Equal("XXXXXX", newSl.Description);
Assert.Equal("XXXXXX", newSl.Notes);
Assert.NotNull(newSl.Software);
var newSoftware = Assert.Single(newSl.Software);
Validate(newSoftware);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.SoftwareList.SoftwareList Build()
{
var info = new Data.Models.SoftwareList.Info
{
Name = "XXXXXX",
Value = "XXXXXX",
};
var sharedfeat = new Data.Models.SoftwareList.SharedFeat
{
Name = "XXXXXX",
Value = "XXXXXX",
};
var feature = new Data.Models.SoftwareList.Feature
{
Name = "XXXXXX",
Value = "XXXXXX",
};
var rom = new Data.Models.SoftwareList.Rom
{
Name = "XXXXXX",
Size = "XXXXXX",
Length = "XXXXXX",
CRC = "XXXXXX",
SHA1 = "XXXXXX",
Offset = "XXXXXX",
Value = "XXXXXX",
Status = "XXXXXX",
LoadFlag = "XXXXXX",
};
var dataarea = new Data.Models.SoftwareList.DataArea
{
Name = "XXXXXX",
Size = "XXXXXX",
Width = "XXXXXX",
Endianness = "XXXXXX",
Rom = [rom],
};
var disk = new Data.Models.SoftwareList.Disk
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Status = "XXXXXX",
Writeable = "XXXXXX",
};
var diskarea = new Data.Models.SoftwareList.DiskArea
{
Name = "XXXXXX",
Disk = [disk],
};
var dipvalue = new Data.Models.SoftwareList.DipValue
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
};
var dipswitch = new Data.Models.SoftwareList.DipSwitch
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
DipValue = [dipvalue],
};
var part = new Data.Models.SoftwareList.Part
{
Name = "XXXXXX",
Interface = "XXXXXX",
Feature = [feature],
DataArea = [dataarea],
DiskArea = [diskarea],
DipSwitch = [dipswitch],
};
var software = new Data.Models.SoftwareList.Software
{
Name = "XXXXXX",
CloneOf = "XXXXXX",
Supported = "XXXXXX",
Description = "XXXXXX",
Year = "XXXXXX",
Publisher = "XXXXXX",
Notes = "XXXXXX",
Info = [info],
SharedFeat = [sharedfeat],
Part = [part],
};
return new Data.Models.SoftwareList.SoftwareList
{
Name = "XXXXXX",
Description = "XXXXXX",
Notes = "XXXXXX",
Software = [software],
};
}
/// <summary>
/// Validate a Software
/// </summary>
private static void Validate(Data.Models.SoftwareList.Software? software)
{
Assert.NotNull(software);
Assert.Equal("XXXXXX", software.Name);
Assert.Equal("XXXXXX", software.CloneOf);
Assert.Equal("XXXXXX", software.Supported);
Assert.Equal("XXXXXX", software.Description);
Assert.Equal("XXXXXX", software.Year);
Assert.Equal("XXXXXX", software.Publisher);
Assert.Equal("XXXXXX", software.Notes);
Assert.NotNull(software.Info);
var info = Assert.Single(software.Info);
Validate(info);
Assert.NotNull(software.SharedFeat);
var sharedfeat = Assert.Single(software.SharedFeat);
Validate(sharedfeat);
Assert.NotNull(software.Part);
var part = Assert.Single(software.Part);
Validate(part);
}
/// <summary>
/// Validate a Info
/// </summary>
private static void Validate(Data.Models.SoftwareList.Info? info)
{
Assert.NotNull(info);
Assert.Equal("XXXXXX", info.Name);
Assert.Equal("XXXXXX", info.Value);
}
/// <summary>
/// Validate a SharedFeat
/// </summary>
private static void Validate(Data.Models.SoftwareList.SharedFeat? sharedfeat)
{
Assert.NotNull(sharedfeat);
Assert.Equal("XXXXXX", sharedfeat.Name);
Assert.Equal("XXXXXX", sharedfeat.Value);
}
/// <summary>
/// Validate a Part
/// </summary>
private static void Validate(Data.Models.SoftwareList.Part? part)
{
Assert.NotNull(part);
Assert.Equal("XXXXXX", part.Name);
Assert.Equal("XXXXXX", part.Interface);
Assert.NotNull(part.Feature);
var feature = Assert.Single(part.Feature);
Validate(feature);
Assert.NotNull(part.DataArea);
var dataarea = Assert.Single(part.DataArea);
Validate(dataarea);
Assert.NotNull(part.DiskArea);
var diskarea = Assert.Single(part.DiskArea);
Validate(diskarea);
Assert.NotNull(part.DipSwitch);
var dipswitch = Assert.Single(part.DipSwitch);
Validate(dipswitch);
}
/// <summary>
/// Validate a Feature
/// </summary>
private static void Validate(Data.Models.SoftwareList.Feature? feature)
{
Assert.NotNull(feature);
Assert.Equal("XXXXXX", feature.Name);
Assert.Equal("XXXXXX", feature.Value);
}
/// <summary>
/// Validate a DataArea
/// </summary>
private static void Validate(Data.Models.SoftwareList.DataArea? dataarea)
{
Assert.NotNull(dataarea);
Assert.Equal("XXXXXX", dataarea.Name);
Assert.Equal("XXXXXX", dataarea.Size);
Assert.Equal("XXXXXX", dataarea.Width);
Assert.Equal("XXXXXX", dataarea.Endianness);
Assert.NotNull(dataarea.Rom);
var rom = Assert.Single(dataarea.Rom);
Validate(rom);
}
/// <summary>
/// Validate a Rom
/// </summary>
private static void Validate(Data.Models.SoftwareList.Rom? rom)
{
Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.Name);
Assert.Equal("XXXXXX", rom.Size);
Assert.Equal("XXXXXX", rom.Length);
Assert.Equal("XXXXXX", rom.CRC);
Assert.Equal("XXXXXX", rom.SHA1);
Assert.Equal("XXXXXX", rom.Offset);
Assert.Equal("XXXXXX", rom.Value);
Assert.Equal("XXXXXX", rom.Status);
Assert.Equal("XXXXXX", rom.LoadFlag);
}
/// <summary>
/// Validate a DiskArea
/// </summary>
private static void Validate(Data.Models.SoftwareList.DiskArea? diskarea)
{
Assert.NotNull(diskarea);
Assert.Equal("XXXXXX", diskarea.Name);
Assert.NotNull(diskarea.Disk);
var disk = Assert.Single(diskarea.Disk);
Validate(disk);
}
/// <summary>
/// Validate a Disk
/// </summary>
private static void Validate(Data.Models.SoftwareList.Disk? disk)
{
Assert.NotNull(disk);
Assert.Equal("XXXXXX", disk.Name);
Assert.Equal("XXXXXX", disk.MD5);
Assert.Equal("XXXXXX", disk.SHA1);
Assert.Equal("XXXXXX", disk.Status);
Assert.Equal("XXXXXX", disk.Writeable);
}
/// <summary>
/// Validate a DipSwitch
/// </summary>
private static void Validate(Data.Models.SoftwareList.DipSwitch? dipswitch)
{
Assert.NotNull(dipswitch);
Assert.Equal("XXXXXX", dipswitch.Name);
Assert.Equal("XXXXXX", dipswitch.Tag);
Assert.Equal("XXXXXX", dipswitch.Mask);
Assert.NotNull(dipswitch.DipValue);
var dipvalue = Assert.Single(dipswitch.DipValue);
Validate(dipvalue);
}
/// <summary>
/// Validate a DipValue
/// </summary>
private static void Validate(Data.Models.SoftwareList.DipValue? dipvalue)
{
Assert.NotNull(dipvalue);
Assert.Equal("XXXXXX", dipvalue.Name);
Assert.Equal("XXXXXX", dipvalue.Value);
Assert.Equal("XXXXXX", dipvalue.Default);
}
}
}

View File

@@ -0,0 +1,213 @@
using System;
using SabreTools.Data.Extensions;
using SabreTools.Data.Models.ASN1;
using Xunit;
namespace SabreTools.Serialization.Test.Extensions
{
public class TypeLengthValueTests
{
#region Formatting
[Fact]
public void Format_EOC()
{
string expected = "Type: V_ASN1_EOC";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_EOC, Length = 0, Value = null };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_ZeroLength()
{
string expected = "Type: V_ASN1_NULL, Length: 0";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_NULL, Length = 0, Value = null };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_InvalidConstructed()
{
string expected = "Type: V_ASN1_OBJECT, V_ASN1_CONSTRUCTED, Length: 1, Value: [INVALID DATA TYPE]";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_OBJECT | ASN1Type.V_ASN1_CONSTRUCTED, Length = 1, Value = (object?)false };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_ValidConstructed()
{
string expected = "Type: V_ASN1_OBJECT, V_ASN1_CONSTRUCTED, Length: 3, Value:\n Type: V_ASN1_BOOLEAN, Length: 1, Value: True";
var boolTlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_BOOLEAN, Length = 1, Value = new byte[] { 0x01 } };
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_OBJECT | ASN1Type.V_ASN1_CONSTRUCTED, Length = 3, Value = new Data.Models.ASN1.TypeLengthValue[] { boolTlv } };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_InvalidDataType()
{
string expected = "Type: V_ASN1_OBJECT, Length: 1, Value: [INVALID DATA TYPE]";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_OBJECT, Length = 1, Value = (object?)false };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_InvalidLength()
{
string expected = "Type: V_ASN1_NULL, Length: 1, Value: [NO DATA]";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_NULL, Length = 1, Value = Array.Empty<byte>() };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_InvalidBooleanLength()
{
string expected = "Type: V_ASN1_BOOLEAN, Length: 2 [Expected length of 1], Value: True";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_BOOLEAN, Length = 2, Value = new byte[] { 0x01 } };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_InvalidBooleanArrayLength()
{
string expected = "Type: V_ASN1_BOOLEAN, Length: 1 [Expected value length of 1], Value: True";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_BOOLEAN, Length = 1, Value = new byte[] { 0x01, 0x00 } };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_ValidBoolean()
{
string expected = "Type: V_ASN1_BOOLEAN, Length: 1, Value: True";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_BOOLEAN, Length = 1, Value = new byte[] { 0x01 } };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_ValidInteger()
{
string expected = "Type: V_ASN1_INTEGER, Length: 1, Value: 1";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_INTEGER, Length = 1, Value = new byte[] { 0x01 } };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_ValidBitString_NoBits()
{
string expected = "Type: V_ASN1_BIT_STRING, Length: 1, Value with 0 unused bits";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_BIT_STRING, Length = 1, Value = new byte[] { 0x00 } };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_ValidBitString_Bits()
{
string expected = "Type: V_ASN1_BIT_STRING, Length: 1, Value with 1 unused bits: 01";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_BIT_STRING, Length = 1, Value = new byte[] { 0x01, 0x01 } };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_ValidOctetString()
{
string expected = "Type: V_ASN1_OCTET_STRING, Length: 1, Value: 01";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_OCTET_STRING, Length = 1, Value = new byte[] { 0x01 } };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_ValidObject()
{
string expected = "Type: V_ASN1_OBJECT, Length: 3, Value: 0.1.2.3 (/ITU-T/1/2/3)";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_OBJECT, Length = 3, Value = new byte[] { 0x01, 0x02, 0x03 } };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_ValidUTF8String()
{
string expected = "Type: V_ASN1_UTF8STRING, Length: 3, Value: ABC";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_UTF8STRING, Length = 3, Value = new byte[] { 0x41, 0x42, 0x43 } };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_ValidPrintableString()
{
string expected = "Type: V_ASN1_PRINTABLESTRING, Length: 3, Value: ABC";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_PRINTABLESTRING, Length = 3, Value = new byte[] { 0x41, 0x42, 0x43 } };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_ValidTeletexString()
{
string expected = "Type: V_ASN1_TELETEXSTRING, Length: 3, Value: ABC";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_TELETEXSTRING, Length = 3, Value = new byte[] { 0x41, 0x42, 0x43 } };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_ValidIA5String()
{
string expected = "Type: V_ASN1_IA5STRING, Length: 3, Value: ABC";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_IA5STRING, Length = 3, Value = new byte[] { 0x41, 0x42, 0x43 } };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_InvalidUTCTime()
{
string expected = "Type: V_ASN1_UTCTIME, Length: 3, Value: ABC";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_UTCTIME, Length = 3, Value = new byte[] { 0x41, 0x42, 0x43 } };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_ValidUTCTime()
{
string expected = "Type: V_ASN1_UTCTIME, Length: 3, Value: 1980-01-01 00:00:00";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_UTCTIME, Length = 3, Value = new byte[] { 0x31, 0x39, 0x38, 0x30, 0x2D, 0x30, 0x31, 0x2D, 0x30, 0x31, 0x20, 0x30, 0x30, 0x3A, 0x30, 0x30, 0x3A, 0x30, 0x30 } };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_ValidBmpString()
{
string expected = "Type: V_ASN1_BMPSTRING, Length: 6, Value: ABC";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_BMPSTRING, Length = 6, Value = new byte[] { 0x41, 0x00, 0x42, 0x00, 0x43, 0x00 } };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
[Fact]
public void Format_ValidUnformatted()
{
string expected = "Type: V_ASN1_OBJECT_DESCRIPTOR, Length: 1, Value: 01";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_OBJECT_DESCRIPTOR, Length = 1, Value = new byte[] { 0x01 } };
string actual = tlv.Format();
Assert.Equal(expected, actual);
}
#endregion
}
}

View File

@@ -0,0 +1,111 @@
using SabreTools.Data.ObjectIdentifier;
using Xunit;
namespace SabreTools.Serialization.Test.ObjectIdentifier
{
// These tests are known to be incomplete due to the sheer number
// of possible OIDs that exist. The tests below are a minimal
// representation of functionality to guarantee proper behavior
// not necessarily absolute outputs
public class ParserTests
{
#region ASN.1
[Fact]
public void ASN1Notation_AlwaysNull()
{
ulong[]? values = null;
string? actual = Parser.ParseOIDToASN1Notation(values);
Assert.Null(actual);
}
#endregion
#region Dot Notation
[Fact]
public void DotNotation_NullValues_Null()
{
ulong[]? values = null;
string? actual = Parser.ParseOIDToDotNotation(values);
Assert.Null(actual);
}
[Fact]
public void DotNotation_EmptyValues_Null()
{
ulong[]? values = [];
string? actual = Parser.ParseOIDToDotNotation(values);
Assert.Null(actual);
}
[Fact]
public void DotNotation_Values_Formatted()
{
string expected = "0.1.2.3";
ulong[]? values = [0, 1, 2, 3];
string? actual = Parser.ParseOIDToDotNotation(values);
Assert.Equal(expected, actual);
}
#endregion
#region Modified OID-IRI
[Fact]
public void ModifiedOIDIRI_NullValues_Null()
{
ulong[]? values = null;
string? actual = Parser.ParseOIDToModifiedOIDIRI(values);
Assert.Null(actual);
}
[Fact]
public void ModifiedOIDIRI_EmptyValues_Null()
{
ulong[]? values = [];
string? actual = Parser.ParseOIDToModifiedOIDIRI(values);
Assert.Null(actual);
}
[Fact]
public void ModifiedOIDIRI_Values_Formatted()
{
string expected = "/ITU-T/[question]/2/3";
ulong[]? values = [0, 1, 2, 3];
string? actual = Parser.ParseOIDToModifiedOIDIRI(values);
Assert.Equal(expected, actual);
}
#endregion
#region OID-IRI
[Fact]
public void OIDIRI_NullValues_Null()
{
ulong[]? values = null;
string? actual = Parser.ParseOIDToOIDIRINotation(values);
Assert.Null(actual);
}
[Fact]
public void OIDIRI_EmptyValues_Null()
{
ulong[]? values = [];
string? actual = Parser.ParseOIDToOIDIRINotation(values);
Assert.Null(actual);
}
[Fact]
public void OIDIRI_Values_Formatted()
{
string expected = "/ITU-T/1/2/3";
ulong[]? values = [0, 1, 2, 3];
string? actual = Parser.ParseOIDToOIDIRINotation(values);
Assert.Equal(expected, actual);
}
#endregion
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class AACSTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new AACS();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new AACS();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new AACS();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new AACS();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new AACS();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new AACS();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,152 @@
using System.IO;
using System.Linq;
using SabreTools.Data.Models.ASN1;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class AbstractSyntaxNotationOneTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new AbstractSyntaxNotationOne();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new AbstractSyntaxNotationOne();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new AbstractSyntaxNotationOne();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new AbstractSyntaxNotationOne();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new AbstractSyntaxNotationOne();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new AbstractSyntaxNotationOne();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void ValidMinimalStream_NotNull()
{
Stream data = new MemoryStream([0x00]);
var deserializer = new AbstractSyntaxNotationOne();
var actual = deserializer.Deserialize(data);
Assert.NotNull(actual);
var actualSingle = Assert.Single(actual);
Assert.Equal(ASN1Type.V_ASN1_EOC, actualSingle.Type);
Assert.Equal(default, actualSingle.Length);
Assert.Null(actualSingle.Value);
}
[Fact]
public void ValidBoolean_NotNull()
{
Stream data = new MemoryStream([0x01, 0x01, 0x01]);
var deserializer = new AbstractSyntaxNotationOne();
var actual = deserializer.Deserialize(data);
Assert.NotNull(actual);
var actualSingle = Assert.Single(actual);
Assert.Equal(ASN1Type.V_ASN1_BOOLEAN, actualSingle.Type);
Assert.Equal(1UL, actualSingle.Length);
Assert.NotNull(actualSingle.Value);
byte[]? valueAsArray = actualSingle.Value as byte[];
Assert.NotNull(valueAsArray);
byte actualValue = Assert.Single(valueAsArray);
Assert.Equal(0x01, actualValue);
}
[Theory]
[InlineData(new byte[] { 0x26, 0x81, 0x03, 0x01, 0x01, 0x01 })]
[InlineData(new byte[] { 0x26, 0x82, 0x00, 0x03, 0x01, 0x01, 0x01 })]
[InlineData(new byte[] { 0x26, 0x83, 0x00, 0x00, 0x03, 0x01, 0x01, 0x01 })]
[InlineData(new byte[] { 0x26, 0x84, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x01 })]
[InlineData(new byte[] { 0x26, 0x85, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x01 })]
[InlineData(new byte[] { 0x26, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x01 })]
[InlineData(new byte[] { 0x26, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x01 })]
[InlineData(new byte[] { 0x26, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x01 })]
public void ComplexValue_NotNull(byte[] arr)
{
Stream data = new MemoryStream(arr);
var deserializer = new AbstractSyntaxNotationOne();
var actual = deserializer.Deserialize(data);
Assert.NotNull(actual);
var actualSingle = Assert.Single(actual);
Assert.Equal(ASN1Type.V_ASN1_CONSTRUCTED | ASN1Type.V_ASN1_OBJECT, actualSingle.Type);
Assert.Equal(3UL, actualSingle.Length);
Assert.NotNull(actualSingle.Value);
TypeLengthValue[]? valueAsArray = actualSingle.Value as TypeLengthValue[];
Assert.NotNull(valueAsArray);
TypeLengthValue actualSub = Assert.Single(valueAsArray);
Assert.Equal(ASN1Type.V_ASN1_BOOLEAN, actualSub.Type);
Assert.Equal(1UL, actualSub.Length);
Assert.NotNull(actualSub.Value);
}
[Theory]
[InlineData(new byte[] { 0x26, 0x80 })]
[InlineData(new byte[] { 0x26, 0x89 })]
public void ComplexValueInvalidLength_Null(byte[] arr)
{
Stream data = new MemoryStream(arr);
var deserializer = new AbstractSyntaxNotationOne();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class AdvancedInstallerTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new AdvancedInstaller();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new AdvancedInstaller();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new AdvancedInstaller();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new AdvancedInstaller();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new AdvancedInstaller();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new AdvancedInstaller();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class AppPkgHeaderTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new AppPkgHeader();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new AppPkgHeader();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new AppPkgHeader();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new AppPkgHeader();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new AppPkgHeader();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new AppPkgHeader();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,240 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class ArchiveDotOrgTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new ArchiveDotOrg();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new ArchiveDotOrg();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new ArchiveDotOrg();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new ArchiveDotOrg();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new ArchiveDotOrg();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new ArchiveDotOrg();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void RoundTripTest()
{
// Get the serializer and deserializer
var deserializer = new ArchiveDotOrg();
var serializer = new SabreTools.Serialization.Writers.ArchiveDotOrg();
// Build the data
Data.Models.ArchiveDotOrg.Files files = Build();
// Serialize to stream
Stream? actual = serializer.Serialize(files);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.ArchiveDotOrg.Files? newFiles = deserializer.Deserialize(actual);
// Validate the data
Assert.NotNull(newFiles);
Assert.NotNull(newFiles.File);
var newFile = Assert.Single(newFiles.File);
Validate(newFile);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.ArchiveDotOrg.Files Build()
{
var file = new Data.Models.ArchiveDotOrg.File
{
Name = "XXXXXX",
Source = "XXXXXX",
BitTorrentMagnetHash = "XXXXXX",
LastModifiedTime = "XXXXXX",
Size = "XXXXXX",
MD5 = "XXXXXX",
CRC32 = "XXXXXX",
SHA1 = "XXXXXX",
FileCount = "XXXXXX",
Format = "XXXXXX",
Original = "XXXXXX",
Summation = "XXXXXX",
MatrixNumber = "XXXXXX",
CollectionCatalogNumber = "XXXXXX",
Publisher = "XXXXXX",
Comment = "XXXXXX",
ASRDetectedLang = "XXXXXX",
ASRDetectedLangConf = "XXXXXX",
ASRTranscribedLang = "XXXXXX",
WhisperASRModuleVersion = "XXXXXX",
WhisperModelHash = "XXXXXX",
WhisperModelName = "XXXXXX",
WhisperVersion = "XXXXXX",
ClothCoverDetectionModuleVersion = "XXXXXX",
hOCRCharToWordhOCRVersion = "XXXXXX",
hOCRCharToWordModuleVersion = "XXXXXX",
hOCRFtsTexthOCRVersion = "XXXXXX",
hOCRFtsTextModuleVersion = "XXXXXX",
hOCRPageIndexhOCRVersion = "XXXXXX",
hOCRPageIndexModuleVersion = "XXXXXX",
TesseractOCR = "XXXXXX",
TesseractOCRConverted = "XXXXXX",
TesseractOCRDetectedLang = "XXXXXX",
TesseractOCRDetectedLangConf = "XXXXXX",
TesseractOCRDetectedScript = "XXXXXX",
TesseractOCRDetectedScriptConf = "XXXXXX",
TesseractOCRModuleVersion = "XXXXXX",
TesseractOCRParameters = "XXXXXX",
PDFModuleVersion = "XXXXXX",
WordConfidenceInterval0To10 = "XXXXXX",
WordConfidenceInterval11To20 = "XXXXXX",
WordConfidenceInterval21To30 = "XXXXXX",
WordConfidenceInterval31To40 = "XXXXXX",
WordConfidenceInterval41To50 = "XXXXXX",
WordConfidenceInterval51To60 = "XXXXXX",
WordConfidenceInterval61To70 = "XXXXXX",
WordConfidenceInterval71To80 = "XXXXXX",
WordConfidenceInterval81To90 = "XXXXXX",
WordConfidenceInterval91To100 = "XXXXXX",
Album = "XXXXXX",
Artist = "XXXXXX",
Bitrate = "XXXXXX",
Creator = "XXXXXX",
Height = "XXXXXX",
Length = "XXXXXX",
PreviewImage = "XXXXXX",
Rotation = "XXXXXX",
Title = "XXXXXX",
Track = "XXXXXX",
Width = "XXXXXX",
};
return new Data.Models.ArchiveDotOrg.Files
{
File = [file]
};
}
/// <summary>
/// Validate a File
/// </summary>
private static void Validate(Data.Models.ArchiveDotOrg.File? file)
{
Assert.NotNull(file);
Assert.Equal("XXXXXX", file.Name);
Assert.Equal("XXXXXX", file.Source);
Assert.Equal("XXXXXX", file.BitTorrentMagnetHash);
Assert.Equal("XXXXXX", file.LastModifiedTime);
Assert.Equal("XXXXXX", file.Size);
Assert.Equal("XXXXXX", file.MD5);
Assert.Equal("XXXXXX", file.CRC32);
Assert.Equal("XXXXXX", file.SHA1);
Assert.Equal("XXXXXX", file.FileCount);
Assert.Equal("XXXXXX", file.Format);
Assert.Equal("XXXXXX", file.Original);
Assert.Equal("XXXXXX", file.Summation);
Assert.Equal("XXXXXX", file.MatrixNumber);
Assert.Equal("XXXXXX", file.CollectionCatalogNumber);
Assert.Equal("XXXXXX", file.Publisher);
Assert.Equal("XXXXXX", file.Comment);
Assert.Equal("XXXXXX", file.ASRDetectedLang);
Assert.Equal("XXXXXX", file.ASRDetectedLangConf);
Assert.Equal("XXXXXX", file.ASRTranscribedLang);
Assert.Equal("XXXXXX", file.WhisperASRModuleVersion);
Assert.Equal("XXXXXX", file.WhisperModelHash);
Assert.Equal("XXXXXX", file.WhisperModelName);
Assert.Equal("XXXXXX", file.WhisperVersion);
Assert.Equal("XXXXXX", file.ClothCoverDetectionModuleVersion);
Assert.Equal("XXXXXX", file.hOCRCharToWordhOCRVersion);
Assert.Equal("XXXXXX", file.hOCRCharToWordModuleVersion);
Assert.Equal("XXXXXX", file.hOCRFtsTexthOCRVersion);
Assert.Equal("XXXXXX", file.hOCRFtsTextModuleVersion);
Assert.Equal("XXXXXX", file.hOCRPageIndexhOCRVersion);
Assert.Equal("XXXXXX", file.hOCRPageIndexModuleVersion);
Assert.Equal("XXXXXX", file.TesseractOCR);
Assert.Equal("XXXXXX", file.TesseractOCRConverted);
Assert.Equal("XXXXXX", file.TesseractOCRDetectedLang);
Assert.Equal("XXXXXX", file.TesseractOCRDetectedLangConf);
Assert.Equal("XXXXXX", file.TesseractOCRDetectedScript);
Assert.Equal("XXXXXX", file.TesseractOCRDetectedScriptConf);
Assert.Equal("XXXXXX", file.TesseractOCRModuleVersion);
Assert.Equal("XXXXXX", file.TesseractOCRParameters);
Assert.Equal("XXXXXX", file.PDFModuleVersion);
Assert.Equal("XXXXXX", file.WordConfidenceInterval0To10);
Assert.Equal("XXXXXX", file.WordConfidenceInterval11To20);
Assert.Equal("XXXXXX", file.WordConfidenceInterval21To30);
Assert.Equal("XXXXXX", file.WordConfidenceInterval31To40);
Assert.Equal("XXXXXX", file.WordConfidenceInterval41To50);
Assert.Equal("XXXXXX", file.WordConfidenceInterval51To60);
Assert.Equal("XXXXXX", file.WordConfidenceInterval61To70);
Assert.Equal("XXXXXX", file.WordConfidenceInterval71To80);
Assert.Equal("XXXXXX", file.WordConfidenceInterval81To90);
Assert.Equal("XXXXXX", file.WordConfidenceInterval91To100);
Assert.Equal("XXXXXX", file.Album);
Assert.Equal("XXXXXX", file.Artist);
Assert.Equal("XXXXXX", file.Bitrate);
Assert.Equal("XXXXXX", file.Creator);
Assert.Equal("XXXXXX", file.Height);
Assert.Equal("XXXXXX", file.Length);
Assert.Equal("XXXXXX", file.PreviewImage);
Assert.Equal("XXXXXX", file.Rotation);
Assert.Equal("XXXXXX", file.Title);
Assert.Equal("XXXXXX", file.Track);
Assert.Equal("XXXXXX", file.Width);
}
}
}

View File

@@ -0,0 +1,217 @@
using System;
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class AttractModeTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new AttractMode();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new AttractMode();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new AttractMode();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new AttractMode();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new AttractMode();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
var data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new AttractMode();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void RoundTripShortTest()
{
// Get the serializer and deserializer
var deserializer = new AttractMode();
var serializer = new SabreTools.Serialization.Writers.AttractMode();
// Build the data
Data.Models.AttractMode.MetadataFile mf = Build();
// Serialize to stream
Stream? actual = serializer.SerializeStream(mf, longHeader: false);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.AttractMode.MetadataFile? newMf = deserializer.Deserialize(actual);
// Validate the data
Assert.NotNull(newMf);
Validate(newMf.Header, longHeader: false);
Assert.NotNull(newMf.Row);
var newRow = Assert.Single(newMf.Row);
Validate(newRow, longHeader: false);
}
[Fact]
public void RoundTripLongTest()
{
// Get the serializer and deserializer
var deserializer = new AttractMode();
var serializer = new SabreTools.Serialization.Writers.AttractMode();
// Build the data
Data.Models.AttractMode.MetadataFile mf = Build();
// Serialize to stream
Stream? actual = serializer.SerializeStream(mf, longHeader: true);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.AttractMode.MetadataFile? newMf = deserializer.Deserialize(actual);
// Validate the data
Assert.NotNull(newMf);
Validate(newMf.Header, longHeader: true);
Assert.NotNull(newMf.Row);
var newRow = Assert.Single(newMf.Row);
Validate(newRow, longHeader: true);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.AttractMode.MetadataFile Build()
{
string[] header = ["header"];
var row = new Data.Models.AttractMode.Row
{
Name = "XXXXXX",
Title = "XXXXXX",
Emulator = "XXXXXX",
CloneOf = "XXXXXX",
Year = "XXXXXX",
Manufacturer = "XXXXXX",
Category = "XXXXXX",
Players = "XXXXXX",
Rotation = "XXXXXX",
Control = "XXXXXX",
Status = "XXXXXX",
DisplayCount = "XXXXXX",
DisplayType = "XXXXXX",
AltRomname = "XXXXXX",
AltTitle = "XXXXXX",
Extra = "XXXXXX",
Buttons = "XXXXXX",
Favorite = "XXXXXX",
Tags = "XXXXXX",
PlayedCount = "XXXXXX",
PlayedTime = "XXXXXX",
FileIsAvailable = "XXXXXX",
};
return new Data.Models.AttractMode.MetadataFile
{
Header = header,
Row = [row],
};
}
/// <summary>
/// Validate a header
/// </summary>
private static void Validate(string[]? header, bool longHeader)
{
Assert.NotNull(header);
if (longHeader)
Assert.True(SabreTools.Serialization.Writers.AttractMode.HeaderArrayWithRomname.SequenceEqual(header));
else
Assert.True(SabreTools.Serialization.Writers.AttractMode.HeaderArrayWithoutRomname.SequenceEqual(header));
}
/// <summary>
/// Validate a Row
/// </summary>
private static void Validate(Data.Models.AttractMode.Row? row, bool longHeader)
{
Assert.NotNull(row);
Assert.Equal("XXXXXX", row.Name);
Assert.Equal("XXXXXX", row.Title);
Assert.Equal("XXXXXX", row.Emulator);
Assert.Equal("XXXXXX", row.CloneOf);
Assert.Equal("XXXXXX", row.Year);
Assert.Equal("XXXXXX", row.Manufacturer);
Assert.Equal("XXXXXX", row.Category);
Assert.Equal("XXXXXX", row.Players);
Assert.Equal("XXXXXX", row.Rotation);
Assert.Equal("XXXXXX", row.Control);
Assert.Equal("XXXXXX", row.Status);
Assert.Equal("XXXXXX", row.DisplayCount);
Assert.Equal("XXXXXX", row.DisplayType);
Assert.Equal("XXXXXX", row.AltRomname);
Assert.Equal("XXXXXX", row.AltTitle);
Assert.Equal("XXXXXX", row.Extra);
Assert.Equal("XXXXXX", row.Buttons);
if (longHeader)
{
Assert.Equal("XXXXXX", row.Favorite);
Assert.Equal("XXXXXX", row.Tags);
Assert.Equal("XXXXXX", row.PlayedCount);
Assert.Equal("XXXXXX", row.PlayedTime);
Assert.Equal("XXXXXX", row.FileIsAvailable);
}
else
{
Assert.Null(row.Favorite);
Assert.Null(row.Tags);
Assert.Null(row.PlayedCount);
Assert.Null(row.PlayedTime);
Assert.Null(row.FileIsAvailable);
}
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class BDPlusTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new BDPlus();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new BDPlus();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new BDPlus();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new BDPlus();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new BDPlus();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new BDPlus();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class BFPKTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new BFPK();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new BFPK();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new BFPK();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new BFPK();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new BFPK();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new BFPK();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class BSPTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new BSP();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new BSP();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new BSP();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new BSP();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new BSP();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new BSP();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class CFBTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new CFB();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new CFB();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new CFB();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new CFB();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new CFB();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new CFB();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class CHDTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new CHD();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new CHD();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new CHD();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new CHD();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new CHD();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new CHD();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class CIATests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new CIA();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new CIA();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new CIA();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new CIA();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new CIA();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new CIA();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class CatalogTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new Catalog();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new Catalog();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new Catalog();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new Catalog();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new Catalog();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new Catalog();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,618 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class ClrMameProTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new ClrMamePro();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new ClrMamePro();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new ClrMamePro();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new ClrMamePro();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new ClrMamePro();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new ClrMamePro();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void RoundTripGameTest()
{
// Get the serializer and deserializer
var deserializer = new ClrMamePro();
var serializer = new SabreTools.Serialization.Writers.ClrMamePro();
// Build the data
Data.Models.ClrMamePro.MetadataFile mf = Build(game: true);
// Serialize to stream
Stream? actual = serializer.SerializeStream(mf);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.ClrMamePro.MetadataFile? newMf = deserializer.Deserialize(actual);
// Validate the data
Assert.NotNull(newMf);
Validate(newMf.ClrMamePro);
Assert.NotNull(newMf.Game);
var newGame = Assert.Single(newMf.Game);
Validate(newGame);
}
[Fact]
public void RoundTripGameWithoutQuotesTest()
{
// Get the serializer and deserializer
var deserializer = new ClrMamePro();
var serializer = new SabreTools.Serialization.Writers.ClrMamePro();
// Build the data
Data.Models.ClrMamePro.MetadataFile mf = Build(game: true);
// Serialize to stream
Stream? actual = serializer.SerializeStream(mf, quotes: false);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.ClrMamePro.MetadataFile? newMf = deserializer.Deserialize(actual);
// Validate the data
Assert.NotNull(newMf);
Validate(newMf.ClrMamePro);
Assert.NotNull(newMf.Game);
var newGame = Assert.Single(newMf.Game);
Validate(newGame);
}
[Fact]
public void RoundTripMachineTest()
{
// Get the serializer and deserializer
var deserializer = new ClrMamePro();
var serializer = new SabreTools.Serialization.Writers.ClrMamePro();
// Build the data
Data.Models.ClrMamePro.MetadataFile mf = Build(game: false);
// Serialize to stream
Stream? actual = serializer.SerializeStream(mf);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.ClrMamePro.MetadataFile? newMf = deserializer.Deserialize(actual);
// Validate the data
Assert.NotNull(newMf);
Validate(newMf.ClrMamePro);
Assert.NotNull(newMf.Game);
var newGame = Assert.Single(newMf.Game);
Validate(newGame);
}
[Fact]
public void RoundTripMachineWithoutQuotesTest()
{
// Get the serializer and deserializer
var deserializer = new ClrMamePro();
var serializer = new SabreTools.Serialization.Writers.ClrMamePro();
// Build the data
Data.Models.ClrMamePro.MetadataFile mf = Build(game: false);
// Serialize to stream
Stream? actual = serializer.SerializeStream(mf, quotes: false);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.ClrMamePro.MetadataFile? newMf = deserializer.Deserialize(actual);
// Validate the data
Assert.NotNull(newMf);
Validate(newMf.ClrMamePro);
Assert.NotNull(newMf.Game);
var newGame = Assert.Single(newMf.Game);
Validate(newGame);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.ClrMamePro.MetadataFile Build(bool game)
{
var cmp = new Data.Models.ClrMamePro.ClrMamePro
{
Name = "XXXXXX",
Description = "XXXXXX",
RootDir = "XXXXXX",
Category = "XXXXXX",
Version = "XXXXXX",
Date = "XXXXXX",
Author = "XXXXXX",
Homepage = "XXXXXX",
Url = "XXXXXX",
Comment = "XXXXXX",
Header = "XXXXXX",
Type = "XXXXXX",
ForceMerging = "XXXXXX",
ForceZipping = "XXXXXX",
ForcePacking = "XXXXXX",
};
var release = new Data.Models.ClrMamePro.Release
{
Name = "XXXXXX",
Region = "XXXXXX",
Language = "XXXXXX",
Date = "XXXXXX",
Default = "XXXXXX",
};
var biosset = new Data.Models.ClrMamePro.BiosSet
{
Name = "XXXXXX",
Description = "XXXXXX",
Default = "XXXXXX",
};
var rom = new Data.Models.ClrMamePro.Rom
{
Name = "XXXXXX",
Size = "XXXXXX",
CRC = "XXXXXX",
MD2 = "XXXXXX",
MD4 = "XXXXXX",
MD5 = "XXXXXX",
RIPEMD128 = "XXXXXX",
RIPEMD160 = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Status = "XXXXXX",
Flags = "XXXXXX",
Date = "XXXXXX",
SHA256 = "XXXXXX",
SHA384 = "XXXXXX",
SHA512 = "XXXXXX",
SpamSum = "XXXXXX",
xxHash364 = "XXXXXX",
xxHash3128 = "XXXXXX",
Region = "XXXXXX",
Offs = "XXXXXX",
Serial = "XXXXXX",
Header = "XXXXXX",
Inverted = "XXXXXX",
MIA = "XXXXXX",
};
var disk = new Data.Models.ClrMamePro.Disk
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Status = "XXXXXX",
Flags = "XXXXXX",
};
var sample = new Data.Models.ClrMamePro.Sample
{
Name = "XXXXXX",
};
var archive = new Data.Models.ClrMamePro.Archive
{
Name = "XXXXXX",
};
var media = new Data.Models.ClrMamePro.Media
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
SHA256 = "XXXXXX",
SpamSum = "XXXXXX",
};
var chip = new Data.Models.ClrMamePro.Chip
{
Type = "XXXXXX",
Name = "XXXXXX",
Flags = "XXXXXX",
Clock = "XXXXXX",
};
var video = new Data.Models.ClrMamePro.Video
{
Screen = "XXXXXX",
Orientation = "XXXXXX",
X = "XXXXXX",
Y = "XXXXXX",
AspectX = "XXXXXX",
AspectY = "XXXXXX",
Freq = "XXXXXX",
};
var sound = new Data.Models.ClrMamePro.Sound
{
Channels = "XXXXXX",
};
var input = new Data.Models.ClrMamePro.Input
{
Players = "XXXXXX",
Control = "XXXXXX",
Buttons = "XXXXXX",
Coins = "XXXXXX",
Tilt = "XXXXXX",
Service = "XXXXXX",
};
var dipswitch = new Data.Models.ClrMamePro.DipSwitch
{
Name = "XXXXXX",
Entry = ["XXXXXX"],
Default = "XXXXXX",
};
var driver = new Data.Models.ClrMamePro.Driver
{
Status = "XXXXXX",
Color = "XXXXXX",
Sound = "XXXXXX",
PaletteSize = "XXXXXX",
Blit = "XXXXXX",
};
// TODO: This omits Set, should that have a separate case?
Data.Models.ClrMamePro.GameBase gameBase = game
? new Data.Models.ClrMamePro.Game()
: new Data.Models.ClrMamePro.Machine();
gameBase.Name = "XXXXXX";
gameBase.Description = "XXXXXX";
gameBase.Year = "XXXXXX";
gameBase.Manufacturer = "XXXXXX";
gameBase.Category = "XXXXXX";
gameBase.CloneOf = "XXXXXX";
gameBase.RomOf = "XXXXXX";
gameBase.SampleOf = "XXXXXX";
gameBase.Release = [release];
gameBase.BiosSet = [biosset];
gameBase.Rom = [rom];
gameBase.Disk = [disk];
gameBase.Sample = [sample];
gameBase.Archive = [archive];
gameBase.Media = [media];
gameBase.Chip = [chip];
gameBase.Video = [video];
gameBase.Sound = sound;
gameBase.Input = input;
gameBase.DipSwitch = [dipswitch];
gameBase.Driver = driver;
return new Data.Models.ClrMamePro.MetadataFile
{
ClrMamePro = cmp,
Game = [gameBase],
};
}
/// <summary>
/// Validate a ClrMamePro
/// </summary>
private static void Validate(Data.Models.ClrMamePro.ClrMamePro? cmp)
{
Assert.NotNull(cmp);
Assert.Equal("XXXXXX", cmp.Name);
Assert.Equal("XXXXXX", cmp.Description);
Assert.Equal("XXXXXX", cmp.RootDir);
Assert.Equal("XXXXXX", cmp.Category);
Assert.Equal("XXXXXX", cmp.Version);
Assert.Equal("XXXXXX", cmp.Date);
Assert.Equal("XXXXXX", cmp.Author);
Assert.Equal("XXXXXX", cmp.Homepage);
Assert.Equal("XXXXXX", cmp.Url);
Assert.Equal("XXXXXX", cmp.Comment);
Assert.Equal("XXXXXX", cmp.Header);
Assert.Equal("XXXXXX", cmp.Type);
Assert.Equal("XXXXXX", cmp.ForceMerging);
Assert.Equal("XXXXXX", cmp.ForceZipping);
Assert.Equal("XXXXXX", cmp.ForcePacking);
}
/// <summary>
/// Validate a GameBase
/// </summary>
private static void Validate(Data.Models.ClrMamePro.GameBase? gb)
{
Assert.NotNull(gb);
Assert.Equal("XXXXXX", gb.Name);
Assert.Equal("XXXXXX", gb.Description);
Assert.Equal("XXXXXX", gb.Year);
Assert.Equal("XXXXXX", gb.Manufacturer);
Assert.Equal("XXXXXX", gb.Category);
Assert.Equal("XXXXXX", gb.CloneOf);
Assert.Equal("XXXXXX", gb.RomOf);
Assert.Equal("XXXXXX", gb.SampleOf);
Assert.NotNull(gb.Release);
var release = Assert.Single(gb.Release);
Validate(release);
Assert.NotNull(gb.BiosSet);
var biosset = Assert.Single(gb.BiosSet);
Validate(biosset);
Assert.NotNull(gb.Rom);
var rom = Assert.Single(gb.Rom);
Validate(rom);
Assert.NotNull(gb.Disk);
var disk = Assert.Single(gb.Disk);
Validate(disk);
Assert.NotNull(gb.Sample);
var sample = Assert.Single(gb.Sample);
Validate(sample);
Assert.NotNull(gb.Archive);
var archive = Assert.Single(gb.Archive);
Validate(archive);
Assert.NotNull(gb.Media);
var media = Assert.Single(gb.Media);
Validate(media);
Assert.NotNull(gb.Chip);
var chip = Assert.Single(gb.Chip);
Validate(chip);
Assert.NotNull(gb.Video);
var video = Assert.Single(gb.Video);
Validate(video);
Validate(gb.Sound);
Validate(gb.Input);
Assert.NotNull(gb.DipSwitch);
var dipswitch = Assert.Single(gb.DipSwitch);
Validate(dipswitch);
Validate(gb.Driver);
}
/// <summary>
/// Validate a Release
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Release? release)
{
Assert.NotNull(release);
Assert.Equal("XXXXXX", release.Name);
Assert.Equal("XXXXXX", release.Region);
Assert.Equal("XXXXXX", release.Language);
Assert.Equal("XXXXXX", release.Date);
Assert.Equal("XXXXXX", release.Default);
}
/// <summary>
/// Validate a BiosSet
/// </summary>
private static void Validate(Data.Models.ClrMamePro.BiosSet? biosset)
{
Assert.NotNull(biosset);
Assert.Equal("XXXXXX", biosset.Name);
Assert.Equal("XXXXXX", biosset.Description);
Assert.Equal("XXXXXX", biosset.Default);
}
/// <summary>
/// Validate a Rom
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Rom? rom)
{
Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.Name);
Assert.Equal("XXXXXX", rom.Size);
Assert.Equal("XXXXXX", rom.CRC);
Assert.Equal("XXXXXX", rom.MD2);
Assert.Equal("XXXXXX", rom.MD4);
Assert.Equal("XXXXXX", rom.MD5);
Assert.Equal("XXXXXX", rom.RIPEMD128);
Assert.Equal("XXXXXX", rom.RIPEMD160);
Assert.Equal("XXXXXX", rom.SHA1);
Assert.Equal("XXXXXX", rom.Merge);
Assert.Equal("XXXXXX", rom.Status);
Assert.Equal("XXXXXX", rom.Flags);
Assert.Equal("XXXXXX", rom.Date);
Assert.Equal("XXXXXX", rom.SHA256);
Assert.Equal("XXXXXX", rom.SHA384);
Assert.Equal("XXXXXX", rom.SHA512);
Assert.Equal("XXXXXX", rom.SpamSum);
Assert.Equal("XXXXXX", rom.xxHash364);
Assert.Equal("XXXXXX", rom.xxHash3128);
Assert.Equal("XXXXXX", rom.Region);
Assert.Equal("XXXXXX", rom.Offs);
Assert.Equal("XXXXXX", rom.Serial);
Assert.Equal("XXXXXX", rom.Header);
Assert.Equal("XXXXXX", rom.Inverted);
Assert.Equal("XXXXXX", rom.MIA);
}
/// <summary>
/// Validate a Disk
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Disk? disk)
{
Assert.NotNull(disk);
Assert.Equal("XXXXXX", disk.Name);
Assert.Equal("XXXXXX", disk.MD5);
Assert.Equal("XXXXXX", disk.SHA1);
Assert.Equal("XXXXXX", disk.Merge);
Assert.Equal("XXXXXX", disk.Status);
Assert.Equal("XXXXXX", disk.Flags);
}
/// <summary>
/// Validate a Sample
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Sample? sample)
{
Assert.NotNull(sample);
Assert.Equal("XXXXXX", sample.Name);
}
/// <summary>
/// Validate a Archive
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Archive? archive)
{
Assert.NotNull(archive);
Assert.Equal("XXXXXX", archive.Name);
}
/// <summary>
/// Validate a Media
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Media? media)
{
Assert.NotNull(media);
Assert.Equal("XXXXXX", media.Name);
Assert.Equal("XXXXXX", media.MD5);
Assert.Equal("XXXXXX", media.SHA1);
Assert.Equal("XXXXXX", media.SHA256);
Assert.Equal("XXXXXX", media.SpamSum);
}
/// <summary>
/// Validate a Chip
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Chip? chip)
{
Assert.NotNull(chip);
Assert.Equal("XXXXXX", chip.Type);
Assert.Equal("XXXXXX", chip.Name);
Assert.Equal("XXXXXX", chip.Flags);
Assert.Equal("XXXXXX", chip.Clock);
}
/// <summary>
/// Validate a Video
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Video? video)
{
Assert.NotNull(video);
Assert.Equal("XXXXXX", video.Screen);
Assert.Equal("XXXXXX", video.Orientation);
Assert.Equal("XXXXXX", video.X);
Assert.Equal("XXXXXX", video.Y);
Assert.Equal("XXXXXX", video.AspectX);
Assert.Equal("XXXXXX", video.AspectY);
Assert.Equal("XXXXXX", video.Freq);
}
/// <summary>
/// Validate a Sound
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Sound? sound)
{
Assert.NotNull(sound);
Assert.Equal("XXXXXX", sound.Channels);
}
/// <summary>
/// Validate a Input
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Input? input)
{
Assert.NotNull(input);
Assert.Equal("XXXXXX", input.Players);
Assert.Equal("XXXXXX", input.Control);
Assert.Equal("XXXXXX", input.Buttons);
Assert.Equal("XXXXXX", input.Coins);
Assert.Equal("XXXXXX", input.Tilt);
Assert.Equal("XXXXXX", input.Service);
}
/// <summary>
/// Validate a DipSwitch
/// </summary>
private static void Validate(Data.Models.ClrMamePro.DipSwitch? dipswitch)
{
Assert.NotNull(dipswitch);
Assert.Equal("XXXXXX", dipswitch.Name);
Assert.NotNull(dipswitch.Entry);
string entry = Assert.Single(dipswitch.Entry);
Assert.Equal("XXXXXX", entry);
Assert.Equal("XXXXXX", dipswitch.Default);
}
/// <summary>
/// Validate a Driver
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Driver? driver)
{
Assert.NotNull(driver);
Assert.Equal("XXXXXX", driver.Status);
Assert.Equal("XXXXXX", driver.Color);
Assert.Equal("XXXXXX", driver.Sound);
Assert.Equal("XXXXXX", driver.PaletteSize);
Assert.Equal("XXXXXX", driver.Blit);
}
}
}

View File

@@ -0,0 +1,118 @@
using System;
using System.IO;
using System.Linq;
using System.Text;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class CueSheetTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new CueSheet();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new CueSheet();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new CueSheet();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new CueSheet();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new CueSheet();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new CueSheet();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
#region ReadQuotedString
[Fact]
public void ReadQuotedString_EmptyReader_Throws()
{
byte[] data = Encoding.UTF8.GetBytes(string.Empty);
var stream = new MemoryStream(data);
var reader = new StreamReader(stream, Encoding.UTF8);
Assert.Throws<ArgumentNullException>(() => CueSheet.ReadQuotedString(reader));
}
[Fact]
public void ReadQuotedString_NoQuotes_Correct()
{
byte[] data = Encoding.UTF8.GetBytes("Test1 Test2");
var stream = new MemoryStream(data);
var reader = new StreamReader(stream, Encoding.UTF8);
string? actual = CueSheet.ReadQuotedString(reader);
Assert.Equal("Test1 Test2", actual);
}
[Fact]
public void ReadQuotedString_SingleLineQuotes_Correct()
{
byte[] data = Encoding.UTF8.GetBytes("\"Test1 Test2\"");
var stream = new MemoryStream(data);
var reader = new StreamReader(stream, Encoding.UTF8);
string? actual = CueSheet.ReadQuotedString(reader);
Assert.Equal("\"Test1 Test2\"", actual);
}
[Fact]
public void ReadQuotedString_MultiLineQuotes_Correct()
{
byte[] data = Encoding.UTF8.GetBytes("\"Test1\nTest2\"");
var stream = new MemoryStream(data);
var reader = new StreamReader(stream, Encoding.UTF8);
string? actual = CueSheet.ReadQuotedString(reader);
Assert.Equal("\"Test1\nTest2\"", actual);
}
#endregion
}
}

View File

@@ -0,0 +1,177 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class DosCenterTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new DosCenter();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new DosCenter();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new DosCenter();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new DosCenter();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new DosCenter();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new DosCenter();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void RoundTripTest()
{
// Get the serializer and deserializer
var deserializer = new DosCenter();
var serializer = new SabreTools.Serialization.Writers.DosCenter();
// Build the data
Data.Models.DosCenter.MetadataFile mf = Build();
// Serialize to stream
Stream? actual = serializer.SerializeStream(mf);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.DosCenter.MetadataFile? newMf = deserializer.Deserialize(actual);
// Validate the data
Assert.NotNull(newMf);
Validate(newMf.DosCenter);
Assert.NotNull(newMf.Game);
var newGame = Assert.Single(newMf.Game);
Validate(newGame);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.DosCenter.MetadataFile Build()
{
var dc = new Data.Models.DosCenter.DosCenter
{
Name = "XXXXXX",
Description = "XXXXXX",
Version = "XXXXXX",
Date = "XXXXXX",
Author = "XXXXXX",
Homepage = "XXXXXX",
Comment = "XXXXXX",
};
var file = new Data.Models.DosCenter.File
{
Name = "XXXXXX",
Size = "XXXXXX",
CRC = "XXXXXX",
SHA1 = "XXXXXX",
Date = "XXXXXX XXXXXX",
};
var game = new Data.Models.DosCenter.Game
{
Name = "XXXXXX",
File = [file],
};
return new Data.Models.DosCenter.MetadataFile
{
DosCenter = dc,
Game = [game],
};
}
/// <summary>
/// Validate a DosCenter
/// </summary>
private static void Validate(Data.Models.DosCenter.DosCenter? cmp)
{
Assert.NotNull(cmp);
Assert.Equal("XXXXXX", cmp.Name);
Assert.Equal("XXXXXX", cmp.Description);
Assert.Equal("XXXXXX", cmp.Version);
Assert.Equal("XXXXXX", cmp.Date);
Assert.Equal("XXXXXX", cmp.Author);
Assert.Equal("XXXXXX", cmp.Homepage);
Assert.Equal("XXXXXX", cmp.Comment);
}
/// <summary>
/// Validate a Game
/// </summary>
private static void Validate(Data.Models.DosCenter.Game? game)
{
Assert.NotNull(game);
Assert.Equal("XXXXXX", game.Name);
Assert.NotNull(game.File);
var file = Assert.Single(game.File);
Validate(file);
}
/// <summary>
/// Validate a File
/// </summary>
private static void Validate(Data.Models.DosCenter.File? rom)
{
Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.Name);
Assert.Equal("XXXXXX", rom.Size);
Assert.Equal("XXXXXX", rom.CRC);
Assert.Equal("XXXXXX", rom.SHA1);
Assert.Equal("XXXXXX XXXXXX", rom.Date);
}
}
}

View File

@@ -0,0 +1,132 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class EverdriveSMDBTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new EverdriveSMDB();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new EverdriveSMDB();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new EverdriveSMDB();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new EverdriveSMDB();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new EverdriveSMDB();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new EverdriveSMDB();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void RoundTripTest()
{
// Get the serializer and deserializer
var deserializer = new EverdriveSMDB();
var serializer = new SabreTools.Serialization.Writers.EverdriveSMDB();
// Build the data
Data.Models.EverdriveSMDB.MetadataFile mf = Build();
// Serialize to stream
Stream? actual = serializer.SerializeStream(mf);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.EverdriveSMDB.MetadataFile? newMf = deserializer.Deserialize(actual);
// Validate the data
Assert.NotNull(newMf);
Assert.NotNull(newMf.Row);
var newRow = Assert.Single(newMf.Row);
Validate(newRow);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.EverdriveSMDB.MetadataFile Build()
{
var row = new Data.Models.EverdriveSMDB.Row
{
SHA256 = "XXXXXX",
Name = "XXXXXX",
SHA1 = "XXXXXX",
MD5 = "XXXXXX",
CRC32 = "XXXXXX",
Size = "XXXXXX",
};
return new Data.Models.EverdriveSMDB.MetadataFile
{
Row = [row],
};
}
/// <summary>
/// Validate a Row
/// </summary>
private static void Validate(Data.Models.EverdriveSMDB.Row? row)
{
Assert.NotNull(row);
Assert.Equal("XXXXXX", row.SHA256);
Assert.Equal("XXXXXX", row.Name);
Assert.Equal("XXXXXX", row.SHA1);
Assert.Equal("XXXXXX", row.MD5);
Assert.Equal("XXXXXX", row.CRC32);
Assert.Equal("XXXXXX", row.Size);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class GCFTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new GCF();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new GCF();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new GCF();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new GCF();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new GCF();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new GCF();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class GZipTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new GZip();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new GZip();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new GZip();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new GZip();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new GZip();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new GZip();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,401 @@
using System;
using System.IO;
using System.Linq;
using SabreTools.Hashing;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class HashfileTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new Hashfile();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new Hashfile();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new Hashfile();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new Hashfile();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new Hashfile();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new Hashfile();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void RoundTripSFVTest()
{
// Get the serializer and deserializer
var deserializer = new Hashfile();
var serializer = new SabreTools.Serialization.Writers.Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.CRC32);
// Serialize to stream
Stream? actual = serializer.SerializeStream(hf, HashType.CRC32);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = deserializer.Deserialize(actual, HashType.CRC32);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.SFV);
var newSfv = Assert.Single(newHf.SFV);
Validate(newSfv);
}
[Fact]
public void RoundTripMD2Test()
{
// Get the serializer and deserializer
var deserializer = new Hashfile();
var serializer = new SabreTools.Serialization.Writers.Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.MD2);
// Serialize to stream
Stream? actual = serializer.SerializeStream(hf, HashType.MD2);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = deserializer.Deserialize(actual, HashType.MD2);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.MD2);
var newMd2 = Assert.Single(newHf.MD2);
Validate(newMd2);
}
[Fact]
public void RoundTripMD4Test()
{
// Get the serializer and deserializer
var deserializer = new Hashfile();
var serializer = new SabreTools.Serialization.Writers.Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.MD4);
// Serialize to stream
Stream? actual = serializer.SerializeStream(hf, HashType.MD4);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = deserializer.Deserialize(actual, HashType.MD4);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.MD4);
var newMd4 = Assert.Single(newHf.MD4);
Validate(newMd4);
}
[Fact]
public void RoundTripMD5Test()
{
// Get the serializer and deserializer
var deserializer = new Hashfile();
var serializer = new SabreTools.Serialization.Writers.Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.MD5);
// Serialize to stream
Stream? actual = serializer.SerializeStream(hf, HashType.MD5);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = deserializer.Deserialize(actual, HashType.MD5);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.MD5);
var newMd5 = Assert.Single(newHf.MD5);
Validate(newMd5);
}
[Fact]
public void RoundTripSHA1Test()
{
// Get the serializer and deserializer
var deserializer = new Hashfile();
var serializer = new SabreTools.Serialization.Writers.Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.SHA1);
// Serialize to stream
Stream? actual = serializer.SerializeStream(hf, HashType.SHA1);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = deserializer.Deserialize(actual, HashType.SHA1);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.SHA1);
var newSha1 = Assert.Single(newHf.SHA1);
Validate(newSha1);
}
[Fact]
public void RoundTripSHA256Test()
{
// Get the serializer and deserializer
var deserializer = new Hashfile();
var serializer = new SabreTools.Serialization.Writers.Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.SHA256);
// Serialize to stream
Stream? actual = serializer.SerializeStream(hf, HashType.SHA256);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = deserializer.Deserialize(actual, HashType.SHA256);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.SHA256);
var newSha256 = Assert.Single(newHf.SHA256);
Validate(newSha256);
}
[Fact]
public void RoundTripSHA384Test()
{
// Get the serializer and deserializer
var deserializer = new Hashfile();
var serializer = new SabreTools.Serialization.Writers.Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.SHA384);
// Serialize to stream
Stream? actual = serializer.SerializeStream(hf, HashType.SHA384);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = deserializer.Deserialize(actual, HashType.SHA384);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.SHA384);
var newSha384 = Assert.Single(newHf.SHA384);
Validate(newSha384);
}
[Fact]
public void RoundTripSHA512Test()
{
// Get the serializer and deserializer
var deserializer = new Hashfile();
var serializer = new SabreTools.Serialization.Writers.Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.SHA512);
// Serialize to stream
Stream? actual = serializer.SerializeStream(hf, HashType.SHA512);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = deserializer.Deserialize(actual, HashType.SHA512);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.SHA512);
var newSha512 = Assert.Single(newHf.SHA512);
Validate(newSha512);
}
[Fact]
public void RoundTripSpamSumTest()
{
// Get the serializer and deserializer
var deserializer = new Hashfile();
var serializer = new SabreTools.Serialization.Writers.Hashfile();
// Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.SpamSum);
// Serialize to stream
Stream? actual = serializer.SerializeStream(hf, HashType.SpamSum);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.Hashfile.Hashfile? newHf = deserializer.Deserialize(actual, HashType.SpamSum);
// Validate the data
Assert.NotNull(newHf);
Assert.NotNull(newHf.SpamSum);
var newSpamsum = Assert.Single(newHf.SpamSum);
Validate(newSpamsum);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.Hashfile.Hashfile Build(HashType hashType)
{
return hashType switch
{
HashType.CRC32 => new Data.Models.Hashfile.Hashfile { SFV = [new Data.Models.Hashfile.SFV { File = "XXXXXX", Hash = "XXXXXX" }] },
HashType.MD2 => new Data.Models.Hashfile.Hashfile { MD2 = [new Data.Models.Hashfile.MD2 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.MD4 => new Data.Models.Hashfile.Hashfile { MD4 = [new Data.Models.Hashfile.MD4 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.MD5 => new Data.Models.Hashfile.Hashfile { MD5 = [new Data.Models.Hashfile.MD5 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SHA1 => new Data.Models.Hashfile.Hashfile { SHA1 = [new Data.Models.Hashfile.SHA1 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SHA256 => new Data.Models.Hashfile.Hashfile { SHA256 = [new Data.Models.Hashfile.SHA256 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SHA384 => new Data.Models.Hashfile.Hashfile { SHA384 = [new Data.Models.Hashfile.SHA384 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SHA512 => new Data.Models.Hashfile.Hashfile { SHA512 = [new Data.Models.Hashfile.SHA512 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SpamSum => new Data.Models.Hashfile.Hashfile { SpamSum = [new Data.Models.Hashfile.SpamSum { Hash = "XXXXXX", File = "XXXXXX" }] },
_ => throw new ArgumentOutOfRangeException(),
};
}
/// <summary>
/// Validate a SFV
/// </summary>
private static void Validate(Data.Models.Hashfile.SFV? sfv)
{
Assert.NotNull(sfv);
Assert.Equal("XXXXXX", sfv.File);
Assert.Equal("XXXXXX", sfv.Hash);
}
/// <summary>
/// Validate a MD2
/// </summary>
private static void Validate(Data.Models.Hashfile.MD2? md2)
{
Assert.NotNull(md2);
Assert.Equal("XXXXXX", md2.Hash);
Assert.Equal("XXXXXX", md2.File);
}
/// <summary>
/// Validate a MD4
/// </summary>
private static void Validate(Data.Models.Hashfile.MD4? md4)
{
Assert.NotNull(md4);
Assert.Equal("XXXXXX", md4.Hash);
Assert.Equal("XXXXXX", md4.File);
}
/// <summary>
/// Validate a MD5
/// </summary>
private static void Validate(Data.Models.Hashfile.MD5? md5)
{
Assert.NotNull(md5);
Assert.Equal("XXXXXX", md5.Hash);
Assert.Equal("XXXXXX", md5.File);
}
/// <summary>
/// Validate a SHA1
/// </summary>
private static void Validate(Data.Models.Hashfile.SHA1? sha1)
{
Assert.NotNull(sha1);
Assert.Equal("XXXXXX", sha1.Hash);
Assert.Equal("XXXXXX", sha1.File);
}
/// <summary>
/// Validate a SHA256
/// </summary>
private static void Validate(Data.Models.Hashfile.SHA256? sha256)
{
Assert.NotNull(sha256);
Assert.Equal("XXXXXX", sha256.Hash);
Assert.Equal("XXXXXX", sha256.File);
}
/// <summary>
/// Validate a SHA384
/// </summary>
private static void Validate(Data.Models.Hashfile.SHA384? sha384)
{
Assert.NotNull(sha384);
Assert.Equal("XXXXXX", sha384.Hash);
Assert.Equal("XXXXXX", sha384.File);
}
/// <summary>
/// Validate a SHA512
/// </summary>
private static void Validate(Data.Models.Hashfile.SHA512? sha512)
{
Assert.NotNull(sha512);
Assert.Equal("XXXXXX", sha512.Hash);
Assert.Equal("XXXXXX", sha512.File);
}
/// <summary>
/// Validate a SpamSum
/// </summary>
private static void Validate(Data.Models.Hashfile.SpamSum? spamsum)
{
Assert.NotNull(spamsum);
Assert.Equal("XXXXXX", spamsum.Hash);
Assert.Equal("XXXXXX", spamsum.File);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class IRDTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new IRD();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new IRD();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new IRD();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new IRD();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new IRD();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new IRD();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class ISO9660Tests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new ISO9660();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new ISO9660();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new ISO9660();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new ISO9660();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new ISO9660();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new ISO9660();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class InstallShieldArchiveV3Tests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new InstallShieldArchiveV3();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new InstallShieldArchiveV3();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new InstallShieldArchiveV3();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new InstallShieldArchiveV3();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new InstallShieldArchiveV3();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new InstallShieldArchiveV3();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class InstallShieldCabinetTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new InstallShieldCabinet();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new InstallShieldCabinet();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new InstallShieldCabinet();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new InstallShieldCabinet();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new InstallShieldCabinet();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new InstallShieldCabinet();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class InstallShieldExecutableFileTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new InstallShieldExecutableFile();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new InstallShieldExecutableFile();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new InstallShieldExecutableFile();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new InstallShieldExecutableFile();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new InstallShieldExecutableFile();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new InstallShieldExecutableFile();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class LZKWAJTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new LZKWAJ();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new LZKWAJ();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new LZKWAJ();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new LZKWAJ();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new LZKWAJ();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new LZKWAJ();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,74 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class LZQBasicTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new LZQBasic();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new LZQBasic();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new LZQBasic();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new LZQBasic();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new LZQBasic();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new LZQBasic();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class LZSZDDTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new LZSZDD();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new LZSZDD();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new LZSZDD();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new LZSZDD();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new LZSZDD();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new LZSZDD();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class LinearExecutableTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new LinearExecutable();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new LinearExecutable();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new LinearExecutable();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new LinearExecutable();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new LinearExecutable();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new LinearExecutable();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,267 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class ListromTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new Listrom();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new Listrom();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new Listrom();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new Listrom();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new Listrom();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new Listrom();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void RoundTripTest()
{
// Get the serializer and deserializer
var deserializer = new Listrom();
var serializer = new SabreTools.Serialization.Writers.Listrom();
// Build the data
Data.Models.Listrom.MetadataFile mf = Build();
// Serialize to stream
Stream? actual = serializer.SerializeStream(mf);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.Listrom.MetadataFile? newMf = deserializer.Deserialize(actual);
// Validate the data
Assert.NotNull(newMf);
Assert.NotNull(newMf.Set);
Assert.Equal(2, newMf.Set.Length);
ValidateDevice(newMf.Set[0]);
ValidateDriver(newMf.Set[1]);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.Listrom.MetadataFile Build()
{
var romGood = new Data.Models.Listrom.Row
{
Name = "XXXXXX",
Size = "12345",
Bad = false,
CRC = Hashing.ZeroHash.CRC32Str,
SHA1 = Hashing.ZeroHash.SHA1Str,
NoGoodDumpKnown = false,
};
var romBad = new Data.Models.Listrom.Row
{
Name = "XXXXXX",
Size = "12345",
Bad = true,
CRC = Hashing.ZeroHash.CRC32Str,
SHA1 = Hashing.ZeroHash.SHA1Str,
NoGoodDumpKnown = false,
};
var diskGoodMd5 = new Data.Models.Listrom.Row
{
Name = "XXXXXX",
Bad = false,
MD5 = Hashing.ZeroHash.MD5Str,
SHA1 = null,
NoGoodDumpKnown = false,
};
var diskGoodSha1 = new Data.Models.Listrom.Row
{
Name = "XXXXXX",
Bad = false,
MD5 = null,
SHA1 = Hashing.ZeroHash.SHA1Str,
NoGoodDumpKnown = false,
};
var diskBad = new Data.Models.Listrom.Row
{
Name = "XXXXXX",
Bad = false,
MD5 = Hashing.ZeroHash.MD5Str,
SHA1 = Hashing.ZeroHash.SHA1Str,
NoGoodDumpKnown = true,
};
var device = new Data.Models.Listrom.Set()
{
Device = "XXXXXX",
Row = [romGood, romBad],
};
var driver = new Data.Models.Listrom.Set()
{
Driver = "XXXXXX",
Row = [diskGoodMd5, diskGoodSha1, diskBad],
};
return new Data.Models.Listrom.MetadataFile
{
Set = [device, driver],
};
}
/// <summary>
/// Validate a Set
/// </summary>
private static void ValidateDevice(Data.Models.Listrom.Set? set)
{
Assert.NotNull(set);
Assert.Equal("XXXXXX", set.Device);
Assert.NotNull(set.Row);
Assert.Equal(2, set.Row.Length);
ValidateGoodRom(set.Row[0]);
ValidateBadRom(set.Row[1]);
}
/// <summary>
/// Validate a Set
/// </summary>
private static void ValidateDriver(Data.Models.Listrom.Set? set)
{
Assert.NotNull(set);
Assert.Equal("XXXXXX", set.Driver);
Assert.NotNull(set.Row);
Assert.Equal(3, set.Row.Length);
ValidateGoodMd5Disk(set.Row[0]);
ValidateGoodSha1Disk(set.Row[1]);
ValidateBadDisk(set.Row[2]);
}
/// <summary>
/// Validate a Row
/// </summary>
private static void ValidateGoodRom(Data.Models.Listrom.Row? row)
{
Assert.NotNull(row);
Assert.Equal("XXXXXX", row.Name);
Assert.Equal("12345", row.Size);
Assert.False(row.Bad);
Assert.Equal(Hashing.ZeroHash.CRC32Str, row.CRC);
Assert.Equal(Hashing.ZeroHash.SHA1Str, row.SHA1);
Assert.False(row.NoGoodDumpKnown);
}
/// <summary>
/// Validate a Row
/// </summary>
private static void ValidateBadRom(Data.Models.Listrom.Row? row)
{
Assert.NotNull(row);
Assert.Equal("XXXXXX", row.Name);
Assert.Equal("12345", row.Size);
Assert.True(row.Bad);
Assert.Equal(Hashing.ZeroHash.CRC32Str, row.CRC);
Assert.Equal(Hashing.ZeroHash.SHA1Str, row.SHA1);
Assert.False(row.NoGoodDumpKnown);
}
/// <summary>
/// Validate a Row
/// </summary>
private static void ValidateGoodMd5Disk(Data.Models.Listrom.Row? row)
{
Assert.NotNull(row);
Assert.Equal("XXXXXX", row.Name);
Assert.False(row.Bad);
Assert.Equal(Hashing.ZeroHash.MD5Str, row.MD5);
Assert.Null(row.SHA1);
Assert.False(row.NoGoodDumpKnown);
}
/// <summary>
/// Validate a Row
/// </summary>
private static void ValidateGoodSha1Disk(Data.Models.Listrom.Row? row)
{
Assert.NotNull(row);
Assert.Equal("XXXXXX", row.Name);
Assert.False(row.Bad);
Assert.Null(row.MD5);
Assert.Equal(Hashing.ZeroHash.SHA1Str, row.SHA1);
Assert.False(row.NoGoodDumpKnown);
}
/// <summary>
/// Validate a Row
/// </summary>
private static void ValidateBadDisk(Data.Models.Listrom.Row? row)
{
Assert.NotNull(row);
Assert.Equal("XXXXXX", row.Name);
Assert.False(row.Bad);
Assert.Null(row.MD5);
Assert.Null(row.SHA1);
Assert.True(row.NoGoodDumpKnown);
}
}
}

View File

@@ -0,0 +1,946 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class ListxmlTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new Listxml();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new Listxml();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new Listxml();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new Listxml();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new Listxml();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new Listxml();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void RoundTripGameTest()
{
// Get the serializer and deserializer
var deserializer = new Listxml();
var serializer = new SabreTools.Serialization.Writers.Listxml();
// Build the data
Data.Models.Listxml.Mame mame = Build(game: true);
// Serialize to stream
Stream? actual = serializer.Serialize(mame);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.Listxml.Mame? newMame = deserializer.Deserialize(actual);
// Validate the data
Assert.NotNull(newMame);
Assert.Equal("XXXXXX", newMame.Build);
Assert.Equal("XXXXXX", newMame.Debug);
Assert.Equal("XXXXXX", newMame.MameConfig);
Assert.NotNull(newMame.Game);
var newGame = Assert.Single(newMame.Game);
Validate(newGame);
}
[Fact]
public void RoundTripMachineTest()
{
// Get the serializer and deserializer
var deserializer = new Listxml();
var serializer = new SabreTools.Serialization.Writers.Listxml();
// Build the data
Data.Models.Listxml.Mame mame = Build(game: false);
// Serialize to stream
Stream? actual = serializer.Serialize(mame);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.Listxml.Mame? newMame = deserializer.Deserialize(actual);
// Validate the data
Assert.NotNull(newMame);
Assert.Equal("XXXXXX", newMame.Build);
Assert.Equal("XXXXXX", newMame.Debug);
Assert.Equal("XXXXXX", newMame.MameConfig);
Assert.NotNull(newMame.Game);
var newGame = Assert.Single(newMame.Game);
Validate(newGame);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.Listxml.Mame Build(bool game)
{
var biosset = new Data.Models.Listxml.BiosSet
{
Name = "XXXXXX",
Description = "XXXXXX",
Default = "XXXXXX",
};
var rom = new Data.Models.Listxml.Rom
{
Name = "XXXXXX",
Bios = "XXXXXX",
Size = "XXXXXX",
CRC = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Region = "XXXXXX",
Offset = "XXXXXX",
Status = "XXXXXX",
Optional = "XXXXXX",
Dispose = "XXXXXX",
SoundOnly = "XXXXXX",
};
var disk = new Data.Models.Listxml.Disk
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Region = "XXXXXX",
Index = "XXXXXX",
Writable = "XXXXXX",
Status = "XXXXXX",
Optional = "XXXXXX",
};
var deviceref = new Data.Models.Listxml.DeviceRef
{
Name = "XXXXXX",
};
var sample = new Data.Models.Listxml.Sample
{
Name = "XXXXXX",
};
var chip = new Data.Models.Listxml.Chip
{
Name = "XXXXXX",
Tag = "XXXXXX",
Type = "XXXXXX",
SoundOnly = "XXXXXX",
Clock = "XXXXXX",
};
var display = new Data.Models.Listxml.Display
{
Tag = "XXXXXX",
Type = "XXXXXX",
Rotate = "XXXXXX",
FlipX = "XXXXXX",
Width = "XXXXXX",
Height = "XXXXXX",
Refresh = "XXXXXX",
PixClock = "XXXXXX",
HTotal = "XXXXXX",
HBEnd = "XXXXXX",
HBStart = "XXXXXX",
VTotal = "XXXXXX",
VBEnd = "XXXXXX",
VBStart = "XXXXXX",
};
var video = new Data.Models.Listxml.Video
{
Screen = "XXXXXX",
Orientation = "XXXXXX",
Width = "XXXXXX",
Height = "XXXXXX",
AspectX = "XXXXXX",
AspectY = "XXXXXX",
Refresh = "XXXXXX",
};
var sound = new Data.Models.Listxml.Sound
{
Channels = "XXXXXX",
};
var control = new Data.Models.Listxml.Control
{
Type = "XXXXXX",
Player = "XXXXXX",
Buttons = "XXXXXX",
ReqButtons = "XXXXXX",
Minimum = "XXXXXX",
Maximum = "XXXXXX",
Sensitivity = "XXXXXX",
KeyDelta = "XXXXXX",
Reverse = "XXXXXX",
Ways = "XXXXXX",
Ways2 = "XXXXXX",
Ways3 = "XXXXXX",
};
var input = new Data.Models.Listxml.Input
{
Service = "XXXXXX",
Tilt = "XXXXXX",
Players = "XXXXXX",
//ControlAttr = "XXXXXX", // Mututally exclusive with input.Control
Buttons = "XXXXXX",
Coins = "XXXXXX",
Control = [control],
};
var condition = new Data.Models.Listxml.Condition
{
Tag = "XXXXXX",
Mask = "XXXXXX",
Relation = "XXXXXX",
Value = "XXXXXX",
};
var diplocation = new Data.Models.Listxml.DipLocation
{
Name = "XXXXXX",
Number = "XXXXXX",
Inverted = "XXXXXX",
};
var dipvalue = new Data.Models.Listxml.DipValue
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var dipswitch = new Data.Models.Listxml.DipSwitch
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
Condition = condition,
DipLocation = [diplocation],
DipValue = [dipvalue],
};
var conflocation = new Data.Models.Listxml.ConfLocation
{
Name = "XXXXXX",
Number = "XXXXXX",
Inverted = "XXXXXX",
};
var confsetting = new Data.Models.Listxml.ConfSetting
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var configuration = new Data.Models.Listxml.Configuration
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
Condition = condition,
ConfLocation = [conflocation],
ConfSetting = [confsetting],
};
var analog = new Data.Models.Listxml.Analog
{
Mask = "XXXXXX",
};
var port = new Data.Models.Listxml.Port
{
Tag = "XXXXXX",
Analog = [analog],
};
var adjuster = new Data.Models.Listxml.Adjuster
{
Name = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var driver = new Data.Models.Listxml.Driver
{
Status = "XXXXXX",
Color = "XXXXXX",
Sound = "XXXXXX",
PaletteSize = "XXXXXX",
Emulation = "XXXXXX",
Cocktail = "XXXXXX",
SaveState = "XXXXXX",
RequiresArtwork = "XXXXXX",
Unofficial = "XXXXXX",
NoSoundHardware = "XXXXXX",
Incomplete = "XXXXXX",
};
var feature = new Data.Models.Listxml.Feature
{
Type = "XXXXXX",
Status = "XXXXXX",
Overall = "XXXXXX",
};
var instance = new Data.Models.Listxml.Instance
{
Name = "XXXXXX",
BriefName = "XXXXXX",
};
var extension = new Data.Models.Listxml.Extension
{
Name = "XXXXXX",
};
var device = new Data.Models.Listxml.Device
{
Type = "XXXXXX",
Tag = "XXXXXX",
FixedImage = "XXXXXX",
Mandatory = "XXXXXX",
Interface = "XXXXXX",
Instance = instance,
Extension = [extension],
};
var slotOption = new Data.Models.Listxml.SlotOption
{
Name = "XXXXXX",
DevName = "XXXXXX",
Default = "XXXXXX",
};
var slot = new Data.Models.Listxml.Slot
{
Name = "XXXXXX",
SlotOption = [slotOption],
};
var softwarelist = new Data.Models.Listxml.SoftwareList
{
Tag = "XXXXXX",
Name = "XXXXXX",
Status = "XXXXXX",
Filter = "XXXXXX",
};
var ramoption = new Data.Models.Listxml.RamOption
{
Name = "XXXXXX",
Default = "XXXXXX",
Content = "XXXXXX",
};
Data.Models.Listxml.GameBase gameBase = game
? new Data.Models.Listxml.Game()
: new Data.Models.Listxml.Machine();
gameBase.Name = "XXXXXX";
gameBase.SourceFile = "XXXXXX";
gameBase.IsBios = "XXXXXX";
gameBase.IsDevice = "XXXXXX";
gameBase.IsMechanical = "XXXXXX";
gameBase.Runnable = "XXXXXX";
gameBase.CloneOf = "XXXXXX";
gameBase.RomOf = "XXXXXX";
gameBase.SampleOf = "XXXXXX";
gameBase.Description = "XXXXXX";
gameBase.Year = "XXXXXX";
gameBase.Manufacturer = "XXXXXX";
gameBase.History = "XXXXXX";
gameBase.BiosSet = [biosset];
gameBase.Rom = [rom];
gameBase.Disk = [disk];
gameBase.DeviceRef = [deviceref];
gameBase.Sample = [sample];
gameBase.Chip = [chip];
gameBase.Display = [display];
gameBase.Video = [video];
gameBase.Sound = sound;
gameBase.Input = input;
gameBase.DipSwitch = [dipswitch];
gameBase.Configuration = [configuration];
gameBase.Port = [port];
gameBase.Adjuster = [adjuster];
gameBase.Driver = driver;
gameBase.Feature = [feature];
gameBase.Device = [device];
gameBase.Slot = [slot];
gameBase.SoftwareList = [softwarelist];
gameBase.RamOption = [ramoption];
return new Data.Models.Listxml.Mame
{
Build = "XXXXXX",
Debug = "XXXXXX",
MameConfig = "XXXXXX",
Game = [gameBase],
};
}
/// <summary>
/// Validate a GameBase
/// </summary>
private static void Validate(Data.Models.Listxml.GameBase? gb)
{
Assert.NotNull(gb);
Assert.Equal("XXXXXX", gb.Name);
Assert.Equal("XXXXXX", gb.SourceFile);
Assert.Equal("XXXXXX", gb.IsBios);
Assert.Equal("XXXXXX", gb.IsDevice);
Assert.Equal("XXXXXX", gb.IsMechanical);
Assert.Equal("XXXXXX", gb.Runnable);
Assert.Equal("XXXXXX", gb.CloneOf);
Assert.Equal("XXXXXX", gb.RomOf);
Assert.Equal("XXXXXX", gb.SampleOf);
Assert.Equal("XXXXXX", gb.Description);
Assert.Equal("XXXXXX", gb.Year);
Assert.Equal("XXXXXX", gb.Manufacturer);
Assert.Equal("XXXXXX", gb.History);
Assert.NotNull(gb.BiosSet);
var biosset = Assert.Single(gb.BiosSet);
Validate(biosset);
Assert.NotNull(gb.Rom);
var rom = Assert.Single(gb.Rom);
Validate(rom);
Assert.NotNull(gb.Disk);
var disk = Assert.Single(gb.Disk);
Validate(disk);
Assert.NotNull(gb.DeviceRef);
var deviceref = Assert.Single(gb.DeviceRef);
Validate(deviceref);
Assert.NotNull(gb.Sample);
var sample = Assert.Single(gb.Sample);
Validate(sample);
Assert.NotNull(gb.Chip);
var chip = Assert.Single(gb.Chip);
Validate(chip);
Assert.NotNull(gb.Display);
var display = Assert.Single(gb.Display);
Validate(display);
Assert.NotNull(gb.Video);
var video = Assert.Single(gb.Video);
Validate(video);
Validate(gb.Sound);
Validate(gb.Input);
Assert.NotNull(gb.DipSwitch);
var dipswitch = Assert.Single(gb.DipSwitch);
Validate(dipswitch);
Assert.NotNull(gb.Configuration);
var configuration = Assert.Single(gb.Configuration);
Validate(configuration);
Assert.NotNull(gb.Port);
var port = Assert.Single(gb.Port);
Validate(port);
Assert.NotNull(gb.Adjuster);
var adjuster = Assert.Single(gb.Adjuster);
Validate(adjuster);
Validate(gb.Driver);
Assert.NotNull(gb.Feature);
var feature = Assert.Single(gb.Feature);
Validate(feature);
Assert.NotNull(gb.Device);
var device = Assert.Single(gb.Device);
Validate(device);
Assert.NotNull(gb.Slot);
var slot = Assert.Single(gb.Slot);
Validate(slot);
Assert.NotNull(gb.SoftwareList);
var softwarelist = Assert.Single(gb.SoftwareList);
Validate(softwarelist);
Assert.NotNull(gb.RamOption);
var ramoption = Assert.Single(gb.RamOption);
Validate(ramoption);
}
/// <summary>
/// Validate a BiosSet
/// </summary>
private static void Validate(Data.Models.Listxml.BiosSet? biosset)
{
Assert.NotNull(biosset);
Assert.Equal("XXXXXX", biosset.Name);
Assert.Equal("XXXXXX", biosset.Description);
Assert.Equal("XXXXXX", biosset.Default);
}
/// <summary>
/// Validate a Rom
/// </summary>
private static void Validate(Data.Models.Listxml.Rom? rom)
{
Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.Name);
Assert.Equal("XXXXXX", rom.Bios);
Assert.Equal("XXXXXX", rom.Size);
Assert.Equal("XXXXXX", rom.CRC);
Assert.Equal("XXXXXX", rom.SHA1);
Assert.Equal("XXXXXX", rom.Merge);
Assert.Equal("XXXXXX", rom.Region);
Assert.Equal("XXXXXX", rom.Offset);
Assert.Equal("XXXXXX", rom.Status);
Assert.Equal("XXXXXX", rom.Optional);
Assert.Equal("XXXXXX", rom.Dispose);
Assert.Equal("XXXXXX", rom.SoundOnly);
}
/// <summary>
/// Validate a Disk
/// </summary>
private static void Validate(Data.Models.Listxml.Disk? disk)
{
Assert.NotNull(disk);
Assert.Equal("XXXXXX", disk.Name);
Assert.Equal("XXXXXX", disk.MD5);
Assert.Equal("XXXXXX", disk.SHA1);
Assert.Equal("XXXXXX", disk.Merge);
Assert.Equal("XXXXXX", disk.Region);
Assert.Equal("XXXXXX", disk.Index);
Assert.Equal("XXXXXX", disk.Writable);
Assert.Equal("XXXXXX", disk.Status);
Assert.Equal("XXXXXX", disk.Optional);
}
/// <summary>
/// Validate a DeviceRef
/// </summary>
private static void Validate(Data.Models.Listxml.DeviceRef? deviceref)
{
Assert.NotNull(deviceref);
Assert.Equal("XXXXXX", deviceref.Name);
}
/// <summary>
/// Validate a Sample
/// </summary>
private static void Validate(Data.Models.Listxml.Sample? sample)
{
Assert.NotNull(sample);
Assert.Equal("XXXXXX", sample.Name);
}
/// <summary>
/// Validate a Chip
/// </summary>
private static void Validate(Data.Models.Listxml.Chip? chip)
{
Assert.NotNull(chip);
Assert.Equal("XXXXXX", chip.Name);
Assert.Equal("XXXXXX", chip.Tag);
Assert.Equal("XXXXXX", chip.Type);
Assert.Equal("XXXXXX", chip.SoundOnly);
Assert.Equal("XXXXXX", chip.Clock);
}
/// <summary>
/// Validate a Display
/// </summary>
private static void Validate(Data.Models.Listxml.Display? display)
{
Assert.NotNull(display);
Assert.Equal("XXXXXX", display.Tag);
Assert.Equal("XXXXXX", display.Type);
Assert.Equal("XXXXXX", display.Rotate);
Assert.Equal("XXXXXX", display.FlipX);
Assert.Equal("XXXXXX", display.Width);
Assert.Equal("XXXXXX", display.Height);
Assert.Equal("XXXXXX", display.Refresh);
Assert.Equal("XXXXXX", display.PixClock);
Assert.Equal("XXXXXX", display.HTotal);
Assert.Equal("XXXXXX", display.HBEnd);
Assert.Equal("XXXXXX", display.HBStart);
Assert.Equal("XXXXXX", display.VTotal);
Assert.Equal("XXXXXX", display.VBEnd);
Assert.Equal("XXXXXX", display.VBStart);
}
/// <summary>
/// Validate a Video
/// </summary>
private static void Validate(Data.Models.Listxml.Video? video)
{
Assert.NotNull(video);
Assert.Equal("XXXXXX", video.Screen);
Assert.Equal("XXXXXX", video.Orientation);
Assert.Equal("XXXXXX", video.Width);
Assert.Equal("XXXXXX", video.Height);
Assert.Equal("XXXXXX", video.AspectX);
Assert.Equal("XXXXXX", video.AspectY);
Assert.Equal("XXXXXX", video.Refresh);
}
/// <summary>
/// Validate a Sound
/// </summary>
private static void Validate(Data.Models.Listxml.Sound? sound)
{
Assert.NotNull(sound);
Assert.Equal("XXXXXX", sound.Channels);
}
/// <summary>
/// Validate a Input
/// </summary>
private static void Validate(Data.Models.Listxml.Input? input)
{
Assert.NotNull(input);
Assert.Equal("XXXXXX", input.Service);
Assert.Equal("XXXXXX", input.Tilt);
Assert.Equal("XXXXXX", input.Players);
//Assert.Equal("XXXXXX", input.ControlAttr); // Mututally exclusive with input.Control
Assert.Equal("XXXXXX", input.Buttons);
Assert.Equal("XXXXXX", input.Coins);
Assert.NotNull(input.Control);
var control = Assert.Single(input.Control);
Validate(control);
}
/// <summary>
/// Validate a Control
/// </summary>
private static void Validate(Data.Models.Listxml.Control? control)
{
Assert.NotNull(control);
Assert.Equal("XXXXXX", control.Type);
Assert.Equal("XXXXXX", control.Player);
Assert.Equal("XXXXXX", control.Buttons);
Assert.Equal("XXXXXX", control.ReqButtons);
Assert.Equal("XXXXXX", control.Minimum);
Assert.Equal("XXXXXX", control.Maximum);
Assert.Equal("XXXXXX", control.Sensitivity);
Assert.Equal("XXXXXX", control.KeyDelta);
Assert.Equal("XXXXXX", control.Reverse);
Assert.Equal("XXXXXX", control.Ways);
Assert.Equal("XXXXXX", control.Ways2);
Assert.Equal("XXXXXX", control.Ways3);
}
/// <summary>
/// Validate a DipSwitch
/// </summary>
private static void Validate(Data.Models.Listxml.DipSwitch? dipswitch)
{
Assert.NotNull(dipswitch);
Assert.Equal("XXXXXX", dipswitch.Name);
Assert.Equal("XXXXXX", dipswitch.Tag);
Assert.Equal("XXXXXX", dipswitch.Mask);
Validate(dipswitch.Condition);
Assert.NotNull(dipswitch.DipLocation);
var diplocation = Assert.Single(dipswitch.DipLocation);
Validate(diplocation);
Assert.NotNull(dipswitch.DipValue);
var dipvalue = Assert.Single(dipswitch.DipValue);
Validate(dipvalue);
}
/// <summary>
/// Validate a Condition
/// </summary>
private static void Validate(Data.Models.Listxml.Condition? condition)
{
Assert.NotNull(condition);
Assert.Equal("XXXXXX", condition.Tag);
Assert.Equal("XXXXXX", condition.Mask);
Assert.Equal("XXXXXX", condition.Relation);
Assert.Equal("XXXXXX", condition.Value);
}
/// <summary>
/// Validate a DipLocation
/// </summary>
private static void Validate(Data.Models.Listxml.DipLocation? diplocation)
{
Assert.NotNull(diplocation);
Assert.Equal("XXXXXX", diplocation.Name);
Assert.Equal("XXXXXX", diplocation.Number);
Assert.Equal("XXXXXX", diplocation.Inverted);
}
/// <summary>
/// Validate a DipValue
/// </summary>
private static void Validate(Data.Models.Listxml.DipValue? dipvalue)
{
Assert.NotNull(dipvalue);
Assert.Equal("XXXXXX", dipvalue.Name);
Assert.Equal("XXXXXX", dipvalue.Value);
Assert.Equal("XXXXXX", dipvalue.Default);
Validate(dipvalue.Condition);
}
/// <summary>
/// Validate a Configuration
/// </summary>
private static void Validate(Data.Models.Listxml.Configuration? configuration)
{
Assert.NotNull(configuration);
Assert.Equal("XXXXXX", configuration.Name);
Assert.Equal("XXXXXX", configuration.Tag);
Assert.Equal("XXXXXX", configuration.Mask);
Validate(configuration.Condition);
Assert.NotNull(configuration.ConfLocation);
var conflocation = Assert.Single(configuration.ConfLocation);
Validate(conflocation);
Assert.NotNull(configuration.ConfSetting);
var confsetting = Assert.Single(configuration.ConfSetting);
Validate(confsetting);
}
/// <summary>
/// Validate a ConfLocation
/// </summary>
private static void Validate(Data.Models.Listxml.ConfLocation? conflocation)
{
Assert.NotNull(conflocation);
Assert.Equal("XXXXXX", conflocation.Name);
Assert.Equal("XXXXXX", conflocation.Number);
Assert.Equal("XXXXXX", conflocation.Inverted);
}
/// <summary>
/// Validate a ConfSetting
/// </summary>
private static void Validate(Data.Models.Listxml.ConfSetting? confsetting)
{
Assert.NotNull(confsetting);
Assert.Equal("XXXXXX", confsetting.Name);
Assert.Equal("XXXXXX", confsetting.Value);
Assert.Equal("XXXXXX", confsetting.Default);
Validate(confsetting.Condition);
}
/// <summary>
/// Validate a Port
/// </summary>
private static void Validate(Data.Models.Listxml.Port? port)
{
Assert.NotNull(port);
Assert.Equal("XXXXXX", port.Tag);
Assert.NotNull(port.Analog);
var analog = Assert.Single(port.Analog);
Validate(analog);
}
/// <summary>
/// Validate a Analog
/// </summary>
private static void Validate(Data.Models.Listxml.Analog? analog)
{
Assert.NotNull(analog);
Assert.Equal("XXXXXX", analog.Mask);
}
/// <summary>
/// Validate a Adjuster
/// </summary>
private static void Validate(Data.Models.Listxml.Adjuster? adjuster)
{
Assert.NotNull(adjuster);
Assert.Equal("XXXXXX", adjuster.Name);
Assert.Equal("XXXXXX", adjuster.Default);
Validate(adjuster.Condition);
}
/// <summary>
/// Validate a Driver
/// </summary>
private static void Validate(Data.Models.Listxml.Driver? driver)
{
Assert.NotNull(driver);
Assert.Equal("XXXXXX", driver.Status);
Assert.Equal("XXXXXX", driver.Color);
Assert.Equal("XXXXXX", driver.Sound);
Assert.Equal("XXXXXX", driver.PaletteSize);
Assert.Equal("XXXXXX", driver.Emulation);
Assert.Equal("XXXXXX", driver.Cocktail);
Assert.Equal("XXXXXX", driver.SaveState);
Assert.Equal("XXXXXX", driver.RequiresArtwork);
Assert.Equal("XXXXXX", driver.Unofficial);
Assert.Equal("XXXXXX", driver.NoSoundHardware);
Assert.Equal("XXXXXX", driver.Incomplete);
}
/// <summary>
/// Validate a Feature
/// </summary>
private static void Validate(Data.Models.Listxml.Feature? feature)
{
Assert.NotNull(feature);
Assert.Equal("XXXXXX", feature.Type);
Assert.Equal("XXXXXX", feature.Status);
Assert.Equal("XXXXXX", feature.Overall);
}
/// <summary>
/// Validate a Device
/// </summary>
private static void Validate(Data.Models.Listxml.Device? device)
{
Assert.NotNull(device);
Assert.Equal("XXXXXX", device.Type);
Assert.Equal("XXXXXX", device.Tag);
Assert.Equal("XXXXXX", device.FixedImage);
Assert.Equal("XXXXXX", device.Mandatory);
Assert.Equal("XXXXXX", device.Interface);
Validate(device.Instance);
Assert.NotNull(device.Extension);
var extension = Assert.Single(device.Extension);
Validate(extension);
}
/// <summary>
/// Validate a Instance
/// </summary>
private static void Validate(Data.Models.Listxml.Instance? instance)
{
Assert.NotNull(instance);
Assert.Equal("XXXXXX", instance.Name);
Assert.Equal("XXXXXX", instance.BriefName);
}
/// <summary>
/// Validate a Extension
/// </summary>
private static void Validate(Data.Models.Listxml.Extension? extension)
{
Assert.NotNull(extension);
Assert.Equal("XXXXXX", extension.Name);
}
/// <summary>
/// Validate a Slot
/// </summary>
private static void Validate(Data.Models.Listxml.Slot? slot)
{
Assert.NotNull(slot);
Assert.Equal("XXXXXX", slot.Name);
Assert.NotNull(slot.SlotOption);
var slotoption = Assert.Single(slot.SlotOption);
Validate(slotoption);
}
/// <summary>
/// Validate a SlotOption
/// </summary>
private static void Validate(Data.Models.Listxml.SlotOption? slotoption)
{
Assert.NotNull(slotoption);
Assert.Equal("XXXXXX", slotoption.Name);
Assert.Equal("XXXXXX", slotoption.DevName);
Assert.Equal("XXXXXX", slotoption.Default);
}
/// <summary>
/// Validate a SoftwareList
/// </summary>
private static void Validate(Data.Models.Listxml.SoftwareList? softwarelist)
{
Assert.NotNull(softwarelist);
Assert.Equal("XXXXXX", softwarelist.Tag);
Assert.Equal("XXXXXX", softwarelist.Name);
Assert.Equal("XXXXXX", softwarelist.Status);
Assert.Equal("XXXXXX", softwarelist.Filter);
}
/// <summary>
/// Validate a RamOption
/// </summary>
private static void Validate(Data.Models.Listxml.RamOption? ramoption)
{
Assert.NotNull(ramoption);
Assert.Equal("XXXXXX", ramoption.Name);
Assert.Equal("XXXXXX", ramoption.Default);
Assert.Equal("XXXXXX", ramoption.Content);
}
}
}

View File

@@ -0,0 +1,621 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class LogiqxTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new Logiqx();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new Logiqx();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new Logiqx();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new Logiqx();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new Logiqx();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new Logiqx();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void RoundTripGameTest()
{
// Get the serializer and deserializer
var deserializer = new Logiqx();
var serializer = new SabreTools.Serialization.Writers.Logiqx();
// Build the data
Data.Models.Logiqx.Datafile df = Build(game: true);
// Serialize to stream
Stream? metadata = serializer.Serialize(df);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Logiqx.Datafile? newDf = deserializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newDf);
Assert.Equal("XXXXXX", newDf.Build);
Assert.Equal("XXXXXX", newDf.Debug);
Assert.Equal("XXXXXX", newDf.SchemaLocation);
Validate(newDf.Header);
Assert.NotNull(newDf.Game);
var newGame = Assert.Single(newDf.Game);
Validate(newGame);
// TODO: Unsupported
Assert.Null(newDf.Dir);
}
[Fact]
public void RoundTripMachineTest()
{
// Get the serializer and deserializer
var deserializer = new Logiqx();
var serializer = new SabreTools.Serialization.Writers.Logiqx();
// Build the data
Data.Models.Logiqx.Datafile df = Build(game: false);
// Serialize to stream
Stream? metadata = serializer.Serialize(df);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.Logiqx.Datafile? newDf = deserializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newDf);
Assert.Equal("XXXXXX", newDf.Build);
Assert.Equal("XXXXXX", newDf.Debug);
Assert.Equal("XXXXXX", newDf.SchemaLocation);
Validate(newDf.Header);
Assert.NotNull(newDf.Game);
var newGame = Assert.Single(newDf.Game);
Validate(newGame);
// TODO: Unsupported
Assert.Null(newDf.Dir);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.Logiqx.Datafile Build(bool game)
{
var clrmamepro = new Data.Models.Logiqx.ClrMamePro
{
Header = "XXXXXX",
ForceMerging = "XXXXXX",
ForceNodump = "XXXXXX",
ForcePacking = "XXXXXX",
};
var romcenter = new Data.Models.Logiqx.RomCenter
{
Plugin = "XXXXXX",
RomMode = "XXXXXX",
BiosMode = "XXXXXX",
SampleMode = "XXXXXX",
LockRomMode = "XXXXXX",
LockBiosMode = "XXXXXX",
LockSampleMode = "XXXXXX",
};
var header = new Data.Models.Logiqx.Header
{
Id = "XXXXXX",
Name = "XXXXXX",
Description = "XXXXXX",
RootDir = "XXXXXX",
Category = "XXXXXX",
Version = "XXXXXX",
Date = "XXXXXX",
Author = "XXXXXX",
Email = "XXXXXX",
Homepage = "XXXXXX",
Url = "XXXXXX",
Comment = "XXXXXX",
Type = "XXXXXX",
ClrMamePro = clrmamepro,
RomCenter = romcenter,
};
var trurip = new Data.Models.Logiqx.Trurip
{
TitleID = "XXXXXX",
Publisher = "XXXXXX",
Developer = "XXXXXX",
Year = "XXXXXX",
Genre = "XXXXXX",
Subgenre = "XXXXXX",
Ratings = "XXXXXX",
Score = "XXXXXX",
Players = "XXXXXX",
Enabled = "XXXXXX",
CRC = "XXXXXX",
Source = "XXXXXX",
CloneOf = "XXXXXX",
RelatedTo = "XXXXXX",
};
var release = new Data.Models.Logiqx.Release
{
Name = "XXXXXX",
Region = "XXXXXX",
Language = "XXXXXX",
Date = "XXXXXX",
Default = "XXXXXX",
};
var biosset = new Data.Models.Logiqx.BiosSet
{
Name = "XXXXXX",
Description = "XXXXXX",
Default = "XXXXXX",
};
var rom = new Data.Models.Logiqx.Rom
{
Name = "XXXXXX",
Size = "XXXXXX",
CRC = "XXXXXX",
MD2 = "XXXXXX",
MD4 = "XXXXXX",
MD5 = "XXXXXX",
RIPEMD128 = "XXXXXX",
RIPEMD160 = "XXXXXX",
SHA1 = "XXXXXX",
SHA256 = "XXXXXX",
SHA384 = "XXXXXX",
SHA512 = "XXXXXX",
SpamSum = "XXXXXX",
xxHash364 = "XXXXXX",
xxHash3128 = "XXXXXX",
Merge = "XXXXXX",
Status = "XXXXXX",
Serial = "XXXXXX",
Header = "XXXXXX",
Date = "XXXXXX",
Inverted = "XXXXXX",
MIA = "XXXXXX",
};
var disk = new Data.Models.Logiqx.Disk
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Status = "XXXXXX",
Region = "XXXXXX",
};
var media = new Data.Models.Logiqx.Media
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
SHA256 = "XXXXXX",
SpamSum = "XXXXXX",
};
var deviceRef = new Data.Models.Logiqx.DeviceRef
{
Name = "XXXXXX",
};
var sample = new Data.Models.Logiqx.Sample
{
Name = "XXXXXX",
};
var archive = new Data.Models.Logiqx.Archive
{
Name = "XXXXXX",
};
var driver = new Data.Models.Logiqx.Driver
{
Status = "XXXXXX",
Emulation = "XXXXXX",
Cocktail = "XXXXXX",
SaveState = "XXXXXX",
RequiresArtwork = "XXXXXX",
Unofficial = "XXXXXX",
NoSoundHardware = "XXXXXX",
Incomplete = "XXXXXX",
};
var softwarelist = new Data.Models.Logiqx.SoftwareList
{
Tag = "XXXXXX",
Name = "XXXXXX",
Status = "XXXXXX",
Filter = "XXXXXX",
};
Data.Models.Logiqx.GameBase gameBase = game
? new Data.Models.Logiqx.Game()
: new Data.Models.Logiqx.Machine();
gameBase.Name = "XXXXXX";
gameBase.SourceFile = "XXXXXX";
gameBase.IsBios = "XXXXXX";
gameBase.IsDevice = "XXXXXX";
gameBase.IsMechanical = "XXXXXX";
gameBase.CloneOf = "XXXXXX";
gameBase.RomOf = "XXXXXX";
gameBase.SampleOf = "XXXXXX";
gameBase.Board = "XXXXXX";
gameBase.RebuildTo = "XXXXXX";
gameBase.Id = "XXXXXX";
gameBase.CloneOfId = "XXXXXX";
gameBase.Runnable = "XXXXXX";
gameBase.Comment = ["XXXXXX"];
gameBase.Description = "XXXXXX";
gameBase.Year = "XXXXXX";
gameBase.Manufacturer = "XXXXXX";
gameBase.Publisher = "XXXXXX";
gameBase.Category = ["XXXXXX"];
gameBase.Trurip = trurip;
gameBase.Release = [release];
gameBase.BiosSet = [biosset];
gameBase.Rom = [rom];
gameBase.Disk = [disk];
gameBase.Media = [media];
gameBase.DeviceRef = [deviceRef];
gameBase.Sample = [sample];
gameBase.Archive = [archive];
gameBase.Driver = driver;
gameBase.SoftwareList = [softwarelist];
return new Data.Models.Logiqx.Datafile
{
Build = "XXXXXX",
Debug = "XXXXXX",
SchemaLocation = "XXXXXX",
Header = header,
Game = [gameBase],
// Dir = [dir], // TODO: Unsupported
};
}
/// <summary>
/// Validate a Header
/// </summary>
private static void Validate(Data.Models.Logiqx.Header? header)
{
Assert.NotNull(header);
Assert.Equal("XXXXXX", header.Id);
Assert.Equal("XXXXXX", header.Name);
Assert.Equal("XXXXXX", header.Description);
Assert.Equal("XXXXXX", header.RootDir);
Assert.Equal("XXXXXX", header.Category);
Assert.Equal("XXXXXX", header.Version);
Assert.Equal("XXXXXX", header.Date);
Assert.Equal("XXXXXX", header.Author);
Assert.Equal("XXXXXX", header.Email);
Assert.Equal("XXXXXX", header.Homepage);
Assert.Equal("XXXXXX", header.Url);
Assert.Equal("XXXXXX", header.Comment);
Assert.Equal("XXXXXX", header.Type);
Validate(header.ClrMamePro);
Validate(header.RomCenter);
}
/// <summary>
/// Validate a ClrMamePro
/// </summary>
private static void Validate(Data.Models.Logiqx.ClrMamePro? cmp)
{
Assert.NotNull(cmp);
Assert.Equal("XXXXXX", cmp.Header);
Assert.Equal("XXXXXX", cmp.ForceMerging);
Assert.Equal("XXXXXX", cmp.ForceNodump);
Assert.Equal("XXXXXX", cmp.ForcePacking);
}
/// <summary>
/// Validate a RomCenter
/// </summary>
private static void Validate(Data.Models.Logiqx.RomCenter? rc)
{
Assert.NotNull(rc);
Assert.Equal("XXXXXX", rc.Plugin);
Assert.Equal("XXXXXX", rc.RomMode);
Assert.Equal("XXXXXX", rc.BiosMode);
Assert.Equal("XXXXXX", rc.SampleMode);
Assert.Equal("XXXXXX", rc.LockRomMode);
Assert.Equal("XXXXXX", rc.LockBiosMode);
Assert.Equal("XXXXXX", rc.LockSampleMode);
}
/// <summary>
/// Validate a GameBase
/// </summary>
private static void Validate(Data.Models.Logiqx.GameBase? gb)
{
Assert.NotNull(gb);
Assert.Equal("XXXXXX", gb.Name);
Assert.Equal("XXXXXX", gb.SourceFile);
Assert.Equal("XXXXXX", gb.IsBios);
Assert.Equal("XXXXXX", gb.IsDevice);
Assert.Equal("XXXXXX", gb.IsMechanical);
Assert.Equal("XXXXXX", gb.CloneOf);
Assert.Equal("XXXXXX", gb.RomOf);
Assert.Equal("XXXXXX", gb.SampleOf);
Assert.Equal("XXXXXX", gb.Board);
Assert.Equal("XXXXXX", gb.RebuildTo);
Assert.Equal("XXXXXX", gb.Id);
Assert.Equal("XXXXXX", gb.CloneOfId);
Assert.Equal("XXXXXX", gb.Runnable);
Assert.NotNull(gb.Comment);
string comment = Assert.Single(gb.Comment);
Assert.Equal("XXXXXX", comment);
Assert.Equal("XXXXXX", gb.Description);
Assert.Equal("XXXXXX", gb.Year);
Assert.Equal("XXXXXX", gb.Manufacturer);
Assert.Equal("XXXXXX", gb.Publisher);
Assert.NotNull(gb.Category);
string category = Assert.Single(gb.Category);
Assert.Equal("XXXXXX", category);
Validate(gb.Trurip);
Assert.NotNull(gb.Release);
var release = Assert.Single(gb.Release);
Validate(release);
Assert.NotNull(gb.BiosSet);
var biosset = Assert.Single(gb.BiosSet);
Validate(biosset);
Assert.NotNull(gb.Rom);
var rom = Assert.Single(gb.Rom);
Validate(rom);
Assert.NotNull(gb.Disk);
var disk = Assert.Single(gb.Disk);
Validate(disk);
Assert.NotNull(gb.Media);
var media = Assert.Single(gb.Media);
Validate(media);
Assert.NotNull(gb.DeviceRef);
var deviceref = Assert.Single(gb.DeviceRef);
Validate(deviceref);
Assert.NotNull(gb.Sample);
var sample = Assert.Single(gb.Sample);
Validate(sample);
Assert.NotNull(gb.Archive);
var archive = Assert.Single(gb.Archive);
Validate(archive);
Validate(gb.Driver);
Assert.NotNull(gb.SoftwareList);
var softwarelist = Assert.Single(gb.SoftwareList);
Validate(softwarelist);
}
/// <summary>
/// Validate a Trurip
/// </summary>
private static void Validate(Data.Models.Logiqx.Trurip? trurip)
{
Assert.NotNull(trurip);
Assert.Equal("XXXXXX", trurip.TitleID);
Assert.Equal("XXXXXX", trurip.Publisher);
Assert.Equal("XXXXXX", trurip.Developer);
Assert.Equal("XXXXXX", trurip.Year);
Assert.Equal("XXXXXX", trurip.Genre);
Assert.Equal("XXXXXX", trurip.Subgenre);
Assert.Equal("XXXXXX", trurip.Ratings);
Assert.Equal("XXXXXX", trurip.Score);
Assert.Equal("XXXXXX", trurip.Players);
Assert.Equal("XXXXXX", trurip.Enabled);
Assert.Equal("XXXXXX", trurip.CRC);
Assert.Equal("XXXXXX", trurip.Source);
Assert.Equal("XXXXXX", trurip.CloneOf);
Assert.Equal("XXXXXX", trurip.RelatedTo);
}
/// <summary>
/// Validate a Release
/// </summary>
private static void Validate(Data.Models.Logiqx.Release? release)
{
Assert.NotNull(release);
Assert.Equal("XXXXXX", release.Name);
Assert.Equal("XXXXXX", release.Region);
Assert.Equal("XXXXXX", release.Language);
Assert.Equal("XXXXXX", release.Date);
Assert.Equal("XXXXXX", release.Default);
}
/// <summary>
/// Validate a BiosSet
/// </summary>
private static void Validate(Data.Models.Logiqx.BiosSet? biosset)
{
Assert.NotNull(biosset);
Assert.Equal("XXXXXX", biosset.Name);
Assert.Equal("XXXXXX", biosset.Description);
Assert.Equal("XXXXXX", biosset.Default);
}
/// <summary>
/// Validate a Rom
/// </summary>
private static void Validate(Data.Models.Logiqx.Rom? rom)
{
Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.Name);
Assert.Equal("XXXXXX", rom.Size);
Assert.Equal("XXXXXX", rom.CRC);
Assert.Equal("XXXXXX", rom.MD2);
Assert.Equal("XXXXXX", rom.MD4);
Assert.Equal("XXXXXX", rom.MD5);
Assert.Equal("XXXXXX", rom.RIPEMD128);
Assert.Equal("XXXXXX", rom.RIPEMD160);
Assert.Equal("XXXXXX", rom.SHA1);
Assert.Equal("XXXXXX", rom.SHA256);
Assert.Equal("XXXXXX", rom.SHA384);
Assert.Equal("XXXXXX", rom.SHA512);
Assert.Equal("XXXXXX", rom.SpamSum);
Assert.Equal("XXXXXX", rom.xxHash364);
Assert.Equal("XXXXXX", rom.xxHash3128);
Assert.Equal("XXXXXX", rom.Merge);
Assert.Equal("XXXXXX", rom.Status);
Assert.Equal("XXXXXX", rom.Serial);
Assert.Equal("XXXXXX", rom.Header);
Assert.Equal("XXXXXX", rom.Date);
Assert.Equal("XXXXXX", rom.Inverted);
Assert.Equal("XXXXXX", rom.MIA);
}
/// <summary>
/// Validate a Disk
/// </summary>
private static void Validate(Data.Models.Logiqx.Disk? disk)
{
Assert.NotNull(disk);
Assert.Equal("XXXXXX", disk.Name);
Assert.Equal("XXXXXX", disk.MD5);
Assert.Equal("XXXXXX", disk.SHA1);
Assert.Equal("XXXXXX", disk.Merge);
Assert.Equal("XXXXXX", disk.Status);
Assert.Equal("XXXXXX", disk.Region);
}
/// <summary>
/// Validate a Media
/// </summary>
private static void Validate(Data.Models.Logiqx.Media? media)
{
Assert.NotNull(media);
Assert.Equal("XXXXXX", media.Name);
Assert.Equal("XXXXXX", media.MD5);
Assert.Equal("XXXXXX", media.SHA1);
Assert.Equal("XXXXXX", media.SHA256);
Assert.Equal("XXXXXX", media.SpamSum);
}
/// <summary>
/// Validate a DeviceRef
/// </summary>
private static void Validate(Data.Models.Logiqx.DeviceRef? deviceref)
{
Assert.NotNull(deviceref);
Assert.Equal("XXXXXX", deviceref.Name);
}
/// <summary>
/// Validate a Sample
/// </summary>
private static void Validate(Data.Models.Logiqx.Sample? sample)
{
Assert.NotNull(sample);
Assert.Equal("XXXXXX", sample.Name);
}
/// <summary>
/// Validate a Archive
/// </summary>
private static void Validate(Data.Models.Logiqx.Archive? archive)
{
Assert.NotNull(archive);
Assert.Equal("XXXXXX", archive.Name);
}
/// <summary>
/// Validate a Driver
/// </summary>
private static void Validate(Data.Models.Logiqx.Driver? driver)
{
Assert.NotNull(driver);
Assert.Equal("XXXXXX", driver.Status);
Assert.Equal("XXXXXX", driver.Emulation);
Assert.Equal("XXXXXX", driver.Cocktail);
Assert.Equal("XXXXXX", driver.SaveState);
Assert.Equal("XXXXXX", driver.RequiresArtwork);
Assert.Equal("XXXXXX", driver.Unofficial);
Assert.Equal("XXXXXX", driver.NoSoundHardware);
Assert.Equal("XXXXXX", driver.Incomplete);
}
/// <summary>
/// Validate a SoftwareList
/// </summary>
private static void Validate(Data.Models.Logiqx.SoftwareList? softwarelist)
{
Assert.NotNull(softwarelist);
Assert.Equal("XXXXXX", softwarelist.Tag);
Assert.Equal("XXXXXX", softwarelist.Name);
Assert.Equal("XXXXXX", softwarelist.Status);
Assert.Equal("XXXXXX", softwarelist.Filter);
}
}
}

View File

@@ -0,0 +1,940 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class M1Tests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new M1();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new M1();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new M1();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new M1();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new M1();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new M1();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void RoundTripGameTest()
{
// Get the serializer and deserializer
var deserializer = new M1();
var serializer = new SabreTools.Serialization.Writers.M1();
// Build the data
Data.Models.Listxml.M1 m1 = Build(game: true);
// Serialize to generic model
Stream? metadata = serializer.Serialize(m1);
Assert.NotNull(metadata);
// Serialize to stream
Data.Models.Listxml.M1? newM1 = deserializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newM1);
Assert.Equal("XXXXXX", newM1.Version);
Assert.NotNull(newM1.Game);
var newGame = Assert.Single(newM1.Game);
Validate(newGame);
}
[Fact]
public void RoundTripMachineTest()
{
// Get the serializer and deserializer
var deserializer = new M1();
var serializer = new SabreTools.Serialization.Writers.M1();
// Build the data
Data.Models.Listxml.M1 m1 = Build(game: false);
// Serialize to generic model
Stream? metadata = serializer.Serialize(m1);
Assert.NotNull(metadata);
// Serialize to stream
Data.Models.Listxml.M1? newM1 = deserializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newM1);
Assert.Equal("XXXXXX", newM1.Version);
Assert.NotNull(newM1.Game);
var newGame = Assert.Single(newM1.Game);
Validate(newGame);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.Listxml.M1 Build(bool game)
{
var biosset = new Data.Models.Listxml.BiosSet
{
Name = "XXXXXX",
Description = "XXXXXX",
Default = "XXXXXX",
};
var rom = new Data.Models.Listxml.Rom
{
Name = "XXXXXX",
Bios = "XXXXXX",
Size = "XXXXXX",
CRC = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Region = "XXXXXX",
Offset = "XXXXXX",
Status = "XXXXXX",
Optional = "XXXXXX",
Dispose = "XXXXXX",
SoundOnly = "XXXXXX",
};
var disk = new Data.Models.Listxml.Disk
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Region = "XXXXXX",
Index = "XXXXXX",
Writable = "XXXXXX",
Status = "XXXXXX",
Optional = "XXXXXX",
};
var deviceref = new Data.Models.Listxml.DeviceRef
{
Name = "XXXXXX",
};
var sample = new Data.Models.Listxml.Sample
{
Name = "XXXXXX",
};
var chip = new Data.Models.Listxml.Chip
{
Name = "XXXXXX",
Tag = "XXXXXX",
Type = "XXXXXX",
SoundOnly = "XXXXXX",
Clock = "XXXXXX",
};
var display = new Data.Models.Listxml.Display
{
Tag = "XXXXXX",
Type = "XXXXXX",
Rotate = "XXXXXX",
FlipX = "XXXXXX",
Width = "XXXXXX",
Height = "XXXXXX",
Refresh = "XXXXXX",
PixClock = "XXXXXX",
HTotal = "XXXXXX",
HBEnd = "XXXXXX",
HBStart = "XXXXXX",
VTotal = "XXXXXX",
VBEnd = "XXXXXX",
VBStart = "XXXXXX",
};
var video = new Data.Models.Listxml.Video
{
Screen = "XXXXXX",
Orientation = "XXXXXX",
Width = "XXXXXX",
Height = "XXXXXX",
AspectX = "XXXXXX",
AspectY = "XXXXXX",
Refresh = "XXXXXX",
};
var sound = new Data.Models.Listxml.Sound
{
Channels = "XXXXXX",
};
var control = new Data.Models.Listxml.Control
{
Type = "XXXXXX",
Player = "XXXXXX",
Buttons = "XXXXXX",
ReqButtons = "XXXXXX",
Minimum = "XXXXXX",
Maximum = "XXXXXX",
Sensitivity = "XXXXXX",
KeyDelta = "XXXXXX",
Reverse = "XXXXXX",
Ways = "XXXXXX",
Ways2 = "XXXXXX",
Ways3 = "XXXXXX",
};
var input = new Data.Models.Listxml.Input
{
Service = "XXXXXX",
Tilt = "XXXXXX",
Players = "XXXXXX",
//ControlAttr = "XXXXXX", // Mututally exclusive with input.Control
Buttons = "XXXXXX",
Coins = "XXXXXX",
Control = [control],
};
var condition = new Data.Models.Listxml.Condition
{
Tag = "XXXXXX",
Mask = "XXXXXX",
Relation = "XXXXXX",
Value = "XXXXXX",
};
var diplocation = new Data.Models.Listxml.DipLocation
{
Name = "XXXXXX",
Number = "XXXXXX",
Inverted = "XXXXXX",
};
var dipvalue = new Data.Models.Listxml.DipValue
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var dipswitch = new Data.Models.Listxml.DipSwitch
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
Condition = condition,
DipLocation = [diplocation],
DipValue = [dipvalue],
};
var conflocation = new Data.Models.Listxml.ConfLocation
{
Name = "XXXXXX",
Number = "XXXXXX",
Inverted = "XXXXXX",
};
var confsetting = new Data.Models.Listxml.ConfSetting
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var configuration = new Data.Models.Listxml.Configuration
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
Condition = condition,
ConfLocation = [conflocation],
ConfSetting = [confsetting],
};
var analog = new Data.Models.Listxml.Analog
{
Mask = "XXXXXX",
};
var port = new Data.Models.Listxml.Port
{
Tag = "XXXXXX",
Analog = [analog],
};
var adjuster = new Data.Models.Listxml.Adjuster
{
Name = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var driver = new Data.Models.Listxml.Driver
{
Status = "XXXXXX",
Color = "XXXXXX",
Sound = "XXXXXX",
PaletteSize = "XXXXXX",
Emulation = "XXXXXX",
Cocktail = "XXXXXX",
SaveState = "XXXXXX",
RequiresArtwork = "XXXXXX",
Unofficial = "XXXXXX",
NoSoundHardware = "XXXXXX",
Incomplete = "XXXXXX",
};
var feature = new Data.Models.Listxml.Feature
{
Type = "XXXXXX",
Status = "XXXXXX",
Overall = "XXXXXX",
};
var instance = new Data.Models.Listxml.Instance
{
Name = "XXXXXX",
BriefName = "XXXXXX",
};
var extension = new Data.Models.Listxml.Extension
{
Name = "XXXXXX",
};
var device = new Data.Models.Listxml.Device
{
Type = "XXXXXX",
Tag = "XXXXXX",
FixedImage = "XXXXXX",
Mandatory = "XXXXXX",
Interface = "XXXXXX",
Instance = instance,
Extension = [extension],
};
var slotOption = new Data.Models.Listxml.SlotOption
{
Name = "XXXXXX",
DevName = "XXXXXX",
Default = "XXXXXX",
};
var slot = new Data.Models.Listxml.Slot
{
Name = "XXXXXX",
SlotOption = [slotOption],
};
var softwarelist = new Data.Models.Listxml.SoftwareList
{
Tag = "XXXXXX",
Name = "XXXXXX",
Status = "XXXXXX",
Filter = "XXXXXX",
};
var ramoption = new Data.Models.Listxml.RamOption
{
Name = "XXXXXX",
Default = "XXXXXX",
Content = "XXXXXX",
};
Data.Models.Listxml.GameBase gameBase = game
? new Data.Models.Listxml.Game()
: new Data.Models.Listxml.Machine();
gameBase.Name = "XXXXXX";
gameBase.SourceFile = "XXXXXX";
gameBase.IsBios = "XXXXXX";
gameBase.IsDevice = "XXXXXX";
gameBase.IsMechanical = "XXXXXX";
gameBase.Runnable = "XXXXXX";
gameBase.CloneOf = "XXXXXX";
gameBase.RomOf = "XXXXXX";
gameBase.SampleOf = "XXXXXX";
gameBase.Description = "XXXXXX";
gameBase.Year = "XXXXXX";
gameBase.Manufacturer = "XXXXXX";
gameBase.History = "XXXXXX";
gameBase.BiosSet = [biosset];
gameBase.Rom = [rom];
gameBase.Disk = [disk];
gameBase.DeviceRef = [deviceref];
gameBase.Sample = [sample];
gameBase.Chip = [chip];
gameBase.Display = [display];
gameBase.Video = [video];
gameBase.Sound = sound;
gameBase.Input = input;
gameBase.DipSwitch = [dipswitch];
gameBase.Configuration = [configuration];
gameBase.Port = [port];
gameBase.Adjuster = [adjuster];
gameBase.Driver = driver;
gameBase.Feature = [feature];
gameBase.Device = [device];
gameBase.Slot = [slot];
gameBase.SoftwareList = [softwarelist];
gameBase.RamOption = [ramoption];
return new Data.Models.Listxml.M1
{
Version = "XXXXXX",
Game = [gameBase],
};
}
/// <summary>
/// Validate a GameBase
/// </summary>
private static void Validate(Data.Models.Listxml.GameBase? gb)
{
Assert.NotNull(gb);
Assert.Equal("XXXXXX", gb.Name);
Assert.Equal("XXXXXX", gb.SourceFile);
Assert.Equal("XXXXXX", gb.IsBios);
Assert.Equal("XXXXXX", gb.IsDevice);
Assert.Equal("XXXXXX", gb.IsMechanical);
Assert.Equal("XXXXXX", gb.Runnable);
Assert.Equal("XXXXXX", gb.CloneOf);
Assert.Equal("XXXXXX", gb.RomOf);
Assert.Equal("XXXXXX", gb.SampleOf);
Assert.Equal("XXXXXX", gb.Description);
Assert.Equal("XXXXXX", gb.Year);
Assert.Equal("XXXXXX", gb.Manufacturer);
Assert.Equal("XXXXXX", gb.History);
Assert.NotNull(gb.BiosSet);
var biosset = Assert.Single(gb.BiosSet);
Validate(biosset);
Assert.NotNull(gb.Rom);
var rom = Assert.Single(gb.Rom);
Validate(rom);
Assert.NotNull(gb.Disk);
var disk = Assert.Single(gb.Disk);
Validate(disk);
Assert.NotNull(gb.DeviceRef);
var deviceref = Assert.Single(gb.DeviceRef);
Validate(deviceref);
Assert.NotNull(gb.Sample);
var sample = Assert.Single(gb.Sample);
Validate(sample);
Assert.NotNull(gb.Chip);
var chip = Assert.Single(gb.Chip);
Validate(chip);
Assert.NotNull(gb.Display);
var display = Assert.Single(gb.Display);
Validate(display);
Assert.NotNull(gb.Video);
var video = Assert.Single(gb.Video);
Validate(video);
Validate(gb.Sound);
Validate(gb.Input);
Assert.NotNull(gb.DipSwitch);
var dipswitch = Assert.Single(gb.DipSwitch);
Validate(dipswitch);
Assert.NotNull(gb.Configuration);
var configuration = Assert.Single(gb.Configuration);
Validate(configuration);
Assert.NotNull(gb.Port);
var port = Assert.Single(gb.Port);
Validate(port);
Assert.NotNull(gb.Adjuster);
var adjuster = Assert.Single(gb.Adjuster);
Validate(adjuster);
Validate(gb.Driver);
Assert.NotNull(gb.Feature);
var feature = Assert.Single(gb.Feature);
Validate(feature);
Assert.NotNull(gb.Device);
var device = Assert.Single(gb.Device);
Validate(device);
Assert.NotNull(gb.Slot);
var slot = Assert.Single(gb.Slot);
Validate(slot);
Assert.NotNull(gb.SoftwareList);
var softwarelist = Assert.Single(gb.SoftwareList);
Validate(softwarelist);
Assert.NotNull(gb.RamOption);
var ramoption = Assert.Single(gb.RamOption);
Validate(ramoption);
}
/// <summary>
/// Validate a BiosSet
/// </summary>
private static void Validate(Data.Models.Listxml.BiosSet? biosset)
{
Assert.NotNull(biosset);
Assert.Equal("XXXXXX", biosset.Name);
Assert.Equal("XXXXXX", biosset.Description);
Assert.Equal("XXXXXX", biosset.Default);
}
/// <summary>
/// Validate a Rom
/// </summary>
private static void Validate(Data.Models.Listxml.Rom? rom)
{
Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.Name);
Assert.Equal("XXXXXX", rom.Bios);
Assert.Equal("XXXXXX", rom.Size);
Assert.Equal("XXXXXX", rom.CRC);
Assert.Equal("XXXXXX", rom.SHA1);
Assert.Equal("XXXXXX", rom.Merge);
Assert.Equal("XXXXXX", rom.Region);
Assert.Equal("XXXXXX", rom.Offset);
Assert.Equal("XXXXXX", rom.Status);
Assert.Equal("XXXXXX", rom.Optional);
Assert.Equal("XXXXXX", rom.Dispose);
Assert.Equal("XXXXXX", rom.SoundOnly);
}
/// <summary>
/// Validate a Disk
/// </summary>
private static void Validate(Data.Models.Listxml.Disk? disk)
{
Assert.NotNull(disk);
Assert.Equal("XXXXXX", disk.Name);
Assert.Equal("XXXXXX", disk.MD5);
Assert.Equal("XXXXXX", disk.SHA1);
Assert.Equal("XXXXXX", disk.Merge);
Assert.Equal("XXXXXX", disk.Region);
Assert.Equal("XXXXXX", disk.Index);
Assert.Equal("XXXXXX", disk.Writable);
Assert.Equal("XXXXXX", disk.Status);
Assert.Equal("XXXXXX", disk.Optional);
}
/// <summary>
/// Validate a DeviceRef
/// </summary>
private static void Validate(Data.Models.Listxml.DeviceRef? deviceref)
{
Assert.NotNull(deviceref);
Assert.Equal("XXXXXX", deviceref.Name);
}
/// <summary>
/// Validate a Sample
/// </summary>
private static void Validate(Data.Models.Listxml.Sample? sample)
{
Assert.NotNull(sample);
Assert.Equal("XXXXXX", sample.Name);
}
/// <summary>
/// Validate a Chip
/// </summary>
private static void Validate(Data.Models.Listxml.Chip? chip)
{
Assert.NotNull(chip);
Assert.Equal("XXXXXX", chip.Name);
Assert.Equal("XXXXXX", chip.Tag);
Assert.Equal("XXXXXX", chip.Type);
Assert.Equal("XXXXXX", chip.SoundOnly);
Assert.Equal("XXXXXX", chip.Clock);
}
/// <summary>
/// Validate a Display
/// </summary>
private static void Validate(Data.Models.Listxml.Display? display)
{
Assert.NotNull(display);
Assert.Equal("XXXXXX", display.Tag);
Assert.Equal("XXXXXX", display.Type);
Assert.Equal("XXXXXX", display.Rotate);
Assert.Equal("XXXXXX", display.FlipX);
Assert.Equal("XXXXXX", display.Width);
Assert.Equal("XXXXXX", display.Height);
Assert.Equal("XXXXXX", display.Refresh);
Assert.Equal("XXXXXX", display.PixClock);
Assert.Equal("XXXXXX", display.HTotal);
Assert.Equal("XXXXXX", display.HBEnd);
Assert.Equal("XXXXXX", display.HBStart);
Assert.Equal("XXXXXX", display.VTotal);
Assert.Equal("XXXXXX", display.VBEnd);
Assert.Equal("XXXXXX", display.VBStart);
}
/// <summary>
/// Validate a Video
/// </summary>
private static void Validate(Data.Models.Listxml.Video? video)
{
Assert.NotNull(video);
Assert.Equal("XXXXXX", video.Screen);
Assert.Equal("XXXXXX", video.Orientation);
Assert.Equal("XXXXXX", video.Width);
Assert.Equal("XXXXXX", video.Height);
Assert.Equal("XXXXXX", video.AspectX);
Assert.Equal("XXXXXX", video.AspectY);
Assert.Equal("XXXXXX", video.Refresh);
}
/// <summary>
/// Validate a Sound
/// </summary>
private static void Validate(Data.Models.Listxml.Sound? sound)
{
Assert.NotNull(sound);
Assert.Equal("XXXXXX", sound.Channels);
}
/// <summary>
/// Validate a Input
/// </summary>
private static void Validate(Data.Models.Listxml.Input? input)
{
Assert.NotNull(input);
Assert.Equal("XXXXXX", input.Service);
Assert.Equal("XXXXXX", input.Tilt);
Assert.Equal("XXXXXX", input.Players);
//Assert.Equal("XXXXXX", input.ControlAttr); // Mututally exclusive with input.Control
Assert.Equal("XXXXXX", input.Buttons);
Assert.Equal("XXXXXX", input.Coins);
Assert.NotNull(input.Control);
var control = Assert.Single(input.Control);
Validate(control);
}
/// <summary>
/// Validate a Control
/// </summary>
private static void Validate(Data.Models.Listxml.Control? control)
{
Assert.NotNull(control);
Assert.Equal("XXXXXX", control.Type);
Assert.Equal("XXXXXX", control.Player);
Assert.Equal("XXXXXX", control.Buttons);
Assert.Equal("XXXXXX", control.ReqButtons);
Assert.Equal("XXXXXX", control.Minimum);
Assert.Equal("XXXXXX", control.Maximum);
Assert.Equal("XXXXXX", control.Sensitivity);
Assert.Equal("XXXXXX", control.KeyDelta);
Assert.Equal("XXXXXX", control.Reverse);
Assert.Equal("XXXXXX", control.Ways);
Assert.Equal("XXXXXX", control.Ways2);
Assert.Equal("XXXXXX", control.Ways3);
}
/// <summary>
/// Validate a DipSwitch
/// </summary>
private static void Validate(Data.Models.Listxml.DipSwitch? dipswitch)
{
Assert.NotNull(dipswitch);
Assert.Equal("XXXXXX", dipswitch.Name);
Assert.Equal("XXXXXX", dipswitch.Tag);
Assert.Equal("XXXXXX", dipswitch.Mask);
Validate(dipswitch.Condition);
Assert.NotNull(dipswitch.DipLocation);
var diplocation = Assert.Single(dipswitch.DipLocation);
Validate(diplocation);
Assert.NotNull(dipswitch.DipValue);
var dipvalue = Assert.Single(dipswitch.DipValue);
Validate(dipvalue);
}
/// <summary>
/// Validate a Condition
/// </summary>
private static void Validate(Data.Models.Listxml.Condition? condition)
{
Assert.NotNull(condition);
Assert.Equal("XXXXXX", condition.Tag);
Assert.Equal("XXXXXX", condition.Mask);
Assert.Equal("XXXXXX", condition.Relation);
Assert.Equal("XXXXXX", condition.Value);
}
/// <summary>
/// Validate a DipLocation
/// </summary>
private static void Validate(Data.Models.Listxml.DipLocation? diplocation)
{
Assert.NotNull(diplocation);
Assert.Equal("XXXXXX", diplocation.Name);
Assert.Equal("XXXXXX", diplocation.Number);
Assert.Equal("XXXXXX", diplocation.Inverted);
}
/// <summary>
/// Validate a DipValue
/// </summary>
private static void Validate(Data.Models.Listxml.DipValue? dipvalue)
{
Assert.NotNull(dipvalue);
Assert.Equal("XXXXXX", dipvalue.Name);
Assert.Equal("XXXXXX", dipvalue.Value);
Assert.Equal("XXXXXX", dipvalue.Default);
Validate(dipvalue.Condition);
}
/// <summary>
/// Validate a Configuration
/// </summary>
private static void Validate(Data.Models.Listxml.Configuration? configuration)
{
Assert.NotNull(configuration);
Assert.Equal("XXXXXX", configuration.Name);
Assert.Equal("XXXXXX", configuration.Tag);
Assert.Equal("XXXXXX", configuration.Mask);
Validate(configuration.Condition);
Assert.NotNull(configuration.ConfLocation);
var conflocation = Assert.Single(configuration.ConfLocation);
Validate(conflocation);
Assert.NotNull(configuration.ConfSetting);
var confsetting = Assert.Single(configuration.ConfSetting);
Validate(confsetting);
}
/// <summary>
/// Validate a ConfLocation
/// </summary>
private static void Validate(Data.Models.Listxml.ConfLocation? conflocation)
{
Assert.NotNull(conflocation);
Assert.Equal("XXXXXX", conflocation.Name);
Assert.Equal("XXXXXX", conflocation.Number);
Assert.Equal("XXXXXX", conflocation.Inverted);
}
/// <summary>
/// Validate a ConfSetting
/// </summary>
private static void Validate(Data.Models.Listxml.ConfSetting? confsetting)
{
Assert.NotNull(confsetting);
Assert.Equal("XXXXXX", confsetting.Name);
Assert.Equal("XXXXXX", confsetting.Value);
Assert.Equal("XXXXXX", confsetting.Default);
Validate(confsetting.Condition);
}
/// <summary>
/// Validate a Port
/// </summary>
private static void Validate(Data.Models.Listxml.Port? port)
{
Assert.NotNull(port);
Assert.Equal("XXXXXX", port.Tag);
Assert.NotNull(port.Analog);
var analog = Assert.Single(port.Analog);
Validate(analog);
}
/// <summary>
/// Validate a Analog
/// </summary>
private static void Validate(Data.Models.Listxml.Analog? analog)
{
Assert.NotNull(analog);
Assert.Equal("XXXXXX", analog.Mask);
}
/// <summary>
/// Validate a Adjuster
/// </summary>
private static void Validate(Data.Models.Listxml.Adjuster? adjuster)
{
Assert.NotNull(adjuster);
Assert.Equal("XXXXXX", adjuster.Name);
Assert.Equal("XXXXXX", adjuster.Default);
Validate(adjuster.Condition);
}
/// <summary>
/// Validate a Driver
/// </summary>
private static void Validate(Data.Models.Listxml.Driver? driver)
{
Assert.NotNull(driver);
Assert.Equal("XXXXXX", driver.Status);
Assert.Equal("XXXXXX", driver.Color);
Assert.Equal("XXXXXX", driver.Sound);
Assert.Equal("XXXXXX", driver.PaletteSize);
Assert.Equal("XXXXXX", driver.Emulation);
Assert.Equal("XXXXXX", driver.Cocktail);
Assert.Equal("XXXXXX", driver.SaveState);
Assert.Equal("XXXXXX", driver.RequiresArtwork);
Assert.Equal("XXXXXX", driver.Unofficial);
Assert.Equal("XXXXXX", driver.NoSoundHardware);
Assert.Equal("XXXXXX", driver.Incomplete);
}
/// <summary>
/// Validate a Feature
/// </summary>
private static void Validate(Data.Models.Listxml.Feature? feature)
{
Assert.NotNull(feature);
Assert.Equal("XXXXXX", feature.Type);
Assert.Equal("XXXXXX", feature.Status);
Assert.Equal("XXXXXX", feature.Overall);
}
/// <summary>
/// Validate a Device
/// </summary>
private static void Validate(Data.Models.Listxml.Device? device)
{
Assert.NotNull(device);
Assert.Equal("XXXXXX", device.Type);
Assert.Equal("XXXXXX", device.Tag);
Assert.Equal("XXXXXX", device.FixedImage);
Assert.Equal("XXXXXX", device.Mandatory);
Assert.Equal("XXXXXX", device.Interface);
Validate(device.Instance);
Assert.NotNull(device.Extension);
var extension = Assert.Single(device.Extension);
Validate(extension);
}
/// <summary>
/// Validate a Instance
/// </summary>
private static void Validate(Data.Models.Listxml.Instance? instance)
{
Assert.NotNull(instance);
Assert.Equal("XXXXXX", instance.Name);
Assert.Equal("XXXXXX", instance.BriefName);
}
/// <summary>
/// Validate a Extension
/// </summary>
private static void Validate(Data.Models.Listxml.Extension? extension)
{
Assert.NotNull(extension);
Assert.Equal("XXXXXX", extension.Name);
}
/// <summary>
/// Validate a Slot
/// </summary>
private static void Validate(Data.Models.Listxml.Slot? slot)
{
Assert.NotNull(slot);
Assert.Equal("XXXXXX", slot.Name);
Assert.NotNull(slot.SlotOption);
var slotoption = Assert.Single(slot.SlotOption);
Validate(slotoption);
}
/// <summary>
/// Validate a SlotOption
/// </summary>
private static void Validate(Data.Models.Listxml.SlotOption? slotoption)
{
Assert.NotNull(slotoption);
Assert.Equal("XXXXXX", slotoption.Name);
Assert.Equal("XXXXXX", slotoption.DevName);
Assert.Equal("XXXXXX", slotoption.Default);
}
/// <summary>
/// Validate a SoftwareList
/// </summary>
private static void Validate(Data.Models.Listxml.SoftwareList? softwarelist)
{
Assert.NotNull(softwarelist);
Assert.Equal("XXXXXX", softwarelist.Tag);
Assert.Equal("XXXXXX", softwarelist.Name);
Assert.Equal("XXXXXX", softwarelist.Status);
Assert.Equal("XXXXXX", softwarelist.Filter);
}
/// <summary>
/// Validate a RamOption
/// </summary>
private static void Validate(Data.Models.Listxml.RamOption? ramoption)
{
Assert.NotNull(ramoption);
Assert.Equal("XXXXXX", ramoption.Name);
Assert.Equal("XXXXXX", ramoption.Default);
Assert.Equal("XXXXXX", ramoption.Content);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class MSDOSTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new MSDOS();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new MSDOS();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new MSDOS();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new MSDOS();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new MSDOS();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new MSDOS();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,940 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class MessTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new Mess();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new Mess();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new Mess();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new Mess();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new Mess();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new Mess();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void RoundTripGameTest()
{
// Get the serializer and deserializer
var deserializer = new Mess();
var serializer = new SabreTools.Serialization.Writers.Mess();
// Build the data
Data.Models.Listxml.Mess m1 = Build(game: true);
// Serialize to generic model
Stream? metadata = serializer.Serialize(m1);
Assert.NotNull(metadata);
// Serialize to stream
Data.Models.Listxml.Mess? newMess = deserializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newMess);
Assert.Equal("XXXXXX", newMess.Version);
Assert.NotNull(newMess.Game);
var newGame = Assert.Single(newMess.Game);
Validate(newGame);
}
[Fact]
public void RoundTripMachineTest()
{
// Get the serializer and deserializer
var deserializer = new Mess();
var serializer = new SabreTools.Serialization.Writers.Mess();
// Build the data
Data.Models.Listxml.Mess m1 = Build(game: false);
// Serialize to generic model
Stream? metadata = serializer.Serialize(m1);
Assert.NotNull(metadata);
// Serialize to stream
Data.Models.Listxml.Mess? newMess = deserializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newMess);
Assert.Equal("XXXXXX", newMess.Version);
Assert.NotNull(newMess.Game);
var newGame = Assert.Single(newMess.Game);
Validate(newGame);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.Listxml.Mess Build(bool game)
{
var biosset = new Data.Models.Listxml.BiosSet
{
Name = "XXXXXX",
Description = "XXXXXX",
Default = "XXXXXX",
};
var rom = new Data.Models.Listxml.Rom
{
Name = "XXXXXX",
Bios = "XXXXXX",
Size = "XXXXXX",
CRC = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Region = "XXXXXX",
Offset = "XXXXXX",
Status = "XXXXXX",
Optional = "XXXXXX",
Dispose = "XXXXXX",
SoundOnly = "XXXXXX",
};
var disk = new Data.Models.Listxml.Disk
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Region = "XXXXXX",
Index = "XXXXXX",
Writable = "XXXXXX",
Status = "XXXXXX",
Optional = "XXXXXX",
};
var deviceref = new Data.Models.Listxml.DeviceRef
{
Name = "XXXXXX",
};
var sample = new Data.Models.Listxml.Sample
{
Name = "XXXXXX",
};
var chip = new Data.Models.Listxml.Chip
{
Name = "XXXXXX",
Tag = "XXXXXX",
Type = "XXXXXX",
SoundOnly = "XXXXXX",
Clock = "XXXXXX",
};
var display = new Data.Models.Listxml.Display
{
Tag = "XXXXXX",
Type = "XXXXXX",
Rotate = "XXXXXX",
FlipX = "XXXXXX",
Width = "XXXXXX",
Height = "XXXXXX",
Refresh = "XXXXXX",
PixClock = "XXXXXX",
HTotal = "XXXXXX",
HBEnd = "XXXXXX",
HBStart = "XXXXXX",
VTotal = "XXXXXX",
VBEnd = "XXXXXX",
VBStart = "XXXXXX",
};
var video = new Data.Models.Listxml.Video
{
Screen = "XXXXXX",
Orientation = "XXXXXX",
Width = "XXXXXX",
Height = "XXXXXX",
AspectX = "XXXXXX",
AspectY = "XXXXXX",
Refresh = "XXXXXX",
};
var sound = new Data.Models.Listxml.Sound
{
Channels = "XXXXXX",
};
var control = new Data.Models.Listxml.Control
{
Type = "XXXXXX",
Player = "XXXXXX",
Buttons = "XXXXXX",
ReqButtons = "XXXXXX",
Minimum = "XXXXXX",
Maximum = "XXXXXX",
Sensitivity = "XXXXXX",
KeyDelta = "XXXXXX",
Reverse = "XXXXXX",
Ways = "XXXXXX",
Ways2 = "XXXXXX",
Ways3 = "XXXXXX",
};
var input = new Data.Models.Listxml.Input
{
Service = "XXXXXX",
Tilt = "XXXXXX",
Players = "XXXXXX",
//ControlAttr = "XXXXXX", // Mututally exclusive with input.Control
Buttons = "XXXXXX",
Coins = "XXXXXX",
Control = [control],
};
var condition = new Data.Models.Listxml.Condition
{
Tag = "XXXXXX",
Mask = "XXXXXX",
Relation = "XXXXXX",
Value = "XXXXXX",
};
var diplocation = new Data.Models.Listxml.DipLocation
{
Name = "XXXXXX",
Number = "XXXXXX",
Inverted = "XXXXXX",
};
var dipvalue = new Data.Models.Listxml.DipValue
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var dipswitch = new Data.Models.Listxml.DipSwitch
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
Condition = condition,
DipLocation = [diplocation],
DipValue = [dipvalue],
};
var conflocation = new Data.Models.Listxml.ConfLocation
{
Name = "XXXXXX",
Number = "XXXXXX",
Inverted = "XXXXXX",
};
var confsetting = new Data.Models.Listxml.ConfSetting
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var configuration = new Data.Models.Listxml.Configuration
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
Condition = condition,
ConfLocation = [conflocation],
ConfSetting = [confsetting],
};
var analog = new Data.Models.Listxml.Analog
{
Mask = "XXXXXX",
};
var port = new Data.Models.Listxml.Port
{
Tag = "XXXXXX",
Analog = [analog],
};
var adjuster = new Data.Models.Listxml.Adjuster
{
Name = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var driver = new Data.Models.Listxml.Driver
{
Status = "XXXXXX",
Color = "XXXXXX",
Sound = "XXXXXX",
PaletteSize = "XXXXXX",
Emulation = "XXXXXX",
Cocktail = "XXXXXX",
SaveState = "XXXXXX",
RequiresArtwork = "XXXXXX",
Unofficial = "XXXXXX",
NoSoundHardware = "XXXXXX",
Incomplete = "XXXXXX",
};
var feature = new Data.Models.Listxml.Feature
{
Type = "XXXXXX",
Status = "XXXXXX",
Overall = "XXXXXX",
};
var instance = new Data.Models.Listxml.Instance
{
Name = "XXXXXX",
BriefName = "XXXXXX",
};
var extension = new Data.Models.Listxml.Extension
{
Name = "XXXXXX",
};
var device = new Data.Models.Listxml.Device
{
Type = "XXXXXX",
Tag = "XXXXXX",
FixedImage = "XXXXXX",
Mandatory = "XXXXXX",
Interface = "XXXXXX",
Instance = instance,
Extension = [extension],
};
var slotOption = new Data.Models.Listxml.SlotOption
{
Name = "XXXXXX",
DevName = "XXXXXX",
Default = "XXXXXX",
};
var slot = new Data.Models.Listxml.Slot
{
Name = "XXXXXX",
SlotOption = [slotOption],
};
var softwarelist = new Data.Models.Listxml.SoftwareList
{
Tag = "XXXXXX",
Name = "XXXXXX",
Status = "XXXXXX",
Filter = "XXXXXX",
};
var ramoption = new Data.Models.Listxml.RamOption
{
Name = "XXXXXX",
Default = "XXXXXX",
Content = "XXXXXX",
};
Data.Models.Listxml.GameBase gameBase = game
? new Data.Models.Listxml.Game()
: new Data.Models.Listxml.Machine();
gameBase.Name = "XXXXXX";
gameBase.SourceFile = "XXXXXX";
gameBase.IsBios = "XXXXXX";
gameBase.IsDevice = "XXXXXX";
gameBase.IsMechanical = "XXXXXX";
gameBase.Runnable = "XXXXXX";
gameBase.CloneOf = "XXXXXX";
gameBase.RomOf = "XXXXXX";
gameBase.SampleOf = "XXXXXX";
gameBase.Description = "XXXXXX";
gameBase.Year = "XXXXXX";
gameBase.Manufacturer = "XXXXXX";
gameBase.History = "XXXXXX";
gameBase.BiosSet = [biosset];
gameBase.Rom = [rom];
gameBase.Disk = [disk];
gameBase.DeviceRef = [deviceref];
gameBase.Sample = [sample];
gameBase.Chip = [chip];
gameBase.Display = [display];
gameBase.Video = [video];
gameBase.Sound = sound;
gameBase.Input = input;
gameBase.DipSwitch = [dipswitch];
gameBase.Configuration = [configuration];
gameBase.Port = [port];
gameBase.Adjuster = [adjuster];
gameBase.Driver = driver;
gameBase.Feature = [feature];
gameBase.Device = [device];
gameBase.Slot = [slot];
gameBase.SoftwareList = [softwarelist];
gameBase.RamOption = [ramoption];
return new Data.Models.Listxml.Mess
{
Version = "XXXXXX",
Game = [gameBase],
};
}
/// <summary>
/// Validate a GameBase
/// </summary>
private static void Validate(Data.Models.Listxml.GameBase? gb)
{
Assert.NotNull(gb);
Assert.Equal("XXXXXX", gb.Name);
Assert.Equal("XXXXXX", gb.SourceFile);
Assert.Equal("XXXXXX", gb.IsBios);
Assert.Equal("XXXXXX", gb.IsDevice);
Assert.Equal("XXXXXX", gb.IsMechanical);
Assert.Equal("XXXXXX", gb.Runnable);
Assert.Equal("XXXXXX", gb.CloneOf);
Assert.Equal("XXXXXX", gb.RomOf);
Assert.Equal("XXXXXX", gb.SampleOf);
Assert.Equal("XXXXXX", gb.Description);
Assert.Equal("XXXXXX", gb.Year);
Assert.Equal("XXXXXX", gb.Manufacturer);
Assert.Equal("XXXXXX", gb.History);
Assert.NotNull(gb.BiosSet);
var biosset = Assert.Single(gb.BiosSet);
Validate(biosset);
Assert.NotNull(gb.Rom);
var rom = Assert.Single(gb.Rom);
Validate(rom);
Assert.NotNull(gb.Disk);
var disk = Assert.Single(gb.Disk);
Validate(disk);
Assert.NotNull(gb.DeviceRef);
var deviceref = Assert.Single(gb.DeviceRef);
Validate(deviceref);
Assert.NotNull(gb.Sample);
var sample = Assert.Single(gb.Sample);
Validate(sample);
Assert.NotNull(gb.Chip);
var chip = Assert.Single(gb.Chip);
Validate(chip);
Assert.NotNull(gb.Display);
var display = Assert.Single(gb.Display);
Validate(display);
Assert.NotNull(gb.Video);
var video = Assert.Single(gb.Video);
Validate(video);
Validate(gb.Sound);
Validate(gb.Input);
Assert.NotNull(gb.DipSwitch);
var dipswitch = Assert.Single(gb.DipSwitch);
Validate(dipswitch);
Assert.NotNull(gb.Configuration);
var configuration = Assert.Single(gb.Configuration);
Validate(configuration);
Assert.NotNull(gb.Port);
var port = Assert.Single(gb.Port);
Validate(port);
Assert.NotNull(gb.Adjuster);
var adjuster = Assert.Single(gb.Adjuster);
Validate(adjuster);
Validate(gb.Driver);
Assert.NotNull(gb.Feature);
var feature = Assert.Single(gb.Feature);
Validate(feature);
Assert.NotNull(gb.Device);
var device = Assert.Single(gb.Device);
Validate(device);
Assert.NotNull(gb.Slot);
var slot = Assert.Single(gb.Slot);
Validate(slot);
Assert.NotNull(gb.SoftwareList);
var softwarelist = Assert.Single(gb.SoftwareList);
Validate(softwarelist);
Assert.NotNull(gb.RamOption);
var ramoption = Assert.Single(gb.RamOption);
Validate(ramoption);
}
/// <summary>
/// Validate a BiosSet
/// </summary>
private static void Validate(Data.Models.Listxml.BiosSet? biosset)
{
Assert.NotNull(biosset);
Assert.Equal("XXXXXX", biosset.Name);
Assert.Equal("XXXXXX", biosset.Description);
Assert.Equal("XXXXXX", biosset.Default);
}
/// <summary>
/// Validate a Rom
/// </summary>
private static void Validate(Data.Models.Listxml.Rom? rom)
{
Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.Name);
Assert.Equal("XXXXXX", rom.Bios);
Assert.Equal("XXXXXX", rom.Size);
Assert.Equal("XXXXXX", rom.CRC);
Assert.Equal("XXXXXX", rom.SHA1);
Assert.Equal("XXXXXX", rom.Merge);
Assert.Equal("XXXXXX", rom.Region);
Assert.Equal("XXXXXX", rom.Offset);
Assert.Equal("XXXXXX", rom.Status);
Assert.Equal("XXXXXX", rom.Optional);
Assert.Equal("XXXXXX", rom.Dispose);
Assert.Equal("XXXXXX", rom.SoundOnly);
}
/// <summary>
/// Validate a Disk
/// </summary>
private static void Validate(Data.Models.Listxml.Disk? disk)
{
Assert.NotNull(disk);
Assert.Equal("XXXXXX", disk.Name);
Assert.Equal("XXXXXX", disk.MD5);
Assert.Equal("XXXXXX", disk.SHA1);
Assert.Equal("XXXXXX", disk.Merge);
Assert.Equal("XXXXXX", disk.Region);
Assert.Equal("XXXXXX", disk.Index);
Assert.Equal("XXXXXX", disk.Writable);
Assert.Equal("XXXXXX", disk.Status);
Assert.Equal("XXXXXX", disk.Optional);
}
/// <summary>
/// Validate a DeviceRef
/// </summary>
private static void Validate(Data.Models.Listxml.DeviceRef? deviceref)
{
Assert.NotNull(deviceref);
Assert.Equal("XXXXXX", deviceref.Name);
}
/// <summary>
/// Validate a Sample
/// </summary>
private static void Validate(Data.Models.Listxml.Sample? sample)
{
Assert.NotNull(sample);
Assert.Equal("XXXXXX", sample.Name);
}
/// <summary>
/// Validate a Chip
/// </summary>
private static void Validate(Data.Models.Listxml.Chip? chip)
{
Assert.NotNull(chip);
Assert.Equal("XXXXXX", chip.Name);
Assert.Equal("XXXXXX", chip.Tag);
Assert.Equal("XXXXXX", chip.Type);
Assert.Equal("XXXXXX", chip.SoundOnly);
Assert.Equal("XXXXXX", chip.Clock);
}
/// <summary>
/// Validate a Display
/// </summary>
private static void Validate(Data.Models.Listxml.Display? display)
{
Assert.NotNull(display);
Assert.Equal("XXXXXX", display.Tag);
Assert.Equal("XXXXXX", display.Type);
Assert.Equal("XXXXXX", display.Rotate);
Assert.Equal("XXXXXX", display.FlipX);
Assert.Equal("XXXXXX", display.Width);
Assert.Equal("XXXXXX", display.Height);
Assert.Equal("XXXXXX", display.Refresh);
Assert.Equal("XXXXXX", display.PixClock);
Assert.Equal("XXXXXX", display.HTotal);
Assert.Equal("XXXXXX", display.HBEnd);
Assert.Equal("XXXXXX", display.HBStart);
Assert.Equal("XXXXXX", display.VTotal);
Assert.Equal("XXXXXX", display.VBEnd);
Assert.Equal("XXXXXX", display.VBStart);
}
/// <summary>
/// Validate a Video
/// </summary>
private static void Validate(Data.Models.Listxml.Video? video)
{
Assert.NotNull(video);
Assert.Equal("XXXXXX", video.Screen);
Assert.Equal("XXXXXX", video.Orientation);
Assert.Equal("XXXXXX", video.Width);
Assert.Equal("XXXXXX", video.Height);
Assert.Equal("XXXXXX", video.AspectX);
Assert.Equal("XXXXXX", video.AspectY);
Assert.Equal("XXXXXX", video.Refresh);
}
/// <summary>
/// Validate a Sound
/// </summary>
private static void Validate(Data.Models.Listxml.Sound? sound)
{
Assert.NotNull(sound);
Assert.Equal("XXXXXX", sound.Channels);
}
/// <summary>
/// Validate a Input
/// </summary>
private static void Validate(Data.Models.Listxml.Input? input)
{
Assert.NotNull(input);
Assert.Equal("XXXXXX", input.Service);
Assert.Equal("XXXXXX", input.Tilt);
Assert.Equal("XXXXXX", input.Players);
//Assert.Equal("XXXXXX", input.ControlAttr); // Mututally exclusive with input.Control
Assert.Equal("XXXXXX", input.Buttons);
Assert.Equal("XXXXXX", input.Coins);
Assert.NotNull(input.Control);
var control = Assert.Single(input.Control);
Validate(control);
}
/// <summary>
/// Validate a Control
/// </summary>
private static void Validate(Data.Models.Listxml.Control? control)
{
Assert.NotNull(control);
Assert.Equal("XXXXXX", control.Type);
Assert.Equal("XXXXXX", control.Player);
Assert.Equal("XXXXXX", control.Buttons);
Assert.Equal("XXXXXX", control.ReqButtons);
Assert.Equal("XXXXXX", control.Minimum);
Assert.Equal("XXXXXX", control.Maximum);
Assert.Equal("XXXXXX", control.Sensitivity);
Assert.Equal("XXXXXX", control.KeyDelta);
Assert.Equal("XXXXXX", control.Reverse);
Assert.Equal("XXXXXX", control.Ways);
Assert.Equal("XXXXXX", control.Ways2);
Assert.Equal("XXXXXX", control.Ways3);
}
/// <summary>
/// Validate a DipSwitch
/// </summary>
private static void Validate(Data.Models.Listxml.DipSwitch? dipswitch)
{
Assert.NotNull(dipswitch);
Assert.Equal("XXXXXX", dipswitch.Name);
Assert.Equal("XXXXXX", dipswitch.Tag);
Assert.Equal("XXXXXX", dipswitch.Mask);
Validate(dipswitch.Condition);
Assert.NotNull(dipswitch.DipLocation);
var diplocation = Assert.Single(dipswitch.DipLocation);
Validate(diplocation);
Assert.NotNull(dipswitch.DipValue);
var dipvalue = Assert.Single(dipswitch.DipValue);
Validate(dipvalue);
}
/// <summary>
/// Validate a Condition
/// </summary>
private static void Validate(Data.Models.Listxml.Condition? condition)
{
Assert.NotNull(condition);
Assert.Equal("XXXXXX", condition.Tag);
Assert.Equal("XXXXXX", condition.Mask);
Assert.Equal("XXXXXX", condition.Relation);
Assert.Equal("XXXXXX", condition.Value);
}
/// <summary>
/// Validate a DipLocation
/// </summary>
private static void Validate(Data.Models.Listxml.DipLocation? diplocation)
{
Assert.NotNull(diplocation);
Assert.Equal("XXXXXX", diplocation.Name);
Assert.Equal("XXXXXX", diplocation.Number);
Assert.Equal("XXXXXX", diplocation.Inverted);
}
/// <summary>
/// Validate a DipValue
/// </summary>
private static void Validate(Data.Models.Listxml.DipValue? dipvalue)
{
Assert.NotNull(dipvalue);
Assert.Equal("XXXXXX", dipvalue.Name);
Assert.Equal("XXXXXX", dipvalue.Value);
Assert.Equal("XXXXXX", dipvalue.Default);
Validate(dipvalue.Condition);
}
/// <summary>
/// Validate a Configuration
/// </summary>
private static void Validate(Data.Models.Listxml.Configuration? configuration)
{
Assert.NotNull(configuration);
Assert.Equal("XXXXXX", configuration.Name);
Assert.Equal("XXXXXX", configuration.Tag);
Assert.Equal("XXXXXX", configuration.Mask);
Validate(configuration.Condition);
Assert.NotNull(configuration.ConfLocation);
var conflocation = Assert.Single(configuration.ConfLocation);
Validate(conflocation);
Assert.NotNull(configuration.ConfSetting);
var confsetting = Assert.Single(configuration.ConfSetting);
Validate(confsetting);
}
/// <summary>
/// Validate a ConfLocation
/// </summary>
private static void Validate(Data.Models.Listxml.ConfLocation? conflocation)
{
Assert.NotNull(conflocation);
Assert.Equal("XXXXXX", conflocation.Name);
Assert.Equal("XXXXXX", conflocation.Number);
Assert.Equal("XXXXXX", conflocation.Inverted);
}
/// <summary>
/// Validate a ConfSetting
/// </summary>
private static void Validate(Data.Models.Listxml.ConfSetting? confsetting)
{
Assert.NotNull(confsetting);
Assert.Equal("XXXXXX", confsetting.Name);
Assert.Equal("XXXXXX", confsetting.Value);
Assert.Equal("XXXXXX", confsetting.Default);
Validate(confsetting.Condition);
}
/// <summary>
/// Validate a Port
/// </summary>
private static void Validate(Data.Models.Listxml.Port? port)
{
Assert.NotNull(port);
Assert.Equal("XXXXXX", port.Tag);
Assert.NotNull(port.Analog);
var analog = Assert.Single(port.Analog);
Validate(analog);
}
/// <summary>
/// Validate a Analog
/// </summary>
private static void Validate(Data.Models.Listxml.Analog? analog)
{
Assert.NotNull(analog);
Assert.Equal("XXXXXX", analog.Mask);
}
/// <summary>
/// Validate a Adjuster
/// </summary>
private static void Validate(Data.Models.Listxml.Adjuster? adjuster)
{
Assert.NotNull(adjuster);
Assert.Equal("XXXXXX", adjuster.Name);
Assert.Equal("XXXXXX", adjuster.Default);
Validate(adjuster.Condition);
}
/// <summary>
/// Validate a Driver
/// </summary>
private static void Validate(Data.Models.Listxml.Driver? driver)
{
Assert.NotNull(driver);
Assert.Equal("XXXXXX", driver.Status);
Assert.Equal("XXXXXX", driver.Color);
Assert.Equal("XXXXXX", driver.Sound);
Assert.Equal("XXXXXX", driver.PaletteSize);
Assert.Equal("XXXXXX", driver.Emulation);
Assert.Equal("XXXXXX", driver.Cocktail);
Assert.Equal("XXXXXX", driver.SaveState);
Assert.Equal("XXXXXX", driver.RequiresArtwork);
Assert.Equal("XXXXXX", driver.Unofficial);
Assert.Equal("XXXXXX", driver.NoSoundHardware);
Assert.Equal("XXXXXX", driver.Incomplete);
}
/// <summary>
/// Validate a Feature
/// </summary>
private static void Validate(Data.Models.Listxml.Feature? feature)
{
Assert.NotNull(feature);
Assert.Equal("XXXXXX", feature.Type);
Assert.Equal("XXXXXX", feature.Status);
Assert.Equal("XXXXXX", feature.Overall);
}
/// <summary>
/// Validate a Device
/// </summary>
private static void Validate(Data.Models.Listxml.Device? device)
{
Assert.NotNull(device);
Assert.Equal("XXXXXX", device.Type);
Assert.Equal("XXXXXX", device.Tag);
Assert.Equal("XXXXXX", device.FixedImage);
Assert.Equal("XXXXXX", device.Mandatory);
Assert.Equal("XXXXXX", device.Interface);
Validate(device.Instance);
Assert.NotNull(device.Extension);
var extension = Assert.Single(device.Extension);
Validate(extension);
}
/// <summary>
/// Validate a Instance
/// </summary>
private static void Validate(Data.Models.Listxml.Instance? instance)
{
Assert.NotNull(instance);
Assert.Equal("XXXXXX", instance.Name);
Assert.Equal("XXXXXX", instance.BriefName);
}
/// <summary>
/// Validate a Extension
/// </summary>
private static void Validate(Data.Models.Listxml.Extension? extension)
{
Assert.NotNull(extension);
Assert.Equal("XXXXXX", extension.Name);
}
/// <summary>
/// Validate a Slot
/// </summary>
private static void Validate(Data.Models.Listxml.Slot? slot)
{
Assert.NotNull(slot);
Assert.Equal("XXXXXX", slot.Name);
Assert.NotNull(slot.SlotOption);
var slotoption = Assert.Single(slot.SlotOption);
Validate(slotoption);
}
/// <summary>
/// Validate a SlotOption
/// </summary>
private static void Validate(Data.Models.Listxml.SlotOption? slotoption)
{
Assert.NotNull(slotoption);
Assert.Equal("XXXXXX", slotoption.Name);
Assert.Equal("XXXXXX", slotoption.DevName);
Assert.Equal("XXXXXX", slotoption.Default);
}
/// <summary>
/// Validate a SoftwareList
/// </summary>
private static void Validate(Data.Models.Listxml.SoftwareList? softwarelist)
{
Assert.NotNull(softwarelist);
Assert.Equal("XXXXXX", softwarelist.Tag);
Assert.Equal("XXXXXX", softwarelist.Name);
Assert.Equal("XXXXXX", softwarelist.Status);
Assert.Equal("XXXXXX", softwarelist.Filter);
}
/// <summary>
/// Validate a RamOption
/// </summary>
private static void Validate(Data.Models.Listxml.RamOption? ramoption)
{
Assert.NotNull(ramoption);
Assert.Equal("XXXXXX", ramoption.Name);
Assert.Equal("XXXXXX", ramoption.Default);
Assert.Equal("XXXXXX", ramoption.Content);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class MicrosoftCabinetTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new MicrosoftCabinet();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new MicrosoftCabinet();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new MicrosoftCabinet();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new MicrosoftCabinet();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new MicrosoftCabinet();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new MicrosoftCabinet();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class MoPaQTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new MoPaQ();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new MoPaQ();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new MoPaQ();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new MoPaQ();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new MoPaQ();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new MoPaQ();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class N3DSTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new N3DS();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new N3DS();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new N3DS();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new N3DS();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new N3DS();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new N3DS();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class NCFTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new NCF();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new NCF();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new NCF();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new NCF();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new NCF();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new NCF();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class NewExecutableTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new NewExecutable();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new NewExecutable();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new NewExecutable();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new NewExecutable();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new NewExecutable();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new NewExecutable();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class NitroTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new Nitro();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new Nitro();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new Nitro();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new Nitro();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new Nitro();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new Nitro();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,517 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class OfflineListTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new OfflineList();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new OfflineList();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new OfflineList();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new OfflineList();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new OfflineList();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new OfflineList();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void RoundTripTest()
{
// Get the serializer and deserializer
var deserializer = new OfflineList();
var serializer = new SabreTools.Serialization.Writers.OfflineList();
// Build the data
Data.Models.OfflineList.Dat dat = Build();
// Serialize to stream
Stream? metadata = serializer.Serialize(dat);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.OfflineList.Dat? newDat = deserializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newDat);
Assert.Equal("XXXXXX", newDat.NoNamespaceSchemaLocation);
Validate(newDat.Configuration);
Validate(newDat.Games);
Validate(newDat.GUI);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.OfflineList.Dat Build()
{
var infos = new Data.Models.OfflineList.Infos
{
Title = new Data.Models.OfflineList.Title
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
Location = new Data.Models.OfflineList.Location
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
Publisher = new Data.Models.OfflineList.Publisher
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
SourceRom = new Data.Models.OfflineList.SourceRom
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
SaveType = new Data.Models.OfflineList.SaveType
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
RomSize = new Data.Models.OfflineList.RomSize
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
ReleaseNumber = new Data.Models.OfflineList.ReleaseNumber
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
ImageNumber = new Data.Models.OfflineList.ImageNumber
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
LanguageNumber = new Data.Models.OfflineList.LanguageNumber
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
Comment = new Data.Models.OfflineList.Comment
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
RomCRC = new Data.Models.OfflineList.RomCRC
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
Im1CRC = new Data.Models.OfflineList.Im1CRC
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
Im2CRC = new Data.Models.OfflineList.Im2CRC
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
Languages = new Data.Models.OfflineList.Languages
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
};
var canopen = new Data.Models.OfflineList.CanOpen
{
Extension = ["XXXXXX"],
};
var daturl = new Data.Models.OfflineList.DatUrl
{
FileName = "XXXXXX",
Content = "XXXXXX",
};
var newdat = new Data.Models.OfflineList.NewDat
{
DatVersionUrl = "XXXXXX",
DatUrl = daturl,
ImUrl = "XXXXXX",
};
var find = new Data.Models.OfflineList.Find
{
Operation = "XXXXXX",
Value = "XXXXXX",
Content = "XXXXXX",
};
var to = new Data.Models.OfflineList.To
{
Value = "XXXXXX",
Default = "XXXXXX",
Auto = "XXXXXX",
Find = [find],
};
var search = new Data.Models.OfflineList.Search
{
To = [to],
};
var configuration = new Data.Models.OfflineList.Configuration
{
DatName = "XXXXXX",
ImFolder = "XXXXXX",
DatVersion = "XXXXXX",
System = "XXXXXX",
ScreenshotsWidth = "XXXXXX",
ScreenshotsHeight = "XXXXXX",
Infos = infos,
CanOpen = canopen,
NewDat = newdat,
Search = search,
RomTitle = "XXXXXX",
};
var fileromcrc = new Data.Models.OfflineList.FileRomCRC
{
Extension = "XXXXXX",
Content = "XXXXXX",
};
var files = new Data.Models.OfflineList.Files
{
RomCRC = [fileromcrc],
};
var game = new Data.Models.OfflineList.Game
{
ImageNumber = "XXXXXX",
ReleaseNumber = "XXXXXX",
Title = "XXXXXX",
SaveType = "XXXXXX",
RomSize = "XXXXXX",
Publisher = "XXXXXX",
Location = "XXXXXX",
SourceRom = "XXXXXX",
Language = "XXXXXX",
Files = files,
Im1CRC = "XXXXXX",
Im2CRC = "XXXXXX",
Comment = "XXXXXX",
DuplicateID = "XXXXXX",
};
var games = new Data.Models.OfflineList.Games
{
Game = [game],
};
var image = new Data.Models.OfflineList.Image
{
X = "XXXXXX",
Y = "XXXXXX",
Width = "XXXXXX",
Height = "XXXXXX",
};
var images = new Data.Models.OfflineList.Images
{
Width = "XXXXXX",
Height = "XXXXXX",
Image = [image],
};
var gui = new Data.Models.OfflineList.GUI
{
Images = images,
};
return new Data.Models.OfflineList.Dat
{
NoNamespaceSchemaLocation = "XXXXXX",
Configuration = configuration,
Games = games,
GUI = gui,
};
}
/// <summary>
/// Validate a Configuration
/// </summary>
private static void Validate(Data.Models.OfflineList.Configuration? configuration)
{
Assert.NotNull(configuration);
Assert.Equal("XXXXXX", configuration.DatName);
Assert.Equal("XXXXXX", configuration.ImFolder);
Assert.Equal("XXXXXX", configuration.DatVersion);
Assert.Equal("XXXXXX", configuration.System);
Assert.Equal("XXXXXX", configuration.ScreenshotsWidth);
Assert.Equal("XXXXXX", configuration.ScreenshotsHeight);
Validate(configuration.Infos);
Validate(configuration.CanOpen);
Validate(configuration.NewDat);
Validate(configuration.Search);
Assert.Equal("XXXXXX", configuration.RomTitle);
}
/// <summary>
/// Validate a Infos
/// </summary>
private static void Validate(Data.Models.OfflineList.Infos? infos)
{
Assert.NotNull(infos);
Validate(infos.Title);
Validate(infos.Location);
Validate(infos.Publisher);
Validate(infos.SourceRom);
Validate(infos.SaveType);
Validate(infos.RomSize);
Validate(infos.ReleaseNumber);
Validate(infos.ImageNumber);
Validate(infos.LanguageNumber);
Validate(infos.Comment);
Validate(infos.RomCRC);
Validate(infos.Im1CRC);
Validate(infos.Im2CRC);
Validate(infos.Languages);
}
/// <summary>
/// Validate a InfoBase
/// </summary>
private static void Validate(Data.Models.OfflineList.InfoBase? info)
{
Assert.NotNull(info);
Assert.Equal("XXXXXX", info.Visible);
Assert.Equal("XXXXXX", info.InNamingOption);
Assert.Equal("XXXXXX", info.Default);
}
/// <summary>
/// Validate a CanOpen
/// </summary>
private static void Validate(Data.Models.OfflineList.CanOpen? canopen)
{
Assert.NotNull(canopen);
Assert.NotNull(canopen.Extension);
string extension = Assert.Single(canopen.Extension);
Assert.Equal("XXXXXX", extension);
}
/// <summary>
/// Validate a NewDat
/// </summary>
private static void Validate(Data.Models.OfflineList.NewDat? newdat)
{
Assert.NotNull(newdat);
Assert.Equal("XXXXXX", newdat.DatVersionUrl);
Validate(newdat.DatUrl);
Assert.Equal("XXXXXX", newdat.ImUrl);
}
/// <summary>
/// Validate a DatUrl
/// </summary>
private static void Validate(Data.Models.OfflineList.DatUrl? daturl)
{
Assert.NotNull(daturl);
Assert.Equal("XXXXXX", daturl.FileName);
Assert.Equal("XXXXXX", daturl.Content);
}
/// <summary>
/// Validate a Search
/// </summary>
private static void Validate(Data.Models.OfflineList.Search? search)
{
Assert.NotNull(search);
Assert.NotNull(search.To);
var to = Assert.Single(search.To);
Validate(to);
}
/// <summary>
/// Validate a To
/// </summary>
private static void Validate(Data.Models.OfflineList.To? to)
{
Assert.NotNull(to);
Assert.Equal("XXXXXX", to.Value);
Assert.Equal("XXXXXX", to.Default);
Assert.Equal("XXXXXX", to.Auto);
Assert.NotNull(to.Find);
var find = Assert.Single(to.Find);
Validate(find);
}
/// <summary>
/// Validate a Find
/// </summary>
private static void Validate(Data.Models.OfflineList.Find? find)
{
Assert.NotNull(find);
Assert.Equal("XXXXXX", find.Operation);
Assert.Equal("XXXXXX", find.Value);
Assert.Equal("XXXXXX", find.Content);
}
/// <summary>
/// Validate a Games
/// </summary>
private static void Validate(Data.Models.OfflineList.Games? games)
{
Assert.NotNull(games);
Assert.NotNull(games.Game);
var game = Assert.Single(games.Game);
Validate(game);
}
/// <summary>
/// Validate a Game
/// </summary>
private static void Validate(Data.Models.OfflineList.Game? game)
{
Assert.NotNull(game);
Assert.Equal("XXXXXX", game.ImageNumber);
Assert.Equal("XXXXXX", game.ReleaseNumber);
Assert.Equal("XXXXXX", game.Title);
Assert.Equal("XXXXXX", game.SaveType);
Assert.Equal("XXXXXX", game.RomSize);
Assert.Equal("XXXXXX", game.Publisher);
Assert.Equal("XXXXXX", game.Location);
Assert.Equal("XXXXXX", game.SourceRom);
Assert.Equal("XXXXXX", game.Language);
Validate(game.Files);
Assert.Equal("XXXXXX", game.Im1CRC);
Assert.Equal("XXXXXX", game.Im2CRC);
Assert.Equal("XXXXXX", game.Comment);
Assert.Equal("XXXXXX", game.DuplicateID);
}
/// <summary>
/// Validate a Files
/// </summary>
private static void Validate(Data.Models.OfflineList.Files? files)
{
Assert.NotNull(files);
Assert.NotNull(files.RomCRC);
var fileromcrc = Assert.Single(files.RomCRC);
Validate(fileromcrc);
}
/// <summary>
/// Validate a FileRomCRC
/// </summary>
private static void Validate(Data.Models.OfflineList.FileRomCRC? fileromcrc)
{
Assert.NotNull(fileromcrc);
Assert.Equal("XXXXXX", fileromcrc.Extension);
Assert.Equal("XXXXXX", fileromcrc.Content);
}
/// <summary>
/// Validate a GUI
/// </summary>
private static void Validate(Data.Models.OfflineList.GUI? gui)
{
Assert.NotNull(gui);
Validate(gui.Images);
}
/// <summary>
/// Validate a Images
/// </summary>
private static void Validate(Data.Models.OfflineList.Images? images)
{
Assert.NotNull(images);
Assert.Equal("XXXXXX", images.Width);
Assert.Equal("XXXXXX", images.Height);
Assert.NotNull(images.Image);
var image = Assert.Single(images.Image);
Validate(image);
}
/// <summary>
/// Validate a Image
/// </summary>
private static void Validate(Data.Models.OfflineList.Image? image)
{
Assert.NotNull(image);
Assert.Equal("XXXXXX", image.X);
Assert.Equal("XXXXXX", image.Y);
Assert.Equal("XXXXXX", image.Width);
Assert.Equal("XXXXXX", image.Height);
}
}
}

View File

@@ -0,0 +1,223 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class OpenMSXTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new OpenMSX();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new OpenMSX();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new OpenMSX();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new OpenMSX();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new OpenMSX();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new OpenMSX();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void RoundTripTest()
{
// Get the serializer and deserializer
var deserializer = new OpenMSX();
var serializer = new SabreTools.Serialization.Writers.OpenMSX();
// Build the data
Data.Models.OpenMSX.SoftwareDb sdb = Build();
// Serialize to stream
Stream? metadata = serializer.Serialize(sdb);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.OpenMSX.SoftwareDb? newSdb = deserializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newSdb);
Assert.Equal("XXXXXX", newSdb.Timestamp);
Assert.NotNull(newSdb.Software);
var software = Assert.Single(newSdb.Software);
Validate(software);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.OpenMSX.SoftwareDb Build()
{
var original = new Data.Models.OpenMSX.Original
{
Value = "XXXXXX",
Content = "XXXXXX",
};
var rom = new Data.Models.OpenMSX.Rom
{
Start = "XXXXXX",
Type = "XXXXXX",
Hash = "XXXXXX",
Remark = "XXXXXX",
};
var dump_rom = new Data.Models.OpenMSX.Dump
{
Original = original,
Rom = rom,
};
var megarom = new Data.Models.OpenMSX.MegaRom
{
Start = "XXXXXX",
Type = "XXXXXX",
Hash = "XXXXXX",
Remark = "XXXXXX",
};
var dump_megarom = new Data.Models.OpenMSX.Dump
{
Original = original,
Rom = megarom,
};
var sccpluscart = new Data.Models.OpenMSX.SCCPlusCart
{
Start = "XXXXXX",
Type = "XXXXXX",
Hash = "XXXXXX",
Remark = "XXXXXX",
};
var dump_sccpluscart = new Data.Models.OpenMSX.Dump
{
Original = original,
Rom = sccpluscart,
};
var software = new Data.Models.OpenMSX.Software
{
Title = "XXXXXX",
GenMSXID = "XXXXXX",
System = "XXXXXX",
Company = "XXXXXX",
Year = "XXXXXX",
Country = "XXXXXX",
Dump = [dump_rom, dump_megarom, dump_sccpluscart],
};
return new Data.Models.OpenMSX.SoftwareDb
{
Timestamp = "XXXXXX",
Software = [software],
};
}
/// <summary>
/// Validate a Software
/// </summary>
private static void Validate(Data.Models.OpenMSX.Software? software)
{
Assert.NotNull(software);
Assert.Equal("XXXXXX", software.Title);
Assert.Equal("XXXXXX", software.GenMSXID);
Assert.Equal("XXXXXX", software.System);
Assert.Equal("XXXXXX", software.Company);
Assert.Equal("XXXXXX", software.Year);
Assert.Equal("XXXXXX", software.Country);
Assert.NotNull(software.Dump);
Assert.Equal(3, software.Dump.Length);
foreach (var dump in software.Dump)
{
Validate(dump);
}
}
/// <summary>
/// Validate a Dump
/// </summary>
private static void Validate(Data.Models.OpenMSX.Dump? dump)
{
Assert.NotNull(dump);
Validate(dump.Original);
Validate(dump.Rom);
}
/// <summary>
/// Validate a Original
/// </summary>
private static void Validate(Data.Models.OpenMSX.Original? original)
{
Assert.NotNull(original);
Assert.Equal("XXXXXX", original.Value);
Assert.Equal("XXXXXX", original.Content);
}
/// <summary>
/// Validate a RomBase
/// </summary>
private static void Validate(Data.Models.OpenMSX.RomBase? rombase)
{
Assert.NotNull(rombase);
Assert.Equal("XXXXXX", rombase.Start);
Assert.Equal("XXXXXX", rombase.Type);
Assert.Equal("XXXXXX", rombase.Hash);
Assert.Equal("XXXXXX", rombase.Remark);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class PAKTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new PAK();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new PAK();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new PAK();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new PAK();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new PAK();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new PAK();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class PFFTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new PFF();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new PFF();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new PFF();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new PFF();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new PFF();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new PFF();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class PICTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new PIC();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new PIC();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new PIC();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new PIC();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new PIC();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new PIC();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class PKZIPTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new PKZIP();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new PKZIP();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new PKZIP();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new PKZIP();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new PKZIP();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new PKZIP();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class PlayJAudioTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new PlayJAudio();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new PlayJAudio();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new PlayJAudio();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new PlayJAudio();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new PlayJAudio();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new PlayJAudio();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class PlayJPlaylistTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new PlayJPlaylist();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new PlayJPlaylist();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new PlayJPlaylist();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new PlayJPlaylist();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new PlayJPlaylist();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new PlayJPlaylist();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class PortableExecutableTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new PortableExecutable();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new PortableExecutable();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new PortableExecutable();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new PortableExecutable();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new PortableExecutable();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new PortableExecutable();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class QuantumTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new Quantum();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new Quantum();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new Quantum();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new Quantum();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new Quantum();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new Quantum();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,220 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class RomCenterTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new RomCenter();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new RomCenter();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new RomCenter();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new RomCenter();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new RomCenter();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new RomCenter();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void RoundTripTest()
{
// Get the serializer and deserializer
var deserializer = new RomCenter();
var serializer = new SabreTools.Serialization.Writers.RomCenter();
// Build the data
Data.Models.RomCenter.MetadataFile mf = Build();
// Serialize to stream
Stream? metadata = serializer.SerializeStream(mf);
Assert.NotNull(metadata);
// Serialize back to original model
Data.Models.RomCenter.MetadataFile? newMf = deserializer.Deserialize(metadata);
// Validate the data
Assert.NotNull(newMf);
Validate(newMf.Credits);
Validate(newMf.Dat);
Validate(newMf.Emulator);
Validate(newMf.Games);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.RomCenter.MetadataFile Build()
{
var credits = new Data.Models.RomCenter.Credits
{
Author = "XXXXXX",
Version = "XXXXXX",
Email = "XXXXXX",
Homepage = "XXXXXX",
Url = "XXXXXX",
Date = "XXXXXX",
Comment = "XXXXXX",
};
var dat = new Data.Models.RomCenter.Dat
{
Version = "XXXXXX",
Plugin = "XXXXXX",
Split = "XXXXXX",
Merge = "XXXXXX",
};
var emulator = new Data.Models.RomCenter.Emulator
{
RefName = "XXXXXX",
Version = "XXXXXX",
};
var rom = new Data.Models.RomCenter.Rom
{
ParentName = "XXXXXX",
ParentDescription = "XXXXXX",
GameName = "XXXXXX",
GameDescription = "XXXXXX",
RomName = "XXXXXX",
RomCRC = "XXXXXX",
RomSize = "XXXXXX",
RomOf = "XXXXXX",
MergeName = "XXXXXX",
};
var games = new Data.Models.RomCenter.Games
{
Rom = [rom],
};
return new Data.Models.RomCenter.MetadataFile
{
Credits = credits,
Dat = dat,
Emulator = emulator,
Games = games,
};
}
/// <summary>
/// Validate a Credits
/// </summary>
private static void Validate(Data.Models.RomCenter.Credits? credits)
{
Assert.NotNull(credits);
Assert.Equal("XXXXXX", credits.Author);
Assert.Equal("XXXXXX", credits.Version);
Assert.Equal("XXXXXX", credits.Email);
Assert.Equal("XXXXXX", credits.Homepage);
Assert.Equal("XXXXXX", credits.Url);
Assert.Equal("XXXXXX", credits.Date);
Assert.Equal("XXXXXX", credits.Comment);
}
/// <summary>
/// Validate a Dat
/// </summary>
private static void Validate(Data.Models.RomCenter.Dat? dat)
{
Assert.NotNull(dat);
Assert.Equal("XXXXXX", dat.Version);
Assert.Equal("XXXXXX", dat.Plugin);
Assert.Equal("XXXXXX", dat.Split);
Assert.Equal("XXXXXX", dat.Merge);
}
/// <summary>
/// Validate a Emulator
/// </summary>
private static void Validate(Data.Models.RomCenter.Emulator? emulator)
{
Assert.NotNull(emulator);
Assert.Equal("XXXXXX", emulator.RefName);
Assert.Equal("XXXXXX", emulator.Version);
}
/// <summary>
/// Validate a Games
/// </summary>
private static void Validate(Data.Models.RomCenter.Games? games)
{
Assert.NotNull(games);
Assert.NotNull(games.Rom);
var rom = Assert.Single(games.Rom);
Validate(rom);
}
/// <summary>
/// Validate a Rom
/// </summary>
private static void Validate(Data.Models.RomCenter.Rom? rom)
{
Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.ParentName);
Assert.Equal("XXXXXX", rom.ParentDescription);
Assert.Equal("XXXXXX", rom.GameName);
Assert.Equal("XXXXXX", rom.GameDescription);
Assert.Equal("XXXXXX", rom.RomName);
Assert.Equal("XXXXXX", rom.RomCRC);
Assert.Equal("XXXXXX", rom.RomSize);
Assert.Equal("XXXXXX", rom.RomOf);
Assert.Equal("XXXXXX", rom.MergeName);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class SFBTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new SFB();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new SFB();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new SFB();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new SFB();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new SFB();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new SFB();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class SFOTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new SFO();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new SFO();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new SFO();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new SFO();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new SFO();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new SFO();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class SGATests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new SGA();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new SGA();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new SGA();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new SGA();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new SGA();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new SGA();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,308 @@
using System;
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class SeparatedValueTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new SeparatedValue();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new SeparatedValue();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new SeparatedValue();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new SeparatedValue();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new SeparatedValue();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new SeparatedValue();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void RoundTripShortTest()
{
// Get the serializer and deserializer
var deserializer = new SeparatedValue();
var serializer = new SabreTools.Serialization.Writers.SeparatedValue();
// Build the data
Data.Models.SeparatedValue.MetadataFile mf = Build();
// Serialize to stream
Stream? actual = serializer.SerializeStream(mf, ',', longHeader: false);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.SeparatedValue.MetadataFile? newMf = deserializer.Deserialize(actual);
// Validate the data
Assert.NotNull(newMf);
Validate(newMf.Header, longHeader: false);
Assert.NotNull(newMf.Row);
Assert.Equal(3, newMf.Row.Length);
ValidateDisk(newMf.Row[0], longHeader: false);
ValidateMedia(newMf.Row[1], longHeader: false);
ValidateRom(newMf.Row[2], longHeader: false);
}
[Fact]
public void RoundTripLongTest()
{
// Get the serializer and deserializer
var deserializer = new SeparatedValue();
var serializer = new SabreTools.Serialization.Writers.SeparatedValue();
// Build the data
Data.Models.SeparatedValue.MetadataFile mf = Build();
// Serialize to stream
Stream? actual = serializer.SerializeStream(mf, ',', longHeader: true);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.SeparatedValue.MetadataFile? newMf = deserializer.Deserialize(actual);
// Validate the data
Assert.NotNull(newMf);
Validate(newMf.Header, longHeader: true);
Assert.NotNull(newMf.Row);
Assert.Equal(3, newMf.Row.Length);
ValidateDisk(newMf.Row[0], longHeader: true);
ValidateMedia(newMf.Row[1], longHeader: true);
ValidateRom(newMf.Row[2], longHeader: true);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.SeparatedValue.MetadataFile Build()
{
string[] header = ["header"];
var disk = new Data.Models.SeparatedValue.Row
{
FileName = "XXXXXX",
InternalName = "XXXXXX",
Description = "XXXXXX",
GameName = "XXXXXX",
GameDescription = "XXXXXX",
Type = "disk",
DiskName = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Status = "XXXXXX",
};
var media = new Data.Models.SeparatedValue.Row
{
FileName = "XXXXXX",
InternalName = "XXXXXX",
Description = "XXXXXX",
GameName = "XXXXXX",
GameDescription = "XXXXXX",
Type = "media",
DiskName = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
SHA256 = "XXXXXX",
SpamSum = "XXXXXX",
};
var rom = new Data.Models.SeparatedValue.Row
{
FileName = "XXXXXX",
InternalName = "XXXXXX",
Description = "XXXXXX",
GameName = "XXXXXX",
GameDescription = "XXXXXX",
Type = "rom",
RomName = "XXXXXX",
Size = "XXXXXX",
CRC = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
SHA256 = "XXXXXX",
SHA384 = "XXXXXX",
SHA512 = "XXXXXX",
SpamSum = "XXXXXX",
Status = "XXXXXX",
};
return new Data.Models.SeparatedValue.MetadataFile
{
Header = header,
Row = [disk, media, rom],
};
}
/// <summary>
/// Validate a header
/// </summary>
private static void Validate(string[]? header, bool longHeader)
{
Assert.NotNull(header);
if (longHeader)
Assert.True(SabreTools.Serialization.Writers.SeparatedValue.HeaderArrayExtended.SequenceEqual(header));
else
Assert.True(SabreTools.Serialization.Writers.SeparatedValue.HeaderArrayStandard.SequenceEqual(header));
}
/// <summary>
/// Validate a Row
/// </summary>
private static void ValidateDisk(Data.Models.SeparatedValue.Row? row, bool longHeader)
{
Assert.NotNull(row);
Assert.Equal("XXXXXX", row.FileName);
Assert.Equal("XXXXXX", row.InternalName);
Assert.Equal("XXXXXX", row.Description);
Assert.Equal("XXXXXX", row.GameName);
Assert.Equal("XXXXXX", row.GameDescription);
Assert.Equal("disk", row.Type);
Assert.NotNull(row.RomName); Assert.Empty(row.RomName);
Assert.Equal("XXXXXX", row.DiskName);
Assert.NotNull(row.Size); Assert.Empty(row.Size);
Assert.NotNull(row.CRC); Assert.Empty(row.CRC);
Assert.Equal("XXXXXX", row.MD5);
Assert.Equal("XXXXXX", row.SHA1);
Assert.NotNull(row.CRC); Assert.Empty(row.CRC);
if (longHeader)
{
Assert.NotNull(row.SHA384); Assert.Empty(row.SHA384);
Assert.NotNull(row.SHA512); Assert.Empty(row.SHA512);
Assert.NotNull(row.SpamSum); Assert.Empty(row.SpamSum);
}
else
{
Assert.Null(row.SHA384);
Assert.Null(row.SHA512);
Assert.Null(row.SpamSum);
}
Assert.Equal("XXXXXX", row.Status);
}
/// <summary>
/// Validate a Row
/// </summary>
private static void ValidateMedia(Data.Models.SeparatedValue.Row? row, bool longHeader)
{
Assert.NotNull(row);
Assert.Equal("XXXXXX", row.FileName);
Assert.Equal("XXXXXX", row.InternalName);
Assert.Equal("XXXXXX", row.Description);
Assert.Equal("XXXXXX", row.GameName);
Assert.Equal("XXXXXX", row.GameDescription);
Assert.Equal("media", row.Type);
Assert.NotNull(row.RomName); Assert.Empty(row.RomName);
Assert.Equal("XXXXXX", row.DiskName);
Assert.NotNull(row.Size); Assert.Empty(row.Size);
Assert.NotNull(row.CRC); Assert.Empty(row.CRC);
Assert.Equal("XXXXXX", row.MD5);
Assert.Equal("XXXXXX", row.SHA1);
Assert.Equal("XXXXXX", row.SHA256);
if (longHeader)
{
Assert.NotNull(row.SHA384); Assert.Empty(row.SHA384);
Assert.NotNull(row.SHA512); Assert.Empty(row.SHA512);
Assert.Equal("XXXXXX", row.SpamSum);
}
else
{
Assert.Null(row.SHA384);
Assert.Null(row.SHA512);
Assert.Null(row.SpamSum);
}
Assert.NotNull(row.Status); Assert.Empty(row.Status);
}
/// <summary>
/// Validate a Row
/// </summary>
private static void ValidateRom(Data.Models.SeparatedValue.Row? row, bool longHeader)
{
Assert.NotNull(row);
Assert.Equal("XXXXXX", row.FileName);
Assert.Equal("XXXXXX", row.InternalName);
Assert.Equal("XXXXXX", row.Description);
Assert.Equal("XXXXXX", row.GameName);
Assert.Equal("XXXXXX", row.GameDescription);
Assert.Equal("rom", row.Type);
Assert.Equal("XXXXXX", row.RomName);
Assert.NotNull(row.DiskName);
Assert.Empty(row.DiskName);
Assert.Equal("XXXXXX", row.Size);
Assert.Equal("XXXXXX", row.CRC);
Assert.Equal("XXXXXX", row.MD5);
Assert.Equal("XXXXXX", row.SHA1);
Assert.Equal("XXXXXX", row.SHA256);
if (longHeader)
{
Assert.Equal("XXXXXX", row.SHA384);
Assert.Equal("XXXXXX", row.SHA512);
Assert.Equal("XXXXXX", row.SpamSum);
}
else
{
Assert.Null(row.SHA384);
Assert.Null(row.SHA512);
Assert.Null(row.SpamSum);
}
Assert.Equal("XXXXXX", row.Status);
}
}
}

View File

@@ -0,0 +1,377 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class SoftwareListTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new SoftwareList();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new SoftwareList();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new SoftwareList();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new SoftwareList();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new SoftwareList();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new SoftwareList();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void RoundTripTest()
{
// Get the serializer and deserializer
var deserializer = new SoftwareList();
var serializer = new SabreTools.Serialization.Writers.SoftwareList();
// Build the data
Data.Models.SoftwareList.SoftwareList sl = Build();
// Serialize to stream
Stream? actual = serializer.Serialize(sl);
Assert.NotNull(actual);
// Serialize back to original model
Data.Models.SoftwareList.SoftwareList? newSl = deserializer.Deserialize(actual);
// Validate the data
Assert.NotNull(newSl);
Assert.Equal("XXXXXX", newSl.Name);
Assert.Equal("XXXXXX", newSl.Description);
Assert.Equal("XXXXXX", newSl.Notes);
Assert.NotNull(newSl.Software);
var newSoftware = Assert.Single(newSl.Software);
Validate(newSoftware);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Data.Models.SoftwareList.SoftwareList Build()
{
var info = new Data.Models.SoftwareList.Info
{
Name = "XXXXXX",
Value = "XXXXXX",
};
var sharedfeat = new Data.Models.SoftwareList.SharedFeat
{
Name = "XXXXXX",
Value = "XXXXXX",
};
var feature = new Data.Models.SoftwareList.Feature
{
Name = "XXXXXX",
Value = "XXXXXX",
};
var rom = new Data.Models.SoftwareList.Rom
{
Name = "XXXXXX",
Size = "XXXXXX",
Length = "XXXXXX",
CRC = "XXXXXX",
SHA1 = "XXXXXX",
Offset = "XXXXXX",
Value = "XXXXXX",
Status = "XXXXXX",
LoadFlag = "XXXXXX",
};
var dataarea = new Data.Models.SoftwareList.DataArea
{
Name = "XXXXXX",
Size = "XXXXXX",
Width = "XXXXXX",
Endianness = "XXXXXX",
Rom = [rom],
};
var disk = new Data.Models.SoftwareList.Disk
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Status = "XXXXXX",
Writeable = "XXXXXX",
};
var diskarea = new Data.Models.SoftwareList.DiskArea
{
Name = "XXXXXX",
Disk = [disk],
};
var dipvalue = new Data.Models.SoftwareList.DipValue
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
};
var dipswitch = new Data.Models.SoftwareList.DipSwitch
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
DipValue = [dipvalue],
};
var part = new Data.Models.SoftwareList.Part
{
Name = "XXXXXX",
Interface = "XXXXXX",
Feature = [feature],
DataArea = [dataarea],
DiskArea = [diskarea],
DipSwitch = [dipswitch],
};
var software = new Data.Models.SoftwareList.Software
{
Name = "XXXXXX",
CloneOf = "XXXXXX",
Supported = "XXXXXX",
Description = "XXXXXX",
Year = "XXXXXX",
Publisher = "XXXXXX",
Notes = "XXXXXX",
Info = [info],
SharedFeat = [sharedfeat],
Part = [part],
};
return new Data.Models.SoftwareList.SoftwareList
{
Name = "XXXXXX",
Description = "XXXXXX",
Notes = "XXXXXX",
Software = [software],
};
}
/// <summary>
/// Validate a Software
/// </summary>
private static void Validate(Data.Models.SoftwareList.Software? software)
{
Assert.NotNull(software);
Assert.Equal("XXXXXX", software.Name);
Assert.Equal("XXXXXX", software.CloneOf);
Assert.Equal("XXXXXX", software.Supported);
Assert.Equal("XXXXXX", software.Description);
Assert.Equal("XXXXXX", software.Year);
Assert.Equal("XXXXXX", software.Publisher);
Assert.Equal("XXXXXX", software.Notes);
Assert.NotNull(software.Info);
var info = Assert.Single(software.Info);
Validate(info);
Assert.NotNull(software.SharedFeat);
var sharedfeat = Assert.Single(software.SharedFeat);
Validate(sharedfeat);
Assert.NotNull(software.Part);
var part = Assert.Single(software.Part);
Validate(part);
}
/// <summary>
/// Validate a Info
/// </summary>
private static void Validate(Data.Models.SoftwareList.Info? info)
{
Assert.NotNull(info);
Assert.Equal("XXXXXX", info.Name);
Assert.Equal("XXXXXX", info.Value);
}
/// <summary>
/// Validate a SharedFeat
/// </summary>
private static void Validate(Data.Models.SoftwareList.SharedFeat? sharedfeat)
{
Assert.NotNull(sharedfeat);
Assert.Equal("XXXXXX", sharedfeat.Name);
Assert.Equal("XXXXXX", sharedfeat.Value);
}
/// <summary>
/// Validate a Part
/// </summary>
private static void Validate(Data.Models.SoftwareList.Part? part)
{
Assert.NotNull(part);
Assert.Equal("XXXXXX", part.Name);
Assert.Equal("XXXXXX", part.Interface);
Assert.NotNull(part.Feature);
var feature = Assert.Single(part.Feature);
Validate(feature);
Assert.NotNull(part.DataArea);
var dataarea = Assert.Single(part.DataArea);
Validate(dataarea);
Assert.NotNull(part.DiskArea);
var diskarea = Assert.Single(part.DiskArea);
Validate(diskarea);
Assert.NotNull(part.DipSwitch);
var dipswitch = Assert.Single(part.DipSwitch);
Validate(dipswitch);
}
/// <summary>
/// Validate a Feature
/// </summary>
private static void Validate(Data.Models.SoftwareList.Feature? feature)
{
Assert.NotNull(feature);
Assert.Equal("XXXXXX", feature.Name);
Assert.Equal("XXXXXX", feature.Value);
}
/// <summary>
/// Validate a DataArea
/// </summary>
private static void Validate(Data.Models.SoftwareList.DataArea? dataarea)
{
Assert.NotNull(dataarea);
Assert.Equal("XXXXXX", dataarea.Name);
Assert.Equal("XXXXXX", dataarea.Size);
Assert.Equal("XXXXXX", dataarea.Width);
Assert.Equal("XXXXXX", dataarea.Endianness);
Assert.NotNull(dataarea.Rom);
var rom = Assert.Single(dataarea.Rom);
Validate(rom);
}
/// <summary>
/// Validate a Rom
/// </summary>
private static void Validate(Data.Models.SoftwareList.Rom? rom)
{
Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.Name);
Assert.Equal("XXXXXX", rom.Size);
Assert.Equal("XXXXXX", rom.Length);
Assert.Equal("XXXXXX", rom.CRC);
Assert.Equal("XXXXXX", rom.SHA1);
Assert.Equal("XXXXXX", rom.Offset);
Assert.Equal("XXXXXX", rom.Value);
Assert.Equal("XXXXXX", rom.Status);
Assert.Equal("XXXXXX", rom.LoadFlag);
}
/// <summary>
/// Validate a DiskArea
/// </summary>
private static void Validate(Data.Models.SoftwareList.DiskArea? diskarea)
{
Assert.NotNull(diskarea);
Assert.Equal("XXXXXX", diskarea.Name);
Assert.NotNull(diskarea.Disk);
var disk = Assert.Single(diskarea.Disk);
Validate(disk);
}
/// <summary>
/// Validate a Disk
/// </summary>
private static void Validate(Data.Models.SoftwareList.Disk? disk)
{
Assert.NotNull(disk);
Assert.Equal("XXXXXX", disk.Name);
Assert.Equal("XXXXXX", disk.MD5);
Assert.Equal("XXXXXX", disk.SHA1);
Assert.Equal("XXXXXX", disk.Status);
Assert.Equal("XXXXXX", disk.Writeable);
}
/// <summary>
/// Validate a DipSwitch
/// </summary>
private static void Validate(Data.Models.SoftwareList.DipSwitch? dipswitch)
{
Assert.NotNull(dipswitch);
Assert.Equal("XXXXXX", dipswitch.Name);
Assert.Equal("XXXXXX", dipswitch.Tag);
Assert.Equal("XXXXXX", dipswitch.Mask);
Assert.NotNull(dipswitch.DipValue);
var dipvalue = Assert.Single(dipswitch.DipValue);
Validate(dipvalue);
}
/// <summary>
/// Validate a DipValue
/// </summary>
private static void Validate(Data.Models.SoftwareList.DipValue? dipvalue)
{
Assert.NotNull(dipvalue);
Assert.Equal("XXXXXX", dipvalue.Name);
Assert.Equal("XXXXXX", dipvalue.Value);
Assert.Equal("XXXXXX", dipvalue.Default);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class TapeArchiveTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new TapeArchive();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new TapeArchive();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new TapeArchive();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new TapeArchive();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new TapeArchive();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new TapeArchive();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class VBSPTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new VBSP();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new VBSP();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new VBSP();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new VBSP();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new VBSP();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new VBSP();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class VPKTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new VPK();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new VPK();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new VPK();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new VPK();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new VPK();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new VPK();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class WAD3Tests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new WAD3();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new WAD3();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new WAD3();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new WAD3();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new WAD3();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new WAD3();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class WiseOverlayHeaderTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new WiseOverlayHeader();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new WiseOverlayHeader();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new WiseOverlayHeader();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new WiseOverlayHeader();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new WiseOverlayHeader();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new WiseOverlayHeader();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class WiseScriptTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new WiseScript();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new WiseScript();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new WiseScript();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new WiseScript();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new WiseScript();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new WiseScript();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class WiseSectionHeaderTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new WiseSectionHeader();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new WiseSectionHeader();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new WiseSectionHeader();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new WiseSectionHeader();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new WiseSectionHeader();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new WiseSectionHeader();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,39 @@
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class XMIDTests
{
[Fact]
public void NullString_Null()
{
string? data = null;
var deserializer = new XMID();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyString_Null()
{
string? data = string.Empty;
var deserializer = new XMID();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidString_Null()
{
string? data = "INVALID";
var deserializer = new XMID();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class XZPTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new XZP();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new XZP();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new XZP();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new XZP();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new XZP();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new XZP();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class XZTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new XZ();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new XZ();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void InvalidArray_Null()
{
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0;
var deserializer = new XZ();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new XZ();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new XZ();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidStream_Null()
{
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new XZ();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -0,0 +1,38 @@
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class XeMIDTests
{
[Fact]
public void NullString_Null()
{
string? data = null;
var deserializer = new XeMID();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyString_Null()
{
string? data = string.Empty;
var deserializer = new XeMID();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void InvalidString_Null()
{
string? data = "INVALID";
var deserializer = new XeMID();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

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