Compare commits

...

117 Commits

Author SHA1 Message Date
Matt Nadareski
9389797448 Bump version 2026-03-15 20:23:35 -04:00
Matt Nadareski
8b7112d12f uint is more correct 2026-03-14 20:51:22 -04:00
Matt Nadareski
4add8f3e64 Update TODO for accuracy 2026-03-14 11:52:07 -04:00
Matt Nadareski
9e6c6af985 Fix missing section case, should never be hit 2026-03-14 11:24:29 -04:00
Matt Nadareski
c82b56d084 Better clarify comment 2026-03-14 11:23:29 -04:00
Matt Nadareski
ea4c51b9f2 Use first nonzero-sized section as overlay address basis 2026-03-14 11:20:40 -04:00
HeroponRikiBestest
463c3ba50d Accurately get OverlayAddress for UPX-compressed executables (#67)
* Add alternate path for OverlayAddress for upx-compressed executables, for benefit of extractions that need an accurate overlay address.

* Use SectionNames

* Update SabreTools.Serialization/Wrappers/PortableExecutable.cs

---------

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

* Fix import alphebetization

* Fixes.

* first part of first attempt at a model

* Reimplement Sku Sis parsing

* First round of fixes

* Make sure stream isn't closed

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

* Code works

* Remove TODOs

* First round of fixes.

* use constants

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

* Remove todo pre PR

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

* Use private helper class

* Remove comment

* Add missing summaries

* Don't use create pattern

* Remove removed variable summary

* Reduce what needs to be passed in

* Further reduce what needs to be passed in

* These didn't get tabbed for some reason

* First round of fixes.

* Second round of changes

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

* WIP 2

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

* continued blocks my behated

* Pre-major-testing

* Forgot to add summaries

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

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

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

* Skip unsupported compression types before opening filestream.

* Reenable non-start cab skipping

* TODO so i don't forget

* TODO so I don't forget

* iterate on continued block correctly.

* Handle incomplete extraction better

* Remove TODOs to ready for PR comments

* Missed one

* Some minor fixes before rewriting everything

* Next round of fixes.

* Next set of fixes

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

* initial

* Fixed

* Move function to proper location, clear memory better

* work so far

* more

* more work

* No more per file seeking

* Finished work for now.

* First round of fixes.

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

* Fix logic error

* Continues

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

* Fix

* fix2

* fix3

* fix4

* Invert multi extent final extent logic
2025-12-02 07:31:31 -05:00
Matt Nadareski
1096232f9d Update GC libraries 2025-11-30 19:40:35 -05:00
Matt Nadareski
4b39ee8d00 Add CRC-16 and CRC-64 dat support 2025-11-29 10:11:05 -05:00
Matt Nadareski
27a9b12bbf Bump version 2025-11-25 07:45:09 -05:00
Matt Nadareski
11319c3341 Update GC.SharpCompress 2025-11-25 07:44:29 -05:00
Matt Nadareski
4de061e0d1 Bump version 2025-11-24 08:59:19 -05:00
Matt Nadareski
258e894c30 Update GC.SharpCompress 2025-11-23 19:59:28 -05:00
Matt Nadareski
8658eaf4e0 Format GHA definitions 2025-11-17 08:39:16 -05:00
Matt Nadareski
6d341abc75 Fix comment about CFB 2025-11-17 08:33:00 -05:00
Matt Nadareski
4821d63b4a Off-by-one spacing 2025-11-15 09:10:34 -05:00
Matt Nadareski
0617bf3170 Process all folders in all MS-CAB files in a set (fixes #43) 2025-11-15 09:00:28 -05:00
Matt Nadareski
425d13a2ac Fix inconsistencies in IS-CAB 2025-11-14 23:21:04 -05:00
Matt Nadareski
8a1e90f537 Reduce unnecessary casts 2025-11-14 21:33:55 -05:00
Matt Nadareski
ddc00948ed Remove red herring zlib code 2025-11-14 21:08:55 -05:00
Matt Nadareski
c96ee81f06 Simplify fixed statements 2025-11-14 20:36:46 -05:00
631 changed files with 18766 additions and 8021 deletions

167
.editorconfig Normal file
View File

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

View File

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

View File

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

10
.vscode/launch.json vendored
View File

@@ -1,9 +1,9 @@
{ {
// Use IntelliSense to find out which attributes exist for C# debugging // Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes // Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": ".NET Core Launch (ExtractionTool)", "name": ".NET Core Launch (ExtractionTool)",
"type": "coreclr", "type": "coreclr",

View File

@@ -10,7 +10,7 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings> <SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>2.1.0</Version> <Version>2.3.0</Version>
</PropertyGroup> </PropertyGroup>
<!-- Support All Frameworks --> <!-- Support All Frameworks -->
@@ -49,8 +49,8 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="SabreTools.CommandLine" Version="[1.4.0]" /> <PackageReference Include="SabreTools.CommandLine" Version="[1.4.0]" />
<PackageReference Include="SabreTools.IO" Version="[1.9.0]" /> <PackageReference Include="SabreTools.IO" Version="[1.9.1]" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="10.0.0" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" /> <PackageReference Include="System.Text.Encoding.CodePages" Version="10.0.3" Condition="!$(TargetFramework.StartsWith(`net2`)) AND !$(TargetFramework.StartsWith(`net3`)) AND !$(TargetFramework.StartsWith(`net40`)) AND !$(TargetFramework.StartsWith(`net452`))" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -150,6 +150,16 @@ namespace ExtractionTool.Features
sz.Extract(OutputPath, Debug); sz.Extract(OutputPath, Debug);
break; break;
// Atari 7800 Cart
case Atari7800Cart a7800:
a7800.Extract(OutputPath, Debug);
break;
// Atari Lynx Cart
case AtariLynxCart lynx:
lynx.Extract(OutputPath, Debug);
break;
// BFPK archive // BFPK archive
case BFPK bfpk: case BFPK bfpk:
bfpk.Extract(OutputPath, Debug); bfpk.Extract(OutputPath, Debug);
@@ -175,6 +185,11 @@ namespace ExtractionTool.Features
cfb.Extract(OutputPath, Debug); cfb.Extract(OutputPath, Debug);
break; break;
// fwNES FDS file
case FDS fds:
fds.Extract(OutputPath, Debug);
break;
// GCF // GCF
case GCF gcf: case GCF gcf:
gcf.Extract(OutputPath, Debug); gcf.Extract(OutputPath, Debug);
@@ -230,6 +245,11 @@ namespace ExtractionTool.Features
nex.Extract(OutputPath, Debug); nex.Extract(OutputPath, Debug);
break; break;
// NES Cart
case NESCart nes:
nes.Extract(OutputPath, Debug);
break;
// PAK // PAK
case PAK pak: case PAK pak:
pak.Extract(OutputPath, Debug); pak.Extract(OutputPath, Debug);

View File

@@ -20,7 +20,7 @@ namespace ExtractionTool
var commandSet = CreateCommands(mainFeature); var commandSet = CreateCommands(mainFeature);
// If we have no args, show the help and quit // If we have no args, show the help and quit
if (args == null || args.Length == 0) if (args is null || args.Length == 0)
{ {
commandSet.OutputAllHelp(); commandSet.OutputAllHelp();
return; return;

View File

@@ -142,7 +142,7 @@ namespace InfoPrint.Features
if (Hash) if (Hash)
{ {
var hashBuilder = PrintHashInfo(file); var hashBuilder = PrintHashInfo(file);
if (hashBuilder != null) if (hashBuilder is not null)
{ {
// Create the output data // Create the output data
string hashData = hashBuilder.ToString(); string hashData = hashBuilder.ToString();
@@ -158,8 +158,8 @@ namespace InfoPrint.Features
{ {
using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
// Read the first 8 bytes // Read the first 16 bytes
byte[] magic = stream.PeekBytes(8); byte[] magic = stream.PeekBytes(16);
// Get the file type // Get the file type
string extension = Path.GetExtension(file).TrimStart('.'); string extension = Path.GetExtension(file).TrimStart('.');
@@ -172,7 +172,7 @@ namespace InfoPrint.Features
var wrapper = WrapperFactory.CreateWrapper(ft, stream); var wrapper = WrapperFactory.CreateWrapper(ft, stream);
// If we don't have a wrapper // If we don't have a wrapper
if (wrapper == null) if (wrapper is null)
{ {
Console.WriteLine($"Either {ft} is not supported or something went wrong during parsing!"); Console.WriteLine($"Either {ft} is not supported or something went wrong during parsing!");
Console.WriteLine(); Console.WriteLine();
@@ -195,7 +195,7 @@ namespace InfoPrint.Features
// Create the output data // Create the output data
var builder = wrapper.ExportStringBuilder(); var builder = wrapper.ExportStringBuilder();
if (builder == null) if (builder is null)
{ {
Console.WriteLine("No item information could be generated"); Console.WriteLine("No item information could be generated");
return; return;
@@ -235,7 +235,7 @@ namespace InfoPrint.Features
{ {
// Get all file hashes for flexibility // Get all file hashes for flexibility
var hashes = HashTool.GetFileHashes(file); var hashes = HashTool.GetFileHashes(file);
if (hashes == null) if (hashes is null)
{ {
if (Debug) Console.WriteLine($"Hashes for {file} could not be retrieved"); if (Debug) Console.WriteLine($"Hashes for {file} could not be retrieved");
return null; return null;
@@ -243,27 +243,29 @@ namespace InfoPrint.Features
// Output subset of available hashes // Output subset of available hashes
var builder = new StringBuilder(); var builder = new StringBuilder();
if (hashes.TryGetValue(HashType.CRC16, out string? crc16) && crc16 != null) if (hashes.TryGetValue(HashType.CRC16, out string? crc16) && crc16 is not null)
builder.AppendLine($"CRC-16 checksum: {crc16}"); builder.AppendLine($"CRC-16 checksum: {crc16}");
if (hashes.TryGetValue(HashType.CRC32, out string? crc32) && crc32 != null) if (hashes.TryGetValue(HashType.CRC32, out string? crc32) && crc32 is not null)
builder.AppendLine($"CRC-32 checksum: {crc32}"); builder.AppendLine($"CRC-32 checksum: {crc32}");
if (hashes.TryGetValue(HashType.MD2, out string? md2) && md2 != null) if (hashes.TryGetValue(HashType.CRC64, out string? crc64) && crc64 is not null)
builder.AppendLine($"CRC-64 checksum: {crc64}");
if (hashes.TryGetValue(HashType.MD2, out string? md2) && md2 is not null)
builder.AppendLine($"MD2 hash: {md2}"); builder.AppendLine($"MD2 hash: {md2}");
if (hashes.TryGetValue(HashType.MD4, out string? md4) && md4 != null) if (hashes.TryGetValue(HashType.MD4, out string? md4) && md4 is not null)
builder.AppendLine($"MD4 hash: {md4}"); builder.AppendLine($"MD4 hash: {md4}");
if (hashes.TryGetValue(HashType.MD5, out string? md5) && md5 != null) if (hashes.TryGetValue(HashType.MD5, out string? md5) && md5 is not null)
builder.AppendLine($"MD5 hash: {md5}"); builder.AppendLine($"MD5 hash: {md5}");
if (hashes.TryGetValue(HashType.RIPEMD128, out string? ripemd128) && ripemd128 != null) if (hashes.TryGetValue(HashType.RIPEMD128, out string? ripemd128) && ripemd128 is not null)
builder.AppendLine($"RIPEMD-128 hash: {ripemd128}"); builder.AppendLine($"RIPEMD-128 hash: {ripemd128}");
if (hashes.TryGetValue(HashType.RIPEMD160, out string? ripemd160) && ripemd160 != null) if (hashes.TryGetValue(HashType.RIPEMD160, out string? ripemd160) && ripemd160 is not null)
builder.AppendLine($"RIPEMD-160 hash: {ripemd160}"); builder.AppendLine($"RIPEMD-160 hash: {ripemd160}");
if (hashes.TryGetValue(HashType.SHA1, out string? sha1) && sha1 != null) if (hashes.TryGetValue(HashType.SHA1, out string? sha1) && sha1 is not null)
builder.AppendLine($"SHA-1 hash: {sha1}"); builder.AppendLine($"SHA-1 hash: {sha1}");
if (hashes.TryGetValue(HashType.SHA256, out string? sha256) && sha256 != null) if (hashes.TryGetValue(HashType.SHA256, out string? sha256) && sha256 is not null)
builder.AppendLine($"SHA-256 hash: {sha256}"); builder.AppendLine($"SHA-256 hash: {sha256}");
if (hashes.TryGetValue(HashType.SHA384, out string? sha384) && sha384 != null) if (hashes.TryGetValue(HashType.SHA384, out string? sha384) && sha384 is not null)
builder.AppendLine($"SHA-384 hash: {sha384}"); builder.AppendLine($"SHA-384 hash: {sha384}");
if (hashes.TryGetValue(HashType.SHA512, out string? sha512) && sha512 != null) if (hashes.TryGetValue(HashType.SHA512, out string? sha512) && sha512 is not null)
builder.AppendLine($"SHA-512 hash: {sha512}"); builder.AppendLine($"SHA-512 hash: {sha512}");
return builder; return builder;

View File

@@ -10,7 +10,7 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings> <SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors> <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>2.1.0</Version> <Version>2.3.0</Version>
</PropertyGroup> </PropertyGroup>
<!-- Support All Frameworks --> <!-- Support All Frameworks -->
@@ -33,8 +33,8 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="SabreTools.CommandLine" Version="[1.4.0]" /> <PackageReference Include="SabreTools.CommandLine" Version="[1.4.0]" />
<PackageReference Include="SabreTools.Hashing" Version="[1.6.0]" /> <PackageReference Include="SabreTools.Hashing" Version="[1.6.1]" />
<PackageReference Include="SabreTools.IO" Version="[1.9.0]" /> <PackageReference Include="SabreTools.IO" Version="[1.9.1]" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -15,7 +15,7 @@ namespace InfoPrint
var commandSet = CreateCommands(mainFeature); var commandSet = CreateCommands(mainFeature);
// If we have no args, show the help and quit // If we have no args, show the help and quit
if (args == null || args.Length == 0) if (args is null || args.Length == 0)
{ {
commandSet.OutputAllHelp(); commandSet.OutputAllHelp();
return; return;

View File

@@ -53,9 +53,12 @@ Options:
| Format Name | Notes | | Format Name | Notes |
| --- | --- | | --- | --- |
| 7-zip archive | .NET Framework 4.6.2 and greater | | 7-zip archive | .NET Framework 4.6.2 and greater |
| Atari 7800 (A78) Cart Image | Header and ROM data |
| Atari Lynx (LNX) Cart Image | Header and ROM data |
| BFPK custom archive format | | | BFPK custom archive format | |
| bzip2 archive | .NET Framework 4.6.2 and greater | | bzip2 archive | .NET Framework 4.6.2 and greater |
| Compound File Binary (CFB) | Only CFB common pieces extractable. .NET Framework 4.0 and greater | | Compound File Binary (CFB) | Only CFB common pieces extractable |
| fwNES FDS file | Header and disk data |
| gzip archive | | | gzip archive | |
| Half-Life Game Cache File (GCF) | | | Half-Life Game Cache File (GCF) | |
| Half-Life Level (BSP) | | | Half-Life Level (BSP) | |
@@ -68,6 +71,7 @@ Options:
| Microsoft LZ-compressed files | KWAJ, QBasic, and SZDD variants | | Microsoft LZ-compressed files | KWAJ, QBasic, and SZDD variants |
| MoPaQ game data archive (MPQ) | Windows only | | MoPaQ game data archive (MPQ) | Windows only |
| New Exectuable | Embedded archives and executables in the overlay and Wise installer | | New Exectuable | Embedded archives and executables in the overlay and Wise installer |
| Nintendo Entertainment System (NES) Cart Image | Header, Trainer data, PRG-ROM, CHR-ROM, Unheadered ROM, and PlayChoice-10 INST-ROM |
| NovaLogic Game Archive Format (PFF) | | | NovaLogic Game Archive Format (PFF) | |
| PKZIP and derived files (ZIP, etc.) | .NET Framework 4.6.2 and greater | | PKZIP and derived files (ZIP, etc.) | .NET Framework 4.6.2 and greater |
| Portable Executable | Embedded archives and executables in the resources and overlay, CExe-packed data, SFX archives (7-zip, PKZIP, and RAR), and Wise installer | | Portable Executable | Embedded archives and executables in the resources and overlay, CExe-packed data, SFX archives (7-zip, PKZIP, and RAR), and Wise installer |

View File

@@ -15,7 +15,7 @@ namespace SabreTools.Serialization.Test.CrossModel
Data.Models.ArchiveDotOrg.Files files = Build(); Data.Models.ArchiveDotOrg.Files files = Build();
// Serialize to generic model // Serialize to generic model
SabreTools.Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(files); Data.Models.Metadata.MetadataFile? metadata = serializer.Serialize(files);
Assert.NotNull(metadata); Assert.NotNull(metadata);
// Serialize back to original model // Serialize back to original model

View File

@@ -27,6 +27,7 @@ namespace SabreTools.Serialization.Test.CrossModel
Assert.NotNull(newMf.Game); Assert.NotNull(newMf.Game);
var newGame = Assert.Single(newMf.Game); var newGame = Assert.Single(newMf.Game);
Validate(newGame); Validate(newGame);
Validate(newMf.Info);
} }
[Fact] [Fact]
@@ -51,6 +52,7 @@ namespace SabreTools.Serialization.Test.CrossModel
Assert.NotNull(newMf.Game); Assert.NotNull(newMf.Game);
var newGame = Assert.Single(newMf.Game); var newGame = Assert.Single(newMf.Game);
Validate(newGame); Validate(newGame);
Validate(newMf.Info);
} }
/// <summary> /// <summary>
@@ -97,7 +99,9 @@ namespace SabreTools.Serialization.Test.CrossModel
{ {
Name = "XXXXXX", Name = "XXXXXX",
Size = "XXXXXX", Size = "XXXXXX",
CRC16 = "XXXXXX",
CRC = "XXXXXX", CRC = "XXXXXX",
CRC64 = "XXXXXX",
MD2 = "XXXXXX", MD2 = "XXXXXX",
MD4 = "XXXXXX", MD4 = "XXXXXX",
MD5 = "XXXXXX", MD5 = "XXXXXX",
@@ -207,6 +211,7 @@ namespace SabreTools.Serialization.Test.CrossModel
: new Data.Models.ClrMamePro.Machine(); : new Data.Models.ClrMamePro.Machine();
gameBase.Name = "XXXXXX"; gameBase.Name = "XXXXXX";
gameBase.Description = "XXXXXX"; gameBase.Description = "XXXXXX";
gameBase.DriverStatus = "XXXXXX";
gameBase.Year = "XXXXXX"; gameBase.Year = "XXXXXX";
gameBase.Manufacturer = "XXXXXX"; gameBase.Manufacturer = "XXXXXX";
gameBase.Category = "XXXXXX"; gameBase.Category = "XXXXXX";
@@ -227,10 +232,16 @@ namespace SabreTools.Serialization.Test.CrossModel
gameBase.DipSwitch = [dipswitch]; gameBase.DipSwitch = [dipswitch];
gameBase.Driver = driver; gameBase.Driver = driver;
var info = new Data.Models.ClrMamePro.Info
{
Source = ["XXXXXX"],
};
return new Data.Models.ClrMamePro.MetadataFile return new Data.Models.ClrMamePro.MetadataFile
{ {
ClrMamePro = cmp, ClrMamePro = cmp,
Game = [gameBase], Game = [gameBase],
Info = info,
}; };
} }
@@ -265,6 +276,7 @@ namespace SabreTools.Serialization.Test.CrossModel
Assert.NotNull(gb); Assert.NotNull(gb);
Assert.Equal("XXXXXX", gb.Name); Assert.Equal("XXXXXX", gb.Name);
Assert.Equal("XXXXXX", gb.Description); Assert.Equal("XXXXXX", gb.Description);
// Assert.Equal("XXXXXX", gb.DriverStatus); // TODO: Needs metadata mapping
Assert.Equal("XXXXXX", gb.Year); Assert.Equal("XXXXXX", gb.Year);
Assert.Equal("XXXXXX", gb.Manufacturer); Assert.Equal("XXXXXX", gb.Manufacturer);
Assert.Equal("XXXXXX", gb.Category); Assert.Equal("XXXXXX", gb.Category);
@@ -350,7 +362,9 @@ namespace SabreTools.Serialization.Test.CrossModel
Assert.NotNull(rom); Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.Name); Assert.Equal("XXXXXX", rom.Name);
Assert.Equal("XXXXXX", rom.Size); Assert.Equal("XXXXXX", rom.Size);
Assert.Equal("XXXXXX", rom.CRC16);
Assert.Equal("XXXXXX", rom.CRC); Assert.Equal("XXXXXX", rom.CRC);
Assert.Equal("XXXXXX", rom.CRC64);
Assert.Equal("XXXXXX", rom.MD2); Assert.Equal("XXXXXX", rom.MD2);
Assert.Equal("XXXXXX", rom.MD4); Assert.Equal("XXXXXX", rom.MD4);
Assert.Equal("XXXXXX", rom.MD5); Assert.Equal("XXXXXX", rom.MD5);
@@ -497,5 +511,16 @@ namespace SabreTools.Serialization.Test.CrossModel
Assert.Equal("XXXXXX", driver.PaletteSize); Assert.Equal("XXXXXX", driver.PaletteSize);
Assert.Equal("XXXXXX", driver.Blit); Assert.Equal("XXXXXX", driver.Blit);
} }
/// <summary>
/// Validate a ClrMamePro
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Info? info)
{
Assert.NotNull(info);
Assert.NotNull(info.Source);
string source = Assert.Single(info.Source);
Assert.Equal("XXXXXX", source);
}
} }
} }

View File

@@ -219,6 +219,7 @@ namespace SabreTools.Serialization.Test.CrossModel
/// </summary> /// </summary>
private static Data.Models.Hashfile.Hashfile Build(HashType hashType) private static Data.Models.Hashfile.Hashfile Build(HashType hashType)
{ {
#pragma warning disable IDE0072
return hashType switch return hashType switch
{ {
HashType.CRC32 => new Data.Models.Hashfile.Hashfile { SFV = [new Data.Models.Hashfile.SFV { File = "XXXXXX", Hash = "XXXXXX" }] }, HashType.CRC32 => new Data.Models.Hashfile.Hashfile { SFV = [new Data.Models.Hashfile.SFV { File = "XXXXXX", Hash = "XXXXXX" }] },
@@ -230,8 +231,9 @@ namespace SabreTools.Serialization.Test.CrossModel
HashType.SHA384 => new Data.Models.Hashfile.Hashfile { SHA384 = [new Data.Models.Hashfile.SHA384 { Hash = "XXXXXX", File = "XXXXXX" }] }, HashType.SHA384 => new Data.Models.Hashfile.Hashfile { SHA384 = [new Data.Models.Hashfile.SHA384 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SHA512 => new Data.Models.Hashfile.Hashfile { SHA512 = [new Data.Models.Hashfile.SHA512 { Hash = "XXXXXX", File = "XXXXXX" }] }, HashType.SHA512 => new Data.Models.Hashfile.Hashfile { SHA512 = [new Data.Models.Hashfile.SHA512 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SpamSum => new Data.Models.Hashfile.Hashfile { SpamSum = [new Data.Models.Hashfile.SpamSum { Hash = "XXXXXX", File = "XXXXXX" }] }, HashType.SpamSum => new Data.Models.Hashfile.Hashfile { SpamSum = [new Data.Models.Hashfile.SpamSum { Hash = "XXXXXX", File = "XXXXXX" }] },
_ => throw new ArgumentOutOfRangeException(), _ => throw new ArgumentOutOfRangeException(nameof(hashType)),
}; };
#pragma warning restore IDE0072
} }
/// <summary> /// <summary>

View File

@@ -150,7 +150,9 @@ namespace SabreTools.Serialization.Test.CrossModel
{ {
Name = "XXXXXX", Name = "XXXXXX",
Size = "XXXXXX", Size = "XXXXXX",
CRC16 = "XXXXXX",
CRC = "XXXXXX", CRC = "XXXXXX",
CRC64 = "XXXXXX",
MD2 = "XXXXXX", MD2 = "XXXXXX",
MD4 = "XXXXXX", MD4 = "XXXXXX",
MD5 = "XXXXXX", MD5 = "XXXXXX",
@@ -464,7 +466,9 @@ namespace SabreTools.Serialization.Test.CrossModel
Assert.NotNull(rom); Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.Name); Assert.Equal("XXXXXX", rom.Name);
Assert.Equal("XXXXXX", rom.Size); Assert.Equal("XXXXXX", rom.Size);
Assert.Equal("XXXXXX", rom.CRC16);
Assert.Equal("XXXXXX", rom.CRC); Assert.Equal("XXXXXX", rom.CRC);
Assert.Equal("XXXXXX", rom.CRC64);
Assert.Equal("XXXXXX", rom.MD2); Assert.Equal("XXXXXX", rom.MD2);
Assert.Equal("XXXXXX", rom.MD4); Assert.Equal("XXXXXX", rom.MD4);
Assert.Equal("XXXXXX", rom.MD5); Assert.Equal("XXXXXX", rom.MD5);

View File

@@ -3,6 +3,7 @@ using SabreTools.Data.Extensions;
using SabreTools.Data.Models.ASN1; using SabreTools.Data.Models.ASN1;
using Xunit; using Xunit;
#pragma warning disable IDE0230 // Use UTF-8 string literal
namespace SabreTools.Serialization.Test.Extensions namespace SabreTools.Serialization.Test.Extensions
{ {
public class TypeLengthValueTests public class TypeLengthValueTests
@@ -31,7 +32,7 @@ namespace SabreTools.Serialization.Test.Extensions
public void Format_InvalidConstructed() public void Format_InvalidConstructed()
{ {
string expected = "Type: V_ASN1_OBJECT, V_ASN1_CONSTRUCTED, Length: 1, Value: [INVALID DATA TYPE]"; string expected = "Type: V_ASN1_OBJECT, V_ASN1_CONSTRUCTED, Length: 1, Value: [INVALID DATA TYPE]";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_OBJECT | ASN1Type.V_ASN1_CONSTRUCTED, Length = 1, Value = (object?)false }; var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_OBJECT | ASN1Type.V_ASN1_CONSTRUCTED, Length = 1, Value = false };
string actual = tlv.Format(); string actual = tlv.Format();
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
} }
@@ -50,7 +51,7 @@ namespace SabreTools.Serialization.Test.Extensions
public void Format_InvalidDataType() public void Format_InvalidDataType()
{ {
string expected = "Type: V_ASN1_OBJECT, Length: 1, Value: [INVALID DATA TYPE]"; string expected = "Type: V_ASN1_OBJECT, Length: 1, Value: [INVALID DATA TYPE]";
var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_OBJECT, Length = 1, Value = (object?)false }; var tlv = new Data.Models.ASN1.TypeLengthValue { Type = ASN1Type.V_ASN1_OBJECT, Length = 1, Value = false };
string actual = tlv.Format(); string actual = tlv.Format();
Assert.Equal(expected, actual); Assert.Equal(expected, actual);
} }

View File

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

View File

@@ -75,7 +75,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new ArchiveDotOrg(); var deserializer = new ArchiveDotOrg();
var serializer = new SabreTools.Serialization.Writers.ArchiveDotOrg(); var serializer = new Serialization.Writers.ArchiveDotOrg();
// Build the data // Build the data
Data.Models.ArchiveDotOrg.Files files = Build(); Data.Models.ArchiveDotOrg.Files files = Build();

View File

@@ -5,14 +5,14 @@ using Xunit;
namespace SabreTools.Serialization.Test.Readers namespace SabreTools.Serialization.Test.Readers
{ {
public class InstallShieldExecutableFileTests public class Atari7800CartTests
{ {
[Fact] [Fact]
public void NullArray_Null() public void NullArray_Null()
{ {
byte[]? data = null; byte[]? data = null;
int offset = 0; int offset = 0;
var deserializer = new InstallShieldExecutableFile(); var deserializer = new Atari7800Cart();
var actual = deserializer.Deserialize(data, offset); var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual); Assert.Null(actual);
@@ -23,7 +23,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
byte[]? data = []; byte[]? data = [];
int offset = 0; int offset = 0;
var deserializer = new InstallShieldExecutableFile(); var deserializer = new Atari7800Cart();
var actual = deserializer.Deserialize(data, offset); var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual); Assert.Null(actual);
@@ -34,7 +34,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)]; byte[]? data = [.. Enumerable.Repeat<byte>(0xFF, 1024)];
int offset = 0; int offset = 0;
var deserializer = new InstallShieldExecutableFile(); var deserializer = new Atari7800Cart();
var actual = deserializer.Deserialize(data, offset); var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual); Assert.Null(actual);
@@ -44,7 +44,7 @@ namespace SabreTools.Serialization.Test.Readers
public void NullStream_Null() public void NullStream_Null()
{ {
Stream? data = null; Stream? data = null;
var deserializer = new InstallShieldExecutableFile(); var deserializer = new Atari7800Cart();
var actual = deserializer.Deserialize(data); var actual = deserializer.Deserialize(data);
Assert.Null(actual); Assert.Null(actual);
@@ -54,7 +54,7 @@ namespace SabreTools.Serialization.Test.Readers
public void EmptyStream_Null() public void EmptyStream_Null()
{ {
Stream? data = new MemoryStream([]); Stream? data = new MemoryStream([]);
var deserializer = new InstallShieldExecutableFile(); var deserializer = new Atari7800Cart();
var actual = deserializer.Deserialize(data); var actual = deserializer.Deserialize(data);
Assert.Null(actual); Assert.Null(actual);
@@ -64,7 +64,7 @@ namespace SabreTools.Serialization.Test.Readers
public void InvalidStream_Null() public void InvalidStream_Null()
{ {
Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]); Stream? data = new MemoryStream([.. Enumerable.Repeat<byte>(0xFF, 1024)]);
var deserializer = new InstallShieldExecutableFile(); var deserializer = new Atari7800Cart();
var actual = deserializer.Deserialize(data); var actual = deserializer.Deserialize(data);
Assert.Null(actual); Assert.Null(actual);

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class AtariLynxCartTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new AtariLynxCart();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new AtariLynxCart();
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 AtariLynxCart();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new AtariLynxCart();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new AtariLynxCart();
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 AtariLynxCart();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -76,7 +76,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new AttractMode(); var deserializer = new AttractMode();
var serializer = new SabreTools.Serialization.Writers.AttractMode(); var serializer = new Serialization.Writers.AttractMode();
// Build the data // Build the data
Data.Models.AttractMode.MetadataFile mf = Build(); Data.Models.AttractMode.MetadataFile mf = Build();
@@ -101,7 +101,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new AttractMode(); var deserializer = new AttractMode();
var serializer = new SabreTools.Serialization.Writers.AttractMode(); var serializer = new Serialization.Writers.AttractMode();
// Build the data // Build the data
Data.Models.AttractMode.MetadataFile mf = Build(); Data.Models.AttractMode.MetadataFile mf = Build();
@@ -168,9 +168,9 @@ namespace SabreTools.Serialization.Test.Readers
{ {
Assert.NotNull(header); Assert.NotNull(header);
if (longHeader) if (longHeader)
Assert.True(SabreTools.Serialization.Writers.AttractMode.HeaderArrayWithRomname.SequenceEqual(header)); Assert.True(Serialization.Writers.AttractMode.HeaderArrayWithRomname.SequenceEqual(header));
else else
Assert.True(SabreTools.Serialization.Writers.AttractMode.HeaderArrayWithoutRomname.SequenceEqual(header)); Assert.True(Serialization.Writers.AttractMode.HeaderArrayWithoutRomname.SequenceEqual(header));
} }
/// <summary> /// <summary>

View File

@@ -75,7 +75,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new ClrMamePro(); var deserializer = new ClrMamePro();
var serializer = new SabreTools.Serialization.Writers.ClrMamePro(); var serializer = new Serialization.Writers.ClrMamePro();
// Build the data // Build the data
Data.Models.ClrMamePro.MetadataFile mf = Build(game: true); Data.Models.ClrMamePro.MetadataFile mf = Build(game: true);
@@ -93,6 +93,7 @@ namespace SabreTools.Serialization.Test.Readers
Assert.NotNull(newMf.Game); Assert.NotNull(newMf.Game);
var newGame = Assert.Single(newMf.Game); var newGame = Assert.Single(newMf.Game);
Validate(newGame); Validate(newGame);
Validate(newMf.Info);
} }
[Fact] [Fact]
@@ -100,7 +101,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new ClrMamePro(); var deserializer = new ClrMamePro();
var serializer = new SabreTools.Serialization.Writers.ClrMamePro(); var serializer = new Serialization.Writers.ClrMamePro();
// Build the data // Build the data
Data.Models.ClrMamePro.MetadataFile mf = Build(game: true); Data.Models.ClrMamePro.MetadataFile mf = Build(game: true);
@@ -118,6 +119,7 @@ namespace SabreTools.Serialization.Test.Readers
Assert.NotNull(newMf.Game); Assert.NotNull(newMf.Game);
var newGame = Assert.Single(newMf.Game); var newGame = Assert.Single(newMf.Game);
Validate(newGame); Validate(newGame);
Validate(newMf.Info);
} }
[Fact] [Fact]
@@ -125,7 +127,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new ClrMamePro(); var deserializer = new ClrMamePro();
var serializer = new SabreTools.Serialization.Writers.ClrMamePro(); var serializer = new Serialization.Writers.ClrMamePro();
// Build the data // Build the data
Data.Models.ClrMamePro.MetadataFile mf = Build(game: false); Data.Models.ClrMamePro.MetadataFile mf = Build(game: false);
@@ -150,7 +152,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new ClrMamePro(); var deserializer = new ClrMamePro();
var serializer = new SabreTools.Serialization.Writers.ClrMamePro(); var serializer = new Serialization.Writers.ClrMamePro();
// Build the data // Build the data
Data.Models.ClrMamePro.MetadataFile mf = Build(game: false); Data.Models.ClrMamePro.MetadataFile mf = Build(game: false);
@@ -214,7 +216,9 @@ namespace SabreTools.Serialization.Test.Readers
{ {
Name = "XXXXXX", Name = "XXXXXX",
Size = "XXXXXX", Size = "XXXXXX",
CRC16 = "XXXXXX",
CRC = "XXXXXX", CRC = "XXXXXX",
CRC64 = "XXXXXX",
MD2 = "XXXXXX", MD2 = "XXXXXX",
MD4 = "XXXXXX", MD4 = "XXXXXX",
MD5 = "XXXXXX", MD5 = "XXXXXX",
@@ -324,6 +328,7 @@ namespace SabreTools.Serialization.Test.Readers
: new Data.Models.ClrMamePro.Machine(); : new Data.Models.ClrMamePro.Machine();
gameBase.Name = "XXXXXX"; gameBase.Name = "XXXXXX";
gameBase.Description = "XXXXXX"; gameBase.Description = "XXXXXX";
gameBase.DriverStatus = "XXXXXX";
gameBase.Year = "XXXXXX"; gameBase.Year = "XXXXXX";
gameBase.Manufacturer = "XXXXXX"; gameBase.Manufacturer = "XXXXXX";
gameBase.Category = "XXXXXX"; gameBase.Category = "XXXXXX";
@@ -344,10 +349,16 @@ namespace SabreTools.Serialization.Test.Readers
gameBase.DipSwitch = [dipswitch]; gameBase.DipSwitch = [dipswitch];
gameBase.Driver = driver; gameBase.Driver = driver;
var info = new Data.Models.ClrMamePro.Info
{
Source = ["XXXXXX"],
};
return new Data.Models.ClrMamePro.MetadataFile return new Data.Models.ClrMamePro.MetadataFile
{ {
ClrMamePro = cmp, ClrMamePro = cmp,
Game = [gameBase], Game = [gameBase],
Info = info,
}; };
} }
@@ -382,6 +393,7 @@ namespace SabreTools.Serialization.Test.Readers
Assert.NotNull(gb); Assert.NotNull(gb);
Assert.Equal("XXXXXX", gb.Name); Assert.Equal("XXXXXX", gb.Name);
Assert.Equal("XXXXXX", gb.Description); Assert.Equal("XXXXXX", gb.Description);
// Assert.Equal("XXXXXX", gb.DriverStatus); // TODO: Needs metadata mapping
Assert.Equal("XXXXXX", gb.Year); Assert.Equal("XXXXXX", gb.Year);
Assert.Equal("XXXXXX", gb.Manufacturer); Assert.Equal("XXXXXX", gb.Manufacturer);
Assert.Equal("XXXXXX", gb.Category); Assert.Equal("XXXXXX", gb.Category);
@@ -467,7 +479,9 @@ namespace SabreTools.Serialization.Test.Readers
Assert.NotNull(rom); Assert.NotNull(rom);
Assert.Equal("XXXXXX", rom.Name); Assert.Equal("XXXXXX", rom.Name);
Assert.Equal("XXXXXX", rom.Size); Assert.Equal("XXXXXX", rom.Size);
Assert.Equal("XXXXXX", rom.CRC16);
Assert.Equal("XXXXXX", rom.CRC); Assert.Equal("XXXXXX", rom.CRC);
Assert.Equal("XXXXXX", rom.CRC64);
Assert.Equal("XXXXXX", rom.MD2); Assert.Equal("XXXXXX", rom.MD2);
Assert.Equal("XXXXXX", rom.MD4); Assert.Equal("XXXXXX", rom.MD4);
Assert.Equal("XXXXXX", rom.MD5); Assert.Equal("XXXXXX", rom.MD5);
@@ -614,5 +628,16 @@ namespace SabreTools.Serialization.Test.Readers
Assert.Equal("XXXXXX", driver.PaletteSize); Assert.Equal("XXXXXX", driver.PaletteSize);
Assert.Equal("XXXXXX", driver.Blit); Assert.Equal("XXXXXX", driver.Blit);
} }
/// <summary>
/// Validate a ClrMamePro
/// </summary>
private static void Validate(Data.Models.ClrMamePro.Info? info)
{
Assert.NotNull(info);
Assert.NotNull(info.Source);
string source = Assert.Single(info.Source);
Assert.Equal("XXXXXX", source);
}
} }
} }

View File

@@ -75,7 +75,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new DosCenter(); var deserializer = new DosCenter();
var serializer = new SabreTools.Serialization.Writers.DosCenter(); var serializer = new Serialization.Writers.DosCenter();
// Build the data // Build the data
Data.Models.DosCenter.MetadataFile mf = Build(); Data.Models.DosCenter.MetadataFile mf = Build();

View File

@@ -75,7 +75,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new EverdriveSMDB(); var deserializer = new EverdriveSMDB();
var serializer = new SabreTools.Serialization.Writers.EverdriveSMDB(); var serializer = new Serialization.Writers.EverdriveSMDB();
// Build the data // Build the data
Data.Models.EverdriveSMDB.MetadataFile mf = Build(); Data.Models.EverdriveSMDB.MetadataFile mf = Build();

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class FDSTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new FDS();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new FDS();
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 FDS();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new FDS();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new FDS();
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 FDS();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -77,7 +77,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new Hashfile(); var deserializer = new Hashfile();
var serializer = new SabreTools.Serialization.Writers.Hashfile(); var serializer = new Serialization.Writers.Hashfile();
// Build the data // Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.CRC32); Data.Models.Hashfile.Hashfile hf = Build(HashType.CRC32);
@@ -101,7 +101,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new Hashfile(); var deserializer = new Hashfile();
var serializer = new SabreTools.Serialization.Writers.Hashfile(); var serializer = new Serialization.Writers.Hashfile();
// Build the data // Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.MD2); Data.Models.Hashfile.Hashfile hf = Build(HashType.MD2);
@@ -125,7 +125,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new Hashfile(); var deserializer = new Hashfile();
var serializer = new SabreTools.Serialization.Writers.Hashfile(); var serializer = new Serialization.Writers.Hashfile();
// Build the data // Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.MD4); Data.Models.Hashfile.Hashfile hf = Build(HashType.MD4);
@@ -149,7 +149,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new Hashfile(); var deserializer = new Hashfile();
var serializer = new SabreTools.Serialization.Writers.Hashfile(); var serializer = new Serialization.Writers.Hashfile();
// Build the data // Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.MD5); Data.Models.Hashfile.Hashfile hf = Build(HashType.MD5);
@@ -173,7 +173,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new Hashfile(); var deserializer = new Hashfile();
var serializer = new SabreTools.Serialization.Writers.Hashfile(); var serializer = new Serialization.Writers.Hashfile();
// Build the data // Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.SHA1); Data.Models.Hashfile.Hashfile hf = Build(HashType.SHA1);
@@ -197,7 +197,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new Hashfile(); var deserializer = new Hashfile();
var serializer = new SabreTools.Serialization.Writers.Hashfile(); var serializer = new Serialization.Writers.Hashfile();
// Build the data // Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.SHA256); Data.Models.Hashfile.Hashfile hf = Build(HashType.SHA256);
@@ -221,7 +221,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new Hashfile(); var deserializer = new Hashfile();
var serializer = new SabreTools.Serialization.Writers.Hashfile(); var serializer = new Serialization.Writers.Hashfile();
// Build the data // Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.SHA384); Data.Models.Hashfile.Hashfile hf = Build(HashType.SHA384);
@@ -245,7 +245,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new Hashfile(); var deserializer = new Hashfile();
var serializer = new SabreTools.Serialization.Writers.Hashfile(); var serializer = new Serialization.Writers.Hashfile();
// Build the data // Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.SHA512); Data.Models.Hashfile.Hashfile hf = Build(HashType.SHA512);
@@ -269,7 +269,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new Hashfile(); var deserializer = new Hashfile();
var serializer = new SabreTools.Serialization.Writers.Hashfile(); var serializer = new Serialization.Writers.Hashfile();
// Build the data // Build the data
Data.Models.Hashfile.Hashfile hf = Build(HashType.SpamSum); Data.Models.Hashfile.Hashfile hf = Build(HashType.SpamSum);
@@ -293,6 +293,7 @@ namespace SabreTools.Serialization.Test.Readers
/// </summary> /// </summary>
private static Data.Models.Hashfile.Hashfile Build(HashType hashType) private static Data.Models.Hashfile.Hashfile Build(HashType hashType)
{ {
#pragma warning disable IDE0072
return hashType switch return hashType switch
{ {
HashType.CRC32 => new Data.Models.Hashfile.Hashfile { SFV = [new Data.Models.Hashfile.SFV { File = "XXXXXX", Hash = "XXXXXX" }] }, HashType.CRC32 => new Data.Models.Hashfile.Hashfile { SFV = [new Data.Models.Hashfile.SFV { File = "XXXXXX", Hash = "XXXXXX" }] },
@@ -304,8 +305,9 @@ namespace SabreTools.Serialization.Test.Readers
HashType.SHA384 => new Data.Models.Hashfile.Hashfile { SHA384 = [new Data.Models.Hashfile.SHA384 { Hash = "XXXXXX", File = "XXXXXX" }] }, HashType.SHA384 => new Data.Models.Hashfile.Hashfile { SHA384 = [new Data.Models.Hashfile.SHA384 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SHA512 => new Data.Models.Hashfile.Hashfile { SHA512 = [new Data.Models.Hashfile.SHA512 { Hash = "XXXXXX", File = "XXXXXX" }] }, HashType.SHA512 => new Data.Models.Hashfile.Hashfile { SHA512 = [new Data.Models.Hashfile.SHA512 { Hash = "XXXXXX", File = "XXXXXX" }] },
HashType.SpamSum => new Data.Models.Hashfile.Hashfile { SpamSum = [new Data.Models.Hashfile.SpamSum { Hash = "XXXXXX", File = "XXXXXX" }] }, HashType.SpamSum => new Data.Models.Hashfile.Hashfile { SpamSum = [new Data.Models.Hashfile.SpamSum { Hash = "XXXXXX", File = "XXXXXX" }] },
_ => throw new ArgumentOutOfRangeException(), _ => throw new ArgumentOutOfRangeException(nameof(hashType)),
}; };
#pragma warning restore IDE0072
} }
/// <summary> /// <summary>

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class InstallShieldExecutableTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new InstallShieldExecutable();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new InstallShieldExecutable();
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 InstallShieldExecutable();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new InstallShieldExecutable();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new InstallShieldExecutable();
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 InstallShieldExecutable();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -75,7 +75,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new Listrom(); var deserializer = new Listrom();
var serializer = new SabreTools.Serialization.Writers.Listrom(); var serializer = new Serialization.Writers.Listrom();
// Build the data // Build the data
Data.Models.Listrom.MetadataFile mf = Build(); Data.Models.Listrom.MetadataFile mf = Build();

View File

@@ -75,7 +75,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new Listxml(); var deserializer = new Listxml();
var serializer = new SabreTools.Serialization.Writers.Listxml(); var serializer = new Serialization.Writers.Listxml();
// Build the data // Build the data
Data.Models.Listxml.Mame mame = Build(game: true); Data.Models.Listxml.Mame mame = Build(game: true);
@@ -103,7 +103,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new Listxml(); var deserializer = new Listxml();
var serializer = new SabreTools.Serialization.Writers.Listxml(); var serializer = new Serialization.Writers.Listxml();
// Build the data // Build the data
Data.Models.Listxml.Mame mame = Build(game: false); Data.Models.Listxml.Mame mame = Build(game: false);

View File

@@ -75,7 +75,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new Logiqx(); var deserializer = new Logiqx();
var serializer = new SabreTools.Serialization.Writers.Logiqx(); var serializer = new Serialization.Writers.Logiqx();
// Build the data // Build the data
Data.Models.Logiqx.Datafile df = Build(game: true); Data.Models.Logiqx.Datafile df = Build(game: true);
@@ -107,7 +107,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new Logiqx(); var deserializer = new Logiqx();
var serializer = new SabreTools.Serialization.Writers.Logiqx(); var serializer = new Serialization.Writers.Logiqx();
// Build the data // Build the data
Data.Models.Logiqx.Datafile df = Build(game: false); Data.Models.Logiqx.Datafile df = Build(game: false);
@@ -215,7 +215,9 @@ namespace SabreTools.Serialization.Test.Readers
{ {
Name = "XXXXXX", Name = "XXXXXX",
Size = "XXXXXX", Size = "XXXXXX",
CRC16 = "XXXXXX",
CRC = "XXXXXX", CRC = "XXXXXX",
CRC64 = "XXXXXX",
MD2 = "XXXXXX", MD2 = "XXXXXX",
MD4 = "XXXXXX", MD4 = "XXXXXX",
MD5 = "XXXXXX", MD5 = "XXXXXX",

View File

@@ -75,7 +75,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new M1(); var deserializer = new M1();
var serializer = new SabreTools.Serialization.Writers.M1(); var serializer = new Serialization.Writers.M1();
// Build the data // Build the data
Data.Models.Listxml.M1 m1 = Build(game: true); Data.Models.Listxml.M1 m1 = Build(game: true);
@@ -101,7 +101,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new M1(); var deserializer = new M1();
var serializer = new SabreTools.Serialization.Writers.M1(); var serializer = new Serialization.Writers.M1();
// Build the data // Build the data
Data.Models.Listxml.M1 m1 = Build(game: false); Data.Models.Listxml.M1 m1 = Build(game: false);

View File

@@ -75,7 +75,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new Mess(); var deserializer = new Mess();
var serializer = new SabreTools.Serialization.Writers.Mess(); var serializer = new Serialization.Writers.Mess();
// Build the data // Build the data
Data.Models.Listxml.Mess m1 = Build(game: true); Data.Models.Listxml.Mess m1 = Build(game: true);
@@ -101,7 +101,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new Mess(); var deserializer = new Mess();
var serializer = new SabreTools.Serialization.Writers.Mess(); var serializer = new Serialization.Writers.Mess();
// Build the data // Build the data
Data.Models.Listxml.Mess m1 = Build(game: false); Data.Models.Listxml.Mess m1 = Build(game: false);

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class NESCartTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new NESCart();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new NESCart();
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 NESCart();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new NESCart();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new NESCart();
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 NESCart();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -75,7 +75,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new OfflineList(); var deserializer = new OfflineList();
var serializer = new SabreTools.Serialization.Writers.OfflineList(); var serializer = new Serialization.Writers.OfflineList();
// Build the data // Build the data
Data.Models.OfflineList.Dat dat = Build(); Data.Models.OfflineList.Dat dat = Build();

View File

@@ -75,7 +75,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new OpenMSX(); var deserializer = new OpenMSX();
var serializer = new SabreTools.Serialization.Writers.OpenMSX(); var serializer = new Serialization.Writers.OpenMSX();
// Build the data // Build the data
Data.Models.OpenMSX.SoftwareDb sdb = Build(); Data.Models.OpenMSX.SoftwareDb sdb = Build();

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class QDTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new QD();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new QD();
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 QD();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new QD();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new QD();
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 QD();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -75,7 +75,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new RomCenter(); var deserializer = new RomCenter();
var serializer = new SabreTools.Serialization.Writers.RomCenter(); var serializer = new Serialization.Writers.RomCenter();
// Build the data // Build the data
Data.Models.RomCenter.MetadataFile mf = Build(); Data.Models.RomCenter.MetadataFile mf = Build();

View File

@@ -76,7 +76,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new SeparatedValue(); var deserializer = new SeparatedValue();
var serializer = new SabreTools.Serialization.Writers.SeparatedValue(); var serializer = new Serialization.Writers.SeparatedValue();
// Build the data // Build the data
Data.Models.SeparatedValue.MetadataFile mf = Build(); Data.Models.SeparatedValue.MetadataFile mf = Build();
@@ -104,7 +104,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new SeparatedValue(); var deserializer = new SeparatedValue();
var serializer = new SabreTools.Serialization.Writers.SeparatedValue(); var serializer = new Serialization.Writers.SeparatedValue();
// Build the data // Build the data
Data.Models.SeparatedValue.MetadataFile mf = Build(); Data.Models.SeparatedValue.MetadataFile mf = Build();
@@ -197,9 +197,9 @@ namespace SabreTools.Serialization.Test.Readers
{ {
Assert.NotNull(header); Assert.NotNull(header);
if (longHeader) if (longHeader)
Assert.True(SabreTools.Serialization.Writers.SeparatedValue.HeaderArrayExtended.SequenceEqual(header)); Assert.True(Serialization.Writers.SeparatedValue.HeaderArrayExtended.SequenceEqual(header));
else else
Assert.True(SabreTools.Serialization.Writers.SeparatedValue.HeaderArrayStandard.SequenceEqual(header)); Assert.True(Serialization.Writers.SeparatedValue.HeaderArrayStandard.SequenceEqual(header));
} }
/// <summary> /// <summary>
@@ -233,6 +233,7 @@ namespace SabreTools.Serialization.Test.Readers
Assert.Null(row.SHA512); Assert.Null(row.SHA512);
Assert.Null(row.SpamSum); Assert.Null(row.SpamSum);
} }
Assert.Equal("XXXXXX", row.Status); Assert.Equal("XXXXXX", row.Status);
} }
@@ -267,6 +268,7 @@ namespace SabreTools.Serialization.Test.Readers
Assert.Null(row.SHA512); Assert.Null(row.SHA512);
Assert.Null(row.SpamSum); Assert.Null(row.SpamSum);
} }
Assert.NotNull(row.Status); Assert.Empty(row.Status); Assert.NotNull(row.Status); Assert.Empty(row.Status);
} }
@@ -302,6 +304,7 @@ namespace SabreTools.Serialization.Test.Readers
Assert.Null(row.SHA512); Assert.Null(row.SHA512);
Assert.Null(row.SpamSum); Assert.Null(row.SpamSum);
} }
Assert.Equal("XXXXXX", row.Status); Assert.Equal("XXXXXX", row.Status);
} }
} }

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class SkuSisTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new SkuSis();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new SkuSis();
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 SkuSis();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new SkuSis();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new SkuSis();
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 SkuSis();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -75,7 +75,7 @@ namespace SabreTools.Serialization.Test.Readers
{ {
// Get the serializer and deserializer // Get the serializer and deserializer
var deserializer = new SoftwareList(); var deserializer = new SoftwareList();
var serializer = new SabreTools.Serialization.Writers.SoftwareList(); var serializer = new Serialization.Writers.SoftwareList();
// Build the data // Build the data
Data.Models.SoftwareList.SoftwareList sl = Build(); Data.Models.SoftwareList.SoftwareList sl = Build();

View File

@@ -0,0 +1,73 @@
using System.IO;
using System.Linq;
using SabreTools.Serialization.Readers;
using Xunit;
namespace SabreTools.Serialization.Test.Readers
{
public class XboxExecutableTests
{
[Fact]
public void NullArray_Null()
{
byte[]? data = null;
int offset = 0;
var deserializer = new XboxExecutable();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void EmptyArray_Null()
{
byte[]? data = [];
int offset = 0;
var deserializer = new XboxExecutable();
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 XboxExecutable();
var actual = deserializer.Deserialize(data, offset);
Assert.Null(actual);
}
[Fact]
public void NullStream_Null()
{
Stream? data = null;
var deserializer = new XboxExecutable();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
[Fact]
public void EmptyStream_Null()
{
Stream? data = new MemoryStream([]);
var deserializer = new XboxExecutable();
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 XboxExecutable();
var actual = deserializer.Deserialize(data);
Assert.Null(actual);
}
}
}

View File

@@ -22,12 +22,12 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4"> <PackageReference Include="coverlet.collector" Version="8.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageReference Include="SabreTools.Hashing" Version="[1.6.0]" /> <PackageReference Include="SabreTools.Hashing" Version="[1.6.1]" />
<PackageReference Include="xunit" Version="2.9.3" /> <PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5"> <PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View File

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

View File

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

View File

@@ -3,6 +3,7 @@ using System.Linq;
using SabreTools.Serialization.Wrappers; using SabreTools.Serialization.Wrappers;
using Xunit; using Xunit;
#pragma warning disable xUnit1004 // Test methods should not be skipped
namespace SabreTools.Serialization.Test.Wrappers namespace SabreTools.Serialization.Test.Wrappers
{ {
public class BZip2Tests public class BZip2Tests

View File

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

View File

@@ -3,6 +3,7 @@ using System.Linq;
using SabreTools.Serialization.Wrappers; using SabreTools.Serialization.Wrappers;
using Xunit; using Xunit;
#pragma warning disable xUnit1004 // Test methods should not be skipped
namespace SabreTools.Serialization.Test.Wrappers namespace SabreTools.Serialization.Test.Wrappers
{ {
public class LDSCRYPTTests public class LDSCRYPTTests

View File

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

View File

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

View File

@@ -4,6 +4,7 @@ using System.Linq;
using SabreTools.Serialization.Wrappers; using SabreTools.Serialization.Wrappers;
using Xunit; using Xunit;
#pragma warning disable xUnit1004 // Test methods should not be skipped
namespace SabreTools.Serialization.Test.Wrappers namespace SabreTools.Serialization.Test.Wrappers
{ {
public class RARTests public class RARTests

View File

@@ -3,6 +3,7 @@ using System.Linq;
using SabreTools.Serialization.Wrappers; using SabreTools.Serialization.Wrappers;
using Xunit; using Xunit;
#pragma warning disable xUnit1004 // Test methods should not be skipped
namespace SabreTools.Serialization.Test.Wrappers namespace SabreTools.Serialization.Test.Wrappers
{ {
public class RealArcadeInstallerTests public class RealArcadeInstallerTests

View File

@@ -3,6 +3,7 @@ using System.Linq;
using SabreTools.Serialization.Wrappers; using SabreTools.Serialization.Wrappers;
using Xunit; using Xunit;
#pragma warning disable xUnit1004 // Test methods should not be skipped
namespace SabreTools.Serialization.Test.Wrappers namespace SabreTools.Serialization.Test.Wrappers
{ {
public class RealArcadeMezzanineTests public class RealArcadeMezzanineTests

View File

@@ -4,6 +4,7 @@ using System.Linq;
using SabreTools.Serialization.Wrappers; using SabreTools.Serialization.Wrappers;
using Xunit; using Xunit;
#pragma warning disable xUnit1004 // Test methods should not be skipped
namespace SabreTools.Serialization.Test.Wrappers namespace SabreTools.Serialization.Test.Wrappers
{ {
public class SevenZipTests public class SevenZipTests

View File

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

View File

@@ -3,6 +3,7 @@ using System.Linq;
using SabreTools.Serialization.Wrappers; using SabreTools.Serialization.Wrappers;
using Xunit; using Xunit;
#pragma warning disable xUnit1004 // Test methods should not be skipped
namespace SabreTools.Serialization.Test.Wrappers namespace SabreTools.Serialization.Test.Wrappers
{ {
public class XZTests public class XZTests

View File

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

View File

@@ -9,7 +9,7 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Files? Deserialize(Data.Models.Metadata.MetadataFile? obj) public override Files? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var files = new Files(); var files = new Files();
@@ -31,7 +31,7 @@ namespace SabreTools.Serialization.CrossModel
private static File[] ConvertFromInternalModel(Data.Models.Metadata.Machine item) private static File[] ConvertFromInternalModel(Data.Models.Metadata.Machine item)
{ {
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey); var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms == null) if (roms is null)
return []; return [];
return Array.ConvertAll(roms, ConvertFromInternalModel); return Array.ConvertAll(roms, ConvertFromInternalModel);

View File

@@ -8,7 +8,7 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(Files? item) public override Data.Models.Metadata.MetadataFile? Serialize(Files? item)
{ {
if (item == null) if (item is null)
return null; return null;
var metadataFile = new Data.Models.Metadata.MetadataFile var metadataFile = new Data.Models.Metadata.MetadataFile
@@ -16,7 +16,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(), [Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(),
}; };
if (item?.File != null && item.File.Length > 0) if (item?.File is not null && item.File.Length > 0)
{ {
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey] metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(item.File, ConvertMachineToInternalModel); = Array.ConvertAll(item.File, ConvertMachineToInternalModel);
@@ -45,7 +45,7 @@ namespace SabreTools.Serialization.CrossModel
var machine = new Data.Models.Metadata.Machine(); var machine = new Data.Models.Metadata.Machine();
var rom = ConvertToInternalModel(item); var rom = ConvertToInternalModel(item);
if (rom != null) if (rom is not null)
machine[Data.Models.Metadata.Machine.RomKey] = new Data.Models.Metadata.Rom[] { rom }; machine[Data.Models.Metadata.Machine.RomKey] = new Data.Models.Metadata.Rom[] { rom };
return machine; return machine;
@@ -56,7 +56,7 @@ namespace SabreTools.Serialization.CrossModel
/// </summary> /// </summary>
private static Data.Models.Metadata.Rom? ConvertToInternalModel(File? item) private static Data.Models.Metadata.Rom? ConvertToInternalModel(File? item)
{ {
if (item == null) if (item is null)
return null; return null;
var rom = new Data.Models.Metadata.Rom var rom = new Data.Models.Metadata.Rom

View File

@@ -9,11 +9,11 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj) public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey); var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
var metadataFile = header != null ? ConvertHeaderFromInternalModel(header) : new MetadataFile(); var metadataFile = header is not null ? ConvertHeaderFromInternalModel(header) : new MetadataFile();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey); var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
var items = new List<Row>(); var items = new List<Row>();
@@ -44,7 +44,7 @@ namespace SabreTools.Serialization.CrossModel
private static Row[] ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item) private static Row[] ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item)
{ {
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey); var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms == null || roms.Length == 0) if (roms is null || roms.Length == 0)
return []; return [];
return Array.ConvertAll(roms, r => ConvertFromInternalModel(r, item)); return Array.ConvertAll(roms, r => ConvertFromInternalModel(r, item));

View File

@@ -8,7 +8,7 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj) public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var metadataFile = new Data.Models.Metadata.MetadataFile var metadataFile = new Data.Models.Metadata.MetadataFile
@@ -16,7 +16,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj), [Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj),
}; };
if (obj?.Row != null && obj.Row.Length > 0) if (obj?.Row is not null && obj.Row.Length > 0)
{ {
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey] metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(obj.Row, ConvertMachineToInternalModel); = Array.ConvertAll(obj.Row, ConvertMachineToInternalModel);
@@ -42,7 +42,7 @@ namespace SabreTools.Serialization.CrossModel
/// </summary> /// </summary>
private static Data.Models.Metadata.Machine? ConvertMachineToInternalModel(Row? item) private static Data.Models.Metadata.Machine? ConvertMachineToInternalModel(Row? item)
{ {
if (item == null) if (item is null)
return null; return null;
var machine = new Data.Models.Metadata.Machine var machine = new Data.Models.Metadata.Machine

View File

@@ -9,6 +9,9 @@ namespace SabreTools.Serialization.CrossModel
/// <typeparam name="TModel">Model convertable to <see cref="MetadataFile"/></typeparam> /// <typeparam name="TModel">Model convertable to <see cref="MetadataFile"/></typeparam>
public abstract class BaseMetadataSerializer<TModel> : ICrossModel<TModel, MetadataFile> public abstract class BaseMetadataSerializer<TModel> : ICrossModel<TModel, MetadataFile>
{ {
/// <inheritdoc/>
public bool Debug { get; set; } = false;
/// <inheritdoc/> /// <inheritdoc/>
public abstract TModel? Deserialize(MetadataFile? obj); public abstract TModel? Deserialize(MetadataFile? obj);

View File

@@ -1,6 +1,7 @@
using System; using System;
using SabreTools.Data.Models.ClrMamePro; using SabreTools.Data.Models.ClrMamePro;
#pragma warning disable CA1822 // Mark members as static
namespace SabreTools.Serialization.CrossModel namespace SabreTools.Serialization.CrossModel
{ {
public partial class ClrMamePro : BaseMetadataSerializer<MetadataFile> public partial class ClrMamePro : BaseMetadataSerializer<MetadataFile>
@@ -12,22 +13,26 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc cref="Deserialize(Data.Models.Metadata.MetadataFile)"/> /// <inheritdoc cref="Deserialize(Data.Models.Metadata.MetadataFile)"/>
public MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj, bool game) public MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj, bool game)
{ {
if (obj == null) if (obj is null)
return null; return null;
var metadataFile = new MetadataFile(); var metadataFile = new MetadataFile();
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey); var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
if (header != null) if (header is not null)
metadataFile.ClrMamePro = ConvertHeaderFromInternalModel(header); metadataFile.ClrMamePro = ConvertHeaderFromInternalModel(header);
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey); var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Length > 0) if (machines is not null && machines.Length > 0)
{ {
metadataFile.Game metadataFile.Game
= Array.ConvertAll(machines, m => ConvertMachineFromInternalModel(m, game)); = Array.ConvertAll(machines, m => ConvertMachineFromInternalModel(m, game));
} }
var info = obj.Read<Data.Models.Metadata.InfoSource>(Data.Models.Metadata.MetadataFile.InfoSourceKey);
if (info is not null)
metadataFile.Info = ConvertInfoSourceFromInternalModel(info);
return metadataFile; return metadataFile;
} }
@@ -66,6 +71,7 @@ namespace SabreTools.Serialization.CrossModel
gameBase.Name = item.ReadString(Data.Models.Metadata.Machine.NameKey); gameBase.Name = item.ReadString(Data.Models.Metadata.Machine.NameKey);
gameBase.Description = item.ReadString(Data.Models.Metadata.Machine.DescriptionKey); gameBase.Description = item.ReadString(Data.Models.Metadata.Machine.DescriptionKey);
// gameBase.DriverStatus = item.ReadString(Data.Models.Metadata.Machine.DriverKey); // TODO: Needs metadata mapping
gameBase.Year = item.ReadString(Data.Models.Metadata.Machine.YearKey); gameBase.Year = item.ReadString(Data.Models.Metadata.Machine.YearKey);
gameBase.Manufacturer = item.ReadString(Data.Models.Metadata.Machine.ManufacturerKey); gameBase.Manufacturer = item.ReadString(Data.Models.Metadata.Machine.ManufacturerKey);
gameBase.Category = item.ReadString(Data.Models.Metadata.Machine.CategoryKey); gameBase.Category = item.ReadString(Data.Models.Metadata.Machine.CategoryKey);
@@ -74,55 +80,55 @@ namespace SabreTools.Serialization.CrossModel
gameBase.SampleOf = item.ReadString(Data.Models.Metadata.Machine.SampleOfKey); gameBase.SampleOf = item.ReadString(Data.Models.Metadata.Machine.SampleOfKey);
var releases = item.Read<Data.Models.Metadata.Release[]>(Data.Models.Metadata.Machine.ReleaseKey); var releases = item.Read<Data.Models.Metadata.Release[]>(Data.Models.Metadata.Machine.ReleaseKey);
if (releases != null && releases.Length > 0) if (releases is not null && releases.Length > 0)
gameBase.Release = Array.ConvertAll(releases, ConvertFromInternalModel); gameBase.Release = Array.ConvertAll(releases, ConvertFromInternalModel);
var biosSets = item.Read<Data.Models.Metadata.BiosSet[]>(Data.Models.Metadata.Machine.BiosSetKey); var biosSets = item.Read<Data.Models.Metadata.BiosSet[]>(Data.Models.Metadata.Machine.BiosSetKey);
if (biosSets != null && biosSets.Length > 0) if (biosSets is not null && biosSets.Length > 0)
gameBase.BiosSet = Array.ConvertAll(biosSets, ConvertFromInternalModel); gameBase.BiosSet = Array.ConvertAll(biosSets, ConvertFromInternalModel);
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey); var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms != null && roms.Length > 0) if (roms is not null && roms.Length > 0)
gameBase.Rom = Array.ConvertAll(roms, ConvertFromInternalModel); gameBase.Rom = Array.ConvertAll(roms, ConvertFromInternalModel);
var disks = item.Read<Data.Models.Metadata.Disk[]>(Data.Models.Metadata.Machine.DiskKey); var disks = item.Read<Data.Models.Metadata.Disk[]>(Data.Models.Metadata.Machine.DiskKey);
if (disks != null && disks.Length > 0) if (disks is not null && disks.Length > 0)
gameBase.Disk = Array.ConvertAll(disks, ConvertFromInternalModel); gameBase.Disk = Array.ConvertAll(disks, ConvertFromInternalModel);
var medias = item.Read<Data.Models.Metadata.Media[]>(Data.Models.Metadata.Machine.MediaKey); var medias = item.Read<Data.Models.Metadata.Media[]>(Data.Models.Metadata.Machine.MediaKey);
if (medias != null && medias.Length > 0) if (medias is not null && medias.Length > 0)
gameBase.Media = Array.ConvertAll(medias, ConvertFromInternalModel); gameBase.Media = Array.ConvertAll(medias, ConvertFromInternalModel);
var samples = item.Read<Data.Models.Metadata.Sample[]>(Data.Models.Metadata.Machine.SampleKey); var samples = item.Read<Data.Models.Metadata.Sample[]>(Data.Models.Metadata.Machine.SampleKey);
if (samples != null && samples.Length > 0) if (samples is not null && samples.Length > 0)
gameBase.Sample = Array.ConvertAll(samples, ConvertFromInternalModel); gameBase.Sample = Array.ConvertAll(samples, ConvertFromInternalModel);
var archives = item.Read<Data.Models.Metadata.Archive[]>(Data.Models.Metadata.Machine.ArchiveKey); var archives = item.Read<Data.Models.Metadata.Archive[]>(Data.Models.Metadata.Machine.ArchiveKey);
if (archives != null && archives.Length > 0) if (archives is not null && archives.Length > 0)
gameBase.Archive = Array.ConvertAll(archives, ConvertFromInternalModel); gameBase.Archive = Array.ConvertAll(archives, ConvertFromInternalModel);
var chips = item.Read<Data.Models.Metadata.Chip[]>(Data.Models.Metadata.Machine.ChipKey); var chips = item.Read<Data.Models.Metadata.Chip[]>(Data.Models.Metadata.Machine.ChipKey);
if (chips != null && chips.Length > 0) if (chips is not null && chips.Length > 0)
gameBase.Chip = Array.ConvertAll(chips, ConvertFromInternalModel); gameBase.Chip = Array.ConvertAll(chips, ConvertFromInternalModel);
var videos = item.Read<Data.Models.Metadata.Video[]>(Data.Models.Metadata.Machine.VideoKey); var videos = item.Read<Data.Models.Metadata.Video[]>(Data.Models.Metadata.Machine.VideoKey);
if (videos != null && videos.Length > 0) if (videos is not null && videos.Length > 0)
gameBase.Video = Array.ConvertAll(videos, ConvertFromInternalModel); gameBase.Video = Array.ConvertAll(videos, ConvertFromInternalModel);
var sound = item.Read<Data.Models.Metadata.Sound>(Data.Models.Metadata.Machine.SoundKey); var sound = item.Read<Data.Models.Metadata.Sound>(Data.Models.Metadata.Machine.SoundKey);
if (sound != null) if (sound is not null)
gameBase.Sound = ConvertFromInternalModel(sound); gameBase.Sound = ConvertFromInternalModel(sound);
var input = item.Read<Data.Models.Metadata.Input>(Data.Models.Metadata.Machine.InputKey); var input = item.Read<Data.Models.Metadata.Input>(Data.Models.Metadata.Machine.InputKey);
if (input != null) if (input is not null)
gameBase.Input = ConvertFromInternalModel(input); gameBase.Input = ConvertFromInternalModel(input);
var dipSwitches = item.Read<Data.Models.Metadata.DipSwitch[]>(Data.Models.Metadata.Machine.DipSwitchKey); var dipSwitches = item.Read<Data.Models.Metadata.DipSwitch[]>(Data.Models.Metadata.Machine.DipSwitchKey);
if (dipSwitches != null && dipSwitches.Length > 0) if (dipSwitches is not null && dipSwitches.Length > 0)
gameBase.DipSwitch = Array.ConvertAll(dipSwitches, ConvertFromInternalModel); gameBase.DipSwitch = Array.ConvertAll(dipSwitches, ConvertFromInternalModel);
var driver = item.Read<Data.Models.Metadata.Driver>(Data.Models.Metadata.Machine.DriverKey); var driver = item.Read<Data.Models.Metadata.Driver>(Data.Models.Metadata.Machine.DriverKey);
if (driver != null) if (driver is not null)
gameBase.Driver = ConvertFromInternalModel(driver); gameBase.Driver = ConvertFromInternalModel(driver);
return gameBase; return gameBase;
@@ -274,7 +280,9 @@ namespace SabreTools.Serialization.CrossModel
{ {
Name = item.ReadString(Data.Models.Metadata.Rom.NameKey), Name = item.ReadString(Data.Models.Metadata.Rom.NameKey),
Size = item.ReadString(Data.Models.Metadata.Rom.SizeKey), Size = item.ReadString(Data.Models.Metadata.Rom.SizeKey),
CRC16 = item.ReadString(Data.Models.Metadata.Rom.CRC16Key),
CRC = item.ReadString(Data.Models.Metadata.Rom.CRCKey), CRC = item.ReadString(Data.Models.Metadata.Rom.CRCKey),
CRC64 = item.ReadString(Data.Models.Metadata.Rom.CRC64Key),
MD2 = item.ReadString(Data.Models.Metadata.Rom.MD2Key), MD2 = item.ReadString(Data.Models.Metadata.Rom.MD2Key),
MD4 = item.ReadString(Data.Models.Metadata.Rom.MD4Key), MD4 = item.ReadString(Data.Models.Metadata.Rom.MD4Key),
MD5 = item.ReadString(Data.Models.Metadata.Rom.MD5Key), MD5 = item.ReadString(Data.Models.Metadata.Rom.MD5Key),
@@ -342,5 +350,19 @@ namespace SabreTools.Serialization.CrossModel
}; };
return video; return video;
} }
/// <summary>
/// Convert from <see cref="Models.Metadata.InfoSource"/> to <see cref="Models.ClrMamePro.Info"/>
/// </summary>
private static Info ConvertInfoSourceFromInternalModel(Data.Models.Metadata.InfoSource item)
{
var info = new Info();
var sources = item.Read<string[]>(Data.Models.Metadata.InfoSource.SourceKey);
if (sources is not null && sources.Length > 0)
info.Source = [.. sources];
return info;
}
} }
} }

View File

@@ -8,20 +8,23 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj) public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var metadataFile = new Data.Models.Metadata.MetadataFile(); var metadataFile = new Data.Models.Metadata.MetadataFile();
if (obj?.ClrMamePro != null) if (obj?.ClrMamePro is not null)
metadataFile[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj.ClrMamePro); metadataFile[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj.ClrMamePro);
if (obj?.Game != null && obj.Game.Length > 0) if (obj?.Game is not null && obj.Game.Length > 0)
{ {
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey] metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(obj.Game, ConvertMachineToInternalModel); = Array.ConvertAll(obj.Game, ConvertMachineToInternalModel);
} }
if (obj?.Info is not null)
metadataFile[Data.Models.Metadata.MetadataFile.InfoSourceKey] = ConvertInfoSourceToInternalModel(obj.Info);
return metadataFile; return metadataFile;
} }
@@ -56,13 +59,14 @@ namespace SabreTools.Serialization.CrossModel
/// </summary> /// </summary>
private static Data.Models.Metadata.Machine? ConvertMachineToInternalModel(GameBase? item) private static Data.Models.Metadata.Machine? ConvertMachineToInternalModel(GameBase? item)
{ {
if (item == null) if (item is null)
return null; return null;
var machine = new Data.Models.Metadata.Machine var machine = new Data.Models.Metadata.Machine
{ {
[Data.Models.Metadata.Machine.NameKey] = item.Name, [Data.Models.Metadata.Machine.NameKey] = item.Name,
[Data.Models.Metadata.Machine.DescriptionKey] = item.Description, [Data.Models.Metadata.Machine.DescriptionKey] = item.Description,
// [Data.Models.Metadata.Machine.DriverKey] = item.DriverStatus, // TODO: Needs metadata mapping
[Data.Models.Metadata.Machine.YearKey] = item.Year, [Data.Models.Metadata.Machine.YearKey] = item.Year,
[Data.Models.Metadata.Machine.ManufacturerKey] = item.Manufacturer, [Data.Models.Metadata.Machine.ManufacturerKey] = item.Manufacturer,
[Data.Models.Metadata.Machine.CategoryKey] = item.Category, [Data.Models.Metadata.Machine.CategoryKey] = item.Category,
@@ -71,73 +75,73 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.Machine.SampleOfKey] = item.SampleOf, [Data.Models.Metadata.Machine.SampleOfKey] = item.SampleOf,
}; };
if (item.Release != null && item.Release.Length > 0) if (item.Release is not null && item.Release.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.ReleaseKey] machine[Data.Models.Metadata.Machine.ReleaseKey]
= Array.ConvertAll(item.Release, ConvertToInternalModel); = Array.ConvertAll(item.Release, ConvertToInternalModel);
} }
if (item.BiosSet != null && item.BiosSet.Length > 0) if (item.BiosSet is not null && item.BiosSet.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.BiosSetKey] machine[Data.Models.Metadata.Machine.BiosSetKey]
= Array.ConvertAll(item.BiosSet, ConvertToInternalModel); = Array.ConvertAll(item.BiosSet, ConvertToInternalModel);
} }
if (item.Rom != null && item.Rom.Length > 0) if (item.Rom is not null && item.Rom.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.RomKey] machine[Data.Models.Metadata.Machine.RomKey]
= Array.ConvertAll(item.Rom, ConvertToInternalModel); = Array.ConvertAll(item.Rom, ConvertToInternalModel);
} }
if (item.Disk != null && item.Disk.Length > 0) if (item.Disk is not null && item.Disk.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.DiskKey] machine[Data.Models.Metadata.Machine.DiskKey]
= Array.ConvertAll(item.Disk, ConvertToInternalModel); = Array.ConvertAll(item.Disk, ConvertToInternalModel);
} }
if (item.Media != null && item.Media.Length > 0) if (item.Media is not null && item.Media.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.MediaKey] machine[Data.Models.Metadata.Machine.MediaKey]
= Array.ConvertAll(item.Media, ConvertToInternalModel); = Array.ConvertAll(item.Media, ConvertToInternalModel);
} }
if (item.Sample != null && item.Sample.Length > 0) if (item.Sample is not null && item.Sample.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.SampleKey] machine[Data.Models.Metadata.Machine.SampleKey]
= Array.ConvertAll(item.Sample, ConvertToInternalModel); = Array.ConvertAll(item.Sample, ConvertToInternalModel);
} }
if (item.Archive != null && item.Archive.Length > 0) if (item.Archive is not null && item.Archive.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.ArchiveKey] machine[Data.Models.Metadata.Machine.ArchiveKey]
= Array.ConvertAll(item.Archive, ConvertToInternalModel); = Array.ConvertAll(item.Archive, ConvertToInternalModel);
} }
if (item.Chip != null && item.Chip.Length > 0) if (item.Chip is not null && item.Chip.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.ChipKey] machine[Data.Models.Metadata.Machine.ChipKey]
= Array.ConvertAll(item.Chip, ConvertToInternalModel); = Array.ConvertAll(item.Chip, ConvertToInternalModel);
} }
if (item.Video != null) if (item.Video is not null)
{ {
machine[Data.Models.Metadata.Machine.VideoKey] machine[Data.Models.Metadata.Machine.VideoKey]
= Array.ConvertAll(item.Video, ConvertToInternalModel); = Array.ConvertAll(item.Video, ConvertToInternalModel);
} }
if (item.Sound != null) if (item.Sound is not null)
machine[Data.Models.Metadata.Machine.SoundKey] = ConvertToInternalModel(item.Sound); machine[Data.Models.Metadata.Machine.SoundKey] = ConvertToInternalModel(item.Sound);
if (item.Input != null) if (item.Input is not null)
machine[Data.Models.Metadata.Machine.InputKey] = ConvertToInternalModel(item.Input); machine[Data.Models.Metadata.Machine.InputKey] = ConvertToInternalModel(item.Input);
if (item.DipSwitch != null && item.DipSwitch.Length > 0) if (item.DipSwitch is not null && item.DipSwitch.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.DipSwitchKey] machine[Data.Models.Metadata.Machine.DipSwitchKey]
= Array.ConvertAll(item.DipSwitch, ConvertToInternalModel); = Array.ConvertAll(item.DipSwitch, ConvertToInternalModel);
} }
if (item.Driver != null) if (item.Driver is not null)
machine[Data.Models.Metadata.Machine.DriverKey] = ConvertToInternalModel(item.Driver); machine[Data.Models.Metadata.Machine.DriverKey] = ConvertToInternalModel(item.Driver);
return machine; return machine;
@@ -289,7 +293,9 @@ namespace SabreTools.Serialization.CrossModel
{ {
[Data.Models.Metadata.Rom.NameKey] = item.Name, [Data.Models.Metadata.Rom.NameKey] = item.Name,
[Data.Models.Metadata.Rom.SizeKey] = item.Size, [Data.Models.Metadata.Rom.SizeKey] = item.Size,
[Data.Models.Metadata.Rom.CRC16Key] = item.CRC16,
[Data.Models.Metadata.Rom.CRCKey] = item.CRC, [Data.Models.Metadata.Rom.CRCKey] = item.CRC,
[Data.Models.Metadata.Rom.CRC64Key] = item.CRC64,
[Data.Models.Metadata.Rom.MD2Key] = item.MD2, [Data.Models.Metadata.Rom.MD2Key] = item.MD2,
[Data.Models.Metadata.Rom.MD4Key] = item.MD4, [Data.Models.Metadata.Rom.MD4Key] = item.MD4,
[Data.Models.Metadata.Rom.MD5Key] = item.MD5, [Data.Models.Metadata.Rom.MD5Key] = item.MD5,
@@ -357,5 +363,22 @@ namespace SabreTools.Serialization.CrossModel
}; };
return video; return video;
} }
/// <summary>
/// Convert from <see cref="Models.ClrMamePro.Info"/> to <see cref="Models.Metadata.InfoSource"/>
/// </summary>
private static Data.Models.Metadata.InfoSource ConvertInfoSourceToInternalModel(Info item)
{
var infoSource = new Data.Models.Metadata.InfoSource();
var sources = item.Source;
if (sources is not null && sources.Length > 0)
{
string[] sourcesCopy = [.. sources];
infoSource[Data.Models.Metadata.InfoSource.SourceKey] = sourcesCopy;
}
return infoSource;
}
} }
} }

