Compare commits

...

398 Commits
1.1.0 ... 1.8.7

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

* Fix typo

* add using System.Text

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

* Proper json deserialize

* Update packages

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

* Bump version, use ST.Models 1.4.1

* Implement JsonFile as interface with UTF8 as default

* typo
2024-04-02 08:46:12 -07:00
Matt Nadareski
d265c14841 Bump version 2024-03-25 14:25:28 -04:00
Matt Nadareski
1148245226 Surface NE/LE/PE methods for other library use 2024-03-24 21:09:12 -04:00
Matt Nadareski
f53d9f94e6 Break if StringFileInfo child is total size 0 2024-03-22 23:46:05 -04:00
Matt Nadareski
4e3d832834 Ensure Listrom serializes to the correct model type 2024-03-19 15:47:13 -04:00
Matt Nadareski
0713dfafb2 Bump version 2024-03-12 16:35:45 -04:00
Matt Nadareski
c0d4f403c3 Update IO package 2024-03-12 16:34:32 -04:00
Matt Nadareski
5ed79166cf Update Models library 2024-03-12 16:29:05 -04:00
Matt Nadareski
17030cfb9f Fix Listxml type key issues 2024-03-12 12:58:27 -04:00
Matt Nadareski
530fa69d3c Fix OpenMSX cross-model serialization keys 2024-03-12 00:46:46 -04:00
Matt Nadareski
7a5956f599 Fix capitalization in RomCenter INI stream serializer 2024-03-11 23:08:10 -04:00
Matt Nadareski
5562768509 Fix separated value cross-model serialization 2024-03-11 22:47:38 -04:00
Matt Nadareski
aa538df229 All doctype overloads to take nullable objects 2024-03-11 22:31:40 -04:00
Matt Nadareski
b7b22cba32 Fix AttractMode writing 2024-03-11 14:52:32 -04:00
Matt Nadareski
fc489125d9 Fix serialization problem for listrom 2024-03-10 00:39:23 -05:00
Matt Nadareski
036589473d Fix serialziation problem for archive.org 2024-03-10 00:36:31 -05:00
Matt Nadareski
432ce85f89 Bump version 2024-03-05 11:16:22 -05:00
Matt Nadareski
438e8067eb Update SabreTools.IO 2024-03-05 11:12:59 -05:00
Matt Nadareski
9715507aaf Add nuget package and PR workflows 2024-02-27 19:17:20 -05:00
Matt Nadareski
b745d4b9f6 Update copyright year 2024-01-30 13:39:23 -05:00
Matt Nadareski
4271bd86b3 Bump version 2024-01-26 09:57:09 -05:00
Matt Nadareski
88de4be27b Fix too-long string values 2024-01-26 01:23:33 -05:00
Matt Nadareski
33905165f7 Bump version 2024-01-05 21:57:50 -05:00
Deterous
83ec3b6950 Update CueSheet.Deserializer.cs (#2)
* Update CueSheet.Deserializer.cs

Don't return null when cuesheet is not ended

* Explicitly deal with new track/file cases
2024-01-02 17:51:27 -08:00
Matt Nadareski
9b5d51884c Use more lenient file reading 2023-12-13 15:45:40 -05:00
Matt Nadareski
aaa6422921 Bump version 2023-11-21 21:11:24 -05:00
Matt Nadareski
f24b88031b Address some suggestions 2023-11-21 21:10:43 -05:00
Matt Nadareski
edf9fed751 Support .NET Framework 2.0 2023-11-21 20:59:20 -05:00
Matt Nadareski
beca747943 Fix other data endpoint issues 2023-11-15 12:44:32 -05:00
Matt Nadareski
58e538eff6 Bump version 2023-11-15 12:41:21 -05:00
Matt Nadareski
4f04c8aa89 Fix end-of-data issue, add .NET 8 syntax 2023-11-15 12:34:57 -05:00
Matt Nadareski
d7c1e4e83a Support ancient .NET 2023-11-14 14:50:47 -05:00
Matt Nadareski
975eefdc61 Expand supported RIDs 2023-11-08 22:51:40 -05:00
Matt Nadareski
d8cd5854ce Enable latest language version 2023-11-07 23:30:26 -05:00
Matt Nadareski
0790fc93b6 Bump version 2023-10-25 15:34:38 -04:00
Matt Nadareski
7f6c128521 Update README 2023-10-25 15:04:22 -04:00
Matt Nadareski
87df6b3ebd Add IRD wrapper 2023-10-25 14:51:07 -04:00
Matt Nadareski
2ca7326074 Implement IRD serializers 2023-10-25 14:43:43 -04:00
Matt Nadareski
3b90af7b3a Split XgdInfo into two proper wrappers 2023-10-25 13:29:59 -04:00
Matt Nadareski
6eda2f2541 Update models, add XgdInfo extensions 2023-10-25 13:17:36 -04:00
Matt Nadareski
defe1c53aa Port a version of XgdInfo from MPF 2023-10-24 23:33:53 -04:00
Matt Nadareski
e5fe0a71ef Add Xbox string serialization 2023-10-24 23:24:17 -04:00
Matt Nadareski
83450f693f Make Strings namespace and move Xbox 2023-10-24 23:20:27 -04:00
Matt Nadareski
1f70e1f544 Remove unnecessary validation / methods from Xbox 2023-10-24 23:05:16 -04:00
Matt Nadareski
4bfc83d5d4 Make XMID consistent with XeMID 2023-10-24 21:50:26 -04:00
Matt Nadareski
7364661900 Add two X360 publishers 2023-10-24 21:43:21 -04:00
Matt Nadareski
1cafc4079d Make XeMID logic a bit clearer 2023-10-24 16:56:41 -04:00
Matt Nadareski
0d62cbd1e9 Add XGD4 PIC reading 2023-09-28 23:25:25 -04:00
Matt Nadareski
bf753262a5 Update Models version 2023-09-22 16:05:20 -04:00
Matt Nadareski
5510b5d19d Fix inconsistent access issue 2023-09-16 00:55:31 -04:00
Matt Nadareski
d0f0ade757 Bump version 2023-09-16 00:44:35 -04:00
Matt Nadareski
26b03d8256 Make some base functionality public 2023-09-16 00:15:44 -04:00
Matt Nadareski
97f685512a Port Wrapper Functionality
* Add core Wrapper code as a test

* Port all but printing and extraction

This also removes the couple of extensions that were ported

* Update README with subsection

* Add all namespaces to README

* Bump version
2023-09-15 20:31:51 -07:00
Matt Nadareski
0f790869d8 Move things around for nullability checks 2023-09-15 22:48:37 -04:00
Matt Nadareski
608edeb630 Port some extensions from BOS
This omits anything that relies on caching, at the moment. There is no easy way of creating a cache for the required pieces in the static context of the extensions.
2023-09-15 22:46:06 -04:00
Matt Nadareski
56066877b1 Split Extensions into multiple files 2023-09-15 22:38:47 -04:00
Matt Nadareski
a530f271d0 Move interfaces to Interfaces namespace 2023-09-15 22:34:47 -04:00
Matt Nadareski
327fd68f04 Bump version 2023-09-13 15:31:24 -04:00
Matt Nadareski
f12d48861f Port XMID/XeMID serialization from MPF 2023-09-13 15:30:32 -04:00
Matt Nadareski
5a613be9bf Port PIC serialization from MPF 2023-09-13 15:11:44 -04:00
Matt Nadareski
226031f3bd Port cuesheet serialization from MPF 2023-09-13 14:55:52 -04:00
Matt Nadareski
e5edf43624 Update Models to 1.1.2 2023-09-13 13:58:42 -04:00
Matt Nadareski
f2019b7ac4 Bump version 2023-09-11 01:23:34 -04:00
Matt Nadareski
0efb6d08e7 Fix serialization issues 2023-09-11 01:23:29 -04:00
Matt Nadareski
7ed1717f56 Add Nuget link 2023-09-10 23:33:41 -04:00
505 changed files with 59845 additions and 19290 deletions

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

@@ -0,0 +1,40 @@
name: Build and Test
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: |
6.0.x
8.0.x
9.0.x
- name: Run tests
run: dotnet test
- name: Run publish script
run: ./publish-nix.sh -d
- name: Upload to rolling
uses: ncipollo/release-action@v1.14.0
with:
allowUpdates: True
artifacts: "*.nupkg,*.snupkg,*.zip"
body: 'Last built commit: ${{ github.sha }}'
name: 'Rolling Release'
prerelease: True
replacesArtifacts: True
tag: "rolling"
updateOnlyUnreleased: True

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

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

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

@@ -0,0 +1,28 @@
{
// 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 (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/net9.0/InfoPrint.dll",
"args": [],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false,
"justMyCode": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
}

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,18 +0,0 @@
namespace SabreTools.Serialization.Files
{
public partial class Hashfile : IFileSerializer<Models.Hashfile.Hashfile>
{
/// <inheritdoc/>
#if NET48
public Models.Hashfile.Hashfile Deserialize(string path)
#else
public Models.Hashfile.Hashfile? Deserialize(string? path)
#endif
{
using (var stream = PathProcessor.OpenStream(path))
{
return new Streams.Hashfile().Deserialize(stream);
}
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,22 +0,0 @@
namespace SabreTools.Serialization.Files
{
/// <summary>
/// Base class for other XML serializers
/// </summary>
/// <typeparam name="T"></typeparam>
public partial class XmlFile<T> : IFileSerializer<T>
{
/// <inheritdoc/>
#if NET48
public T Deserialize(string path)
#else
public T? Deserialize(string? path)
#endif
{
using (var data = PathProcessor.OpenStream(path))
{
return new Streams.XmlFile<T>().Deserialize(data);
}
}
}
}

View File

@@ -1,53 +0,0 @@
using System.IO;
namespace SabreTools.Serialization.Files
{
/// <summary>
/// Base class for other XML serializers
/// </summary>
/// <typeparam name="T"></typeparam>
public partial class XmlFile<T> : IFileSerializer<T>
{
/// <inheritdoc/>
#if NET48
public bool Serialize(T obj, string path)
#else
public bool Serialize(T? obj, string? path)
#endif
=> Serialize(obj, path, null, null, null, null);
/// <summary>
/// Serializes the defined type to an XML file
/// </summary>
/// <param name="obj">Data to serialize</param>
/// <param name="path">Path to the file to serialize to</param>
/// <param name="obj">Data to serialize</param>
/// <param name="name">Optional DOCTYPE name</param>
/// <param name="pubid">Optional DOCTYPE pubid</param>
/// <param name="sysid">Optional DOCTYPE sysid</param>
/// <param name="subset">Optional DOCTYPE name</param>
/// <returns>True on successful serialization, false otherwise</returns>
#if NET48
public bool Serialize(T obj, string path, string name = null, string pubid = null, string sysid = null, string subset = null)
#else
public bool Serialize(T? obj, string? path, string? name = null, string? pubid = null, string? sysid = null, string? subset = null)
#endif
{
if (string.IsNullOrWhiteSpace(path))
return false;
using (var stream = new Streams.XmlFile<T>().Serialize(obj, name, pubid, sysid, subset))
{
if (stream == null)
return false;
using (var fs = File.OpenWrite(path))
{
stream.CopyTo(fs);
}
return true;
}
}
}
}

View File

@@ -1,33 +0,0 @@
namespace SabreTools.Serialization
{
/// <summary>
/// Defines how to serialize to and from files
/// </summary>
public interface IFileSerializer<T>
{
/// <summary>
/// Deserialize a file into <typeparamref name="T"/>
/// </summary>
/// <typeparam name="T">Type of object to deserialize to</typeparam>
/// <param name="path">Path to deserialize from</param>
/// <returns>Filled object on success, null on error</returns>
#if NET48
T Deserialize(string path);
#else
T? Deserialize(string? path);
#endif
/// <summary>
/// Sserialize a <typeparamref name="T"/> into a file
/// </summary>
/// <typeparam name="T">Type of object to serialize from</typeparam>
/// <param name="obj">Data to serialize</param>
/// <param name="path">Path to the file to serialize to</param>
/// <returns>True on successful serialization, false otherwise</returns>
#if NET48
bool Serialize(T obj, string path);
#else
bool Serialize(T? obj, string? path);
#endif
}
}

View File

@@ -1,34 +0,0 @@
using System.IO;
namespace SabreTools.Serialization
{
/// <summary>
/// Defines how to serialize to and from Streams
/// </summary>
public interface IStreamSerializer<T>
{
/// <summary>
/// Deserialize a Stream into <typeparamref name="T"/>
/// </summary>
/// <typeparam name="T">Type of object to deserialize to</typeparam>
/// <param name="data">Stream to parse</param>
/// <returns>Filled object on success, null on error</returns>
#if NET48
T Deserialize(Stream data);
#else
T? Deserialize(Stream? data);
#endif
/// <summary>
/// Serialize a <typeparamref name="T"/> into a Stream
/// </summary>
/// <typeparam name="T">Type of object to serialize from</typeparam>
/// <param name="obj">Data to serialize</param>
/// <returns>Filled object on success, null on error</returns>
#if NET48
Stream Serialize(T obj);
#else
Stream? Serialize(T? obj);
#endif
}
}

View File

@@ -0,0 +1,37 @@
<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</TargetFrameworks>
<OutputType>Exe</OutputType>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>1.8.7</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`))">
<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</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\SabreTools.Serialization\SabreTools.Serialization.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="SabreTools.IO" Version="1.6.3" />
</ItemGroup>
</Project>

119
InfoPrint/Options.cs Normal file
View File

@@ -0,0 +1,119 @@
using System;
using System.Collections.Generic;
namespace InfoPrint
{
/// <summary>
/// Set of options for the test executable
/// </summary>
internal sealed class Options
{
#region Properties
/// <summary>
/// Enable debug output for relevant operations
/// </summary>
public bool Debug { get; private set; } = false;
/// <summary>
/// Set of input paths to use for operations
/// </summary>
public List<string> InputPaths { get; private set; } = [];
#if NETCOREAPP
/// <summary>
/// Enable JSON output
/// </summary>
public bool Json { get; private set; } = false;
#endif
#endregion
/// <summary>
/// Parse commandline arguments into an Options object
/// </summary>
public static Options? ParseOptions(string[] args)
{
// If we have invalid arguments
if (args == null || args.Length == 0)
return null;
// Create an Options object
var options = new Options();
// Parse the features
int index = 0;
for (; index < args.Length; index++)
{
string arg = args[index];
bool featureFound = false;
switch (arg)
{
case "-?":
case "-h":
case "--help":
return null;
default:
break;
}
// If the flag wasn't a feature
if (!featureFound)
break;
}
// Parse the options and paths
for (; index < args.Length; index++)
{
string arg = args[index];
switch (arg)
{
case "-d":
case "--debug":
options.Debug = true;
break;
case "-j":
case "--json":
#if NETCOREAPP
options.Json = true;
#else
Console.WriteLine("JSON output not available in .NET Framework");
#endif
break;
default:
options.InputPaths.Add(arg);
break;
}
}
// Validate we have any input paths to work on
if (options.InputPaths.Count == 0)
{
Console.WriteLine("At least one path is required!");
return null;
}
return options;
}
/// <summary>
/// Display help text
/// </summary>
public static void DisplayHelp()
{
Console.WriteLine("Information Printing Program");
Console.WriteLine();
Console.WriteLine("infoprint.exe <options> file|directory ...");
Console.WriteLine();
Console.WriteLine("Options:");
Console.WriteLine("-?, -h, --help Display this help text and quit");
Console.WriteLine("-d, --debug Enable debug mode");
#if NETCOREAPP
Console.WriteLine("-j, --json Print info as JSON");
#endif
}
}
}

132
InfoPrint/Program.cs Normal file
View File

@@ -0,0 +1,132 @@
using System;
using System.IO;
using SabreTools.IO.Extensions;
using SabreTools.Serialization;
using SabreTools.Serialization.Wrappers;
namespace InfoPrint
{
public static class Program
{
public static void Main(string[] args)
{
// Get the options from the arguments
var options = Options.ParseOptions(args);
// If we have an invalid state
if (options == null)
{
Options.DisplayHelp();
return;
}
// Loop through the input paths
foreach (string inputPath in options.InputPaths)
{
#if NETFRAMEWORK
PrintPathInfo(inputPath, false, options.Debug);
#else
PrintPathInfo(inputPath, options.Json, options.Debug);
#endif
}
}
/// <summary>
/// Wrapper to print information for a single path
/// </summary>
/// <param name="path">File or directory path</param>
/// <param name="json">Enable JSON output, if supported</param>
/// <param name="debug">Enable debug output</param>
private static void PrintPathInfo(string path, bool json, bool debug)
{
Console.WriteLine($"Checking possible path: {path}");
// Check if the file or directory exists
if (File.Exists(path))
{
PrintFileInfo(path, json, debug);
}
else if (Directory.Exists(path))
{
foreach (string file in IOExtensions.SafeEnumerateFiles(path, "*", SearchOption.AllDirectories))
{
PrintFileInfo(file, json, debug);
}
}
else
{
Console.WriteLine($"{path} does not exist, skipping...");
}
}
/// <summary>
/// Print information for a single file, if possible
/// </summary>
private static void PrintFileInfo(string file, bool json, bool debug)
{
Console.WriteLine($"Attempting to print info for {file}");
try
{
using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
// Read the first 8 bytes
byte[]? magic = stream.ReadBytes(8);
stream.Seek(0, SeekOrigin.Begin);
// 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;
}
// Get the base info output name
string filenameBase = $"info-{DateTime.Now:yyyy-MM-dd_HHmmss.ffff}";
#if NETCOREAPP
// If we have the JSON flag
if (json)
{
// Create the output data
string serializedData = wrapper.ExportJSON();
Console.WriteLine(serializedData);
// Write the output data
using var jsw = new StreamWriter(File.OpenWrite($"{filenameBase}.json"));
jsw.WriteLine(serializedData);
}
#endif
// Create the output data
var builder = wrapper.ExportStringBuilder();
if (builder == null)
{
Console.WriteLine("No item information could be generated");
return;
}
// Write the output data
Console.WriteLine(builder);
using var sw = new StreamWriter(File.OpenWrite($"{filenameBase}.txt"));
sw.WriteLine(builder.ToString());
}
catch (Exception ex)
{
Console.WriteLine(debug ? ex : "[Exception opening file, please try again]");
Console.WriteLine();
}
}
}
}

View File

@@ -1,107 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SabreTools.Models.Metadata;
namespace SabreTools.Serialization
{
public static class Internal
{
/// <summary>
/// Extract nested items from a Dump
/// </summary>
#if NET48
public static DatItem[] ExtractItems(Dump item)
#else
public static DatItem[]? ExtractItems(Dump? item)
#endif
{
if (item == null)
return null;
var datItems = new List<DatItem>();
var rom = item.Read<Rom>(Dump.RomKey);
if (rom != null)
datItems.Add(rom);
var megaRom = item.Read<Rom>(Dump.MegaRomKey);
if (megaRom != null)
datItems.Add(megaRom);
var sccPlusCart = item.Read<Rom>(Dump.SCCPlusCartKey);
if (sccPlusCart != null)
datItems.Add(sccPlusCart);
return datItems.ToArray();
}
/// <summary>
/// Extract nested items from a Part
/// </summary>
#if NET48
public static DatItem[] ExtractItems(Part item)
#else
public static DatItem[]? ExtractItems(Part? item)
#endif
{
if (item == null)
return null;
var datItems = new List<DatItem>();
var features = item.Read<Feature[]>(Part.FeatureKey);
if (features != null && features.Any())
datItems.AddRange(features);
var dataAreas = item.Read<DataArea[]>(Part.DataAreaKey);
if (dataAreas != null && dataAreas.Any())
{
datItems.AddRange(dataAreas
.Where(d => d != null)
.SelectMany(ExtractItems));
}
var diskAreas = item.Read<DiskArea[]>(Part.DiskAreaKey);
if (diskAreas != null && diskAreas.Any())
{
datItems.AddRange(diskAreas
.Where(d => d != null)
.SelectMany(ExtractItems));
}
var dipSwitches = item.Read<DipSwitch[]>(Part.DipSwitchKey);
if (dipSwitches != null && dipSwitches.Any())
{
datItems.AddRange(dipSwitches
.Where(d => d != null));
}
return datItems.ToArray();
}
/// <summary>
/// Extract nested items from a DataArea
/// </summary>
private static Rom[] ExtractItems(DataArea item)
{
var roms = item.Read<Rom[]>(DataArea.RomKey);
if (roms == null || !roms.Any())
return Array.Empty<Rom>();
return roms.ToArray();
}
/// <summary>
/// Extract nested items from a DiskArea
/// </summary>
private static Disk[] ExtractItems(DiskArea item)
{
var roms = item.Read<Disk[]>(DiskArea.DiskKey);
if (roms == null || !roms.Any())
return Array.Empty<Disk>();
return roms.ToArray();
}
}
}

View File

@@ -1,32 +0,0 @@
namespace SabreTools.Serialization
{
/// <summary>
/// XML deserializer for Logiqx-derived metadata files
/// </summary>
public static class Logiqx
{
/// <summary>
/// name field for DOCTYPE
/// </summary>
public const string DocTypeName = "datafile";
/// <summary>
/// pubid field for DOCTYPE
/// </summary>
public const string DocTypePubId = "-//Logiqx//DTD ROM Management Datafile//EN";
/// <summary>
/// sysid field for DOCTYPE
/// </summary>
public const string DocTypeSysId = "http://www.logiqx.com/Dats/datafile.dtd";
/// <summary>
/// subset field for DOCTYPE
/// </summary>
#if NET48
public const string DocTypeSubset = null;
#else
public const string? DocTypeSubset = null;
#endif
}
}

View File

@@ -1,36 +0,0 @@
namespace SabreTools.Serialization
{
/// <summary>
/// XML deserializer for OpenMSX software database files
/// </summary>
public static class OpenMSX
{
/// <summary>
/// name field for DOCTYPE
/// </summary>
public const string DocTypeName = "softwaredb";
/// <summary>
/// pubid field for DOCTYPE
/// </summary>
#if NET48
public const string DocTypePubId = null;
#else
public const string? DocTypePubId = null;
#endif
/// <summary>
/// sysid field for DOCTYPE
/// </summary>
public const string DocTypeSysId = "softwaredb1.dtd";
/// <summary>
/// subset field for DOCTYPE
/// </summary>
#if NET48
public const string DocTypeSubset = null;
#else
public const string? DocTypeSubset = null;
#endif
}
}

View File

@@ -1,3 +1,48 @@
# 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).
## Releases
For the most recent stable build, download the latest release here: [Releases Page](https://github.com/SabreTools/SabreTools.Serialization/releases)
For the latest WIP build here: [Rolling Release](https://github.com/SabreTools/SabreTools.Serialization/releases/tag/rolling)
## Interfaces
Below is a table representing the various conversion interfaces that are implemented within this library.
| Interface Name | Source Type | Destination Type |
| --- | --- | --- |
| `IByteDeserializer` | `byte[]?` | Model |
| `IByteSerializer` | Model | `byte[]?` |
| `IFileDeserializer` | `string?` path | Model |
| `IFileSerializer` | Model | `string?` path |
| `IModelSerializer` | Model | Model |
| `IStreamDeserializer` | `Stream?` | Model |
| `IStreamSerializer` | Model | `Stream?` |
| `IStringDeserializer` | `string?` representation | Model |
| `IStringSerializer` | Model | `string?` representation |
Below is a table representing the various non-conversion interfaces that are implemented within this library.
| Interface Name | Purpose |
| --- | --- |
| `IPrinter` | Provides a formatted output for a model |
| `IWrapper` / `IWrapper<T>` | Wraps a model or set of models to provide additional functionality |
## Namespaces
Below is a table of all namespaces within the library and what they represent
| Namespace | Description |
| --- | --- |
| `SabreTools.Serialization.CrossModel` | Convert between models; mainly used for metadata files converting to and from a common, `Dictionary`-based model |
| `SabreTools.Serialization.Deserializers` | Convert from external sources to models |
| `SabreTools.Serialization.Printers` | Export model information in a formatted manner |
| `SabreTools.Serialization.Serializers` | Convert from models to external sources |
| `SabreTools.Serialization.Wrappers` | Classes that wrap serialization and models to allow for including extension properties |

View File

@@ -0,0 +1,173 @@
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class ArchiveDotOrgTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new Serialization.CrossModel.ArchiveDotOrg();
// Build the data
Models.ArchiveDotOrg.Files files = Build();
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(files);
Assert.NotNull(metadata);
// Serialize back to original model
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 Models.ArchiveDotOrg.Files Build()
{
var file = new 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 Models.ArchiveDotOrg.Files
{
File = [file]
};
}
/// <summary>
/// Validate a File
/// </summary>
private static void Validate(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,111 @@
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class AttractModeTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new Serialization.CrossModel.AttractMode();
// Build the data
Models.AttractMode.MetadataFile mf = Build();
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(mf);
Assert.NotNull(metadata);
// Serialize back to original model
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 Models.AttractMode.MetadataFile Build()
{
string[] header = ["header"];
var row = new 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 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(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,492 @@
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class ClrMameProTests
{
[Fact]
public void RoundTripGameTest()
{
// Get the cross-model serializer
var serializer = new Serialization.CrossModel.ClrMamePro();
// Build the data
Models.ClrMamePro.MetadataFile mf = Build(game: true);
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(mf);
Assert.NotNull(metadata);
// Serialize back to original model
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 Serialization.CrossModel.ClrMamePro();
// Build the data
Models.ClrMamePro.MetadataFile mf = Build(game: false);
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(mf);
Assert.NotNull(metadata);
// Serialize back to original model
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 Models.ClrMamePro.MetadataFile Build(bool game)
{
var cmp = new 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 Models.ClrMamePro.Release
{
Name = "XXXXXX",
Region = "XXXXXX",
Language = "XXXXXX",
Date = "XXXXXX",
Default = "XXXXXX",
};
var biosset = new Models.ClrMamePro.BiosSet
{
Name = "XXXXXX",
Description = "XXXXXX",
Default = "XXXXXX",
};
var rom = new Models.ClrMamePro.Rom
{
Name = "XXXXXX",
Size = "XXXXXX",
CRC = "XXXXXX",
MD5 = "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 Models.ClrMamePro.Disk
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Status = "XXXXXX",
Flags = "XXXXXX",
};
var sample = new Models.ClrMamePro.Sample
{
Name = "XXXXXX",
};
var archive = new Models.ClrMamePro.Archive
{
Name = "XXXXXX",
};
var media = new Models.ClrMamePro.Media
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
SHA256 = "XXXXXX",
SpamSum = "XXXXXX",
};
var chip = new Models.ClrMamePro.Chip
{
Type = "XXXXXX",
Name = "XXXXXX",
Flags = "XXXXXX",
Clock = "XXXXXX",
};
var video = new Models.ClrMamePro.Video
{
Screen = "XXXXXX",
Orientation = "XXXXXX",
X = "XXXXXX",
Y = "XXXXXX",
AspectX = "XXXXXX",
AspectY = "XXXXXX",
Freq = "XXXXXX",
};
var sound = new Models.ClrMamePro.Sound
{
Channels = "XXXXXX",
};
var input = new Models.ClrMamePro.Input
{
Players = "XXXXXX",
Control = "XXXXXX",
Buttons = "XXXXXX",
Coins = "XXXXXX",
Tilt = "XXXXXX",
Service = "XXXXXX",
};
var dipswitch = new Models.ClrMamePro.DipSwitch
{
Name = "XXXXXX",
Entry = ["XXXXXX"],
Default = "XXXXXX",
};
var driver = new Models.ClrMamePro.Driver
{
Status = "XXXXXX",
Color = "XXXXXX",
Sound = "XXXXXX",
PaletteSize = "XXXXXX",
Blit = "XXXXXX",
};
// TODO: This omits Set, should that have a separate case?
Models.ClrMamePro.GameBase gameBase = game
? new Models.ClrMamePro.Game()
: new 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 Models.ClrMamePro.MetadataFile
{
ClrMamePro = cmp,
Game = [gameBase],
};
}
/// <summary>
/// Validate a ClrMamePro
/// </summary>
private static void Validate(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(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(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(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(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.MD5);
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(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(Models.ClrMamePro.Sample? sample)
{
Assert.NotNull(sample);
Assert.Equal("XXXXXX", sample.Name);
}
/// <summary>
/// Validate a Archive
/// </summary>
private static void Validate(Models.ClrMamePro.Archive? archive)
{
Assert.NotNull(archive);
Assert.Equal("XXXXXX", archive.Name);
}
/// <summary>
/// Validate a Media
/// </summary>
private static void Validate(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(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(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(Models.ClrMamePro.Sound? sound)
{
Assert.NotNull(sound);
Assert.Equal("XXXXXX", sound.Channels);
}
/// <summary>
/// Validate a Input
/// </summary>
private static void Validate(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(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(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,110 @@
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class DosCenterTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new Serialization.CrossModel.DosCenter();
// Build the data
Models.DosCenter.MetadataFile mf = Build();
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(mf);
Assert.NotNull(metadata);
// Serialize back to original model
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 Models.DosCenter.MetadataFile Build()
{
var dc = new Models.DosCenter.DosCenter
{
Name = "XXXXXX",
Description = "XXXXXX",
Version = "XXXXXX",
Date = "XXXXXX",
Author = "XXXXXX",
Homepage = "XXXXXX",
Comment = "XXXXXX",
};
var file = new Models.DosCenter.File
{
Name = "XXXXXX",
Size = "XXXXXX",
CRC = "XXXXXX",
SHA1 = "XXXXXX",
Date = "XXXXXX",
};
var game = new Models.DosCenter.Game
{
Name = "XXXXXX",
File = [file],
};
return new Models.DosCenter.MetadataFile
{
DosCenter = dc,
Game = [game],
};
}
/// <summary>
/// Validate a DosCenter
/// </summary>
private static void Validate(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(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(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,65 @@
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class EverdriveSMDBTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new Serialization.CrossModel.EverdriveSMDB();
// Build the data
Models.EverdriveSMDB.MetadataFile mf = Build();
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(mf);
Assert.NotNull(metadata);
// Serialize back to original model
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 Models.EverdriveSMDB.MetadataFile Build()
{
var row = new Models.EverdriveSMDB.Row
{
SHA256 = "XXXXXX",
Name = "XXXXXX",
SHA1 = "XXXXXX",
MD5 = "XXXXXX",
CRC32 = "XXXXXX",
Size = "XXXXXX",
};
return new Models.EverdriveSMDB.MetadataFile
{
Row = [row],
};
}
/// <summary>
/// Validate a Row
/// </summary>
private static void Validate(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,326 @@
using System;
using SabreTools.Hashing;
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class HashfileTests
{
[Fact]
public void RoundTripSFVTest()
{
// Get the cross-model serializer
var serializer = new Serialization.CrossModel.Hashfile();
// Build the data
Models.Hashfile.Hashfile hf = Build(HashType.CRC32);
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
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 Serialization.CrossModel.Hashfile();
// Build the data
Models.Hashfile.Hashfile hf = Build(HashType.MD2);
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
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 Serialization.CrossModel.Hashfile();
// Build the data
Models.Hashfile.Hashfile hf = Build(HashType.MD4);
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
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 Serialization.CrossModel.Hashfile();
// Build the data
Models.Hashfile.Hashfile hf = Build(HashType.MD5);
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
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 Serialization.CrossModel.Hashfile();
// Build the data
Models.Hashfile.Hashfile hf = Build(HashType.SHA1);
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
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 Serialization.CrossModel.Hashfile();
// Build the data
Models.Hashfile.Hashfile hf = Build(HashType.SHA256);
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
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 Serialization.CrossModel.Hashfile();
// Build the data
Models.Hashfile.Hashfile hf = Build(HashType.SHA384);
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
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 Serialization.CrossModel.Hashfile();
// Build the data
Models.Hashfile.Hashfile hf = Build(HashType.SHA512);
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
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 Serialization.CrossModel.Hashfile();
// Build the data
Models.Hashfile.Hashfile hf = Build(HashType.SpamSum);
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(hf);
Assert.NotNull(metadata);
// Serialize back to original model
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 Models.Hashfile.Hashfile Build(HashType hashType)
{
return hashType switch
{
HashType.CRC32 => new Models.Hashfile.Hashfile { SFV = [new Models.Hashfile.SFV { File = "XXXXXX", Hash = "XXXXXX" }] },
HashType.MD2 => new Models.Hashfile.Hashfile { MD2 = [new Models.Hashfile.MD2 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.MD4 => new Models.Hashfile.Hashfile { MD4 = [new Models.Hashfile.MD4 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.MD5 => new Models.Hashfile.Hashfile { MD5 = [new Models.Hashfile.MD5 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SHA1 => new Models.Hashfile.Hashfile { SHA1 = [new Models.Hashfile.SHA1 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SHA256 => new Models.Hashfile.Hashfile { SHA256 = [new Models.Hashfile.SHA256 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SHA384 => new Models.Hashfile.Hashfile { SHA384 = [new Models.Hashfile.SHA384 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SHA512 => new Models.Hashfile.Hashfile { SHA512 = [new Models.Hashfile.SHA512 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SpamSum => new Models.Hashfile.Hashfile { SpamSum = [new Models.Hashfile.SpamSum { Hash = "XXXXXX", File = "XXXXXX" }] },
_ => throw new ArgumentOutOfRangeException(),
};
}
/// <summary>
/// Validate a SFV
/// </summary>
private static void Validate(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(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(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(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(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(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(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(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(Models.Hashfile.SpamSum? spamsum)
{
Assert.NotNull(spamsum);
Assert.Equal("XXXXXX", spamsum.Hash);
Assert.Equal("XXXXXX", spamsum.File);
}
}
}

View File

@@ -0,0 +1,127 @@
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class ListromTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new Serialization.CrossModel.Listrom();
// Build the data
Models.Listrom.MetadataFile mf = Build();
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(mf);
Assert.NotNull(metadata);
// Serialize back to original model
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 Models.Listrom.MetadataFile Build()
{
var rom = new Models.Listrom.Row
{
Name = "XXXXXX",
Size = "XXXXXX",
Bad = true,
CRC = "XXXXXX",
SHA1 = "XXXXXX",
NoGoodDumpKnown = false,
};
var disk = new Models.Listrom.Row
{
Name = "XXXXXX",
Bad = false,
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
NoGoodDumpKnown = true,
};
var device = new Models.Listrom.Set()
{
Device = "XXXXXX",
Row = [rom],
};
var driver = new Models.Listrom.Set()
{
Driver = "XXXXXX",
Row = [disk],
};
return new Models.Listrom.MetadataFile
{
Set = [device, driver],
};
}
/// <summary>
/// Validate a Set
/// </summary>
private static void ValidateDevice(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(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(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(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,878 @@
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class ListxmlTests
{
[Fact]
public void RoundTripGameTest()
{
// Get the cross-model serializer
var serializer = new Serialization.CrossModel.Listxml();
// Build the data
Models.Listxml.Mame mame = Build(game: true);
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(mame);
Assert.NotNull(metadata);
// Serialize back to original model
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 Serialization.CrossModel.Listxml();
// Build the data
Models.Listxml.Mame mame = Build(game: false);
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(mame);
Assert.NotNull(metadata);
// Serialize back to original model
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 Models.Listxml.Mame Build(bool game)
{
var biosset = new Models.Listxml.BiosSet
{
Name = "XXXXXX",
Description = "XXXXXX",
Default = "XXXXXX",
};
var rom = new 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 Models.Listxml.Disk
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Region = "XXXXXX",
Index = "XXXXXX",
Writable = "XXXXXX",
Status = "XXXXXX",
Optional = "XXXXXX",
};
var deviceref = new Models.Listxml.DeviceRef
{
Name = "XXXXXX",
};
var sample = new Models.Listxml.Sample
{
Name = "XXXXXX",
};
var chip = new Models.Listxml.Chip
{
Name = "XXXXXX",
Tag = "XXXXXX",
Type = "XXXXXX",
SoundOnly = "XXXXXX",
Clock = "XXXXXX",
};
var display = new 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 Models.Listxml.Video
{
Screen = "XXXXXX",
Orientation = "XXXXXX",
Width = "XXXXXX",
Height = "XXXXXX",
AspectX = "XXXXXX",
AspectY = "XXXXXX",
Refresh = "XXXXXX",
};
var sound = new Models.Listxml.Sound
{
Channels = "XXXXXX",
};
var control = new 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 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 Models.Listxml.Condition
{
Tag = "XXXXXX",
Mask = "XXXXXX",
Relation = "XXXXXX",
Value = "XXXXXX",
};
var diplocation = new Models.Listxml.DipLocation
{
Name = "XXXXXX",
Number = "XXXXXX",
Inverted = "XXXXXX",
};
var dipvalue = new Models.Listxml.DipValue
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var dipswitch = new Models.Listxml.DipSwitch
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
Condition = condition,
DipLocation = [diplocation],
DipValue = [dipvalue],
};
var conflocation = new Models.Listxml.ConfLocation
{
Name = "XXXXXX",
Number = "XXXXXX",
Inverted = "XXXXXX",
};
var confsetting = new Models.Listxml.ConfSetting
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var configuration = new Models.Listxml.Configuration
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
Condition = condition,
ConfLocation = [conflocation],
ConfSetting = [confsetting],
};
var analog = new Models.Listxml.Analog
{
Mask = "XXXXXX",
};
var port = new Models.Listxml.Port
{
Tag = "XXXXXX",
Analog = [analog],
};
var adjuster = new Models.Listxml.Adjuster
{
Name = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var driver = new 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 Models.Listxml.Feature
{
Type = "XXXXXX",
Status = "XXXXXX",
Overall = "XXXXXX",
};
var instance = new Models.Listxml.Instance
{
Name = "XXXXXX",
BriefName = "XXXXXX",
};
var extension = new Models.Listxml.Extension
{
Name = "XXXXXX",
};
var device = new Models.Listxml.Device
{
Type = "XXXXXX",
Tag = "XXXXXX",
FixedImage = "XXXXXX",
Mandatory = "XXXXXX",
Interface = "XXXXXX",
Instance = instance,
Extension = [extension],
};
var slotOption = new Models.Listxml.SlotOption
{
Name = "XXXXXX",
DevName = "XXXXXX",
Default = "XXXXXX",
};
var slot = new Models.Listxml.Slot
{
Name = "XXXXXX",
SlotOption = [slotOption],
};
var softwarelist = new Models.Listxml.SoftwareList
{
Tag = "XXXXXX",
Name = "XXXXXX",
Status = "XXXXXX",
Filter = "XXXXXX",
};
var ramoption = new Models.Listxml.RamOption
{
Name = "XXXXXX",
Default = "XXXXXX",
Content = "XXXXXX",
};
Models.Listxml.GameBase gameBase = game
? new Models.Listxml.Game()
: new 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 Models.Listxml.Mame
{
Build = "XXXXXX",
Debug = "XXXXXX",
MameConfig = "XXXXXX",
Game = [gameBase],
};
}
/// <summary>
/// Validate a GameBase
/// </summary>
private static void Validate(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(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(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(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(Models.Listxml.DeviceRef? deviceref)
{
Assert.NotNull(deviceref);
Assert.Equal("XXXXXX", deviceref.Name);
}
/// <summary>
/// Validate a Sample
/// </summary>
private static void Validate(Models.Listxml.Sample? sample)
{
Assert.NotNull(sample);
Assert.Equal("XXXXXX", sample.Name);
}
/// <summary>
/// Validate a Chip
/// </summary>
private static void Validate(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(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(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(Models.Listxml.Sound? sound)
{
Assert.NotNull(sound);
Assert.Equal("XXXXXX", sound.Channels);
}
/// <summary>
/// Validate a Input
/// </summary>
private static void Validate(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(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(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(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(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(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(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(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(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(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(Models.Listxml.Analog? analog)
{
Assert.NotNull(analog);
Assert.Equal("XXXXXX", analog.Mask);
}
/// <summary>
/// Validate a Adjuster
/// </summary>
private static void Validate(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(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(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(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(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(Models.Listxml.Extension? extension)
{
Assert.NotNull(extension);
Assert.Equal("XXXXXX", extension.Name);
}
/// <summary>
/// Validate a Slot
/// </summary>
private static void Validate(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(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(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(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,545 @@
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class LogiqxTests
{
[Fact]
public void RoundTripGameTest()
{
// Get the cross-model serializer
var serializer = new Serialization.CrossModel.Logiqx();
// Build the data
Models.Logiqx.Datafile df = Build(game: true);
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(df);
Assert.NotNull(metadata);
// Serialize back to original model
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);
var newGame = Assert.Single(newDf.Game);
Validate(newGame);
// TODO: Unsupported
Assert.Null(newDf.Dir);
}
[Fact]
public void RoundTripMachineTest()
{
// Get the cross-model serializer
var serializer = new Serialization.CrossModel.Logiqx();
// Build the data
Models.Logiqx.Datafile df = Build(game: false);
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(df);
Assert.NotNull(metadata);
// Serialize back to original model
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);
var newGame = Assert.Single(newDf.Game);
Validate(newGame);
// TODO: Unsupported
Assert.Null(newDf.Dir);
}
/// <summary>
/// Build model for serialization and deserialization
/// </summary>
private static Models.Logiqx.Datafile Build(bool game)
{
var clrmamepro = new Models.Logiqx.ClrMamePro
{
Header = "XXXXXX",
ForceMerging = "XXXXXX",
ForceNodump = "XXXXXX",
ForcePacking = "XXXXXX",
};
var romcenter = new Models.Logiqx.RomCenter
{
Plugin = "XXXXXX",
RomMode = "XXXXXX",
BiosMode = "XXXXXX",
SampleMode = "XXXXXX",
LockRomMode = "XXXXXX",
LockBiosMode = "XXXXXX",
LockSampleMode = "XXXXXX",
};
var header = new 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 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 Models.Logiqx.Release
{
Name = "XXXXXX",
Region = "XXXXXX",
Language = "XXXXXX",
Date = "XXXXXX",
Default = "XXXXXX",
};
var biosset = new Models.Logiqx.BiosSet
{
Name = "XXXXXX",
Description = "XXXXXX",
Default = "XXXXXX",
};
var rom = new Models.Logiqx.Rom
{
Name = "XXXXXX",
Size = "XXXXXX",
CRC = "XXXXXX",
MD5 = "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 Models.Logiqx.Disk
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Status = "XXXXXX",
Region = "XXXXXX",
};
var media = new Models.Logiqx.Media
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
SHA256 = "XXXXXX",
SpamSum = "XXXXXX",
};
var deviceRef = new Models.Logiqx.DeviceRef
{
Name = "XXXXXX",
};
var sample = new Models.Logiqx.Sample
{
Name = "XXXXXX",
};
var archive = new Models.Logiqx.Archive
{
Name = "XXXXXX",
};
var driver = new Models.Logiqx.Driver
{
Status = "XXXXXX",
Emulation = "XXXXXX",
Cocktail = "XXXXXX",
SaveState = "XXXXXX",
RequiresArtwork = "XXXXXX",
Unofficial = "XXXXXX",
NoSoundHardware = "XXXXXX",
Incomplete = "XXXXXX",
};
var softwarelist = new Models.Logiqx.SoftwareList
{
Tag = "XXXXXX",
Name = "XXXXXX",
Status = "XXXXXX",
Filter = "XXXXXX",
};
Models.Logiqx.GameBase gameBase = game
? new Models.Logiqx.Game()
: new 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 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(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(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(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(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(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(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(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(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.MD5);
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(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(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(Models.Logiqx.DeviceRef? deviceref)
{
Assert.NotNull(deviceref);
Assert.Equal("XXXXXX", deviceref.Name);
}
/// <summary>
/// Validate a Sample
/// </summary>
private static void Validate(Models.Logiqx.Sample? sample)
{
Assert.NotNull(sample);
Assert.Equal("XXXXXX", sample.Name);
}
/// <summary>
/// Validate a Archive
/// </summary>
private static void Validate(Models.Logiqx.Archive? archive)
{
Assert.NotNull(archive);
Assert.Equal("XXXXXX", archive.Name);
}
/// <summary>
/// Validate a Driver
/// </summary>
private static void Validate(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(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,872 @@
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class M1Tests
{
[Fact]
public void RoundTripGameTest()
{
// Get the cross-model serializer
var serializer = new Serialization.CrossModel.M1();
// Build the data
Models.Listxml.M1 m1 = Build(game: true);
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(m1);
Assert.NotNull(metadata);
// Serialize back to original model
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 Serialization.CrossModel.M1();
// Build the data
Models.Listxml.M1 m1 = Build(game: false);
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(m1);
Assert.NotNull(metadata);
// Serialize back to original model
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 Models.Listxml.M1 Build(bool game)
{
var biosset = new Models.Listxml.BiosSet
{
Name = "XXXXXX",
Description = "XXXXXX",
Default = "XXXXXX",
};
var rom = new 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 Models.Listxml.Disk
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Merge = "XXXXXX",
Region = "XXXXXX",
Index = "XXXXXX",
Writable = "XXXXXX",
Status = "XXXXXX",
Optional = "XXXXXX",
};
var deviceref = new Models.Listxml.DeviceRef
{
Name = "XXXXXX",
};
var sample = new Models.Listxml.Sample
{
Name = "XXXXXX",
};
var chip = new Models.Listxml.Chip
{
Name = "XXXXXX",
Tag = "XXXXXX",
Type = "XXXXXX",
SoundOnly = "XXXXXX",
Clock = "XXXXXX",
};
var display = new 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 Models.Listxml.Video
{
Screen = "XXXXXX",
Orientation = "XXXXXX",
Width = "XXXXXX",
Height = "XXXXXX",
AspectX = "XXXXXX",
AspectY = "XXXXXX",
Refresh = "XXXXXX",
};
var sound = new Models.Listxml.Sound
{
Channels = "XXXXXX",
};
var control = new 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 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 Models.Listxml.Condition
{
Tag = "XXXXXX",
Mask = "XXXXXX",
Relation = "XXXXXX",
Value = "XXXXXX",
};
var diplocation = new Models.Listxml.DipLocation
{
Name = "XXXXXX",
Number = "XXXXXX",
Inverted = "XXXXXX",
};
var dipvalue = new Models.Listxml.DipValue
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var dipswitch = new Models.Listxml.DipSwitch
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
Condition = condition,
DipLocation = [diplocation],
DipValue = [dipvalue],
};
var conflocation = new Models.Listxml.ConfLocation
{
Name = "XXXXXX",
Number = "XXXXXX",
Inverted = "XXXXXX",
};
var confsetting = new Models.Listxml.ConfSetting
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var configuration = new Models.Listxml.Configuration
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
Condition = condition,
ConfLocation = [conflocation],
ConfSetting = [confsetting],
};
var analog = new Models.Listxml.Analog
{
Mask = "XXXXXX",
};
var port = new Models.Listxml.Port
{
Tag = "XXXXXX",
Analog = [analog],
};
var adjuster = new Models.Listxml.Adjuster
{
Name = "XXXXXX",
Default = "XXXXXX",
Condition = condition,
};
var driver = new 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 Models.Listxml.Feature
{
Type = "XXXXXX",
Status = "XXXXXX",
Overall = "XXXXXX",
};
var instance = new Models.Listxml.Instance
{
Name = "XXXXXX",
BriefName = "XXXXXX",
};
var extension = new Models.Listxml.Extension
{
Name = "XXXXXX",
};
var device = new Models.Listxml.Device
{
Type = "XXXXXX",
Tag = "XXXXXX",
FixedImage = "XXXXXX",
Mandatory = "XXXXXX",
Interface = "XXXXXX",
Instance = instance,
Extension = [extension],
};
var slotOption = new Models.Listxml.SlotOption
{
Name = "XXXXXX",
DevName = "XXXXXX",
Default = "XXXXXX",
};
var slot = new Models.Listxml.Slot
{
Name = "XXXXXX",
SlotOption = [slotOption],
};
var softwarelist = new Models.Listxml.SoftwareList
{
Tag = "XXXXXX",
Name = "XXXXXX",
Status = "XXXXXX",
Filter = "XXXXXX",
};
var ramoption = new Models.Listxml.RamOption
{
Name = "XXXXXX",
Default = "XXXXXX",
Content = "XXXXXX",
};
Models.Listxml.GameBase gameBase = game
? new Models.Listxml.Game()
: new 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 Models.Listxml.M1
{
Version = "XXXXXX",
Game = [gameBase],
};
}
/// <summary>
/// Validate a GameBase
/// </summary>
private static void Validate(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(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(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(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(Models.Listxml.DeviceRef? deviceref)
{
Assert.NotNull(deviceref);
Assert.Equal("XXXXXX", deviceref.Name);
}
/// <summary>
/// Validate a Sample
/// </summary>
private static void Validate(Models.Listxml.Sample? sample)
{
Assert.NotNull(sample);
Assert.Equal("XXXXXX", sample.Name);
}
/// <summary>
/// Validate a Chip
/// </summary>
private static void Validate(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(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(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(Models.Listxml.Sound? sound)
{
Assert.NotNull(sound);
Assert.Equal("XXXXXX", sound.Channels);
}
/// <summary>
/// Validate a Input
/// </summary>
private static void Validate(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(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(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(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(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(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(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(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(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(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(Models.Listxml.Analog? analog)
{
Assert.NotNull(analog);
Assert.Equal("XXXXXX", analog.Mask);
}
/// <summary>
/// Validate a Adjuster
/// </summary>
private static void Validate(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(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(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(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(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(Models.Listxml.Extension? extension)
{
Assert.NotNull(extension);
Assert.Equal("XXXXXX", extension.Name);
}
/// <summary>
/// Validate a Slot
/// </summary>
private static void Validate(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(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(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(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,450 @@
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class OfflineListTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new Serialization.CrossModel.OfflineList();
// Build the data
Models.OfflineList.Dat dat = Build();
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(dat);
Assert.NotNull(metadata);
// Serialize back to original model
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 Models.OfflineList.Dat Build()
{
var infos = new Models.OfflineList.Infos
{
Title = new Models.OfflineList.Title
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
Location = new Models.OfflineList.Location
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
Publisher = new Models.OfflineList.Publisher
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
SourceRom = new Models.OfflineList.SourceRom
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
SaveType = new Models.OfflineList.SaveType
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
RomSize = new Models.OfflineList.RomSize
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
ReleaseNumber = new Models.OfflineList.ReleaseNumber
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
ImageNumber = new Models.OfflineList.ImageNumber
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
LanguageNumber = new Models.OfflineList.LanguageNumber
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
Comment = new Models.OfflineList.Comment
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
RomCRC = new Models.OfflineList.RomCRC
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
Im1CRC = new Models.OfflineList.Im1CRC
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
Im2CRC = new Models.OfflineList.Im2CRC
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
Languages = new Models.OfflineList.Languages
{
Visible = "XXXXXX",
InNamingOption = "XXXXXX",
Default = "XXXXXX",
},
};
var canopen = new Models.OfflineList.CanOpen
{
Extension = ["XXXXXX"],
};
var daturl = new Models.OfflineList.DatUrl
{
FileName = "XXXXXX",
Content = "XXXXXX",
};
var newdat = new Models.OfflineList.NewDat
{
DatVersionUrl = "XXXXXX",
DatUrl = daturl,
ImUrl = "XXXXXX",
};
var find = new Models.OfflineList.Find
{
Operation = "XXXXXX",
Value = "XXXXXX",
Content = "XXXXXX",
};
var to = new Models.OfflineList.To
{
Value = "XXXXXX",
Default = "XXXXXX",
Auto = "XXXXXX",
Find = [find],
};
var search = new Models.OfflineList.Search
{
To = [to],
};
var configuration = new 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 Models.OfflineList.FileRomCRC
{
Extension = "XXXXXX",
Content = "XXXXXX",
};
var files = new Models.OfflineList.Files
{
RomCRC = [fileromcrc],
};
var game = new 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 Models.OfflineList.Games
{
Game = [game],
};
var image = new Models.OfflineList.Image
{
X = "XXXXXX",
Y = "XXXXXX",
Width = "XXXXXX",
Height = "XXXXXX",
};
var images = new Models.OfflineList.Images
{
Width = "XXXXXX",
Height = "XXXXXX",
Image = [image],
};
var gui = new Models.OfflineList.GUI
{
Images = images,
};
return new Models.OfflineList.Dat
{
NoNamespaceSchemaLocation = "XXXXXX",
Configuration = configuration,
Games = games,
GUI = gui,
};
}
/// <summary>
/// Validate a Configuration
/// </summary>
private static void Validate(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(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(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(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(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(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(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(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(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(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(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(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(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(Models.OfflineList.GUI? gui)
{
Assert.NotNull(gui);
Validate(gui.Images);
}
/// <summary>
/// Validate a Images
/// </summary>
private static void Validate(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(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,156 @@
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class OpenMSXTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new Serialization.CrossModel.OpenMSX();
// Build the data
Models.OpenMSX.SoftwareDb sdb = Build();
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(sdb);
Assert.NotNull(metadata);
// Serialize back to original model
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 Models.OpenMSX.SoftwareDb Build()
{
var original = new Models.OpenMSX.Original
{
Value = "XXXXXX",
Content = "XXXXXX",
};
var rom = new Models.OpenMSX.Rom
{
Start = "XXXXXX",
Type = "XXXXXX",
Hash = "XXXXXX",
Remark = "XXXXXX",
};
var dump_rom = new Models.OpenMSX.Dump
{
Original = original,
Rom = rom,
};
var megarom = new Models.OpenMSX.MegaRom
{
Start = "XXXXXX",
Type = "XXXXXX",
Hash = "XXXXXX",
Remark = "XXXXXX",
};
var dump_megarom = new Models.OpenMSX.Dump
{
Original = original,
Rom = megarom,
};
var sccpluscart = new Models.OpenMSX.SCCPlusCart
{
Start = "XXXXXX",
Type = "XXXXXX",
Hash = "XXXXXX",
Remark = "XXXXXX",
};
var dump_sccpluscart = new Models.OpenMSX.Dump
{
Original = original,
Rom = sccpluscart,
};
var software = new Models.OpenMSX.Software
{
Title = "XXXXXX",
GenMSXID = "XXXXXX",
System = "XXXXXX",
Company = "XXXXXX",
Year = "XXXXXX",
Country = "XXXXXX",
Dump = [dump_rom, dump_megarom, dump_sccpluscart],
};
return new Models.OpenMSX.SoftwareDb
{
Timestamp = "XXXXXX",
Software = [software],
};
}
/// <summary>
/// Validate a Software
/// </summary>
private static void Validate(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(Models.OpenMSX.Dump? dump)
{
Assert.NotNull(dump);
Validate(dump.Original);
Validate(dump.Rom);
}
/// <summary>
/// Validate a Original
/// </summary>
private static void Validate(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(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,153 @@
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class RomCenterTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new Serialization.CrossModel.RomCenter();
// Build the data
Models.RomCenter.MetadataFile mf = Build();
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(mf);
Assert.NotNull(metadata);
// Serialize back to original model
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 Models.RomCenter.MetadataFile Build()
{
var credits = new Models.RomCenter.Credits
{
Author = "XXXXXX",
Version = "XXXXXX",
Email = "XXXXXX",
Homepage = "XXXXXX",
Url = "XXXXXX",
Date = "XXXXXX",
Comment = "XXXXXX",
};
var dat = new Models.RomCenter.Dat
{
Version = "XXXXXX",
Plugin = "XXXXXX",
Split = "XXXXXX",
Merge = "XXXXXX",
};
var emulator = new Models.RomCenter.Emulator
{
RefName = "XXXXXX",
Version = "XXXXXX",
};
var rom = new Models.RomCenter.Rom
{
ParentName = "XXXXXX",
ParentDescription = "XXXXXX",
GameName = "XXXXXX",
GameDescription = "XXXXXX",
RomName = "XXXXXX",
RomCRC = "XXXXXX",
RomSize = "XXXXXX",
RomOf = "XXXXXX",
MergeName = "XXXXXX",
};
var games = new Models.RomCenter.Games
{
Rom = [rom],
};
return new Models.RomCenter.MetadataFile
{
Credits = credits,
Dat = dat,
Emulator = emulator,
Games = games,
};
}
/// <summary>
/// Validate a Credits
/// </summary>
private static void Validate(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(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(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(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(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,182 @@
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class SeparatedValueTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new Serialization.CrossModel.SeparatedValue();
// Build the data
Models.SeparatedValue.MetadataFile mf = Build();
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(mf);
Assert.NotNull(metadata);
// Serialize back to original model
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 Models.SeparatedValue.MetadataFile Build()
{
string[] header = ["header"];
var disk = new 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 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 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 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(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(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(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,310 @@
using Xunit;
namespace SabreTools.Serialization.Test.CrossModel
{
public class SoftwareListTests
{
[Fact]
public void RoundTripTest()
{
// Get the cross-model serializer
var serializer = new Serialization.CrossModel.SoftwareList();
// Build the data
Models.SoftwareList.SoftwareList sl = Build();
// Serialize to generic model
Models.Metadata.MetadataFile? metadata = serializer.Serialize(sl);
Assert.NotNull(metadata);
// Serialize back to original model
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 Models.SoftwareList.SoftwareList Build()
{
var info = new Models.SoftwareList.Info
{
Name = "XXXXXX",
Value = "XXXXXX",
};
var sharedfeat = new Models.SoftwareList.SharedFeat
{
Name = "XXXXXX",
Value = "XXXXXX",
};
var feature = new Models.SoftwareList.Feature
{
Name = "XXXXXX",
Value = "XXXXXX",
};
var rom = new Models.SoftwareList.Rom
{
Name = "XXXXXX",
Size = "XXXXXX",
Length = "XXXXXX",
CRC = "XXXXXX",
SHA1 = "XXXXXX",
Offset = "XXXXXX",
Value = "XXXXXX",
Status = "XXXXXX",
LoadFlag = "XXXXXX",
};
var dataarea = new Models.SoftwareList.DataArea
{
Name = "XXXXXX",
Size = "XXXXXX",
Width = "XXXXXX",
Endianness = "XXXXXX",
Rom = [rom],
};
var disk = new Models.SoftwareList.Disk
{
Name = "XXXXXX",
MD5 = "XXXXXX",
SHA1 = "XXXXXX",
Status = "XXXXXX",
Writeable = "XXXXXX",
};
var diskarea = new Models.SoftwareList.DiskArea
{
Name = "XXXXXX",
Disk = [disk],
};
var dipvalue = new Models.SoftwareList.DipValue
{
Name = "XXXXXX",
Value = "XXXXXX",
Default = "XXXXXX",
};
var dipswitch = new Models.SoftwareList.DipSwitch
{
Name = "XXXXXX",
Tag = "XXXXXX",
Mask = "XXXXXX",
DipValue = [dipvalue],
};
var part = new Models.SoftwareList.Part
{
Name = "XXXXXX",
Interface = "XXXXXX",
Feature = [feature],
DataArea = [dataarea],
DiskArea = [diskarea],
DipSwitch = [dipswitch],
};
var software = new 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 Models.SoftwareList.SoftwareList
{
Name = "XXXXXX",
Description = "XXXXXX",
Notes = "XXXXXX",
Software = [software],
};
}
/// <summary>
/// Validate a Software
/// </summary>
private static void Validate(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(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(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(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(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(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(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(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(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(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(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.Deserializers;
using Xunit;
namespace SabreTools.Serialization.Test.Deserializers
{
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,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Deserializers;
using Xunit;
namespace SabreTools.Serialization.Test.Deserializers
{
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,241 @@
using System;
using System.IO;
using System.Linq;
using SabreTools.Serialization.Deserializers;
using Xunit;
namespace SabreTools.Serialization.Test.Deserializers
{
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 Serialization.Deserializers.ArchiveDotOrg();
var serializer = new Serialization.Serializers.ArchiveDotOrg();
// Build the data
Models.ArchiveDotOrg.Files files = Build();
// Serialize to stream
Stream? actual = serializer.Serialize(files);
Assert.NotNull(actual);
// Serialize back to original model
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 Models.ArchiveDotOrg.Files Build()
{
var file = new 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 Models.ArchiveDotOrg.Files
{
File = [file]
};
}
/// <summary>
/// Validate a File
/// </summary>
private static void Validate(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.Deserializers;
using Xunit;
namespace SabreTools.Serialization.Test.Deserializers
{
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 Serialization.Deserializers.AttractMode();
var serializer = new Serialization.Serializers.AttractMode();
// Build the data
Models.AttractMode.MetadataFile mf = Build();
// Serialize to stream
Stream? actual = serializer.Serialize(mf, longHeader: false);
Assert.NotNull(actual);
// Serialize back to original model
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 Serialization.Deserializers.AttractMode();
var serializer = new Serialization.Serializers.AttractMode();
// Build the data
Models.AttractMode.MetadataFile mf = Build();
// Serialize to stream
Stream? actual = serializer.Serialize(mf, longHeader: true);
Assert.NotNull(actual);
// Serialize back to original model
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 Models.AttractMode.MetadataFile Build()
{
string[] header = ["header"];
var row = new 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 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(Serialization.Serializers.AttractMode.HeaderArrayWithRomname.SequenceEqual(header));
else
Assert.True(Serialization.Serializers.AttractMode.HeaderArrayWithoutRomname.SequenceEqual(header));
}
/// <summary>
/// Validate a Row
/// </summary>
private static void Validate(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.Deserializers;
using Xunit;
namespace SabreTools.Serialization.Test.Deserializers
{
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.Deserializers;
using Xunit;
namespace SabreTools.Serialization.Test.Deserializers
{
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.Deserializers;
using Xunit;
namespace SabreTools.Serialization.Test.Deserializers
{
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.Deserializers;
using Xunit;
namespace SabreTools.Serialization.Test.Deserializers
{
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.Deserializers;
using Xunit;
namespace SabreTools.Serialization.Test.Deserializers
{
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.Deserializers;
using Xunit;
namespace SabreTools.Serialization.Test.Deserializers
{
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);
}
}
}

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