View File

@@ -8,17 +8,17 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj) public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var metadataFile = new MetadataFile(); var metadataFile = new MetadataFile();
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey); var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
if (header != null) if (header is not null)
metadataFile.DosCenter = ConvertHeaderFromInternalModel(header); metadataFile.DosCenter = ConvertHeaderFromInternalModel(header);
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey); var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Length > 0) if (machines is not null && machines.Length > 0)
metadataFile.Game = Array.ConvertAll(machines, ConvertMachineFromInternalModel); metadataFile.Game = Array.ConvertAll(machines, ConvertMachineFromInternalModel);
return metadataFile; return metadataFile;
@@ -53,7 +53,7 @@ namespace SabreTools.Serialization.CrossModel
}; };
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey); var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms != null && roms.Length > 0) if (roms is not null && roms.Length > 0)
game.File = Array.ConvertAll(roms, ConvertFromInternalModel); game.File = Array.ConvertAll(roms, ConvertFromInternalModel);
return game; return game;

View File

@@ -8,15 +8,15 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj) public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var metadataFile = new Data.Models.Metadata.MetadataFile(); var metadataFile = new Data.Models.Metadata.MetadataFile();
if (obj?.DosCenter != null) if (obj?.DosCenter is not null)
metadataFile[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj.DosCenter); metadataFile[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj.DosCenter);
if (obj?.Game != null && obj.Game.Length > 0) if (obj?.Game is not null && obj.Game.Length > 0)
{ {
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey] metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(obj.Game, ConvertMachineToInternalModel); = Array.ConvertAll(obj.Game, ConvertMachineToInternalModel);
@@ -53,7 +53,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.Machine.NameKey] = item.Name, [Data.Models.Metadata.Machine.NameKey] = item.Name,
}; };
if (item.File != null && item.File.Length > 0) if (item.File is not null && item.File.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.RomKey] machine[Data.Models.Metadata.Machine.RomKey]
= Array.ConvertAll(item.File, ConvertToInternalModel); = Array.ConvertAll(item.File, ConvertToInternalModel);

View File

@@ -9,7 +9,7 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj) public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var metadataFile = new MetadataFile(); var metadataFile = new MetadataFile();
@@ -32,7 +32,7 @@ namespace SabreTools.Serialization.CrossModel
private static Row[] ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item) private static Row[] ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item)
{ {
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey); var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms == null || roms.Length == 0) if (roms is null || roms.Length == 0)
return []; return [];
return Array.ConvertAll(roms, ConvertFromInternalModel); return Array.ConvertAll(roms, ConvertFromInternalModel);

View File

@@ -8,7 +8,7 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj) public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var metadataFile = new Data.Models.Metadata.MetadataFile var metadataFile = new Data.Models.Metadata.MetadataFile
@@ -16,7 +16,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(), [Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(),
}; };
if (obj?.Row != null && obj.Row.Length > 0) if (obj?.Row is not null && obj.Row.Length > 0)
{ {
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey] metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(obj.Row, ConvertMachineToInternalModel); = Array.ConvertAll(obj.Row, ConvertMachineToInternalModel);

View File

@@ -0,0 +1,85 @@
using System.Collections.Generic;
using SabreTools.Data.Models.NES;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
/// <see href="https://www.nesdev.org/wiki/FDS_disk_format"/>
/// <see href="https://gist.github.com/einstein95/6545066905680466cdf200c4cc8ca4f0"/>
public partial class FamicomDiskSystem : ICrossModel<FDS, QD>
{
/// <inheritdoc/>
public bool Debug { get; set; } = false;
/// <inheritdoc/>
public FDS? Deserialize(QD? obj)
{
// Ignore invalid data
if (obj?.Data is null || obj.Data.Length == 0)
return null;
// Ignore incomplete data
if ((obj.Data.Length % 65536) != 0)
return null;
// Determine the number of sides
byte sides = (byte)(obj.Data.Length / 65536);
if (sides < 1)
return null;
// Create the FDS for output
var fds = new FDS
{
Header = new FDSHeader
{
IdentificationString = Constants.FDSSignatureBytes,
DiskSides = sides,
}
};
// Loop over the sides and convert
List<byte> converted = [];
for (int i = 0; i < sides; i++)
{
// Convert the data to manipulate
List<byte> data = [.. obj.Data];
// Delete block 01 checksum
data.RemoveRange(0x38, 2);
// Delete block 02 checksum
int pos = 0x3A;
data.RemoveRange(pos, 2);
// Loop while there are more files
while (data[pos] == 3)
{
// Get the filesize
ushort filesize = (ushort)((data[pos + 0x0E] << 8) | data[pos + 0x0D]);
// Delete block 03 checksum
data.RemoveRange(pos + 0x10, 2);
// Skip the file data
pos = pos + 0x10 + 1 + filesize;
// Delete block 04 checksum
data.RemoveRange(pos, 2);
}
// Ensure the data is correctly sized
if (data.Count > 65500)
data = data.GetRange(0, 65500);
else if (data.Count < 65500)
data.AddRange(new byte[65500 - data.Count]);
// Add the data to the output
converted.AddRange(data);
}
// Assign the converted data and return
fds.Data = [.. converted];
return fds;
}
}
}

View File

@@ -0,0 +1,132 @@
using System.Collections.Generic;
using SabreTools.Data.Models.NES;
using SabreTools.Serialization.Interfaces;
namespace SabreTools.Serialization.CrossModel
{
/// <see href="https://www.nesdev.org/wiki/FDS_disk_format"/>
/// <see href="https://gist.github.com/einstein95/6545066905680466cdf200c4cc8ca4f0"/>
public partial class FamicomDiskSystem : ICrossModel<FDS, QD>
{
/// <inheritdoc/>
public QD? Serialize(FDS? obj)
=> Serialize(obj, false);
/// <inheritdoc/>
/// <param name="nul">True to insert null checksums on conversion, false otherwise</param>
public QD? Serialize(FDS? obj, bool nul)
{
// Ignore invalid data
if (obj?.Data is null || obj.Data.Length == 0)
return null;
// Ignore incomplete data
if ((obj.Data.Length % 65500) != 0)
return null;
// Determine the number of sides
byte sides = obj.Header != null
? obj.Header.DiskSides
: (byte)(obj.Data.Length / 65500);
if (sides < 1)
return null;
// Create the QD for output
var qd = new QD();
// Loop over the sides and convert
List<byte> converted = [];
for (int i = 0; i < sides; i++)
{
// Convert the data to manipulate
List<byte> data = [.. obj.Data];
// If the data is unexpected
if (data[0] != 0x01)
break;
// Insert block 01 checksum
InsertCrc(data, 0, 0x38, nul);
// Insert block 02 checksum
int pos = 0x3A;
InsertCrc(data, pos, pos + 2, nul);
// Loop while there are more files
pos = 0x3E;
while (data[pos] == 3)
{
// Get the filesize
ushort filesize = (ushort)((data[pos + 0x0E] << 8) | data[pos + 0x0D]);
// Insert block 03 checksum
InsertCrc(data, pos, pos + 0x10, nul);
// Skip the file data
pos += 0x10 + 2;
// Insert block 04 checksum
InsertCrc(data, pos, pos + 1 + filesize, nul);
pos += 1 + filesize + 2;
}
// Ensure the data is correctly sized
if (data.Count > 65536)
data = data.GetRange(0, 65536);
else if (data.Count < 65536)
data.AddRange(new byte[65536 - data.Count]);
// Add the data to the output
converted.AddRange(data);
}
// Assign the converted data and return
qd.Data = [.. converted];
return qd;
}
private void InsertCrc(List<byte> data, int start, int end, bool nul)
{
if (!nul)
{
byte[] temp = new byte[end - start];
data.CopyTo(start, temp, 0, temp.Length);
ushort crc = FdsCrc(temp);
data.Insert(end + 0, (byte)(crc & 0xFF));
data.Insert(end + 1, (byte)(crc >> 0x08));
}
else
{
data.Insert(end + 0, 0);
data.Insert(end + 1, 0);
}
}
// TODO: Replace with CRC-16/KERMIT from Hashing
private ushort FdsCrc(byte[] data)
{
// http://forums.nesdev.com/viewtopic.php?p=194867
// Do not include any existing checksum, not even the blank checksums 00 00 or FF FF.
// The formula will automatically count 2 0x00 bytes without the programmer adding them manually.
// Also, do not include the gap terminator (0x80) in the data.
// If you wish to do so, change sum to 0x0000.
ushort s = 0x8000;
byte[] padded = [.. data, 0x00, 0x00];
foreach (byte b in padded)
{
s |= (ushort)(b << 16);
for (int i = 0; i < 8; i++)
{
if ((s & 1) != 0)
{
unchecked { s ^= (ushort)(0x8408 << 1); }
}
s >>= 1;
}
}
return s;
}
}
}

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using SabreTools.Data.Models.Hashfile; using SabreTools.Data.Models.Hashfile;
using SabreTools.Hashing; using SabreTools.Hashing;
#pragma warning disable CA1822 // Mark members as static
namespace SabreTools.Serialization.CrossModel namespace SabreTools.Serialization.CrossModel
{ {
public partial class Hashfile : BaseMetadataSerializer<Data.Models.Hashfile.Hashfile> public partial class Hashfile : BaseMetadataSerializer<Data.Models.Hashfile.Hashfile>
@@ -14,11 +15,11 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public Data.Models.Hashfile.Hashfile? Deserialize(Data.Models.Metadata.MetadataFile? obj, HashType hash) public Data.Models.Hashfile.Hashfile? Deserialize(Data.Models.Metadata.MetadataFile? obj, HashType hash)
{ {
if (obj == null) if (obj is null)
return null; return null;
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey); var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines == null || machines.Length == 0) if (machines is null || machines.Length == 0)
return null; return null;
var hashfiles = Array.ConvertAll(machines, var hashfiles = Array.ConvertAll(machines,
@@ -38,27 +39,27 @@ namespace SabreTools.Serialization.CrossModel
foreach (var hashfile in hashfiles) foreach (var hashfile in hashfiles)
{ {
if (hashfile.SFV != null && hashfile.SFV.Length > 0) if (hashfile.SFV is not null && hashfile.SFV.Length > 0)
sfvs.AddRange(hashfile.SFV); sfvs.AddRange(hashfile.SFV);
if (hashfile.MD2 != null && hashfile.MD2.Length > 0) if (hashfile.MD2 is not null && hashfile.MD2.Length > 0)
md2s.AddRange(hashfile.MD2); md2s.AddRange(hashfile.MD2);
if (hashfile.MD4 != null && hashfile.MD4.Length > 0) if (hashfile.MD4 is not null && hashfile.MD4.Length > 0)
md4s.AddRange(hashfile.MD4); md4s.AddRange(hashfile.MD4);
if (hashfile.MD5 != null && hashfile.MD5.Length > 0) if (hashfile.MD5 is not null && hashfile.MD5.Length > 0)
md5s.AddRange(hashfile.MD5); md5s.AddRange(hashfile.MD5);
if (hashfile.RIPEMD128 != null && hashfile.RIPEMD128.Length > 0) if (hashfile.RIPEMD128 is not null && hashfile.RIPEMD128.Length > 0)
ripemd128s.AddRange(hashfile.RIPEMD128); ripemd128s.AddRange(hashfile.RIPEMD128);
if (hashfile.RIPEMD160 != null && hashfile.RIPEMD160.Length > 0) if (hashfile.RIPEMD160 is not null && hashfile.RIPEMD160.Length > 0)
ripemd160s.AddRange(hashfile.RIPEMD160); ripemd160s.AddRange(hashfile.RIPEMD160);
if (hashfile.SHA1 != null && hashfile.SHA1.Length > 0) if (hashfile.SHA1 is not null && hashfile.SHA1.Length > 0)
sha1s.AddRange(hashfile.SHA1); sha1s.AddRange(hashfile.SHA1);
if (hashfile.SHA256 != null && hashfile.SHA256.Length > 0) if (hashfile.SHA256 is not null && hashfile.SHA256.Length > 0)
sha256s.AddRange(hashfile.SHA256); sha256s.AddRange(hashfile.SHA256);
if (hashfile.SHA384 != null && hashfile.SHA384.Length > 0) if (hashfile.SHA384 is not null && hashfile.SHA384.Length > 0)
sha384s.AddRange(hashfile.SHA384); sha384s.AddRange(hashfile.SHA384);
if (hashfile.SHA512 != null && hashfile.SHA512.Length > 0) if (hashfile.SHA512 is not null && hashfile.SHA512.Length > 0)
sha512s.AddRange(hashfile.SHA512); sha512s.AddRange(hashfile.SHA512);
if (hashfile.SpamSum != null && hashfile.SpamSum.Length > 0) if (hashfile.SpamSum is not null && hashfile.SpamSum.Length > 0)
spamsums.AddRange(hashfile.SpamSum); spamsums.AddRange(hashfile.SpamSum);
} }
@@ -96,7 +97,7 @@ namespace SabreTools.Serialization.CrossModel
private static Data.Models.Hashfile.Hashfile ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item, HashType hash) private static Data.Models.Hashfile.Hashfile ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item, HashType hash)
{ {
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey); var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms == null) if (roms is null)
return new Data.Models.Hashfile.Hashfile(); return new Data.Models.Hashfile.Hashfile();
return new Data.Models.Hashfile.Hashfile return new Data.Models.Hashfile.Hashfile

View File

@@ -8,7 +8,7 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(Data.Models.Hashfile.Hashfile? obj) public override Data.Models.Metadata.MetadataFile? Serialize(Data.Models.Hashfile.Hashfile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var metadataFile = new Data.Models.Metadata.MetadataFile var metadataFile = new Data.Models.Metadata.MetadataFile
@@ -41,27 +41,27 @@ namespace SabreTools.Serialization.CrossModel
{ {
var machine = new Data.Models.Metadata.Machine(); var machine = new Data.Models.Metadata.Machine();
if (item.SFV != null && item.SFV.Length > 0) if (item.SFV is not null && item.SFV.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SFV, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SFV, ConvertToInternalModel);
else if (item.MD2 != null && item.MD2.Length > 0) else if (item.MD2 is not null && item.MD2.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.MD2, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.MD2, ConvertToInternalModel);
else if (item.MD4 != null && item.MD4.Length > 0) else if (item.MD4 is not null && item.MD4.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.MD4, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.MD4, ConvertToInternalModel);
else if (item.MD5 != null && item.MD5.Length > 0) else if (item.MD5 is not null && item.MD5.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.MD5, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.MD5, ConvertToInternalModel);
else if (item.RIPEMD128 != null && item.RIPEMD128.Length > 0) else if (item.RIPEMD128 is not null && item.RIPEMD128.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.RIPEMD128, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.RIPEMD128, ConvertToInternalModel);
else if (item.RIPEMD160 != null && item.RIPEMD160.Length > 0) else if (item.RIPEMD160 is not null && item.RIPEMD160.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.RIPEMD160, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.RIPEMD160, ConvertToInternalModel);
else if (item.SHA1 != null && item.SHA1.Length > 0) else if (item.SHA1 is not null && item.SHA1.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SHA1, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SHA1, ConvertToInternalModel);
else if (item.SHA256 != null && item.SHA256.Length > 0) else if (item.SHA256 is not null && item.SHA256.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SHA256, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SHA256, ConvertToInternalModel);
else if (item.SHA384 != null && item.SHA384.Length > 0) else if (item.SHA384 is not null && item.SHA384.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SHA384, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SHA384, ConvertToInternalModel);
else if (item.SHA512 != null && item.SHA512.Length > 0) else if (item.SHA512 is not null && item.SHA512.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SHA512, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SHA512, ConvertToInternalModel);
else if (item.SpamSum != null && item.SpamSum.Length > 0) else if (item.SpamSum is not null && item.SpamSum.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SpamSum, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.SpamSum, ConvertToInternalModel);
return machine; return machine;

View File

@@ -9,13 +9,13 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj) public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var metadataFile = new MetadataFile(); var metadataFile = new MetadataFile();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey); var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Length > 0) if (machines is not null && machines.Length > 0)
metadataFile.Set = Array.ConvertAll(machines, ConvertMachineFromInternalModel); metadataFile.Set = Array.ConvertAll(machines, ConvertMachineFromInternalModel);
return metadataFile; return metadataFile;
@@ -35,13 +35,13 @@ namespace SabreTools.Serialization.CrossModel
var rowItems = new List<Row>(); var rowItems = new List<Row>();
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey); var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms != null) if (roms is not null)
{ {
rowItems.AddRange(Array.ConvertAll(roms, ConvertFromInternalModel)); rowItems.AddRange(Array.ConvertAll(roms, ConvertFromInternalModel));
} }
var disks = item.Read<Data.Models.Metadata.Disk[]>(Data.Models.Metadata.Machine.DiskKey); var disks = item.Read<Data.Models.Metadata.Disk[]>(Data.Models.Metadata.Machine.DiskKey);
if (disks != null) if (disks is not null)
rowItems.AddRange(Array.ConvertAll(disks, ConvertFromInternalModel)); rowItems.AddRange(Array.ConvertAll(disks, ConvertFromInternalModel));
set.Row = [.. rowItems]; set.Row = [.. rowItems];
@@ -60,9 +60,9 @@ namespace SabreTools.Serialization.CrossModel
SHA1 = item.ReadString(Data.Models.Metadata.Disk.SHA1Key), SHA1 = item.ReadString(Data.Models.Metadata.Disk.SHA1Key),
}; };
if (item[Data.Models.Metadata.Disk.StatusKey] as string == "nodump") if ((item[Data.Models.Metadata.Disk.StatusKey] as string) == "nodump")
row.NoGoodDumpKnown = true; row.NoGoodDumpKnown = true;
else if (item[Data.Models.Metadata.Disk.StatusKey] as string == "baddump") else if ((item[Data.Models.Metadata.Disk.StatusKey] as string) == "baddump")
row.Bad = true; row.Bad = true;
return row; return row;
@@ -81,9 +81,9 @@ namespace SabreTools.Serialization.CrossModel
SHA1 = item.ReadString(Data.Models.Metadata.Rom.SHA1Key), SHA1 = item.ReadString(Data.Models.Metadata.Rom.SHA1Key),
}; };
if (item[Data.Models.Metadata.Rom.StatusKey] as string == "nodump") if ((item[Data.Models.Metadata.Rom.StatusKey] as string) == "nodump")
row.NoGoodDumpKnown = true; row.NoGoodDumpKnown = true;
else if (item[Data.Models.Metadata.Rom.StatusKey] as string == "baddump") else if ((item[Data.Models.Metadata.Rom.StatusKey] as string) == "baddump")
row.Bad = true; row.Bad = true;
return row; return row;

View File

@@ -9,7 +9,7 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj) public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var metadataFile = new Data.Models.Metadata.MetadataFile var metadataFile = new Data.Models.Metadata.MetadataFile
@@ -17,7 +17,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(), [Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(),
}; };
if (obj?.Set != null && obj.Set.Length > 0) if (obj?.Set is not null && obj.Set.Length > 0)
{ {
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey] metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(obj.Set, ConvertMachineToInternalModel); = Array.ConvertAll(obj.Set, ConvertMachineToInternalModel);
@@ -54,7 +54,7 @@ namespace SabreTools.Serialization.CrossModel
machine[Data.Models.Metadata.Machine.NameKey] = item.Driver; machine[Data.Models.Metadata.Machine.NameKey] = item.Driver;
} }
if (item.Row != null && item.Row.Length > 0) if (item.Row is not null && item.Row.Length > 0)
{ {
var disks = new List<Data.Models.Metadata.Disk>(); var disks = new List<Data.Models.Metadata.Disk>();
var roms = new List<Data.Models.Metadata.Rom>(); var roms = new List<Data.Models.Metadata.Rom>();
@@ -79,7 +79,7 @@ namespace SabreTools.Serialization.CrossModel
/// </summary> /// </summary>
private static Data.Models.Metadata.DatItem ConvertToInternalModel(Row item) private static Data.Models.Metadata.DatItem ConvertToInternalModel(Row item)
{ {
if (item.Size == null) if (item.Size is null)
{ {
var disk = new Data.Models.Metadata.Disk var disk = new Data.Models.Metadata.Disk
{ {

View File

@@ -8,14 +8,14 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Mame? Deserialize(Data.Models.Metadata.MetadataFile? obj) public override Mame? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey); var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
var mame = header != null ? ConvertMameFromInternalModel(header) : new Mame(); var mame = header is not null ? ConvertMameFromInternalModel(header) : new Mame();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey); var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Length > 0) if (machines is not null && machines.Length > 0)
mame.Game = Array.ConvertAll(machines, ConvertMachineFromInternalModel); mame.Game = Array.ConvertAll(machines, ConvertMachineFromInternalModel);
return mame; return mame;
@@ -59,83 +59,83 @@ namespace SabreTools.Serialization.CrossModel
}; };
var biosSets = item.Read<Data.Models.Metadata.BiosSet[]>(Data.Models.Metadata.Machine.BiosSetKey); var biosSets = item.Read<Data.Models.Metadata.BiosSet[]>(Data.Models.Metadata.Machine.BiosSetKey);
if (biosSets != null && biosSets.Length > 0) if (biosSets is not null && biosSets.Length > 0)
machine.BiosSet = Array.ConvertAll(biosSets, ConvertFromInternalModel); machine.BiosSet = Array.ConvertAll(biosSets, ConvertFromInternalModel);
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey); var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms != null && roms.Length > 0) if (roms is not null && roms.Length > 0)
machine.Rom = Array.ConvertAll(roms, ConvertFromInternalModel); machine.Rom = Array.ConvertAll(roms, ConvertFromInternalModel);
var disks = item.Read<Data.Models.Metadata.Disk[]>(Data.Models.Metadata.Machine.DiskKey); var disks = item.Read<Data.Models.Metadata.Disk[]>(Data.Models.Metadata.Machine.DiskKey);
if (disks != null && disks.Length > 0) if (disks is not null && disks.Length > 0)
machine.Disk = Array.ConvertAll(disks, ConvertFromInternalModel); machine.Disk = Array.ConvertAll(disks, ConvertFromInternalModel);
var deviceRefs = item.Read<Data.Models.Metadata.DeviceRef[]>(Data.Models.Metadata.Machine.DeviceRefKey); var deviceRefs = item.Read<Data.Models.Metadata.DeviceRef[]>(Data.Models.Metadata.Machine.DeviceRefKey);
if (deviceRefs != null && deviceRefs.Length > 0) if (deviceRefs is not null && deviceRefs.Length > 0)
machine.DeviceRef = Array.ConvertAll(deviceRefs, ConvertFromInternalModel); machine.DeviceRef = Array.ConvertAll(deviceRefs, ConvertFromInternalModel);
var samples = item.Read<Data.Models.Metadata.Sample[]>(Data.Models.Metadata.Machine.SampleKey); var samples = item.Read<Data.Models.Metadata.Sample[]>(Data.Models.Metadata.Machine.SampleKey);
if (samples != null && samples.Length > 0) if (samples is not null && samples.Length > 0)
machine.Sample = Array.ConvertAll(samples, ConvertFromInternalModel); machine.Sample = Array.ConvertAll(samples, ConvertFromInternalModel);
var chips = item.Read<Data.Models.Metadata.Chip[]>(Data.Models.Metadata.Machine.ChipKey); var chips = item.Read<Data.Models.Metadata.Chip[]>(Data.Models.Metadata.Machine.ChipKey);
if (chips != null && chips.Length > 0) if (chips is not null && chips.Length > 0)
machine.Chip = Array.ConvertAll(chips, ConvertFromInternalModel); machine.Chip = Array.ConvertAll(chips, ConvertFromInternalModel);
var displays = item.Read<Data.Models.Metadata.Display[]>(Data.Models.Metadata.Machine.DisplayKey); var displays = item.Read<Data.Models.Metadata.Display[]>(Data.Models.Metadata.Machine.DisplayKey);
if (displays != null && displays.Length > 0) if (displays is not null && displays.Length > 0)
machine.Display = Array.ConvertAll(displays, ConvertFromInternalModel); machine.Display = Array.ConvertAll(displays, ConvertFromInternalModel);
var videos = item.Read<Data.Models.Metadata.Video[]>(Data.Models.Metadata.Machine.VideoKey); var videos = item.Read<Data.Models.Metadata.Video[]>(Data.Models.Metadata.Machine.VideoKey);
if (videos != null && videos.Length > 0) if (videos is not null && videos.Length > 0)
machine.Video = Array.ConvertAll(videos, ConvertFromInternalModel); machine.Video = Array.ConvertAll(videos, ConvertFromInternalModel);
var sound = item.Read<Data.Models.Metadata.Sound>(Data.Models.Metadata.Machine.SoundKey); var sound = item.Read<Data.Models.Metadata.Sound>(Data.Models.Metadata.Machine.SoundKey);
if (sound != null) if (sound is not null)
machine.Sound = ConvertFromInternalModel(sound); machine.Sound = ConvertFromInternalModel(sound);
var input = item.Read<Data.Models.Metadata.Input>(Data.Models.Metadata.Machine.InputKey); var input = item.Read<Data.Models.Metadata.Input>(Data.Models.Metadata.Machine.InputKey);
if (input != null) if (input is not null)
machine.Input = ConvertFromInternalModel(input); machine.Input = ConvertFromInternalModel(input);
var dipSwitches = item.Read<Data.Models.Metadata.DipSwitch[]>(Data.Models.Metadata.Machine.DipSwitchKey); var dipSwitches = item.Read<Data.Models.Metadata.DipSwitch[]>(Data.Models.Metadata.Machine.DipSwitchKey);
if (dipSwitches != null && dipSwitches.Length > 0) if (dipSwitches is not null && dipSwitches.Length > 0)
machine.DipSwitch = Array.ConvertAll(dipSwitches, ConvertFromInternalModel); machine.DipSwitch = Array.ConvertAll(dipSwitches, ConvertFromInternalModel);
var configurations = item.Read<Data.Models.Metadata.Configuration[]>(Data.Models.Metadata.Machine.ConfigurationKey); var configurations = item.Read<Data.Models.Metadata.Configuration[]>(Data.Models.Metadata.Machine.ConfigurationKey);
if (configurations != null && configurations.Length > 0) if (configurations is not null && configurations.Length > 0)
machine.Configuration = Array.ConvertAll(configurations, ConvertFromInternalModel); machine.Configuration = Array.ConvertAll(configurations, ConvertFromInternalModel);
var ports = item.Read<Data.Models.Metadata.Port[]>(Data.Models.Metadata.Machine.PortKey); var ports = item.Read<Data.Models.Metadata.Port[]>(Data.Models.Metadata.Machine.PortKey);
if (ports != null && ports.Length > 0) if (ports is not null && ports.Length > 0)
machine.Port = Array.ConvertAll(ports, ConvertFromInternalModel); machine.Port = Array.ConvertAll(ports, ConvertFromInternalModel);
var adjusters = item.Read<Data.Models.Metadata.Adjuster[]>(Data.Models.Metadata.Machine.AdjusterKey); var adjusters = item.Read<Data.Models.Metadata.Adjuster[]>(Data.Models.Metadata.Machine.AdjusterKey);
if (adjusters != null && adjusters.Length > 0) if (adjusters is not null && adjusters.Length > 0)
machine.Adjuster = Array.ConvertAll(adjusters, ConvertFromInternalModel); machine.Adjuster = Array.ConvertAll(adjusters, ConvertFromInternalModel);
var driver = item.Read<Data.Models.Metadata.Driver>(Data.Models.Metadata.Machine.DriverKey); var driver = item.Read<Data.Models.Metadata.Driver>(Data.Models.Metadata.Machine.DriverKey);
if (driver != null) if (driver is not null)
machine.Driver = ConvertFromInternalModel(driver); machine.Driver = ConvertFromInternalModel(driver);
var features = item.Read<Data.Models.Metadata.Feature[]>(Data.Models.Metadata.Machine.FeatureKey); var features = item.Read<Data.Models.Metadata.Feature[]>(Data.Models.Metadata.Machine.FeatureKey);
if (features != null && features.Length > 0) if (features is not null && features.Length > 0)
machine.Feature = Array.ConvertAll(features, ConvertFromInternalModel); machine.Feature = Array.ConvertAll(features, ConvertFromInternalModel);
var devices = item.Read<Data.Models.Metadata.Device[]>(Data.Models.Metadata.Machine.DeviceKey); var devices = item.Read<Data.Models.Metadata.Device[]>(Data.Models.Metadata.Machine.DeviceKey);
if (devices != null && devices.Length > 0) if (devices is not null && devices.Length > 0)
machine.Device = Array.ConvertAll(devices, ConvertFromInternalModel); machine.Device = Array.ConvertAll(devices, ConvertFromInternalModel);
var slots = item.Read<Data.Models.Metadata.Slot[]>(Data.Models.Metadata.Machine.SlotKey); var slots = item.Read<Data.Models.Metadata.Slot[]>(Data.Models.Metadata.Machine.SlotKey);
if (slots != null && slots.Length > 0) if (slots is not null && slots.Length > 0)
machine.Slot = Array.ConvertAll(slots, ConvertFromInternalModel); machine.Slot = Array.ConvertAll(slots, ConvertFromInternalModel);
var softwareLists = item.Read<Data.Models.Metadata.SoftwareList[]>(Data.Models.Metadata.Machine.SoftwareListKey); var softwareLists = item.Read<Data.Models.Metadata.SoftwareList[]>(Data.Models.Metadata.Machine.SoftwareListKey);
if (softwareLists != null && softwareLists.Length > 0) if (softwareLists is not null && softwareLists.Length > 0)
machine.SoftwareList = Array.ConvertAll(softwareLists, ConvertFromInternalModel); machine.SoftwareList = Array.ConvertAll(softwareLists, ConvertFromInternalModel);
var ramOptions = item.Read<Data.Models.Metadata.RamOption[]>(Data.Models.Metadata.Machine.RamOptionKey); var ramOptions = item.Read<Data.Models.Metadata.RamOption[]>(Data.Models.Metadata.Machine.RamOptionKey);
if (ramOptions != null && ramOptions.Length > 0) if (ramOptions is not null && ramOptions.Length > 0)
machine.RamOption = Array.ConvertAll(ramOptions, ConvertFromInternalModel); machine.RamOption = Array.ConvertAll(ramOptions, ConvertFromInternalModel);
return machine; return machine;
@@ -153,7 +153,7 @@ namespace SabreTools.Serialization.CrossModel
}; };
var condition = item.Read<Data.Models.Metadata.Condition>(Data.Models.Metadata.Adjuster.ConditionKey); var condition = item.Read<Data.Models.Metadata.Condition>(Data.Models.Metadata.Adjuster.ConditionKey);
if (condition != null) if (condition is not null)
adjuster.Condition = ConvertFromInternalModel(condition); adjuster.Condition = ConvertFromInternalModel(condition);
return adjuster; return adjuster;
@@ -229,15 +229,15 @@ namespace SabreTools.Serialization.CrossModel
}; };
var condition = item.Read<Data.Models.Metadata.Condition>(Data.Models.Metadata.Configuration.ConditionKey); var condition = item.Read<Data.Models.Metadata.Condition>(Data.Models.Metadata.Configuration.ConditionKey);
if (condition != null) if (condition is not null)
configuration.Condition = ConvertFromInternalModel(condition); configuration.Condition = ConvertFromInternalModel(condition);
var confLocations = item.Read<Data.Models.Metadata.ConfLocation[]>(Data.Models.Metadata.Configuration.ConfLocationKey); var confLocations = item.Read<Data.Models.Metadata.ConfLocation[]>(Data.Models.Metadata.Configuration.ConfLocationKey);
if (confLocations != null && confLocations.Length > 0) if (confLocations is not null && confLocations.Length > 0)
configuration.ConfLocation = Array.ConvertAll(confLocations, ConvertFromInternalModel); configuration.ConfLocation = Array.ConvertAll(confLocations, ConvertFromInternalModel);
var confSettings = item.Read<Data.Models.Metadata.ConfSetting[]>(Data.Models.Metadata.Configuration.ConfSettingKey); var confSettings = item.Read<Data.Models.Metadata.ConfSetting[]>(Data.Models.Metadata.Configuration.ConfSettingKey);
if (confSettings != null && confSettings.Length > 0) if (confSettings is not null && confSettings.Length > 0)
configuration.ConfSetting = Array.ConvertAll(confSettings, ConvertFromInternalModel); configuration.ConfSetting = Array.ConvertAll(confSettings, ConvertFromInternalModel);
return configuration; return configuration;
@@ -270,7 +270,7 @@ namespace SabreTools.Serialization.CrossModel
}; };
var condition = item.Read<Data.Models.Metadata.Condition>(Data.Models.Metadata.ConfSetting.ConditionKey); var condition = item.Read<Data.Models.Metadata.Condition>(Data.Models.Metadata.ConfSetting.ConditionKey);
if (condition != null) if (condition is not null)
confSetting.Condition = ConvertFromInternalModel(condition); confSetting.Condition = ConvertFromInternalModel(condition);
return confSetting; return confSetting;
@@ -314,11 +314,11 @@ namespace SabreTools.Serialization.CrossModel
}; };
var instance = item.Read<Data.Models.Metadata.Instance>(Data.Models.Metadata.Device.InstanceKey); var instance = item.Read<Data.Models.Metadata.Instance>(Data.Models.Metadata.Device.InstanceKey);
if (instance != null) if (instance is not null)
device.Instance = ConvertFromInternalModel(instance); device.Instance = ConvertFromInternalModel(instance);
var extensions = item.Read<Data.Models.Metadata.Extension[]>(Data.Models.Metadata.Device.ExtensionKey); var extensions = item.Read<Data.Models.Metadata.Extension[]>(Data.Models.Metadata.Device.ExtensionKey);
if (extensions != null && extensions.Length > 0) if (extensions is not null && extensions.Length > 0)
device.Extension = Array.ConvertAll(extensions, ConvertFromInternalModel); device.Extension = Array.ConvertAll(extensions, ConvertFromInternalModel);
return device; return device;
@@ -363,15 +363,15 @@ namespace SabreTools.Serialization.CrossModel
}; };
var condition = item.Read<Data.Models.Metadata.Condition>(Data.Models.Metadata.DipSwitch.ConditionKey); var condition = item.Read<Data.Models.Metadata.Condition>(Data.Models.Metadata.DipSwitch.ConditionKey);
if (condition != null) if (condition is not null)
dipSwitch.Condition = ConvertFromInternalModel(condition); dipSwitch.Condition = ConvertFromInternalModel(condition);
var dipLocations = item.Read<Data.Models.Metadata.DipLocation[]>(Data.Models.Metadata.DipSwitch.DipLocationKey); var dipLocations = item.Read<Data.Models.Metadata.DipLocation[]>(Data.Models.Metadata.DipSwitch.DipLocationKey);
if (dipLocations != null && dipLocations.Length > 0) if (dipLocations is not null && dipLocations.Length > 0)
dipSwitch.DipLocation = Array.ConvertAll(dipLocations, ConvertFromInternalModel); dipSwitch.DipLocation = Array.ConvertAll(dipLocations, ConvertFromInternalModel);
var dipValues = item.Read<Data.Models.Metadata.DipValue[]>(Data.Models.Metadata.DipSwitch.DipValueKey); var dipValues = item.Read<Data.Models.Metadata.DipValue[]>(Data.Models.Metadata.DipSwitch.DipValueKey);
if (dipValues != null && dipValues.Length > 0) if (dipValues is not null && dipValues.Length > 0)
dipSwitch.DipValue = Array.ConvertAll(dipValues, ConvertFromInternalModel); dipSwitch.DipValue = Array.ConvertAll(dipValues, ConvertFromInternalModel);
return dipSwitch; return dipSwitch;
@@ -390,7 +390,7 @@ namespace SabreTools.Serialization.CrossModel
}; };
var condition = item.Read<Data.Models.Metadata.Condition>(Data.Models.Metadata.DipValue.ConditionKey); var condition = item.Read<Data.Models.Metadata.Condition>(Data.Models.Metadata.DipValue.ConditionKey);
if (condition != null) if (condition is not null)
dipValue.Condition = ConvertFromInternalModel(condition); dipValue.Condition = ConvertFromInternalModel(condition);
return dipValue; return dipValue;
@@ -504,11 +504,11 @@ namespace SabreTools.Serialization.CrossModel
}; };
var controlAttr = item.ReadString(Data.Models.Metadata.Input.ControlKey); var controlAttr = item.ReadString(Data.Models.Metadata.Input.ControlKey);
if (controlAttr != null) if (controlAttr is not null)
input.ControlAttr = controlAttr; input.ControlAttr = controlAttr;
var controls = item.Read<Data.Models.Metadata.Control[]>(Data.Models.Metadata.Input.ControlKey); var controls = item.Read<Data.Models.Metadata.Control[]>(Data.Models.Metadata.Input.ControlKey);
if (controls != null && controls.Length > 0) if (controls is not null && controls.Length > 0)
input.Control = Array.ConvertAll(controls, ConvertFromInternalModel); input.Control = Array.ConvertAll(controls, ConvertFromInternalModel);
return input; return input;
@@ -538,7 +538,7 @@ namespace SabreTools.Serialization.CrossModel
}; };
var analogs = item.Read<Data.Models.Metadata.Analog[]>(Data.Models.Metadata.Port.AnalogKey); var analogs = item.Read<Data.Models.Metadata.Analog[]>(Data.Models.Metadata.Port.AnalogKey);
if (analogs != null && analogs.Length > 0) if (analogs is not null && analogs.Length > 0)
port.Analog = Array.ConvertAll(analogs, ConvertFromInternalModel); port.Analog = Array.ConvertAll(analogs, ConvertFromInternalModel);
return port; return port;
@@ -604,7 +604,7 @@ namespace SabreTools.Serialization.CrossModel
}; };
var slotOptions = item.Read<Data.Models.Metadata.SlotOption[]>(Data.Models.Metadata.Slot.SlotOptionKey); var slotOptions = item.Read<Data.Models.Metadata.SlotOption[]>(Data.Models.Metadata.Slot.SlotOptionKey);
if (slotOptions != null && slotOptions.Length > 0) if (slotOptions is not null && slotOptions.Length > 0)
slot.SlotOption = Array.ConvertAll(slotOptions, ConvertFromInternalModel); slot.SlotOption = Array.ConvertAll(slotOptions, ConvertFromInternalModel);
return slot; return slot;

View File

@@ -8,7 +8,7 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(Mame? item) public override Data.Models.Metadata.MetadataFile? Serialize(Mame? item)
{ {
if (item == null) if (item is null)
return null; return null;
var metadataFile = new Data.Models.Metadata.MetadataFile var metadataFile = new Data.Models.Metadata.MetadataFile
@@ -16,7 +16,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item), [Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
}; };
if (item?.Game != null && item.Game.Length > 0) if (item?.Game is not null && item.Game.Length > 0)
{ {
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey] metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(item.Game, ConvertMachineToInternalModel); = Array.ConvertAll(item.Game, ConvertMachineToInternalModel);
@@ -61,112 +61,112 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.Machine.HistoryKey] = item.History, [Data.Models.Metadata.Machine.HistoryKey] = item.History,
}; };
if (item.BiosSet != null && item.BiosSet.Length > 0) if (item.BiosSet is not null && item.BiosSet.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.BiosSetKey] machine[Data.Models.Metadata.Machine.BiosSetKey]
= Array.ConvertAll(item.BiosSet, ConvertToInternalModel); = Array.ConvertAll(item.BiosSet, ConvertToInternalModel);
} }
if (item.Rom != null && item.Rom.Length > 0) if (item.Rom is not null && item.Rom.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.RomKey] machine[Data.Models.Metadata.Machine.RomKey]
= Array.ConvertAll(item.Rom, ConvertToInternalModel); = Array.ConvertAll(item.Rom, ConvertToInternalModel);
} }
if (item.Disk != null && item.Disk.Length > 0) if (item.Disk is not null && item.Disk.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.DiskKey] machine[Data.Models.Metadata.Machine.DiskKey]
= Array.ConvertAll(item.Disk, ConvertToInternalModel); = Array.ConvertAll(item.Disk, ConvertToInternalModel);
} }
if (item.DeviceRef != null && item.DeviceRef.Length > 0) if (item.DeviceRef is not null && item.DeviceRef.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.DeviceRefKey] machine[Data.Models.Metadata.Machine.DeviceRefKey]
= Array.ConvertAll(item.DeviceRef, ConvertToInternalModel); = Array.ConvertAll(item.DeviceRef, ConvertToInternalModel);
} }
if (item.Sample != null && item.Sample.Length > 0) if (item.Sample is not null && item.Sample.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.SampleKey] machine[Data.Models.Metadata.Machine.SampleKey]
= Array.ConvertAll(item.Sample, ConvertToInternalModel); = Array.ConvertAll(item.Sample, ConvertToInternalModel);
} }
if (item.Chip != null && item.Chip.Length > 0) if (item.Chip is not null && item.Chip.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.ChipKey] machine[Data.Models.Metadata.Machine.ChipKey]
= Array.ConvertAll(item.Chip, ConvertToInternalModel); = Array.ConvertAll(item.Chip, ConvertToInternalModel);
} }
if (item.Display != null && item.Display.Length > 0) if (item.Display is not null && item.Display.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.DisplayKey] machine[Data.Models.Metadata.Machine.DisplayKey]
= Array.ConvertAll(item.Display, ConvertToInternalModel); = Array.ConvertAll(item.Display, ConvertToInternalModel);
} }
if (item.Video != null && item.Video.Length > 0) if (item.Video is not null && item.Video.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.VideoKey] machine[Data.Models.Metadata.Machine.VideoKey]
= Array.ConvertAll(item.Video, ConvertToInternalModel); = Array.ConvertAll(item.Video, ConvertToInternalModel);
} }
if (item.Sound != null) if (item.Sound is not null)
machine[Data.Models.Metadata.Machine.SoundKey] = ConvertToInternalModel(item.Sound); machine[Data.Models.Metadata.Machine.SoundKey] = ConvertToInternalModel(item.Sound);
if (item.Input != null) if (item.Input is not null)
machine[Data.Models.Metadata.Machine.InputKey] = ConvertToInternalModel(item.Input); machine[Data.Models.Metadata.Machine.InputKey] = ConvertToInternalModel(item.Input);
if (item.DipSwitch != null && item.DipSwitch.Length > 0) if (item.DipSwitch is not null && item.DipSwitch.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.DipSwitchKey] machine[Data.Models.Metadata.Machine.DipSwitchKey]
= Array.ConvertAll(item.DipSwitch, ConvertToInternalModel); = Array.ConvertAll(item.DipSwitch, ConvertToInternalModel);
} }
if (item.Configuration != null && item.Configuration.Length > 0) if (item.Configuration is not null && item.Configuration.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.ConfigurationKey] machine[Data.Models.Metadata.Machine.ConfigurationKey]
= Array.ConvertAll(item.Configuration, ConvertToInternalModel); = Array.ConvertAll(item.Configuration, ConvertToInternalModel);
} }
if (item.Port != null && item.Port.Length > 0) if (item.Port is not null && item.Port.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.PortKey] machine[Data.Models.Metadata.Machine.PortKey]
= Array.ConvertAll(item.Port, ConvertToInternalModel); = Array.ConvertAll(item.Port, ConvertToInternalModel);
} }
if (item.Adjuster != null && item.Adjuster.Length > 0) if (item.Adjuster is not null && item.Adjuster.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.AdjusterKey] machine[Data.Models.Metadata.Machine.AdjusterKey]
= Array.ConvertAll(item.Adjuster, ConvertToInternalModel); = Array.ConvertAll(item.Adjuster, ConvertToInternalModel);
} }
if (item.Driver != null) if (item.Driver is not null)
machine[Data.Models.Metadata.Machine.DriverKey] = ConvertToInternalModel(item.Driver); machine[Data.Models.Metadata.Machine.DriverKey] = ConvertToInternalModel(item.Driver);
if (item.Feature != null && item.Feature.Length > 0) if (item.Feature is not null && item.Feature.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.FeatureKey] machine[Data.Models.Metadata.Machine.FeatureKey]
= Array.ConvertAll(item.Feature, ConvertToInternalModel); = Array.ConvertAll(item.Feature, ConvertToInternalModel);
} }
if (item.Device != null && item.Device.Length > 0) if (item.Device is not null && item.Device.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.DeviceKey] machine[Data.Models.Metadata.Machine.DeviceKey]
= Array.ConvertAll(item.Device, ConvertToInternalModel); = Array.ConvertAll(item.Device, ConvertToInternalModel);
} }
if (item.Slot != null && item.Slot.Length > 0) if (item.Slot is not null && item.Slot.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.SlotKey] machine[Data.Models.Metadata.Machine.SlotKey]
= Array.ConvertAll(item.Slot, ConvertToInternalModel); = Array.ConvertAll(item.Slot, ConvertToInternalModel);
} }
if (item.SoftwareList != null && item.SoftwareList.Length > 0) if (item.SoftwareList is not null && item.SoftwareList.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.SoftwareListKey] machine[Data.Models.Metadata.Machine.SoftwareListKey]
= Array.ConvertAll(item.SoftwareList, ConvertToInternalModel); = Array.ConvertAll(item.SoftwareList, ConvertToInternalModel);
} }
if (item.RamOption != null && item.RamOption.Length > 0) if (item.RamOption is not null && item.RamOption.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.RamOptionKey] machine[Data.Models.Metadata.Machine.RamOptionKey]
= Array.ConvertAll(item.RamOption, ConvertToInternalModel); = Array.ConvertAll(item.RamOption, ConvertToInternalModel);
@@ -186,7 +186,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.Adjuster.DefaultKey] = item.Default, [Data.Models.Metadata.Adjuster.DefaultKey] = item.Default,
}; };
if (item.Condition != null) if (item.Condition is not null)
adjuster[Data.Models.Metadata.Adjuster.ConditionKey] = ConvertToInternalModel(item.Condition); adjuster[Data.Models.Metadata.Adjuster.ConditionKey] = ConvertToInternalModel(item.Condition);
return adjuster; return adjuster;
@@ -261,16 +261,16 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.Configuration.MaskKey] = item.Mask, [Data.Models.Metadata.Configuration.MaskKey] = item.Mask,
}; };
if (item.Condition != null) if (item.Condition is not null)
configuration[Data.Models.Metadata.Configuration.ConditionKey] = ConvertToInternalModel(item.Condition); configuration[Data.Models.Metadata.Configuration.ConditionKey] = ConvertToInternalModel(item.Condition);
if (item.ConfLocation != null && item.ConfLocation.Length > 0) if (item.ConfLocation is not null && item.ConfLocation.Length > 0)
{ {
configuration[Data.Models.Metadata.Configuration.ConfLocationKey] configuration[Data.Models.Metadata.Configuration.ConfLocationKey]
= Array.ConvertAll(item.ConfLocation, ConvertToInternalModel); = Array.ConvertAll(item.ConfLocation, ConvertToInternalModel);
} }
if (item.ConfSetting != null && item.ConfSetting.Length > 0) if (item.ConfSetting is not null && item.ConfSetting.Length > 0)
{ {
configuration[Data.Models.Metadata.Configuration.ConfSettingKey] configuration[Data.Models.Metadata.Configuration.ConfSettingKey]
= Array.ConvertAll(item.ConfSetting, ConvertToInternalModel); = Array.ConvertAll(item.ConfSetting, ConvertToInternalModel);
@@ -305,7 +305,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.ConfSetting.DefaultKey] = item.Default, [Data.Models.Metadata.ConfSetting.DefaultKey] = item.Default,
}; };
if (item.Condition != null) if (item.Condition is not null)
confSetting[Data.Models.Metadata.ConfSetting.ConditionKey] = ConvertToInternalModel(item.Condition); confSetting[Data.Models.Metadata.ConfSetting.ConditionKey] = ConvertToInternalModel(item.Condition);
return confSetting; return confSetting;
@@ -348,10 +348,10 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.Device.InterfaceKey] = item.Interface, [Data.Models.Metadata.Device.InterfaceKey] = item.Interface,
}; };
if (item.Instance != null) if (item.Instance is not null)
device[Data.Models.Metadata.Device.InstanceKey] = ConvertToInternalModel(item.Instance); device[Data.Models.Metadata.Device.InstanceKey] = ConvertToInternalModel(item.Instance);
if (item.Extension != null && item.Extension.Length > 0) if (item.Extension is not null && item.Extension.Length > 0)
{ {
device[Data.Models.Metadata.Device.ExtensionKey] device[Data.Models.Metadata.Device.ExtensionKey]
= Array.ConvertAll(item.Extension, ConvertToInternalModel); = Array.ConvertAll(item.Extension, ConvertToInternalModel);
@@ -398,16 +398,16 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.DipSwitch.MaskKey] = item.Mask, [Data.Models.Metadata.DipSwitch.MaskKey] = item.Mask,
}; };
if (item.Condition != null) if (item.Condition is not null)
dipSwitch[Data.Models.Metadata.DipSwitch.ConditionKey] = ConvertToInternalModel(item.Condition); dipSwitch[Data.Models.Metadata.DipSwitch.ConditionKey] = ConvertToInternalModel(item.Condition);
if (item.DipLocation != null && item.DipLocation.Length > 0) if (item.DipLocation is not null && item.DipLocation.Length > 0)
{ {
dipSwitch[Data.Models.Metadata.DipSwitch.DipLocationKey] dipSwitch[Data.Models.Metadata.DipSwitch.DipLocationKey]
= Array.ConvertAll(item.DipLocation, ConvertToInternalModel); = Array.ConvertAll(item.DipLocation, ConvertToInternalModel);
} }
if (item.DipValue != null && item.DipValue.Length > 0) if (item.DipValue is not null && item.DipValue.Length > 0)
{ {
dipSwitch[Data.Models.Metadata.DipSwitch.DipValueKey] dipSwitch[Data.Models.Metadata.DipSwitch.DipValueKey]
= Array.ConvertAll(item.DipValue, ConvertToInternalModel); = Array.ConvertAll(item.DipValue, ConvertToInternalModel);
@@ -428,7 +428,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.DipValue.DefaultKey] = item.Default, [Data.Models.Metadata.DipValue.DefaultKey] = item.Default,
}; };
if (item.Condition != null) if (item.Condition is not null)
dipValue[Data.Models.Metadata.DipValue.ConditionKey] = ConvertToInternalModel(item.Condition); dipValue[Data.Models.Metadata.DipValue.ConditionKey] = ConvertToInternalModel(item.Condition);
return dipValue; return dipValue;
@@ -542,7 +542,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.Input.CoinsKey] = item.Coins, [Data.Models.Metadata.Input.CoinsKey] = item.Coins,
}; };
if (item.Control != null && item.Control.Length > 0) if (item.Control is not null && item.Control.Length > 0)
{ {
input[Data.Models.Metadata.Input.ControlKey] input[Data.Models.Metadata.Input.ControlKey]
= Array.ConvertAll(item.Control, ConvertToInternalModel); = Array.ConvertAll(item.Control, ConvertToInternalModel);
@@ -574,7 +574,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.Port.TagKey] = item.Tag, [Data.Models.Metadata.Port.TagKey] = item.Tag,
}; };
if (item.Analog != null && item.Analog.Length > 0) if (item.Analog is not null && item.Analog.Length > 0)
{ {
port[Data.Models.Metadata.Port.AnalogKey] port[Data.Models.Metadata.Port.AnalogKey]
= Array.ConvertAll(item.Analog, ConvertToInternalModel); = Array.ConvertAll(item.Analog, ConvertToInternalModel);
@@ -642,7 +642,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.Slot.NameKey] = item.Name, [Data.Models.Metadata.Slot.NameKey] = item.Name,
}; };
if (item.SlotOption != null && item.SlotOption.Length > 0) if (item.SlotOption is not null && item.SlotOption.Length > 0)
{ {
slot[Data.Models.Metadata.Slot.SlotOptionKey] slot[Data.Models.Metadata.Slot.SlotOptionKey]
= Array.ConvertAll(item.SlotOption, ConvertToInternalModel); = Array.ConvertAll(item.SlotOption, ConvertToInternalModel);

View File

@@ -1,6 +1,7 @@
using System; using System;
using SabreTools.Data.Models.Logiqx; using SabreTools.Data.Models.Logiqx;
#pragma warning disable CA1822 // Mark members as static
namespace SabreTools.Serialization.CrossModel namespace SabreTools.Serialization.CrossModel
{ {
public partial class Logiqx : BaseMetadataSerializer<Datafile> public partial class Logiqx : BaseMetadataSerializer<Datafile>
@@ -12,13 +13,13 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public Datafile? Deserialize(Data.Models.Metadata.MetadataFile? obj, bool game) public Datafile? Deserialize(Data.Models.Metadata.MetadataFile? obj, bool game)
{ {
if (obj == null) if (obj is null)
return null; return null;
var datafile = new Datafile(); var datafile = new Datafile();
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey); var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
if (header != null) if (header is not null)
{ {
datafile.Build = header.ReadString(Data.Models.Metadata.Header.BuildKey); datafile.Build = header.ReadString(Data.Models.Metadata.Header.BuildKey);
datafile.Debug = header.ReadString(Data.Models.Metadata.Header.DebugKey); datafile.Debug = header.ReadString(Data.Models.Metadata.Header.DebugKey);
@@ -27,7 +28,7 @@ namespace SabreTools.Serialization.CrossModel
} }
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey); var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Length > 0) if (machines is not null && machines.Length > 0)
datafile.Game = Array.ConvertAll(machines, m => ConvertMachineFromInternalModel(m, game)); datafile.Game = Array.ConvertAll(machines, m => ConvertMachineFromInternalModel(m, game));
return datafile; return datafile;
@@ -60,19 +61,19 @@ namespace SabreTools.Serialization.CrossModel
string? forceNodump = item.ReadString(Data.Models.Metadata.Header.ForceNodumpKey); string? forceNodump = item.ReadString(Data.Models.Metadata.Header.ForceNodumpKey);
string? forceUnpacking = item.ReadString(Data.Models.Metadata.Header.ForcePackingKey); string? forceUnpacking = item.ReadString(Data.Models.Metadata.Header.ForcePackingKey);
if (headerVal != null if (headerVal is not null
|| forceMerging != null || forceMerging is not null
|| forceNodump != null || forceNodump is not null
|| forceUnpacking != null) || forceUnpacking is not null)
{ {
header.ClrMamePro = new Data.Models.Logiqx.ClrMamePro(); header.ClrMamePro = new Data.Models.Logiqx.ClrMamePro();
if (headerVal != null) if (headerVal is not null)
header.ClrMamePro.Header = headerVal; header.ClrMamePro.Header = headerVal;
if (forceMerging != null) if (forceMerging is not null)
header.ClrMamePro.ForceMerging = forceMerging; header.ClrMamePro.ForceMerging = forceMerging;
if (forceNodump != null) if (forceNodump is not null)
header.ClrMamePro.ForceNodump = forceNodump; header.ClrMamePro.ForceNodump = forceNodump;
if (forceUnpacking != null) if (forceUnpacking is not null)
header.ClrMamePro.ForcePacking = forceUnpacking; header.ClrMamePro.ForcePacking = forceUnpacking;
} }
@@ -84,28 +85,28 @@ namespace SabreTools.Serialization.CrossModel
string? lockBiosMode = item.ReadString(Data.Models.Metadata.Header.LockBiosModeKey); string? lockBiosMode = item.ReadString(Data.Models.Metadata.Header.LockBiosModeKey);
string? lockSampleMode = item.ReadString(Data.Models.Metadata.Header.LockSampleModeKey); string? lockSampleMode = item.ReadString(Data.Models.Metadata.Header.LockSampleModeKey);
if (plugin != null if (plugin is not null
|| romMode != null || romMode is not null
|| biosMode != null || biosMode is not null
|| sampleMode != null || sampleMode is not null
|| lockRomMode != null || lockRomMode is not null
|| lockBiosMode != null || lockBiosMode is not null
|| lockSampleMode != null) || lockSampleMode is not null)
{ {
header.RomCenter = new Data.Models.Logiqx.RomCenter(); header.RomCenter = new Data.Models.Logiqx.RomCenter();
if (plugin != null) if (plugin is not null)
header.RomCenter.Plugin = plugin; header.RomCenter.Plugin = plugin;
if (romMode != null) if (romMode is not null)
header.RomCenter.RomMode = romMode; header.RomCenter.RomMode = romMode;
if (biosMode != null) if (biosMode is not null)
header.RomCenter.BiosMode = biosMode; header.RomCenter.BiosMode = biosMode;
if (sampleMode != null) if (sampleMode is not null)
header.RomCenter.SampleMode = sampleMode; header.RomCenter.SampleMode = sampleMode;
if (lockRomMode != null) if (lockRomMode is not null)
header.RomCenter.LockRomMode = lockRomMode; header.RomCenter.LockRomMode = lockRomMode;
if (lockBiosMode != null) if (lockBiosMode is not null)
header.RomCenter.LockBiosMode = lockBiosMode; header.RomCenter.LockBiosMode = lockBiosMode;
if (lockSampleMode != null) if (lockSampleMode is not null)
header.RomCenter.LockSampleMode = lockSampleMode; header.RomCenter.LockSampleMode = lockSampleMode;
} }
@@ -140,47 +141,47 @@ namespace SabreTools.Serialization.CrossModel
gameBase.Category = item.ReadStringArray(Data.Models.Metadata.Machine.CategoryKey); gameBase.Category = item.ReadStringArray(Data.Models.Metadata.Machine.CategoryKey);
var trurip = item.Read<Trurip>(Data.Models.Metadata.Machine.TruripKey); var trurip = item.Read<Trurip>(Data.Models.Metadata.Machine.TruripKey);
if (trurip != null) if (trurip is not null)
gameBase.Trurip = trurip; gameBase.Trurip = trurip;
var releases = item.Read<Data.Models.Metadata.Release[]>(Data.Models.Metadata.Machine.ReleaseKey); var releases = item.Read<Data.Models.Metadata.Release[]>(Data.Models.Metadata.Machine.ReleaseKey);
if (releases != null && releases.Length > 0) if (releases is not null && releases.Length > 0)
gameBase.Release = Array.ConvertAll(releases, ConvertFromInternalModel); gameBase.Release = Array.ConvertAll(releases, ConvertFromInternalModel);
var biosSets = item.Read<Data.Models.Metadata.BiosSet[]>(Data.Models.Metadata.Machine.BiosSetKey); var biosSets = item.Read<Data.Models.Metadata.BiosSet[]>(Data.Models.Metadata.Machine.BiosSetKey);
if (biosSets != null && biosSets.Length > 0) if (biosSets is not null && biosSets.Length > 0)
gameBase.BiosSet = Array.ConvertAll(biosSets, ConvertFromInternalModel); gameBase.BiosSet = Array.ConvertAll(biosSets, ConvertFromInternalModel);
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey); var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms != null && roms.Length > 0) if (roms is not null && roms.Length > 0)
gameBase.Rom = Array.ConvertAll(roms, ConvertFromInternalModel); gameBase.Rom = Array.ConvertAll(roms, ConvertFromInternalModel);
var disks = item.Read<Data.Models.Metadata.Disk[]>(Data.Models.Metadata.Machine.DiskKey); var disks = item.Read<Data.Models.Metadata.Disk[]>(Data.Models.Metadata.Machine.DiskKey);
if (disks != null && disks.Length > 0) if (disks is not null && disks.Length > 0)
gameBase.Disk = Array.ConvertAll(disks, ConvertFromInternalModel); gameBase.Disk = Array.ConvertAll(disks, ConvertFromInternalModel);
var medias = item.Read<Data.Models.Metadata.Media[]>(Data.Models.Metadata.Machine.MediaKey); var medias = item.Read<Data.Models.Metadata.Media[]>(Data.Models.Metadata.Machine.MediaKey);
if (medias != null && medias.Length > 0) if (medias is not null && medias.Length > 0)
gameBase.Media = Array.ConvertAll(medias, ConvertFromInternalModel); gameBase.Media = Array.ConvertAll(medias, ConvertFromInternalModel);
var deviceRefs = item.Read<Data.Models.Metadata.DeviceRef[]>(Data.Models.Metadata.Machine.DeviceRefKey); var deviceRefs = item.Read<Data.Models.Metadata.DeviceRef[]>(Data.Models.Metadata.Machine.DeviceRefKey);
if (deviceRefs != null && deviceRefs.Length > 0) if (deviceRefs is not null && deviceRefs.Length > 0)
gameBase.DeviceRef = Array.ConvertAll(deviceRefs, ConvertFromInternalModel); gameBase.DeviceRef = Array.ConvertAll(deviceRefs, ConvertFromInternalModel);
var samples = item.Read<Data.Models.Metadata.Sample[]>(Data.Models.Metadata.Machine.SampleKey); var samples = item.Read<Data.Models.Metadata.Sample[]>(Data.Models.Metadata.Machine.SampleKey);
if (samples != null && samples.Length > 0) if (samples is not null && samples.Length > 0)
gameBase.Sample = Array.ConvertAll(samples, ConvertFromInternalModel); gameBase.Sample = Array.ConvertAll(samples, ConvertFromInternalModel);
var archives = item.Read<Data.Models.Metadata.Archive[]>(Data.Models.Metadata.Machine.ArchiveKey); var archives = item.Read<Data.Models.Metadata.Archive[]>(Data.Models.Metadata.Machine.ArchiveKey);
if (archives != null && archives.Length > 0) if (archives is not null && archives.Length > 0)
gameBase.Archive = Array.ConvertAll(archives, ConvertFromInternalModel); gameBase.Archive = Array.ConvertAll(archives, ConvertFromInternalModel);
var driver = item.Read<Data.Models.Metadata.Driver>(Data.Models.Metadata.Machine.DriverKey); var driver = item.Read<Data.Models.Metadata.Driver>(Data.Models.Metadata.Machine.DriverKey);
if (driver != null) if (driver is not null)
gameBase.Driver = ConvertFromInternalModel(driver); gameBase.Driver = ConvertFromInternalModel(driver);
var softwareLists = item.Read<Data.Models.Metadata.SoftwareList[]>(Data.Models.Metadata.Machine.SoftwareListKey); var softwareLists = item.Read<Data.Models.Metadata.SoftwareList[]>(Data.Models.Metadata.Machine.SoftwareListKey);
if (softwareLists != null && softwareLists.Length > 0) if (softwareLists is not null && softwareLists.Length > 0)
gameBase.SoftwareList = Array.ConvertAll(softwareLists, ConvertFromInternalModel); gameBase.SoftwareList = Array.ConvertAll(softwareLists, ConvertFromInternalModel);
return gameBase; return gameBase;
@@ -301,7 +302,9 @@ namespace SabreTools.Serialization.CrossModel
{ {
Name = item.ReadString(Data.Models.Metadata.Rom.NameKey), Name = item.ReadString(Data.Models.Metadata.Rom.NameKey),
Size = item.ReadString(Data.Models.Metadata.Rom.SizeKey), Size = item.ReadString(Data.Models.Metadata.Rom.SizeKey),
CRC16 = item.ReadString(Data.Models.Metadata.Rom.CRC16Key),
CRC = item.ReadString(Data.Models.Metadata.Rom.CRCKey), CRC = item.ReadString(Data.Models.Metadata.Rom.CRCKey),
CRC64 = item.ReadString(Data.Models.Metadata.Rom.CRC64Key),
MD2 = item.ReadString(Data.Models.Metadata.Rom.MD2Key), MD2 = item.ReadString(Data.Models.Metadata.Rom.MD2Key),
MD4 = item.ReadString(Data.Models.Metadata.Rom.MD4Key), MD4 = item.ReadString(Data.Models.Metadata.Rom.MD4Key),
MD5 = item.ReadString(Data.Models.Metadata.Rom.MD5Key), MD5 = item.ReadString(Data.Models.Metadata.Rom.MD5Key),

View File

@@ -8,7 +8,7 @@ namespace SabreTools.Serialization.CrossModel
{ {
public override Data.Models.Metadata.MetadataFile? Serialize(Datafile? item) public override Data.Models.Metadata.MetadataFile? Serialize(Datafile? item)
{ {
if (item == null) if (item is null)
return null; return null;
var metadataFile = new Data.Models.Metadata.MetadataFile var metadataFile = new Data.Models.Metadata.MetadataFile
@@ -18,7 +18,7 @@ namespace SabreTools.Serialization.CrossModel
var machines = new List<Data.Models.Metadata.Machine>(); var machines = new List<Data.Models.Metadata.Machine>();
if (item.Game != null && item.Game.Length > 0) if (item.Game is not null && item.Game.Length > 0)
machines.AddRange(Array.ConvertAll(item.Game, g => ConvertMachineToInternalModel(g))); machines.AddRange(Array.ConvertAll(item.Game, g => ConvertMachineToInternalModel(g)));
foreach (var dir in item.Dir ?? []) foreach (var dir in item.Dir ?? [])
@@ -37,7 +37,7 @@ namespace SabreTools.Serialization.CrossModel
/// </summary> /// </summary>
private static Data.Models.Metadata.Header ConvertHeaderToInternalModel(Datafile item) private static Data.Models.Metadata.Header ConvertHeaderToInternalModel(Datafile item)
{ {
var header = item.Header != null ? ConvertHeaderToInternalModel(item.Header) : []; var header = item.Header is not null ? ConvertHeaderToInternalModel(item.Header) : [];
header[Data.Models.Metadata.Header.BuildKey] = item.Build; header[Data.Models.Metadata.Header.BuildKey] = item.Build;
header[Data.Models.Metadata.Header.DebugKey] = item.Debug; header[Data.Models.Metadata.Header.DebugKey] = item.Debug;
@@ -68,7 +68,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.Header.TypeKey] = item.Type, [Data.Models.Metadata.Header.TypeKey] = item.Type,
}; };
if (item.ClrMamePro != null) if (item.ClrMamePro is not null)
{ {
header[Data.Models.Metadata.Header.HeaderKey] = item.ClrMamePro.Header; header[Data.Models.Metadata.Header.HeaderKey] = item.ClrMamePro.Header;
header[Data.Models.Metadata.Header.ForceMergingKey] = item.ClrMamePro.ForceMerging; header[Data.Models.Metadata.Header.ForceMergingKey] = item.ClrMamePro.ForceMerging;
@@ -76,7 +76,7 @@ namespace SabreTools.Serialization.CrossModel
header[Data.Models.Metadata.Header.ForcePackingKey] = item.ClrMamePro.ForcePacking; header[Data.Models.Metadata.Header.ForcePackingKey] = item.ClrMamePro.ForcePacking;
} }
if (item.RomCenter != null) if (item.RomCenter is not null)
{ {
header[Data.Models.Metadata.Header.PluginKey] = item.RomCenter.Plugin; header[Data.Models.Metadata.Header.PluginKey] = item.RomCenter.Plugin;
header[Data.Models.Metadata.Header.RomModeKey] = item.RomCenter.RomMode; header[Data.Models.Metadata.Header.RomModeKey] = item.RomCenter.RomMode;
@@ -97,12 +97,12 @@ namespace SabreTools.Serialization.CrossModel
{ {
// Get the directory name // Get the directory name
string? dirName = item.Name; string? dirName = item.Name;
if (parent != null) if (parent is not null)
dirName = $"{parent}\\{item.Name}"; dirName = $"{parent}\\{item.Name}";
// Handle machine items // Handle machine items
Data.Models.Metadata.Machine[] machines = []; Data.Models.Metadata.Machine[] machines = [];
if (item.Game != null && item.Game.Length > 0) if (item.Game is not null && item.Game.Length > 0)
machines = Array.ConvertAll(item.Game, g => ConvertMachineToInternalModel(g, dirName)); machines = Array.ConvertAll(item.Game, g => ConvertMachineToInternalModel(g, dirName));
// Handle dir items // Handle dir items
@@ -121,7 +121,7 @@ namespace SabreTools.Serialization.CrossModel
private static Data.Models.Metadata.Machine ConvertMachineToInternalModel(GameBase item, string? dir = null) private static Data.Models.Metadata.Machine ConvertMachineToInternalModel(GameBase item, string? dir = null)
{ {
string? machineName = item.Name; string? machineName = item.Name;
if (machineName != null && dir != null) if (machineName is not null && dir is not null)
machineName = $"{dir}\\{machineName}"; machineName = $"{dir}\\{machineName}";
var machine = new Data.Models.Metadata.Machine var machine = new Data.Models.Metadata.Machine
@@ -148,34 +148,34 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.Machine.TruripKey] = item.Trurip, [Data.Models.Metadata.Machine.TruripKey] = item.Trurip,
}; };
if (item.Release != null && item.Release.Length > 0) if (item.Release is not null && item.Release.Length > 0)
machine[Data.Models.Metadata.Machine.ReleaseKey] = Array.ConvertAll(item.Release, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.ReleaseKey] = Array.ConvertAll(item.Release, ConvertToInternalModel);
if (item.BiosSet != null && item.BiosSet.Length > 0) if (item.BiosSet is not null && item.BiosSet.Length > 0)
machine[Data.Models.Metadata.Machine.BiosSetKey] = Array.ConvertAll(item.BiosSet, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.BiosSetKey] = Array.ConvertAll(item.BiosSet, ConvertToInternalModel);
if (item.Rom != null && item.Rom.Length > 0) if (item.Rom is not null && item.Rom.Length > 0)
machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.Rom, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.RomKey] = Array.ConvertAll(item.Rom, ConvertToInternalModel);
if (item.Disk != null && item.Disk.Length > 0) if (item.Disk is not null && item.Disk.Length > 0)
machine[Data.Models.Metadata.Machine.DiskKey] = Array.ConvertAll(item.Disk, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.DiskKey] = Array.ConvertAll(item.Disk, ConvertToInternalModel);
if (item.Media != null && item.Media.Length > 0) if (item.Media is not null && item.Media.Length > 0)
machine[Data.Models.Metadata.Machine.MediaKey] = Array.ConvertAll(item.Media, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.MediaKey] = Array.ConvertAll(item.Media, ConvertToInternalModel);
if (item.DeviceRef != null && item.DeviceRef.Length > 0) if (item.DeviceRef is not null && item.DeviceRef.Length > 0)
machine[Data.Models.Metadata.Machine.DeviceRefKey] = Array.ConvertAll(item.DeviceRef, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.DeviceRefKey] = Array.ConvertAll(item.DeviceRef, ConvertToInternalModel);
if (item.Sample != null && item.Sample.Length > 0) if (item.Sample is not null && item.Sample.Length > 0)
machine[Data.Models.Metadata.Machine.SampleKey] = Array.ConvertAll(item.Sample, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.SampleKey] = Array.ConvertAll(item.Sample, ConvertToInternalModel);
if (item.Archive != null && item.Archive.Length > 0) if (item.Archive is not null && item.Archive.Length > 0)
machine[Data.Models.Metadata.Machine.ArchiveKey] = Array.ConvertAll(item.Archive, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.ArchiveKey] = Array.ConvertAll(item.Archive, ConvertToInternalModel);
if (item.Driver != null) if (item.Driver is not null)
machine[Data.Models.Metadata.Machine.DriverKey] = ConvertToInternalModel(item.Driver); machine[Data.Models.Metadata.Machine.DriverKey] = ConvertToInternalModel(item.Driver);
if (item.SoftwareList != null && item.SoftwareList.Length > 0) if (item.SoftwareList is not null && item.SoftwareList.Length > 0)
machine[Data.Models.Metadata.Machine.SoftwareListKey] = Array.ConvertAll(item.SoftwareList, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.SoftwareListKey] = Array.ConvertAll(item.SoftwareList, ConvertToInternalModel);
return machine; return machine;
@@ -296,7 +296,9 @@ namespace SabreTools.Serialization.CrossModel
{ {
[Data.Models.Metadata.Rom.NameKey] = item.Name, [Data.Models.Metadata.Rom.NameKey] = item.Name,
[Data.Models.Metadata.Rom.SizeKey] = item.Size, [Data.Models.Metadata.Rom.SizeKey] = item.Size,
[Data.Models.Metadata.Rom.CRC16Key] = item.CRC16,
[Data.Models.Metadata.Rom.CRCKey] = item.CRC, [Data.Models.Metadata.Rom.CRCKey] = item.CRC,
[Data.Models.Metadata.Rom.CRC64Key] = item.CRC64,
[Data.Models.Metadata.Rom.MD2Key] = item.MD2, [Data.Models.Metadata.Rom.MD2Key] = item.MD2,
[Data.Models.Metadata.Rom.MD4Key] = item.MD4, [Data.Models.Metadata.Rom.MD4Key] = item.MD4,
[Data.Models.Metadata.Rom.MD5Key] = item.MD5, [Data.Models.Metadata.Rom.MD5Key] = item.MD5,

View File

@@ -7,14 +7,14 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Data.Models.Listxml.M1? Deserialize(Data.Models.Metadata.MetadataFile? obj) public override Data.Models.Listxml.M1? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey); var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
var m1 = header != null ? ConvertM1FromInternalModel(header) : new Data.Models.Listxml.M1(); var m1 = header is not null ? ConvertM1FromInternalModel(header) : new Data.Models.Listxml.M1();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey); var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Length > 0) if (machines is not null && machines.Length > 0)
m1.Game = Array.ConvertAll(machines, Listxml.ConvertMachineFromInternalModel); m1.Game = Array.ConvertAll(machines, Listxml.ConvertMachineFromInternalModel);
return m1; return m1;

View File

@@ -7,7 +7,7 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(Data.Models.Listxml.M1? item) public override Data.Models.Metadata.MetadataFile? Serialize(Data.Models.Listxml.M1? item)
{ {
if (item == null) if (item is null)
return null; return null;
var metadataFile = new Data.Models.Metadata.MetadataFile var metadataFile = new Data.Models.Metadata.MetadataFile
@@ -15,7 +15,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item), [Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
}; };
if (item?.Game != null && item.Game.Length > 0) if (item?.Game is not null && item.Game.Length > 0)
{ {
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey] metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(item.Game, Listxml.ConvertMachineToInternalModel); = Array.ConvertAll(item.Game, Listxml.ConvertMachineToInternalModel);

View File

@@ -7,14 +7,14 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Data.Models.Listxml.Mess? Deserialize(Data.Models.Metadata.MetadataFile? obj) public override Data.Models.Listxml.Mess? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey); var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
var m1 = header != null ? ConvertMessFromInternalModel(header) : new Data.Models.Listxml.Mess(); var m1 = header is not null ? ConvertMessFromInternalModel(header) : new Data.Models.Listxml.Mess();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey); var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Length > 0) if (machines is not null && machines.Length > 0)
m1.Game = Array.ConvertAll(machines, Listxml.ConvertMachineFromInternalModel); m1.Game = Array.ConvertAll(machines, Listxml.ConvertMachineFromInternalModel);
return m1; return m1;

View File

@@ -7,7 +7,7 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(Data.Models.Listxml.Mess? item) public override Data.Models.Metadata.MetadataFile? Serialize(Data.Models.Listxml.Mess? item)
{ {
if (item == null) if (item is null)
return null; return null;
var metadataFile = new Data.Models.Metadata.MetadataFile var metadataFile = new Data.Models.Metadata.MetadataFile
@@ -15,7 +15,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item), [Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
}; };
if (item?.Game != null && item.Game.Length > 0) if (item?.Game is not null && item.Game.Length > 0)
{ {
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey] metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(item.Game, Listxml.ConvertMachineToInternalModel); = Array.ConvertAll(item.Game, Listxml.ConvertMachineToInternalModel);

View File

@@ -8,14 +8,14 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Dat? Deserialize(Data.Models.Metadata.MetadataFile? obj) public override Dat? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey); var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
var dat = header != null ? ConvertHeaderFromInternalModel(header) : new Dat(); var dat = header is not null ? ConvertHeaderFromInternalModel(header) : new Dat();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey); var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Length > 0) if (machines is not null && machines.Length > 0)
{ {
dat.Games = new Games dat.Games = new Games
{ {
@@ -97,7 +97,7 @@ namespace SabreTools.Serialization.CrossModel
}; };
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey); var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms != null && roms.Length > 0) if (roms is not null && roms.Length > 0)
{ {
var romSizes = Array.ConvertAll(roms, r => r.ReadLong(Data.Models.Metadata.Rom.SizeKey) ?? -1); var romSizes = Array.ConvertAll(roms, r => r.ReadLong(Data.Models.Metadata.Rom.SizeKey) ?? -1);
game.RomSize = Array.Find(romSizes, s => s > -1).ToString(); game.RomSize = Array.Find(romSizes, s => s > -1).ToString();

View File

@@ -8,7 +8,7 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(Dat? item) public override Data.Models.Metadata.MetadataFile? Serialize(Dat? item)
{ {
if (item == null) if (item is null)
return null; return null;
var metadataFile = new Data.Models.Metadata.MetadataFile var metadataFile = new Data.Models.Metadata.MetadataFile
@@ -16,7 +16,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item), [Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
}; };
if (item?.Games?.Game != null && item.Games.Game.Length > 0) if (item?.Games?.Game is not null && item.Games.Game.Length > 0)
{ {
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey] metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(item.Games.Game, ConvertMachineToInternalModel); = Array.ConvertAll(item.Games.Game, ConvertMachineToInternalModel);
@@ -35,7 +35,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.Header.SchemaLocationKey] = item.NoNamespaceSchemaLocation, [Data.Models.Metadata.Header.SchemaLocationKey] = item.NoNamespaceSchemaLocation,
}; };
if (item.Configuration != null) if (item.Configuration is not null)
{ {
header[Data.Models.Metadata.Header.NameKey] = item.Configuration.DatName; header[Data.Models.Metadata.Header.NameKey] = item.Configuration.DatName;
header[Data.Models.Metadata.Header.ImFolderKey] = item.Configuration.ImFolder; header[Data.Models.Metadata.Header.ImFolderKey] = item.Configuration.ImFolder;
@@ -50,7 +50,7 @@ namespace SabreTools.Serialization.CrossModel
header[Data.Models.Metadata.Header.RomTitleKey] = item.Configuration.RomTitle; header[Data.Models.Metadata.Header.RomTitleKey] = item.Configuration.RomTitle;
} }
if (item.GUI != null) if (item.GUI is not null)
{ {
header[Data.Models.Metadata.Header.ImagesKey] = item.GUI.Images; header[Data.Models.Metadata.Header.ImagesKey] = item.GUI.Images;
} }
@@ -79,7 +79,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.Machine.DuplicateIDKey] = item.DuplicateID, [Data.Models.Metadata.Machine.DuplicateIDKey] = item.DuplicateID,
}; };
if (item.Files?.RomCRC != null && item.Files.RomCRC.Length > 0) if (item.Files?.RomCRC is not null && item.Files.RomCRC.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.RomKey] machine[Data.Models.Metadata.Machine.RomKey]
= Array.ConvertAll(item.Files.RomCRC, romCRC => = Array.ConvertAll(item.Files.RomCRC, romCRC =>

View File

@@ -8,14 +8,14 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override SoftwareDb? Deserialize(Data.Models.Metadata.MetadataFile? obj) public override SoftwareDb? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey); var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
var softwareDb = header != null ? ConvertHeaderFromInternalModel(header) : new SoftwareDb(); var softwareDb = header is not null ? ConvertHeaderFromInternalModel(header) : new SoftwareDb();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey); var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Length > 0) if (machines is not null && machines.Length > 0)
softwareDb.Software = Array.ConvertAll(machines, ConvertMachineFromInternalModel); softwareDb.Software = Array.ConvertAll(machines, ConvertMachineFromInternalModel);
return softwareDb; return softwareDb;
@@ -49,7 +49,7 @@ namespace SabreTools.Serialization.CrossModel
}; };
var dumps = item.Read<Data.Models.Metadata.Dump[]>(Data.Models.Metadata.Machine.DumpKey); var dumps = item.Read<Data.Models.Metadata.Dump[]>(Data.Models.Metadata.Machine.DumpKey);
if (dumps != null && dumps.Length > 0) if (dumps is not null && dumps.Length > 0)
game.Dump = Array.ConvertAll(dumps, ConvertFromInternalModel); game.Dump = Array.ConvertAll(dumps, ConvertFromInternalModel);
return game; return game;
@@ -63,19 +63,19 @@ namespace SabreTools.Serialization.CrossModel
var dump = new Dump(); var dump = new Dump();
var original = item.Read<Data.Models.Metadata.Original>(Data.Models.Metadata.Dump.OriginalKey); var original = item.Read<Data.Models.Metadata.Original>(Data.Models.Metadata.Dump.OriginalKey);
if (original != null) if (original is not null)
dump.Original = ConvertFromInternalModel(original); dump.Original = ConvertFromInternalModel(original);
var rom = item.Read<Data.Models.Metadata.Rom>(Data.Models.Metadata.Dump.RomKey); var rom = item.Read<Data.Models.Metadata.Rom>(Data.Models.Metadata.Dump.RomKey);
if (rom != null) if (rom is not null)
dump.Rom = ConvertRomFromInternalModel(rom); dump.Rom = ConvertRomFromInternalModel(rom);
var megaRom = item.Read<Data.Models.Metadata.Rom>(Data.Models.Metadata.Dump.MegaRomKey); var megaRom = item.Read<Data.Models.Metadata.Rom>(Data.Models.Metadata.Dump.MegaRomKey);
if (megaRom != null) if (megaRom is not null)
dump.Rom = ConvertMegaRomFromInternalModel(megaRom); dump.Rom = ConvertMegaRomFromInternalModel(megaRom);
var sccPlusCart = item.Read<Data.Models.Metadata.Rom>(Data.Models.Metadata.Dump.SCCPlusCartKey); var sccPlusCart = item.Read<Data.Models.Metadata.Rom>(Data.Models.Metadata.Dump.SCCPlusCartKey);
if (sccPlusCart != null) if (sccPlusCart is not null)
dump.Rom = ConvertSCCPlusCartFromInternalModel(sccPlusCart); dump.Rom = ConvertSCCPlusCartFromInternalModel(sccPlusCart);
return dump; return dump;

View File

@@ -8,7 +8,7 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(SoftwareDb? item) public override Data.Models.Metadata.MetadataFile? Serialize(SoftwareDb? item)
{ {
if (item == null) if (item is null)
return null; return null;
var metadataFile = new Data.Models.Metadata.MetadataFile var metadataFile = new Data.Models.Metadata.MetadataFile
@@ -16,7 +16,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item), [Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
}; };
if (item?.Software != null && item.Software.Length > 0) if (item?.Software is not null && item.Software.Length > 0)
{ {
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey] metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(item.Software, ConvertMachineToInternalModel); = Array.ConvertAll(item.Software, ConvertMachineToInternalModel);
@@ -52,7 +52,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.Machine.CountryKey] = item.Country, [Data.Models.Metadata.Machine.CountryKey] = item.Country,
}; };
if (item.Dump != null && item.Dump.Length > 0) if (item.Dump is not null && item.Dump.Length > 0)
{ {
machine[Data.Models.Metadata.Machine.DumpKey] machine[Data.Models.Metadata.Machine.DumpKey]
= Array.ConvertAll(item.Dump, ConvertToInternalModel); = Array.ConvertAll(item.Dump, ConvertToInternalModel);
@@ -68,10 +68,10 @@ namespace SabreTools.Serialization.CrossModel
{ {
var dump = new Data.Models.Metadata.Dump(); var dump = new Data.Models.Metadata.Dump();
if (item.Original != null) if (item.Original is not null)
dump[Data.Models.Metadata.Dump.OriginalKey] = ConvertToInternalModel(item.Original); dump[Data.Models.Metadata.Dump.OriginalKey] = ConvertToInternalModel(item.Original);
if (item.Rom != null) if (item.Rom is not null)
{ {
switch (item.Rom) switch (item.Rom)
{ {
@@ -86,6 +86,10 @@ namespace SabreTools.Serialization.CrossModel
case SCCPlusCart sccPlusCart: case SCCPlusCart sccPlusCart:
dump[Data.Models.Metadata.Dump.SCCPlusCartKey] = ConvertToInternalModel(sccPlusCart); dump[Data.Models.Metadata.Dump.SCCPlusCartKey] = ConvertToInternalModel(sccPlusCart);
break; break;
default:
// TODO: Log invalid values
break;
} }
} }

View File

@@ -9,11 +9,11 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj) public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey); var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
var metadataFile = header != null ? ConvertHeaderFromInternalModel(header) : new MetadataFile(); var metadataFile = header is not null ? ConvertHeaderFromInternalModel(header) : new MetadataFile();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey); var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
var items = new List<Rom>(); var items = new List<Rom>();
@@ -85,7 +85,7 @@ namespace SabreTools.Serialization.CrossModel
private static Rom[] ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item) private static Rom[] ConvertMachineFromInternalModel(Data.Models.Metadata.Machine item)
{ {
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey); var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms == null) if (roms is null)
return []; return [];
return Array.ConvertAll(roms, r => ConvertFromInternalModel(r, item)); return Array.ConvertAll(roms, r => ConvertFromInternalModel(r, item));

View File

@@ -8,7 +8,7 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj) public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var metadataFile = new Data.Models.Metadata.MetadataFile var metadataFile = new Data.Models.Metadata.MetadataFile
@@ -16,7 +16,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj), [Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj),
}; };
if (obj?.Games?.Rom != null && obj.Games.Rom.Length > 0) if (obj?.Games?.Rom is not null && obj.Games.Rom.Length > 0)
{ {
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey] metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(obj.Games.Rom, ConvertMachineToInternalModel); = Array.ConvertAll(obj.Games.Rom, ConvertMachineToInternalModel);
@@ -32,7 +32,7 @@ namespace SabreTools.Serialization.CrossModel
{ {
var header = new Data.Models.Metadata.Header(); var header = new Data.Models.Metadata.Header();
if (item.Credits != null) if (item.Credits is not null)
{ {
header[Data.Models.Metadata.Header.AuthorKey] = item.Credits.Author; header[Data.Models.Metadata.Header.AuthorKey] = item.Credits.Author;
header[Data.Models.Metadata.Header.VersionKey] = item.Credits.Version; header[Data.Models.Metadata.Header.VersionKey] = item.Credits.Version;
@@ -43,7 +43,7 @@ namespace SabreTools.Serialization.CrossModel
header[Data.Models.Metadata.Header.CommentKey] = item.Credits.Comment; header[Data.Models.Metadata.Header.CommentKey] = item.Credits.Comment;
} }
if (item.Dat != null) if (item.Dat is not null)
{ {
header[Data.Models.Metadata.Header.DatVersionKey] = item.Dat.Version; header[Data.Models.Metadata.Header.DatVersionKey] = item.Dat.Version;
header[Data.Models.Metadata.Header.PluginKey] = item.Dat.Plugin; header[Data.Models.Metadata.Header.PluginKey] = item.Dat.Plugin;
@@ -54,7 +54,7 @@ namespace SabreTools.Serialization.CrossModel
header[Data.Models.Metadata.Header.ForceMergingKey] = "merge"; header[Data.Models.Metadata.Header.ForceMergingKey] = "merge";
} }
if (item.Emulator != null) if (item.Emulator is not null)
{ {
header[Data.Models.Metadata.Header.RefNameKey] = item.Emulator.RefName; header[Data.Models.Metadata.Header.RefNameKey] = item.Emulator.RefName;
header[Data.Models.Metadata.Header.EmulatorVersionKey] = item.Emulator.Version; header[Data.Models.Metadata.Header.EmulatorVersionKey] = item.Emulator.Version;

View File

@@ -9,11 +9,11 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj) public override MetadataFile? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey); var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
var metadataFile = header != null ? ConvertHeaderFromInternalModel(header) : new MetadataFile(); var metadataFile = header is not null ? ConvertHeaderFromInternalModel(header) : new MetadataFile();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey); var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
var items = new List<Row>(); var items = new List<Row>();
@@ -46,21 +46,21 @@ namespace SabreTools.Serialization.CrossModel
var rowItems = new List<Row>(); var rowItems = new List<Row>();
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey); var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.Machine.RomKey);
if (roms != null && roms.Length > 0) if (roms is not null && roms.Length > 0)
{ {
rowItems.AddRange( rowItems.AddRange(
Array.ConvertAll(roms, r => ConvertFromInternalModel(r, item, header))); Array.ConvertAll(roms, r => ConvertFromInternalModel(r, item, header)));
} }
var disks = item.Read<Data.Models.Metadata.Disk[]>(Data.Models.Metadata.Machine.DiskKey); var disks = item.Read<Data.Models.Metadata.Disk[]>(Data.Models.Metadata.Machine.DiskKey);
if (disks != null && disks.Length > 0) if (disks is not null && disks.Length > 0)
{ {
rowItems.AddRange( rowItems.AddRange(
Array.ConvertAll(disks, d => ConvertFromInternalModel(d, item, header))); Array.ConvertAll(disks, d => ConvertFromInternalModel(d, item, header)));
} }
var media = item.Read<Data.Models.Metadata.Media[]>(Data.Models.Metadata.Machine.MediaKey); var media = item.Read<Data.Models.Metadata.Media[]>(Data.Models.Metadata.Machine.MediaKey);
if (media != null && media.Length > 0) if (media is not null && media.Length > 0)
{ {
rowItems.AddRange( rowItems.AddRange(
Array.ConvertAll(media, m => ConvertFromInternalModel(m, item, header))); Array.ConvertAll(media, m => ConvertFromInternalModel(m, item, header)));

View File

@@ -8,7 +8,7 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj) public override Data.Models.Metadata.MetadataFile? Serialize(MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var metadataFile = new Data.Models.Metadata.MetadataFile var metadataFile = new Data.Models.Metadata.MetadataFile
@@ -16,7 +16,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj), [Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(obj),
}; };
if (obj?.Row != null && obj.Row.Length > 0) if (obj?.Row is not null && obj.Row.Length > 0)
{ {
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey] metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(obj.Row, ConvertMachineToInternalModel); = Array.ConvertAll(obj.Row, ConvertMachineToInternalModel);
@@ -35,7 +35,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.Header.HeaderKey] = item.Header, [Data.Models.Metadata.Header.HeaderKey] = item.Header,
}; };
if (item.Row != null && item.Row.Length > 0) if (item.Row is not null && item.Row.Length > 0)
{ {
var first = item.Row[0]; var first = item.Row[0];
header["FILENAME"] = first.FileName; // TODO: Make this an actual key to retrieve on an item -- OriginalFilename header["FILENAME"] = first.FileName; // TODO: Make this an actual key to retrieve on an item -- OriginalFilename
@@ -71,6 +71,10 @@ namespace SabreTools.Serialization.CrossModel
case Data.Models.Metadata.Rom rom: case Data.Models.Metadata.Rom rom:
machine[Data.Models.Metadata.Machine.RomKey] = new Data.Models.Metadata.Rom[] { rom }; machine[Data.Models.Metadata.Machine.RomKey] = new Data.Models.Metadata.Rom[] { rom };
break; break;
default:
// TODO: Log invalid values
break;
} }
return machine; return machine;

View File

@@ -8,14 +8,14 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Data.Models.SoftwareList.SoftwareList? Deserialize(Data.Models.Metadata.MetadataFile? obj) public override Data.Models.SoftwareList.SoftwareList? Deserialize(Data.Models.Metadata.MetadataFile? obj)
{ {
if (obj == null) if (obj is null)
return null; return null;
var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey); var header = obj.Read<Data.Models.Metadata.Header>(Data.Models.Metadata.MetadataFile.HeaderKey);
var metadataFile = header != null ? ConvertHeaderFromInternalModel(header) : new Data.Models.SoftwareList.SoftwareList(); var metadataFile = header is not null ? ConvertHeaderFromInternalModel(header) : new Data.Models.SoftwareList.SoftwareList();
var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey); var machines = obj.Read<Data.Models.Metadata.Machine[]>(Data.Models.Metadata.MetadataFile.MachineKey);
if (machines != null && machines.Length > 0) if (machines is not null && machines.Length > 0)
metadataFile.Software = Array.ConvertAll(machines, ConvertMachineFromInternalModel); metadataFile.Software = Array.ConvertAll(machines, ConvertMachineFromInternalModel);
return metadataFile; return metadataFile;
@@ -52,15 +52,15 @@ namespace SabreTools.Serialization.CrossModel
}; };
var infos = item.Read<Data.Models.Metadata.Info[]>(Data.Models.Metadata.Machine.InfoKey); var infos = item.Read<Data.Models.Metadata.Info[]>(Data.Models.Metadata.Machine.InfoKey);
if (infos != null && infos.Length > 0) if (infos is not null && infos.Length > 0)
software.Info = Array.ConvertAll(infos, ConvertFromInternalModel); software.Info = Array.ConvertAll(infos, ConvertFromInternalModel);
var sharedFeats = item.Read<Data.Models.Metadata.SharedFeat[]>(Data.Models.Metadata.Machine.SharedFeatKey); var sharedFeats = item.Read<Data.Models.Metadata.SharedFeat[]>(Data.Models.Metadata.Machine.SharedFeatKey);
if (sharedFeats != null && sharedFeats.Length > 0) if (sharedFeats is not null && sharedFeats.Length > 0)
software.SharedFeat = Array.ConvertAll(sharedFeats, ConvertFromInternalModel); software.SharedFeat = Array.ConvertAll(sharedFeats, ConvertFromInternalModel);
var parts = item.Read<Data.Models.Metadata.Part[]>(Data.Models.Metadata.Machine.PartKey); var parts = item.Read<Data.Models.Metadata.Part[]>(Data.Models.Metadata.Machine.PartKey);
if (parts != null && parts.Length > 0) if (parts is not null && parts.Length > 0)
software.Part = Array.ConvertAll(parts, ConvertFromInternalModel); software.Part = Array.ConvertAll(parts, ConvertFromInternalModel);
return software; return software;
@@ -80,7 +80,7 @@ namespace SabreTools.Serialization.CrossModel
}; };
var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.DataArea.RomKey); var roms = item.Read<Data.Models.Metadata.Rom[]>(Data.Models.Metadata.DataArea.RomKey);
if (roms != null && roms.Length > 0) if (roms is not null && roms.Length > 0)
dataArea.Rom = Array.ConvertAll(roms, ConvertFromInternalModel); dataArea.Rom = Array.ConvertAll(roms, ConvertFromInternalModel);
return dataArea; return dataArea;
@@ -99,7 +99,7 @@ namespace SabreTools.Serialization.CrossModel
}; };
var dipValues = item.Read<Data.Models.Metadata.DipValue[]>(Data.Models.Metadata.DipSwitch.DipValueKey); var dipValues = item.Read<Data.Models.Metadata.DipValue[]>(Data.Models.Metadata.DipSwitch.DipValueKey);
if (dipValues != null && dipValues.Length > 0) if (dipValues is not null && dipValues.Length > 0)
dipSwitch.DipValue = Array.ConvertAll(dipValues, ConvertFromInternalModel); dipSwitch.DipValue = Array.ConvertAll(dipValues, ConvertFromInternalModel);
return dipSwitch; return dipSwitch;
@@ -146,7 +146,7 @@ namespace SabreTools.Serialization.CrossModel
}; };
var disks = item.Read<Data.Models.Metadata.Disk[]>(Data.Models.Metadata.DiskArea.DiskKey); var disks = item.Read<Data.Models.Metadata.Disk[]>(Data.Models.Metadata.DiskArea.DiskKey);
if (disks != null && disks.Length > 0) if (disks is not null && disks.Length > 0)
diskArea.Disk = Array.ConvertAll(disks, ConvertFromInternalModel); diskArea.Disk = Array.ConvertAll(disks, ConvertFromInternalModel);
return diskArea; return diskArea;
@@ -190,19 +190,19 @@ namespace SabreTools.Serialization.CrossModel
}; };
var features = item.Read<Data.Models.Metadata.Feature[]>(Data.Models.Metadata.Part.FeatureKey); var features = item.Read<Data.Models.Metadata.Feature[]>(Data.Models.Metadata.Part.FeatureKey);
if (features != null && features.Length > 0) if (features is not null && features.Length > 0)
part.Feature = Array.ConvertAll(features, ConvertFromInternalModel); part.Feature = Array.ConvertAll(features, ConvertFromInternalModel);
var dataAreas = item.Read<Data.Models.Metadata.DataArea[]>(Data.Models.Metadata.Part.DataAreaKey); var dataAreas = item.Read<Data.Models.Metadata.DataArea[]>(Data.Models.Metadata.Part.DataAreaKey);
if (dataAreas != null && dataAreas.Length > 0) if (dataAreas is not null && dataAreas.Length > 0)
part.DataArea = Array.ConvertAll(dataAreas, ConvertFromInternalModel); part.DataArea = Array.ConvertAll(dataAreas, ConvertFromInternalModel);
var diskAreas = item.Read<Data.Models.Metadata.DiskArea[]>(Data.Models.Metadata.Part.DiskAreaKey); var diskAreas = item.Read<Data.Models.Metadata.DiskArea[]>(Data.Models.Metadata.Part.DiskAreaKey);
if (diskAreas != null && diskAreas.Length > 0) if (diskAreas is not null && diskAreas.Length > 0)
part.DiskArea = Array.ConvertAll(diskAreas, ConvertFromInternalModel); part.DiskArea = Array.ConvertAll(diskAreas, ConvertFromInternalModel);
var dipSwitches = item.Read<Data.Models.Metadata.DipSwitch[]>(Data.Models.Metadata.Part.DipSwitchKey); var dipSwitches = item.Read<Data.Models.Metadata.DipSwitch[]>(Data.Models.Metadata.Part.DipSwitchKey);
if (dipSwitches != null && dipSwitches.Length > 0) if (dipSwitches is not null && dipSwitches.Length > 0)
part.DipSwitch = Array.ConvertAll(dipSwitches, ConvertFromInternalModel); part.DipSwitch = Array.ConvertAll(dipSwitches, ConvertFromInternalModel);
return part; return part;

View File

@@ -8,7 +8,7 @@ namespace SabreTools.Serialization.CrossModel
/// <inheritdoc/> /// <inheritdoc/>
public override Data.Models.Metadata.MetadataFile? Serialize(Data.Models.SoftwareList.SoftwareList? item) public override Data.Models.Metadata.MetadataFile? Serialize(Data.Models.SoftwareList.SoftwareList? item)
{ {
if (item == null) if (item is null)
return null; return null;
var metadataFile = new Data.Models.Metadata.MetadataFile var metadataFile = new Data.Models.Metadata.MetadataFile
@@ -16,7 +16,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item), [Data.Models.Metadata.MetadataFile.HeaderKey] = ConvertHeaderToInternalModel(item),
}; };
if (item?.Software != null && item.Software.Length > 0) if (item?.Software is not null && item.Software.Length > 0)
{ {
metadataFile[Data.Models.Metadata.MetadataFile.MachineKey] metadataFile[Data.Models.Metadata.MetadataFile.MachineKey]
= Array.ConvertAll(item.Software, ConvertMachineToInternalModel); = Array.ConvertAll(item.Software, ConvertMachineToInternalModel);
@@ -55,13 +55,13 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.Machine.NotesKey] = item.Notes, [Data.Models.Metadata.Machine.NotesKey] = item.Notes,
}; };
if (item.Info != null && item.Info.Length > 0) if (item.Info is not null && item.Info.Length > 0)
machine[Data.Models.Metadata.Machine.InfoKey] = Array.ConvertAll(item.Info, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.InfoKey] = Array.ConvertAll(item.Info, ConvertToInternalModel);
if (item.SharedFeat != null && item.SharedFeat.Length > 0) if (item.SharedFeat is not null && item.SharedFeat.Length > 0)
machine[Data.Models.Metadata.Machine.SharedFeatKey] = Array.ConvertAll(item.SharedFeat, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.SharedFeatKey] = Array.ConvertAll(item.SharedFeat, ConvertToInternalModel);
if (item.Part != null && item.Part.Length > 0) if (item.Part is not null && item.Part.Length > 0)
machine[Data.Models.Metadata.Machine.PartKey] = Array.ConvertAll(item.Part, ConvertToInternalModel); machine[Data.Models.Metadata.Machine.PartKey] = Array.ConvertAll(item.Part, ConvertToInternalModel);
return machine; return machine;
@@ -80,7 +80,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.DataArea.EndiannessKey] = item.Endianness, [Data.Models.Metadata.DataArea.EndiannessKey] = item.Endianness,
}; };
if (item.Rom != null && item.Rom.Length > 0) if (item.Rom is not null && item.Rom.Length > 0)
dataArea[Data.Models.Metadata.DataArea.RomKey] = Array.ConvertAll(item.Rom, ConvertToInternalModel); dataArea[Data.Models.Metadata.DataArea.RomKey] = Array.ConvertAll(item.Rom, ConvertToInternalModel);
return dataArea; return dataArea;
@@ -98,7 +98,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.DipSwitch.MaskKey] = item.Mask, [Data.Models.Metadata.DipSwitch.MaskKey] = item.Mask,
}; };
if (item.DipValue != null && item.DipValue.Length > 0) if (item.DipValue is not null && item.DipValue.Length > 0)
dipSwitch[Data.Models.Metadata.DipSwitch.DipValueKey] = Array.ConvertAll(item.DipValue, ConvertToInternalModel); dipSwitch[Data.Models.Metadata.DipSwitch.DipValueKey] = Array.ConvertAll(item.DipValue, ConvertToInternalModel);
return dipSwitch; return dipSwitch;
@@ -144,7 +144,7 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.DiskArea.NameKey] = item.Name, [Data.Models.Metadata.DiskArea.NameKey] = item.Name,
}; };
if (item.Disk != null && item.Disk.Length > 0) if (item.Disk is not null && item.Disk.Length > 0)
diskArea[Data.Models.Metadata.DiskArea.DiskKey] = Array.ConvertAll(item.Disk, ConvertToInternalModel); diskArea[Data.Models.Metadata.DiskArea.DiskKey] = Array.ConvertAll(item.Disk, ConvertToInternalModel);
return diskArea; return diskArea;
@@ -187,16 +187,16 @@ namespace SabreTools.Serialization.CrossModel
[Data.Models.Metadata.Part.InterfaceKey] = item.Interface, [Data.Models.Metadata.Part.InterfaceKey] = item.Interface,
}; };
if (item.Feature != null && item.Feature.Length > 0) if (item.Feature is not null && item.Feature.Length > 0)
part[Data.Models.Metadata.Part.FeatureKey] = Array.ConvertAll(item.Feature, ConvertToInternalModel); part[Data.Models.Metadata.Part.FeatureKey] = Array.ConvertAll(item.Feature, ConvertToInternalModel);
if (item.DataArea != null && item.DataArea.Length > 0) if (item.DataArea is not null && item.DataArea.Length > 0)
part[Data.Models.Metadata.Part.DataAreaKey] = Array.ConvertAll(item.DataArea, ConvertToInternalModel); part[Data.Models.Metadata.Part.DataAreaKey] = Array.ConvertAll(item.DataArea, ConvertToInternalModel);
if (item.DiskArea != null && item.DiskArea.Length > 0) if (item.DiskArea is not null && item.DiskArea.Length > 0)
part[Data.Models.Metadata.Part.DiskAreaKey] = Array.ConvertAll(item.DiskArea, ConvertToInternalModel); part[Data.Models.Metadata.Part.DiskAreaKey] = Array.ConvertAll(item.DiskArea, ConvertToInternalModel);
if (item.DipSwitch != null && item.DipSwitch.Length > 0) if (item.DipSwitch is not null && item.DipSwitch.Length > 0)
part[Data.Models.Metadata.Part.DipSwitchKey] = Array.ConvertAll(item.DipSwitch, ConvertToInternalModel); part[Data.Models.Metadata.Part.DipSwitchKey] = Array.ConvertAll(item.DipSwitch, ConvertToInternalModel);
return part; return part;

View File

@@ -0,0 +1,327 @@
using System.Collections.Generic;
using SabreTools.Data.Models.Atari7800;
namespace SabreTools.Data.Extensions
{
public static class Atari7800Cart
{
/// <summary>
/// Convert a <see cref="AudioDevice"/> value to string
/// </summary>
public static string FromAudioDevice(this AudioDevice audio)
{
string[] devices = new string[4];
byte pokey = (byte)((byte)audio & 0x0F);
devices[0] = pokey switch
{
0 => "POKEY - none",
1 => "POKEY - @440",
2 => "POKEY - @450",
3 => "POKEY - @450+@440",
4 => "POKEY - @800",
5 => "POKEY - @4000",
_ => $"Unknown {pokey}",
};
byte ym2151 = (byte)(((byte)audio >> 1) & 0x01);
devices[1] = ym2151 switch
{
0 => "No YM2151 @460",
1 => "YM2151 @460",
_ => $"Unknown {ym2151}",
};
byte covox = (byte)(((byte)audio >> 2) & 0x01);
devices[2] = covox switch
{
0 => "No COVOX @430",
1 => "COVOX @430",
_ => $"Unknown {covox}",
};
byte adpcm = (byte)(((byte)audio >> 3) & 0x01);
devices[3] = adpcm switch
{
0 => "No ADPCM Audio Stream @420",
1 => "ADPCM Audio Stream @420",
_ => $"Unknown {adpcm}",
};
return string.Join(", ", [.. devices]);
}
/// <summary>
/// Convert a <see cref="CartType"/> value to string
/// </summary>
public static string FromCartType(this CartType type)
{
List<string> types = [];
#if NET20 || NET35
if ((type & CartType.PokeyAt4000) != 0)
#else
if (type.HasFlag(CartType.PokeyAt4000))
#endif
types.Add("pokey at $4000");
#if NET20 || NET35
if ((type & CartType.SupergameBankSwitched) != 0)
#else
if (type.HasFlag(CartType.SupergameBankSwitched))
#endif
types.Add("supergame bank switched");
#if NET20 || NET35
if ((type & CartType.SupergameRamAt4000) != 0)
#else
if (type.HasFlag(CartType.SupergameRamAt4000))
#endif
types.Add("supergame ram at $4000");
#if NET20 || NET35
if ((type & CartType.RomAt4000) != 0)
#else
if (type.HasFlag(CartType.RomAt4000))
#endif
types.Add("rom at $4000");
#if NET20 || NET35
if ((type & CartType.Bank6At4000) != 0)
#else
if (type.HasFlag(CartType.Bank6At4000))
#endif
types.Add("bank 6 at $4000");
#if NET20 || NET35
if ((type & CartType.BankedRam) != 0)
#else
if (type.HasFlag(CartType.BankedRam))
#endif
types.Add("banked ram");
#if NET20 || NET35
if ((type & CartType.PokeyAt450) != 0)
#else
if (type.HasFlag(CartType.PokeyAt450))
#endif
types.Add("pokey at $450");
#if NET20 || NET35
if ((type & CartType.MirrorRamAt4000) != 0)
#else
if (type.HasFlag(CartType.MirrorRamAt4000))
#endif
types.Add("mirror ram at $4000");
#if NET20 || NET35
if ((type & CartType.ActivisionBanking) != 0)
#else
if (type.HasFlag(CartType.ActivisionBanking))
#endif
types.Add("activision banking");
#if NET20 || NET35
if ((type & CartType.AbsoluteBanking) != 0)
#else
if (type.HasFlag(CartType.AbsoluteBanking))
#endif
types.Add("absolute banking");
#if NET20 || NET35
if ((type & CartType.PokeyAt440) != 0)
#else
if (type.HasFlag(CartType.PokeyAt440))
#endif
types.Add("pokey at $440");
#if NET20 || NET35
if ((type & CartType.Ym2151At460461) != 0)
#else
if (type.HasFlag(CartType.Ym2151At460461))
#endif
types.Add("ym2151 at $460/$461");
#if NET20 || NET35
if ((type & CartType.Souper) != 0)
#else
if (type.HasFlag(CartType.Souper))
#endif
types.Add("souper");
#if NET20 || NET35
if ((type & CartType.Banksets) != 0)
#else
if (type.HasFlag(CartType.Banksets))
#endif
types.Add("banksets");
#if NET20 || NET35
if ((type & CartType.HaltBankedRam) != 0)
#else
if (type.HasFlag(CartType.HaltBankedRam))
#endif
types.Add("halt banked ram");
#if NET20 || NET35
if ((type & CartType.PokeyAt800) != 0)
#else
if (type.HasFlag(CartType.PokeyAt800))
#endif
types.Add("pokey@800");
// If no flags are set
if (types.Count == 0)
types.Add("N/A");
return string.Join(", ", [.. types]);
}
/// <summary>
/// Convert a <see cref="ControllerType"/> value to string
/// </summary>
public static string FromControllerType(this ControllerType type)
{
return type switch
{
ControllerType.None => "none",
ControllerType.Joystick => "7800 joystick",
ControllerType.Lightgun => "lightgun",
ControllerType.Paddle => "paddle",
ControllerType.Trakball => "trakball",
ControllerType.VcsJoystick => "2600 joystick",
ControllerType.VcsDriving => "2600 driving",
ControllerType.VcsKeypad => "2600 keypad",
ControllerType.STMouse => "ST mouse",
ControllerType.AmigaMouse => "Amiga mouse",
ControllerType.AtariVoxSaveKey => "AtariVox/SaveKey",
ControllerType.SNES2Atari => "SNES2Atari",
ControllerType.Mega7800 => "Mega7800",
_ => $"Unknown {(byte)type}",
};
}
/// <summary>
/// Convert a <see cref="Interrupt"/> value to string
/// </summary>
public static string FromInterrupt(this Interrupt interrupt)
{
return interrupt switch
{
Interrupt.None => "None",
Interrupt.Pokey1 => "POKEY 1 (@450 | @800 | @4000)",
Interrupt.Pokey2 => "POKEY 2 (@440)",
Interrupt.YM2151 => "YM2151",
_ => $"Unknown {(byte)interrupt}",
};
}
/// <summary>
/// Convert a <see cref="Mapper"/> value to string
/// </summary>
public static string FromMapper(this Mapper mapper)
{
return mapper switch
{
Mapper.Linear => "Linear",
Mapper.SuperGame => "SuperGame",
Mapper.Activision => "Activision",
Mapper.Absolute => "Absolute",
Mapper.Souper => "Souper",
_ => $"Unknown {(byte)mapper}",
};
}
/// <summary>
/// Convert a <see cref="MapperOptions"/> value to string
/// </summary>
public static string FromMapperOptions(this MapperOptions options)
{
string[] romOptions = new string[2];
byte option4000 = (byte)((byte)options & 0x0F);
romOptions[0] = option4000 switch
{
0 => "Option at @4000 - none",
1 => "Option at @4000 - 16K RAM",
2 => "Option at @4000 - 8K EXRAM/A8",
3 => "Option at @4000 - 32K EXRAM/M2",
4 => "Option at @4000 - EXROM",
5 => "Option at @4000 - EXFIX",
6 => "Option at @4000 - 32k EXRAM/X2",
_ => $"Unknown {option4000}",
};
byte romType = (byte)(((byte)options >> 7) & 0x01);
romOptions[1] = romType switch
{
0 => "Standard ROM",
1 => "Bankset ROM",
_ => $"Unknown {romType}",
};
return string.Join(", ", [.. romOptions]);
}
/// <summary>
/// Convert a <see cref="SaveDevice"/> value to string
/// </summary>
public static string FromSaveDevice(this SaveDevice device)
{
return device switch
{
SaveDevice.None => "None",
SaveDevice.HSC => "HSC",
SaveDevice.SaveKeyAtariVox => "SaveKey/AtariVox",
_ => $"Unknown {(byte)device}",
};
}
/// <summary>
/// Convert a <see cref="SlotPassthroughDevice"/> value to string
/// </summary>
public static string FromSlotPassthroughDevice(this SlotPassthroughDevice device)
{
return device switch
{
SlotPassthroughDevice.None => "None",
SlotPassthroughDevice.XM => "XM",
_ => $"Unknown {(byte)device}",
};
}
/// <summary>
/// Convert a <see cref="TVType"/> value to string
/// </summary>
public static string FromTVType(this TVType type)
{
string[] types = new string[3];
byte standard = (byte)((byte)type & 0x01);
types[0] = standard switch
{
0 => "NTSC",
1 => "PAL",
_ => $"Unknown {standard}",
};
byte connection = (byte)(((byte)type >> 1) & 0x01);
types[1] = connection switch
{
0 => "Component",
1 => "Composite",
_ => $"Unknown {standard}",
};
byte region = (byte)(((byte)type >> 2) & 0x01);
types[2] = region switch
{
0 => "Single-region",
1 => "Multi-region",
_ => $"Unknown {standard}",
};
return string.Join(", ", [.. types]);
}
}
}

View File

@@ -0,0 +1,21 @@
using SabreTools.Data.Models.AtariLynx;
namespace SabreTools.Data.Extensions
{
public static class AtariLynxCart
{
/// <summary>
/// Convert a <see cref="Rotation"/> value to string
/// </summary>
public static string FromRotation(this Rotation rotation)
{
return rotation switch
{
Rotation.NoRotation => "No rotation (horizontal, buttons right)",
Rotation.RotateLeft => "Rotate left (vertical, buttons down)",
Rotation.RotateRight => "Rotate right (vertical, buttons up)",
_ => $"Unknown {(byte)rotation}",
};
}
}
}

View File

@@ -1,308 +1,312 @@
using System; using System;
using System.IO; using System.IO;
using SabreTools.Data.Models.CDROM; using SabreTools.Data.Models.CDROM;
using SabreTools.IO.Extensions; using SabreTools.IO.Extensions;
namespace SabreTools.Data.Extensions namespace SabreTools.Data.Extensions
{ {
public static class CDROM public static class CDROM
{ {
/// <summary> /// <summary>
/// Get the sector mode for a CD-ROM stream /// Get the sector mode for a CD-ROM stream
/// </summary> /// </summary>
/// <param name="stream">Stream to derive the sector mode from</param> /// <param name="stream">Stream to derive the sector mode from</param>
/// <returns>Sector mode from the stream on success, <see cref="SectorMode.UNKNOWN"/> on error</returns> /// <returns>Sector mode from the stream on success, <see cref="SectorMode.UNKNOWN"/> on error</returns>
public static SectorMode GetSectorMode(this Stream stream) public static SectorMode GetSectorMode(this Stream stream)
{ {
try try
{ {
byte modeByte = stream.ReadByteValue(); byte modeByte = stream.ReadByteValue();
if (modeByte == 0) if (modeByte == 0)
{ {
return SectorMode.MODE0; return SectorMode.MODE0;
} }
else if (modeByte == 1) else if (modeByte == 1)
{ {
return SectorMode.MODE1; return SectorMode.MODE1;
} }
else if (modeByte == 2) else if (modeByte == 2)
{ {
stream.SeekIfPossible(2, SeekOrigin.Current); stream.SeekIfPossible(2, SeekOrigin.Current);
byte submode = stream.ReadByteValue(); byte submode = stream.ReadByteValue();
if ((submode & 0x20) == 0x20) if ((submode & 0x20) == 0x20)
return SectorMode.MODE2_FORM2; return SectorMode.MODE2_FORM2;
else else
return SectorMode.MODE2_FORM1; return SectorMode.MODE2_FORM1;
} }
else else
{ {
return SectorMode.UNKNOWN; return SectorMode.UNKNOWN;
} }
} }
catch catch
{ {
// Ignore the actual error // Ignore the actual error
return SectorMode.UNKNOWN; return SectorMode.UNKNOWN;
} }
}
}
/// <summary>
/// <summary> /// Get the user data size for a sector mode
/// Get the user data size for a sector mode /// </summary>
/// </summary> /// <param name="mode">Sector mode to get a value for</param>
/// <param name="mode">Sector mode to get a value for</param> /// <returns>User data size, if possible</returns>
/// <returns>User data size, if possible</returns> public static long GetUserDataSize(this SectorMode mode)
public static long GetUserDataSize(this SectorMode mode) {
{ return mode switch
return mode switch {
{ SectorMode.UNKNOWN => Constants.Mode0DataSize,
SectorMode.MODE0 => Constants.Mode0DataSize, SectorMode.MODE0 => Constants.Mode0DataSize,
SectorMode.MODE1 => Constants.Mode1DataSize, SectorMode.MODE1 => Constants.Mode1DataSize,
SectorMode.MODE2 => Constants.Mode0DataSize, SectorMode.MODE2 => Constants.Mode0DataSize,
SectorMode.MODE2_FORM1 => Constants.Mode2Form1DataSize, SectorMode.MODE2_FORM1 => Constants.Mode2Form1DataSize,
SectorMode.MODE2_FORM2 => Constants.Mode2Form2DataSize, SectorMode.MODE2_FORM2 => Constants.Mode2Form2DataSize,
_ => Constants.Mode0DataSize, _ => Constants.Mode0DataSize,
}; };
} }
/// <summary> /// <summary>
/// Get the user data end offset for a sector mode /// Get the user data end offset for a sector mode
/// </summary> /// </summary>
/// <param name="mode">Sector mode to get a value for</param> /// <param name="mode">Sector mode to get a value for</param>
/// <returns>User data end offset, if possible</returns> /// <returns>User data end offset, if possible</returns>
public static long GetUserDataEnd(this SectorMode mode) public static long GetUserDataEnd(this SectorMode mode)
{ {
return mode switch return mode switch
{ {
SectorMode.MODE0 => Constants.Mode0UserDataEnd, // TODO: Support flexible sector length (2352) SectorMode.UNKNOWN => Constants.Mode0UserDataEnd,
SectorMode.MODE1 => Constants.Mode1UserDataEnd, SectorMode.MODE0 => Constants.Mode0UserDataEnd, // TODO: Support flexible sector length (2352)
SectorMode.MODE2 => Constants.Mode0UserDataEnd, // TODO: Support flexible sector length (2352) SectorMode.MODE1 => Constants.Mode1UserDataEnd,
SectorMode.MODE2_FORM1 => Constants.Mode2Form1UserDataEnd, SectorMode.MODE2 => Constants.Mode0UserDataEnd, // TODO: Support flexible sector length (2352)
SectorMode.MODE2_FORM2 => Constants.Mode2Form2UserDataEnd, // TODO: Support flexible sector length (2348) SectorMode.MODE2_FORM1 => Constants.Mode2Form1UserDataEnd,
_ => Constants.Mode0UserDataEnd, SectorMode.MODE2_FORM2 => Constants.Mode2Form2UserDataEnd, // TODO: Support flexible sector length (2348)
}; _ => Constants.Mode0UserDataEnd,
} };
}
/// <summary>
/// Get the user data start offset for a sector mode /// <summary>
/// </summary> /// Get the user data start offset for a sector mode
/// <param name="mode">Sector mode to get a value for</param> /// </summary>
/// <returns>User data start offset, if possible</returns> /// <param name="mode">Sector mode to get a value for</param>
public static long GetUserDataStart(this SectorMode mode) /// <returns>User data start offset, if possible</returns>
{ public static long GetUserDataStart(this SectorMode mode)
return mode switch {
{ return mode switch
SectorMode.MODE0 => Constants.Mode0UserDataStart, {
SectorMode.MODE1 => Constants.Mode1UserDataStart, SectorMode.UNKNOWN => Constants.Mode0UserDataStart,
SectorMode.MODE2 => Constants.Mode0UserDataStart, SectorMode.MODE0 => Constants.Mode0UserDataStart,
SectorMode.MODE2_FORM1 => Constants.Mode2Form1UserDataStart, SectorMode.MODE1 => Constants.Mode1UserDataStart,
SectorMode.MODE2_FORM2 => Constants.Mode2Form2UserDataStart, SectorMode.MODE2 => Constants.Mode0UserDataStart,
_ => Constants.Mode0UserDataStart, SectorMode.MODE2_FORM1 => Constants.Mode2Form1UserDataStart,
}; SectorMode.MODE2_FORM2 => Constants.Mode2Form2UserDataStart,
} _ => Constants.Mode0UserDataStart,
};
/// <summary> }
/// Creates a stream that provides only the user data of a CDROM stream
/// </summary> /// <summary>
public class ISO9660Stream : Stream /// Creates a stream that provides only the user data of a CDROM stream
{ /// </summary>
// Base CDROM stream (2352-byte sector) public class ISO9660Stream : Stream
private readonly Stream _baseStream; {
// Base CDROM stream (2352-byte sector)
// State variables private readonly Stream _baseStream;
private long _position = 0;
private SectorMode _currentMode = SectorMode.UNKNOWN; // State variables
private long _userDataStart = Constants.Mode1UserDataStart; private long _position = 0;
private long _userDataEnd = Constants.Mode1UserDataEnd; private SectorMode _currentMode = SectorMode.UNKNOWN;
private long _isoSectorSize = Constants.Mode1DataSize; private long _userDataStart = Constants.Mode1UserDataStart;
private long _userDataEnd = Constants.Mode1UserDataEnd;
public ISO9660Stream(Stream inputStream) #pragma warning disable IDE0044
{ private long _isoSectorSize = Constants.Mode1DataSize;
if (!inputStream.CanSeek || !inputStream.CanRead) #pragma warning restore IDE0044
throw new ArgumentException("Stream must be readable and seekable.", nameof(inputStream));
public ISO9660Stream(Stream inputStream)
_baseStream = inputStream; {
} if (!inputStream.CanSeek || !inputStream.CanRead)
throw new ArgumentException("Stream must be readable and seekable.", nameof(inputStream));
/// <inheritdoc/>
public override bool CanRead => _baseStream.CanRead; _baseStream = inputStream;
}
/// <inheritdoc/>
public override bool CanSeek => _baseStream.CanSeek; /// <inheritdoc/>
public override bool CanRead => _baseStream.CanRead;
/// <inheritdoc/>
public override bool CanWrite => false; /// <inheritdoc/>
public override bool CanSeek => _baseStream.CanSeek;
/// <inheritdoc/>
public override void Flush() => _baseStream.Flush(); /// <inheritdoc/>
public override bool CanWrite => false;
/// <inheritdoc/>
public override long Length /// <inheritdoc/>
=> (_baseStream.Length / Constants.CDROMSectorSize) * _isoSectorSize; public override void Flush() => _baseStream.Flush();
/// <inheritdoc/> /// <inheritdoc/>
public override void SetLength(long value) public override long Length
=> throw new NotSupportedException("Setting the length of this stream is not supported."); => _baseStream.Length / Constants.CDROMSectorSize * _isoSectorSize;
/// <inheritdoc/> /// <inheritdoc/>
public override void Write(byte[] buffer, int offset, int count) public override void SetLength(long value)
=> throw new NotSupportedException("Writing to this stream is not supported."); => throw new NotSupportedException("Setting the length of this stream is not supported.");
/// <inheritdoc/> /// <inheritdoc/>
protected override void Dispose(bool disposing) public override void Write(byte[] buffer, int offset, int count)
{ => throw new NotSupportedException("Writing to this stream is not supported.");
if (disposing)
_baseStream.Dispose(); /// <inheritdoc/>
protected override void Dispose(bool disposing)
base.Dispose(disposing); {
} if (disposing)
_baseStream.Dispose();
/// <inheritdoc/>
public override long Position base.Dispose(disposing);
{ }
// Get the position of the underlying ISO9660 stream
get /// <inheritdoc/>
{ public override long Position
// Get the user data location based on the current sector mode {
SetState(_position); // Get the position of the underlying ISO9660 stream
get
// Get the number of ISO sectors before current position {
long isoPosition = (_position / Constants.CDROMSectorSize) * _isoSectorSize; // Get the user data location based on the current sector mode
SetState(_position);
// Add the within-sector position
long remainder = _position % Constants.CDROMSectorSize; // Get the number of ISO sectors before current position
if (remainder > _userDataEnd) long isoPosition = _position / Constants.CDROMSectorSize * _isoSectorSize;
isoPosition += _isoSectorSize;
else if (remainder > _userDataStart) // Add the within-sector position
isoPosition += remainder - _userDataStart; long remainder = _position % Constants.CDROMSectorSize;
if (remainder > _userDataEnd)
return isoPosition; isoPosition += _isoSectorSize;
} else if (remainder > _userDataStart)
set isoPosition += remainder - _userDataStart;
{
// Seek to the underlying ISO9660 position return isoPosition;
Seek(value, SeekOrigin.Begin); }
} set
} {
// Seek to the underlying ISO9660 position
/// <inheritdoc/> Seek(value, SeekOrigin.Begin);
public override int Read(byte[] buffer, int offset, int count) }
{ }
int totalRead = 0;
int remaining = count; /// <inheritdoc/>
public override int Read(byte[] buffer, int offset, int count)
while (remaining > 0 && _position < _baseStream.Length) {
{ int totalRead = 0;
// Determine location of current sector int remaining = count;
long baseStreamOffset = _position - (_position % Constants.CDROMSectorSize);
while (remaining > 0 && _position < _baseStream.Length)
// Set the current sector's mode and user data location {
SetState(baseStreamOffset); // Determine location of current sector
long baseStreamOffset = _position - (_position % Constants.CDROMSectorSize);
// Deal with case where base position is not in ISO stream
long remainder = _position % Constants.CDROMSectorSize; // Set the current sector's mode and user data location
long sectorOffset = remainder - _userDataStart; SetState(baseStreamOffset);
if (remainder < _userDataStart)
{ // Deal with case where base position is not in ISO stream
baseStreamOffset += _userDataStart; long remainder = _position % Constants.CDROMSectorSize;
sectorOffset = 0; long sectorOffset = remainder - _userDataStart;
_position += _userDataStart; if (remainder < _userDataStart)
} {
else if (remainder >= _userDataEnd) baseStreamOffset += _userDataStart;
{ sectorOffset = 0;
baseStreamOffset += Constants.CDROMSectorSize; _position += _userDataStart;
sectorOffset = 0; }
_position += Constants.CDROMSectorSize - _userDataEnd + _userDataStart; else if (remainder >= _userDataEnd)
} {
else baseStreamOffset += Constants.CDROMSectorSize;
{ sectorOffset = 0;
baseStreamOffset += remainder; _position += Constants.CDROMSectorSize - _userDataEnd + _userDataStart;
} }
else
// Sanity check on read location before seeking {
if (baseStreamOffset < 0 || baseStreamOffset > _baseStream.Length) baseStreamOffset += remainder;
throw new ArgumentOutOfRangeException(nameof(offset), "Attempted to seek outside the stream boundaries."); }
// Seek to target position in base CDROM stream // Sanity check on read location before seeking
_baseStream.SeekIfPossible(baseStreamOffset, SeekOrigin.Begin); if (baseStreamOffset < 0 || baseStreamOffset > _baseStream.Length)
throw new ArgumentOutOfRangeException(nameof(offset), "Attempted to seek outside the stream boundaries.");
// Read the remaining bytes, up to max of one ISO sector (2048 bytes)
int bytesToRead = (int)Math.Min(remaining, _isoSectorSize - sectorOffset); // Seek to target position in base CDROM stream
_baseStream.SeekIfPossible(baseStreamOffset, SeekOrigin.Begin);
// Don't overshoot end of stream
bytesToRead = (int)Math.Min(bytesToRead, _baseStream.Length - _position); // Read the remaining bytes, up to max of one ISO sector (2048 bytes)
int bytesToRead = (int)Math.Min(remaining, _isoSectorSize - sectorOffset);
// Finish reading if no more bytes to be read
if (bytesToRead <= 0) // Don't overshoot end of stream
break; bytesToRead = (int)Math.Min(bytesToRead, _baseStream.Length - _position);
// Read up to 2048 bytes from base CDROM stream // Finish reading if no more bytes to be read
int bytesRead = _baseStream.Read(buffer, offset + totalRead, bytesToRead); if (bytesToRead <= 0)
break;
// Update state for base stream
_position = _baseStream.Position; // Read up to 2048 bytes from base CDROM stream
if (bytesToRead == (_isoSectorSize - sectorOffset)) int bytesRead = _baseStream.Read(buffer, offset + totalRead, bytesToRead);
_position += (Constants.CDROMSectorSize - _userDataEnd) + _userDataStart;
// Update state for base stream
// Update state for ISO stream _position = _baseStream.Position;
totalRead += bytesRead; if (bytesToRead == (_isoSectorSize - sectorOffset))
remaining -= bytesRead; _position += Constants.CDROMSectorSize - _userDataEnd + _userDataStart;
if (bytesRead == 0) // Update state for ISO stream
break; totalRead += bytesRead;
} remaining -= bytesRead;
return totalRead; if (bytesRead == 0)
} break;
}
/// <inheritdoc/>
public override long Seek(long offset, SeekOrigin origin) return totalRead;
{ }
// Get the intended position for the ISO9660 stream
long targetPosition = origin switch /// <inheritdoc/>
{ public override long Seek(long offset, SeekOrigin origin)
SeekOrigin.Begin => offset, {
SeekOrigin.Current => Position + offset, // Get the intended position for the ISO9660 stream
SeekOrigin.End => Length + offset, long targetPosition = origin switch
_ => throw new ArgumentException("Invalid SeekOrigin.", nameof(origin)), {
}; SeekOrigin.Begin => offset,
SeekOrigin.Current => Position + offset,
// Get the number of ISO sectors before current position SeekOrigin.End => Length + offset,
long newPosition = (targetPosition / _isoSectorSize) * Constants.CDROMSectorSize; _ => throw new ArgumentException("Invalid SeekOrigin.", nameof(origin)),
};
// Set the current sector's mode and user data location
SetState(newPosition); // Get the number of ISO sectors before current position
long newPosition = targetPosition / _isoSectorSize * Constants.CDROMSectorSize;
// Add the within-sector position
newPosition += _userDataStart + (targetPosition % _isoSectorSize); // Set the current sector's mode and user data location
if (newPosition < 0 || newPosition > _baseStream.Length) SetState(newPosition);
throw new ArgumentOutOfRangeException(nameof(offset), "Attempted to seek outside the stream boundaries.");
// Add the within-sector position
_position = _baseStream.SeekIfPossible(newPosition, SeekOrigin.Begin); newPosition += _userDataStart + (targetPosition % _isoSectorSize);
return Position; if (newPosition < 0 || newPosition > _baseStream.Length)
} throw new ArgumentOutOfRangeException(nameof(offset), "Attempted to seek outside the stream boundaries.");
/// <summary> _position = _baseStream.SeekIfPossible(newPosition, SeekOrigin.Begin);
/// Update the current stream state based on the location return Position;
/// </summary> }
/// <param name="sectorLocation">Sector location to update from</param>
private void SetState(long sectorLocation) /// <summary>
{ /// Update the current stream state based on the location
long current = _baseStream.Position; /// </summary>
long modePosition = sectorLocation - (sectorLocation % Constants.CDROMSectorSize) + 15; /// <param name="sectorLocation">Sector location to update from</param>
private void SetState(long sectorLocation)
// Get the current sector mode {
_baseStream.SeekIfPossible(modePosition, SeekOrigin.Begin); long current = _baseStream.Position;
_currentMode = _baseStream.GetSectorMode(); long modePosition = sectorLocation - (sectorLocation % Constants.CDROMSectorSize) + 15;
// Set the user data location variables // Get the current sector mode
_userDataStart = _currentMode.GetUserDataStart(); _baseStream.SeekIfPossible(modePosition, SeekOrigin.Begin);
_userDataEnd = _currentMode.GetUserDataEnd(); _currentMode = _baseStream.GetSectorMode();
// _isoSectorSize = _currentMode.GetUserDataSize();
// Set the user data location variables
// Reset the stream position _userDataStart = _currentMode.GetUserDataStart();
_baseStream.SeekIfPossible(current, SeekOrigin.Begin); _userDataEnd = _currentMode.GetUserDataEnd();
} // _isoSectorSize = _currentMode.GetUserDataSize();
}
} // Reset the stream position
} _baseStream.SeekIfPossible(current, SeekOrigin.Begin);
}
}
}
}

View File

@@ -13,7 +13,7 @@ namespace SabreTools.Data.Extensions
public static string? DecodeStreamName(this byte[]? input) public static string? DecodeStreamName(this byte[]? input)
{ {
// Ignore invalid inputs // Ignore invalid inputs
if (input == null) if (input is null)
return null; return null;
else if (input.Length == 0) else if (input.Length == 0)
return string.Empty; return string.Empty;
@@ -69,7 +69,7 @@ namespace SabreTools.Data.Extensions
public static string? DecodeStreamName(this string? input) public static string? DecodeStreamName(this string? input)
{ {
// Ignore invalid inputs // Ignore invalid inputs
if (input == null) if (input is null)
return null; return null;
else if (input.Length == 0) else if (input.Length == 0)
return string.Empty; return string.Empty;

View File

@@ -1,54 +1,54 @@
using SabreTools.Data.Models.ISO9660; using SabreTools.Data.Models.ISO9660;
using SabreTools.Numerics; using SabreTools.Numerics;
namespace SabreTools.Data.Extensions namespace SabreTools.Data.Extensions
{ {
public static class ISO9660 public static class ISO9660
{ {
/// <summary> /// <summary>
/// Get the logical block size from a sector length /// Get the logical block size from a sector length
/// </summary> /// </summary>
/// <param name="vd">Volume descriptor containing block information</param> /// <param name="vd">Volume descriptor containing block information</param>
/// <param name="sectorLength">Defined sector length</param> /// <param name="sectorLength">Defined sector length</param>
/// <returns>Size of a logical block</returns> /// <returns>Size of a logical block</returns>
public static short GetLogicalBlockSize(this VolumeDescriptor vd, short sectorLength) public static short GetLogicalBlockSize(this VolumeDescriptor vd, short sectorLength)
{ {
BothInt16 blockSize; BothInt16 blockSize;
if (vd is PrimaryVolumeDescriptor pvd) if (vd is PrimaryVolumeDescriptor pvd)
blockSize = pvd.LogicalBlockSize; blockSize = pvd.LogicalBlockSize;
else if (vd is SupplementaryVolumeDescriptor svd) else if (vd is SupplementaryVolumeDescriptor svd)
blockSize = svd.LogicalBlockSize; blockSize = svd.LogicalBlockSize;
else else
return sectorLength; return sectorLength;
// If the block size is inconsistent // If the block size is inconsistent
if (!blockSize.IsValid) if (!blockSize.IsValid)
{ {
bool leValid = BlockSizeValid(blockSize.LittleEndian, sectorLength); bool leValid = BlockSizeValid(blockSize.LittleEndian, sectorLength);
bool beValid = BlockSizeValid(blockSize.BigEndian, sectorLength); bool beValid = BlockSizeValid(blockSize.BigEndian, sectorLength);
if (leValid && !beValid) if (leValid && !beValid)
blockSize = blockSize.LittleEndian; blockSize = blockSize.LittleEndian;
else if (beValid && !leValid) else if (beValid && !leValid)
blockSize = blockSize.BigEndian; blockSize = blockSize.BigEndian;
else else
return sectorLength; return sectorLength;
} }
// Validate logical block size // Validate logical block size
if (!BlockSizeValid(blockSize, sectorLength)) if (!BlockSizeValid(blockSize, sectorLength))
blockSize = sectorLength; blockSize = sectorLength;
return blockSize; return blockSize;
} }
/// <summary> /// <summary>
/// Indicates if a block size is valid /// Indicates if a block size is valid
/// </summary> /// </summary>
/// <param name="blockSize">Block length to check</param> /// <param name="blockSize">Block length to check</param>
/// <param name="sectorLength">Defined sector length</param> /// <param name="sectorLength">Defined sector length</param>
/// <returns>True if the block length is valid, false otherwise</returns> /// <returns>True if the block length is valid, false otherwise</returns>
private static bool BlockSizeValid(short blockSize, short sectorLength) private static bool BlockSizeValid(short blockSize, short sectorLength)
=> blockSize >= 512 && blockSize <= sectorLength && (blockSize & (blockSize - 1)) == 0; => blockSize >= 512 && blockSize <= sectorLength && (blockSize & (blockSize - 1)) == 0;
} }
} }

View File

@@ -14,7 +14,7 @@ namespace SabreTools.Data.Extensions
public static bool IsCompressed(this FileDescriptor? fileDescriptor) public static bool IsCompressed(this FileDescriptor? fileDescriptor)
{ {
// Ignore invalid descriptors // Ignore invalid descriptors
if (fileDescriptor == null) if (fileDescriptor is null)
return true; return true;
#if NET20 || NET35 #if NET20 || NET35
@@ -32,7 +32,7 @@ namespace SabreTools.Data.Extensions
public static bool IsInvalid(this FileDescriptor? fileDescriptor) public static bool IsInvalid(this FileDescriptor? fileDescriptor)
{ {
// Ignore invalid descriptors // Ignore invalid descriptors
if (fileDescriptor == null) if (fileDescriptor is null)
return true; return true;
#if NET20 || NET35 #if NET20 || NET35
@@ -50,7 +50,7 @@ namespace SabreTools.Data.Extensions
public static bool IsObfuscated(this FileDescriptor? fileDescriptor) public static bool IsObfuscated(this FileDescriptor? fileDescriptor)
{ {
// Ignore invalid descriptors // Ignore invalid descriptors
if (fileDescriptor == null) if (fileDescriptor is null)
return false; return false;
#if NET20 || NET35 #if NET20 || NET35
@@ -68,7 +68,7 @@ namespace SabreTools.Data.Extensions
public static bool IsSplit(this FileDescriptor? fileDescriptor) public static bool IsSplit(this FileDescriptor? fileDescriptor)
{ {
// Ignore invalid descriptors // Ignore invalid descriptors
if (fileDescriptor == null) if (fileDescriptor is null)
return false; return false;
#if NET20 || NET35 #if NET20 || NET35
@@ -90,7 +90,7 @@ namespace SabreTools.Data.Extensions
public static int GetMajorVersion(this Cabinet? cabinet) public static int GetMajorVersion(this Cabinet? cabinet)
{ {
// Ignore invalid cabinets // Ignore invalid cabinets
if (cabinet == null) if (cabinet is null)
return -1; return -1;
return cabinet.CommonHeader.GetMajorVersion(); return cabinet.CommonHeader.GetMajorVersion();
@@ -104,7 +104,7 @@ namespace SabreTools.Data.Extensions
public static int GetMajorVersion(this CommonHeader? commonHeader) public static int GetMajorVersion(this CommonHeader? commonHeader)
{ {
// Ignore invalid headers // Ignore invalid headers
if (commonHeader == null) if (commonHeader is null)
return -1; return -1;
uint majorVersion = commonHeader.Version; uint majorVersion = commonHeader.Version;

View File

@@ -0,0 +1,241 @@
using SabreTools.Data.Models.NES;
namespace SabreTools.Data.Extensions
{
public static class NESCart
{
/// <summary>
/// Convert a <see cref="ConsoleType"/> value to string
/// </summary>
public static string FromConsoleType(this ConsoleType type)
{
return type switch
{
ConsoleType.StandardSystem => "Nintendo Entertainment System/Family Computer",
ConsoleType.VSUnisystem => "VS Unisystem",
ConsoleType.PlayChoice10 => "PlayChoice-10 (8 KB of Hint Screen data stored after CHR data)",
ConsoleType.ExtendedConsoleType => "Extended Console Type",
_ => $"Unknown {(byte)type}",
};
}
/// <summary>
/// Convert a <see cref="CPUPPUTiming"/> value to string
/// </summary>
public static string FromCPUPPUTiming(this CPUPPUTiming timing)
{
return timing switch
{
CPUPPUTiming.RP2C02 => "RP2C02 (NTSC NES)",
CPUPPUTiming.RP2C07 => "RP2C07 (Licensed PAL NES)",
CPUPPUTiming.MultipleRegion => "Multiple-region",
CPUPPUTiming.UA6538 => "UA6538 (Dendy)",
_ => $"Unknown {(byte)timing}",
};
}
/// <summary>
/// Convert a <see cref="DefaultExpansionDevice"/> value to string
/// </summary>
public static string FromDefaultExpansionDevice(this DefaultExpansionDevice device)
{
return device switch
{
DefaultExpansionDevice.Unspecified => "Unspecified",
DefaultExpansionDevice.StandardControllers => "Standard NES/Famicom controllers",
DefaultExpansionDevice.NESFourScore => "NES Four Score/Satellite with two additional standard controllers",
DefaultExpansionDevice.FamicomFourPlayersAdapter => "Famicom Four Players Adapter with two additional standard controllers using the 'simple' protocol",
DefaultExpansionDevice.VsSystem4016 => "Vs. System (1P via $4016)",
DefaultExpansionDevice.VsSystem4017 => "Vs. System (1P via $4017)",
DefaultExpansionDevice.Reserved06 => "Reserved (0x06)",
DefaultExpansionDevice.VsZapper => "Vs. Zapper",
DefaultExpansionDevice.Zapper4017 => "Zapper ($4017)",
DefaultExpansionDevice.TwoZappers => "Two Zappers",
DefaultExpansionDevice.BandaiHyperShotLightgun => "Bandai Hyper Shot Lightgun",
DefaultExpansionDevice.PowerPadSideA => "Power Pad Side A",
DefaultExpansionDevice.PowerPadSideB => "Power Pad Side B",
DefaultExpansionDevice.FamilyTrainerSideA => "Family Trainer Side A",
DefaultExpansionDevice.FamilyTrainerSideB => "Family Trainer Side B",
DefaultExpansionDevice.ArkanoidVausControllerNES => "Arkanoid Vaus Controller (NES)",
DefaultExpansionDevice.ArkanoidVausControllerFamicom => "Arkanoid Vaus Controller (Famicom)",
DefaultExpansionDevice.TwoVausControllersPlusFamicomDataRecorder => "Two Vaus Controllers plus Famicom Data Recorder",
DefaultExpansionDevice.KonamiHyperShotController => "Konami Hyper Shot Controller",
DefaultExpansionDevice.CoconutsPachinkoController => "Coconuts Pachinko Controller",
DefaultExpansionDevice.ExcitingBoxingPunchingBag => "Exciting Boxing Punching Bag (Blowup Doll)",
DefaultExpansionDevice.JissenMahjongController => "Jissen Mahjong Controller",
DefaultExpansionDevice.YonezawaPartyTap => "米澤 (Yonezawa) Party Tap",
DefaultExpansionDevice.OekaKidsTablet => "Oeka Kids Tablet",
DefaultExpansionDevice.SunsoftBarcodeBattler => "Sunsoft Barcode Battler",
DefaultExpansionDevice.MiraclePianoKeyboard => "Miracle Piano Keyboard",
DefaultExpansionDevice.PokkunMoguraaTapTapMat => "Pokkun Moguraa Tap-tap Mat (Whack-a-Mole Mat and Mallet)",
DefaultExpansionDevice.TopRider => "Top Rider (Inflatable Bicycle)",
DefaultExpansionDevice.DoubleFisted => "Double-Fisted (Requires or allows use of two controllers by one player)",
DefaultExpansionDevice.Famicom3DSystem => "Famicom 3D System",
DefaultExpansionDevice.DoremikkoKeyboard => "Doremikko Keyboard",
DefaultExpansionDevice.ROBGyromite => "R.O.B. Gyromite",
DefaultExpansionDevice.FamicomDataRecorder => "Famicom Data Recorder ('silent' keyboard)",
DefaultExpansionDevice.ASCIITurboFile => "ASCII Turbo File",
DefaultExpansionDevice.IGSStorageBattleBox => "IGS Storage Battle Box",
DefaultExpansionDevice.FamilyBASICKeyboardPlusFamicomDataRecorder => "Family BASIC Keyboard plus Famicom Data Recorder",
DefaultExpansionDevice.DongdaPECKeyboard => "东达 (Dōngdá) PEC Keyboard",
DefaultExpansionDevice.BitCorpBit79Keyboard => "普澤 (Pǔzé, a.k.a. Bit Corp.) Bit-79 Keyboard",
DefaultExpansionDevice.SuborKeyboard => "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard",
DefaultExpansionDevice.SuborKeyboardPlusMacroWinnersMouse => "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus Macro Winners Mouse",
DefaultExpansionDevice.SuborKeyboardPlusSuborMouse4016 => "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus Subor Mouse via $4016",
DefaultExpansionDevice.SNESMouse4016 => "SNES Mouse ($4016)",
DefaultExpansionDevice.Multicart => "Multicart",
DefaultExpansionDevice.TwoSNESControllers => "Two SNES controllers replacing the two standard NES controllers",
DefaultExpansionDevice.RacerMateBicycle => "RacerMate Bicycle",
DefaultExpansionDevice.UForce => "U-Force",
DefaultExpansionDevice.ROBStackUp => "R.O.B. Stack-Up",
DefaultExpansionDevice.CityPatrolmanLightgun => "City Patrolman Lightgun",
DefaultExpansionDevice.SharpC1CassetteInterface => "Sharp C1 Cassette Interface",
DefaultExpansionDevice.StandardControllerWithSwappedInputs => "Standard Controller with swapped Left-Right/Up-Down/B-A",
DefaultExpansionDevice.ExcaliburSudokuPad => "Excalibur Sudoku Pad",
DefaultExpansionDevice.ABLPinball => "ABL Pinball",
DefaultExpansionDevice.GoldenNuggetCasinoExtraButtons => "Golden Nugget Casino extra buttons",
DefaultExpansionDevice.KedaKeyboard => "科达 (Kēdá) Keyboard",
DefaultExpansionDevice.SuborKeyboardPlusSuborMouse4017 => "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus Subor Mouse via $4017",
DefaultExpansionDevice.PortTestController => "Port test controller",
DefaultExpansionDevice.BandaiMultiGamePlayerGamepad => "Bandai Multi Game Player Gamepad buttons",
DefaultExpansionDevice.VenomTVDanceMat => "Venom TV Dance Mat",
DefaultExpansionDevice.LGTVRemoteControl => "LG TV Remote Control",
DefaultExpansionDevice.FamicomNetworkController => "Famicom Network Controller",
DefaultExpansionDevice.KingFishingController => "King Fishing Controller",
DefaultExpansionDevice.CroakyKaraokeController => "Croaky Karaoke Controller",
DefaultExpansionDevice.KingwonKeyboard => "科王 (Kēwáng, a.k.a. Kingwon) Keyboard",
DefaultExpansionDevice.ZechengKeyboard => "泽诚 (Zéchéng) Keyboard",
DefaultExpansionDevice.SuborKeyboardPlusL90RotatedPS2Mouse4017 => "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus L90-rotated PS/2 mouse in $4017",
DefaultExpansionDevice.PS2KeyboardInUM6578PS2PortPS2Mouse4017 => "PS/2 Keyboard in UM6578 PS/2 port, PS/2 Mouse via $4017",
DefaultExpansionDevice.PS2MouseInUM6578PS2Port => "PS/2 Mouse in UM6578 PS/2 port",
DefaultExpansionDevice.YuxingMouse4016 => "裕兴 (Yùxìng) Mouse via $4016",
DefaultExpansionDevice.SuborKeyboardPlusYuxingMouse4016 => "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus 裕兴 (Yùxìng) Mouse mouse in $4016",
DefaultExpansionDevice.GigggleTVPump => "Gigggle TV Pump",
DefaultExpansionDevice.BBKKeyboardPlusR90RotatedPS2Mouse4017 => "步步高 (Bùbùgāo, a.k.a. BBK) Keyboard plus R90-rotated PS/2 mouse in $4017",
DefaultExpansionDevice.MagicalCooking => "Magical Cooking",
DefaultExpansionDevice.SNESMouse4017 => "SNES Mouse ($4017)",
DefaultExpansionDevice.Zapper4016 => "Zapper ($4016)",
DefaultExpansionDevice.ArkanoidVausControllerPrototype => "Arkanoid Vaus Controller (Prototype)",
DefaultExpansionDevice.TVMahjongGameController => "TV 麻雀 Game (TV Mahjong Game) Controller",
DefaultExpansionDevice.MahjongGekitouDensetsuController => "麻雀激闘伝説 (Mahjong Gekitou Densetsu) Controller",
DefaultExpansionDevice.SuborKeyboardPlusXInvertedPS2Mouse4017 => "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus X-inverted PS/2 mouse in $4017",
DefaultExpansionDevice.IBMPCXTKeyboard => "IBM PC/XT Keyboard",
DefaultExpansionDevice.SuborKeyboardPlusMegaBookMouse => "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus Mega Book Mouse",
_ => $"Unknown {(byte)device}",
};
}
/// <summary>
/// Convert a <see cref="ExtendedConsoleType"/> value to string
/// </summary>
public static string FromExtendedConsoleType(this ExtendedConsoleType type)
{
return type switch
{
ExtendedConsoleType.RegularSystem => "Regular NES/Famicom/Dendy",
ExtendedConsoleType.NintendoVsSystem => "Nintendo Vs. System",
ExtendedConsoleType.Playchoice10 => "Playchoice 10",
ExtendedConsoleType.RegularFamicloneDecimalMode => "Regular Famiclone, but with CPU that supports Decimal Mode",
ExtendedConsoleType.RegularNESWithEPSM => "Regular NES/Famicom with EPSM module or plug-through cartridge",
ExtendedConsoleType.VRTechnologyVT01 => "V.R. Technology VT01 with red/cyan STN palette",
ExtendedConsoleType.VRTechnologyVT02 => "V.R. Technology VT02",
ExtendedConsoleType.VRTechnologyVT03 => "V.R. Technology VT03",
ExtendedConsoleType.VRTechnologyVT09 => "V.R. Technology VT09",
ExtendedConsoleType.VRTechnologyVT32 => "V.R. Technology VT32",
ExtendedConsoleType.VRTechnologyVT369 => "V.R. Technology VT369",
ExtendedConsoleType.UMCUM6578 => "UMC UM6578",
ExtendedConsoleType.FamicomNetworkSystem => "Famicom Network System",
ExtendedConsoleType.ReservedD => "Reserved (0x0D)",
ExtendedConsoleType.ReservedE => "Reserved (0x0E)",
ExtendedConsoleType.ReservedF => "Reserved (0x0F)",
_ => $"Unknown {(byte)type}",
};
}
/// <summary>
/// Convert a <see cref="NametableArrangement"/> value to string
/// </summary>
public static string FromNametableArrangement(this NametableArrangement type)
{
return type switch
{
NametableArrangement.Vertical => "Vertical",
NametableArrangement.Horizontal => "Horizontal",
_ => $"Unknown {(byte)type}",
};
}
/// <summary>
/// Convert a <see cref="TVSystem"/> value to string
/// </summary>
public static string FromTVSystem(this TVSystem system)
{
return system switch
{
TVSystem.NTSC => "NTSC",
TVSystem.PAL => "PAL",
_ => $"Unknown {(byte)system}",
};
}
/// <summary>
/// Convert a <see cref="TVSystemExtended"/> value to string
/// </summary>
public static string FromTVSystemExtended(this TVSystemExtended system)
{
return system switch
{
TVSystemExtended.NTSC => "NTSC",
TVSystemExtended.DualCompatible1 => "Dual-compatible (0x01)",
TVSystemExtended.PAL => "PAL",
TVSystemExtended.DualCompatible3 => "Dual-compatible (0x03)",
_ => $"Unknown {(byte)system}",
};
}
/// <summary>
/// Convert a <see cref="VsHardwareType"/> value to string
/// </summary>
public static string FromVsHardwareType(this VsHardwareType type)
{
return type switch
{
VsHardwareType.VsUnisystem => "Vs. Unisystem (normal)",
VsHardwareType.VsUnisystemRBIBaseballProtection => "Vs. Unisystem (RBI Baseball protection)",
VsHardwareType.VsUnisystemTKOBoxingProtection => "Vs. Unisystem (TKO Boxing protection)",
VsHardwareType.VsUnisystemSuperXeviousProtection => "Vs. Unisystem (Super Xevious protection)",
VsHardwareType.VsUnisystemVsIceClimberJapanProtection => "Vs. Unisystem (Vs. Ice Climber Japan protection)",
VsHardwareType.VsDualSystem => "Vs. Dual System (normal)",
VsHardwareType.VsDualSystemRaidOnBungelingBayProtection => "Vs. Dual System (Raid on Bungeling Bay protection)",
_ => $"Unknown {(byte)type}",
};
}
/// <summary>
/// Convert a <see cref="VsSystemType"/> value to string
/// </summary>
public static string FromVsSystemType(this VsSystemType type)
{
return type switch
{
VsSystemType.AnyRP2C03RC2C03Variant => "Any RP2C03/RC2C03 variant",
VsSystemType.Reserved1 => "Reserved (0x01)",
VsSystemType.RP2C040001 => "RP2C04-0001",
VsSystemType.RP2C040002 => "RP2C04-0002",
VsSystemType.RP2C040003 => "RP2C04-0003",
VsSystemType.RP2C040004 => "RP2C04-0004",
VsSystemType.Reserved6 => "Reserved (0x06)",
VsSystemType.Reserved7 => "Reserved (0x07)",
VsSystemType.RC2C0501 => "RC2C05-01 (signature unknown)",
VsSystemType.RC2C0502 => "RC2C05-02 ($2002 AND $3F =$3D)",
VsSystemType.RC2C0503 => "RC2C05-03 ($2002 AND $1F =$1C)",
VsSystemType.RC2C0504 => "RC2C05-04 ($2002 AND $1F =$1B)",
VsSystemType.ReservedC => "Reserved (0x0C)",
VsSystemType.ReservedD => "Reserved (0x0D)",
VsSystemType.ReservedE => "Reserved (0x0E)",
VsSystemType.ReservedF => "Reserved (0x0F)",
_ => $"Unknown {(byte)type}",
};
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,7 @@ namespace SabreTools.Data.Extensions
/// </summary> /// </summary>
public static StringBuilder AppendLine(this StringBuilder sb, char? value, string prefixString) public static StringBuilder AppendLine(this StringBuilder sb, char? value, string prefixString)
{ {
string valueString = (value == null ? "[NULL]" : value.Value.ToString()); string valueString = value is null ? "[NULL]" : value.Value.ToString();
return sb.AppendLine($"{prefixString}: {valueString}"); return sb.AppendLine($"{prefixString}: {valueString}");
} }
@@ -256,7 +256,7 @@ namespace SabreTools.Data.Extensions
/// </summary> /// </summary>
public static StringBuilder AppendLine(this StringBuilder sb, byte[]? value, string prefixString) public static StringBuilder AppendLine(this StringBuilder sb, byte[]? value, string prefixString)
{ {
string valueString = (value == null ? "[NULL]" : BitConverter.ToString(value).Replace('-', ' ')); string valueString = value is null ? "[NULL]" : BitConverter.ToString(value).Replace('-', ' ');
if (valueString.Length == 0) if (valueString.Length == 0)
return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: [EMPTY]");
@@ -268,7 +268,25 @@ namespace SabreTools.Data.Extensions
/// </summary> /// </summary>
public static StringBuilder AppendLine(this StringBuilder sb, byte[]? value, string prefixString, Encoding encoding) public static StringBuilder AppendLine(this StringBuilder sb, byte[]? value, string prefixString, Encoding encoding)
{ {
string valueString = (value == null ? "[NULL]" : encoding.GetString(value).Replace("\0", string.Empty)); string valueString = value is null ? "[NULL]" : encoding.GetString(value).Replace("\0", string.Empty);
if (valueString.Length == 0)
return sb.AppendLine($"{prefixString}: [EMPTY]");
return sb.AppendLine($"{prefixString}: {valueString}");
}
/// <summary>
/// Append a line containing a UInt8[][] value to a StringBuilder
/// </summary>
public static StringBuilder AppendLine(this StringBuilder sb, byte[][]? value, string prefixString)
{
string valueString = "[NULL]";
if (value is not null)
{
var valueArr = Array.ConvertAll(value, ba => ba is null ? "[NULL]" : BitConverter.ToString(ba).Replace('-', ' '));
valueString = string.Join(", ", valueArr);
}
if (valueString.Length == 0) if (valueString.Length == 0)
return sb.AppendLine($"{prefixString}: [EMPTY]"); return sb.AppendLine($"{prefixString}: [EMPTY]");
@@ -281,7 +299,7 @@ namespace SabreTools.Data.Extensions
public static StringBuilder AppendLine(this StringBuilder sb, char[]? value, string prefixString) public static StringBuilder AppendLine(this StringBuilder sb, char[]? value, string prefixString)
{ {
string valueString = "[NULL]"; string valueString = "[NULL]";
if (value != null) if (value is not null)
{ {
var valueArr = Array.ConvertAll(value, c => c.ToString()); var valueArr = Array.ConvertAll(value, c => c.ToString());
valueString = string.Join(", ", valueArr); valueString = string.Join(", ", valueArr);
@@ -299,7 +317,7 @@ namespace SabreTools.Data.Extensions
public static StringBuilder AppendLine(this StringBuilder sb, short[]? value, string prefixString) public static StringBuilder AppendLine(this StringBuilder sb, short[]? value, string prefixString)
{ {
string valueString = "[NULL]"; string valueString = "[NULL]";
if (value != null) if (value is not null)
{ {
var valueArr = Array.ConvertAll(value, s => s.ToString()); var valueArr = Array.ConvertAll(value, s => s.ToString());
valueString = string.Join(", ", valueArr); valueString = string.Join(", ", valueArr);
@@ -317,7 +335,7 @@ namespace SabreTools.Data.Extensions
public static StringBuilder AppendLine(this StringBuilder sb, ushort[]? value, string prefixString) public static StringBuilder AppendLine(this StringBuilder sb, ushort[]? value, string prefixString)
{ {
string valueString = "[NULL]"; string valueString = "[NULL]";
if (value != null) if (value is not null)
{ {
var valueArr = Array.ConvertAll(value, u => u.ToString()); var valueArr = Array.ConvertAll(value, u => u.ToString());
valueString = string.Join(", ", valueArr); valueString = string.Join(", ", valueArr);
@@ -335,7 +353,7 @@ namespace SabreTools.Data.Extensions
public static StringBuilder AppendLine(this StringBuilder sb, int[]? value, string prefixString) public static StringBuilder AppendLine(this StringBuilder sb, int[]? value, string prefixString)
{ {
string valueString = "[NULL]"; string valueString = "[NULL]";
if (value != null) if (value is not null)
{ {
var valueArr = Array.ConvertAll(value, i => i.ToString()); var valueArr = Array.ConvertAll(value, i => i.ToString());
valueString = string.Join(", ", valueArr); valueString = string.Join(", ", valueArr);
@@ -353,7 +371,7 @@ namespace SabreTools.Data.Extensions
public static StringBuilder AppendLine(this StringBuilder sb, uint[]? value, string prefixString) public static StringBuilder AppendLine(this StringBuilder sb, uint[]? value, string prefixString)
{ {
string valueString = "[NULL]"; string valueString = "[NULL]";
if (value != null) if (value is not null)
{ {
var valueArr = Array.ConvertAll(value, u => u.ToString()); var valueArr = Array.ConvertAll(value, u => u.ToString());
valueString = string.Join(", ", valueArr); valueString = string.Join(", ", valueArr);
@@ -371,7 +389,7 @@ namespace SabreTools.Data.Extensions
public static StringBuilder AppendLine(this StringBuilder sb, float[]? value, string prefixString) public static StringBuilder AppendLine(this StringBuilder sb, float[]? value, string prefixString)
{ {
string valueString = "[NULL]"; string valueString = "[NULL]";
if (value != null) if (value is not null)
{ {
var valueArr = Array.ConvertAll(value, u => u.ToString()); var valueArr = Array.ConvertAll(value, u => u.ToString());
valueString = string.Join(", ", valueArr); valueString = string.Join(", ", valueArr);
@@ -389,7 +407,7 @@ namespace SabreTools.Data.Extensions
public static StringBuilder AppendLine(this StringBuilder sb, long[]? value, string prefixString) public static StringBuilder AppendLine(this StringBuilder sb, long[]? value, string prefixString)
{ {
string valueString = "[NULL]"; string valueString = "[NULL]";
if (value != null) if (value is not null)
{ {
var valueArr = Array.ConvertAll(value, l => l.ToString()); var valueArr = Array.ConvertAll(value, l => l.ToString());
valueString = string.Join(", ", valueArr); valueString = string.Join(", ", valueArr);
@@ -407,7 +425,7 @@ namespace SabreTools.Data.Extensions
public static StringBuilder AppendLine(this StringBuilder sb, ulong[]? value, string prefixString) public static StringBuilder AppendLine(this StringBuilder sb, ulong[]? value, string prefixString)
{ {
string valueString = "[NULL]"; string valueString = "[NULL]";
if (value != null) if (value is not null)
{ {
var valueArr = Array.ConvertAll(value, u => u.ToString()); var valueArr = Array.ConvertAll(value, u => u.ToString());
valueString = string.Join(", ", valueArr); valueString = string.Join(", ", valueArr);
@@ -425,7 +443,7 @@ namespace SabreTools.Data.Extensions
public static StringBuilder AppendLine(this StringBuilder sb, double[]? value, string prefixString) public static StringBuilder AppendLine(this StringBuilder sb, double[]? value, string prefixString)
{ {
string valueString = "[NULL]"; string valueString = "[NULL]";
if (value != null) if (value is not null)
{ {
var valueArr = Array.ConvertAll(value, u => u.ToString()); var valueArr = Array.ConvertAll(value, u => u.ToString());
valueString = string.Join(", ", valueArr); valueString = string.Join(", ", valueArr);
@@ -437,13 +455,31 @@ namespace SabreTools.Data.Extensions
return sb.AppendLine($"{prefixString}: {valueString}"); return sb.AppendLine($"{prefixString}: {valueString}");
} }
/// <summary>
/// Append a line containing a String[] value to a StringBuilder
/// </summary>
public static StringBuilder AppendLine(this StringBuilder sb, string?[]? value, string prefixString)
{
string valueString = "[NULL]";
if (value is not null)
{
var valueArr = Array.ConvertAll(value, s => s is null ? "[NULL]" : s);
valueString = string.Join(", ", valueArr);
}
if (valueString.Length == 0)
return sb.AppendLine($"{prefixString}: [EMPTY]");
return sb.AppendLine($"{prefixString}: {valueString}");
}
/// <summary> /// <summary>
/// Append a line containing a UInt64[] value to a StringBuilder /// Append a line containing a UInt64[] value to a StringBuilder
/// </summary> /// </summary>
public static StringBuilder AppendLine(this StringBuilder sb, Guid[]? value, string prefixString) public static StringBuilder AppendLine(this StringBuilder sb, Guid[]? value, string prefixString)
{ {
string valueString = "[NULL]"; string valueString = "[NULL]";
if (value != null) if (value is not null)
{ {
var valueArr = Array.ConvertAll(value, g => g.ToString()); var valueArr = Array.ConvertAll(value, g => g.ToString());
valueString = string.Join(", ", valueArr); valueString = string.Join(", ", valueArr);

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