diff --git a/.clang-format b/.clang-format
new file mode 100644
index 000000000..ef874186d
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,51 @@
+---
+Language: Cpp
+BasedOnStyle: LLVM
+AccessModifierOffset: -4
+AlignConsecutiveAssignments: true
+AlignConsecutiveDeclarations: true
+AlignOperands: true
+AllowShortBlocksOnASingleLine: true
+AllowShortIfStatementsOnASingleLine: true
+AllowShortLoopsOnASingleLine: true
+AlwaysBreakAfterDefinitionReturnType: false
+AlwaysBreakTemplateDeclarations: Yes
+BraceWrapping:
+ AfterCaseLabel: true
+ AfterClass: true
+ AfterControlStatement: true
+ AfterEnum: true
+ AfterFunction: true
+ AfterNamespace: true
+ AfterStruct: true
+ AfterUnion: true
+ AfterExternBlock: false
+ BeforeCatch: true
+ BeforeElse: true
+ BeforeLambdaBody: true
+ BeforeWhile: true
+ SplitEmptyFunction: true
+ SplitEmptyRecord: true
+ SplitEmptyNamespace: true
+BreakBeforeBraces: Custom
+BreakConstructorInitializers: AfterColon
+ColumnLimit: 120
+IncludeCategories:
+ - Regex: '^<.*'
+ Priority: 1
+ - Regex: '^".*'
+ Priority: 2
+ - Regex: '.*'
+ Priority: 3
+IncludeIsMainRegex: '([-_](test|unittest))?$'
+IndentCaseBlocks: true
+IndentWidth: 4
+InsertNewlineAtEOF: true
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 2
+NamespaceIndentation: All
+SpaceAfterTemplateKeyword: false
+SpacesInAngles: false
+TabWidth: 4
+...
diff --git a/.editorconfig b/.editorconfig
index 25aaa3207..cb0ffabf0 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,216 +1,1482 @@
[*]
-charset = utf-8
-end_of_line = lf
-trim_trailing_whitespace = false
-insert_final_newline = false
-indent_style = space
-indent_size = 4
+charset = utf-8
+end_of_line = lf
+indent_size = 2
+indent_style = space
+insert_final_newline = false
+max_line_length = 120
+tab_width = 2
+trim_trailing_whitespace = true
+ij_continuation_indent_size = 4
+ij_formatter_off_tag = @formatter:off
+ij_formatter_on_tag = @formatter:on
+ij_formatter_tags_enabled = true
+ij_smart_tabs = false
+ij_visual_guides =
+ij_wrap_on_typing = false
# Microsoft .NET properties
-csharp_new_line_between_query_expression_clauses = false
-csharp_preferred_modifier_order = public, private, protected, internal, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async:suggestion
-csharp_prefer_braces = false:warning
-csharp_space_after_keywords_in_control_flow_statements = false
-csharp_style_var_elsewhere = false:suggestion
-csharp_style_var_for_built_in_types = false:suggestion
-csharp_style_var_when_type_is_apparent = true:suggestion
-csharp_using_directive_placement = inside_namespace:silent
-dotnet_naming_rule.unity_serialized_field_rule.import_to_resharper = True
-dotnet_naming_rule.unity_serialized_field_rule.resharper_description = Unity serialized field
-dotnet_naming_rule.unity_serialized_field_rule.resharper_guid = 5f0fdb63-c892-4d2c-9324-15c80b22a7ef
-dotnet_naming_rule.unity_serialized_field_rule.severity = warning
-dotnet_naming_rule.unity_serialized_field_rule.style = lower_camel_case_style
-dotnet_naming_rule.unity_serialized_field_rule.symbols = unity_serialized_field_symbols
-dotnet_naming_rule.unity_serialized_field_rule_1.import_to_resharper = True
-dotnet_naming_rule.unity_serialized_field_rule_1.resharper_description = Unity serialized field
-dotnet_naming_rule.unity_serialized_field_rule_1.resharper_guid = 5f0fdb63-c892-4d2c-9324-15c80b22a7ef
-dotnet_naming_rule.unity_serialized_field_rule_1.severity = warning
-dotnet_naming_rule.unity_serialized_field_rule_1.style = lower_camel_case_style
-dotnet_naming_rule.unity_serialized_field_rule_1.symbols = unity_serialized_field_symbols_1
-dotnet_naming_style.lower_camel_case_style.capitalization = camel_case
-dotnet_naming_symbols.unity_serialized_field_symbols.applicable_accessibilities = *
-dotnet_naming_symbols.unity_serialized_field_symbols.applicable_kinds =
-dotnet_naming_symbols.unity_serialized_field_symbols.resharper_applicable_kinds = unity_serialised_field
-dotnet_naming_symbols.unity_serialized_field_symbols.resharper_required_modifiers = instance
-dotnet_naming_symbols.unity_serialized_field_symbols_1.applicable_accessibilities = *
-dotnet_naming_symbols.unity_serialized_field_symbols_1.applicable_kinds =
-dotnet_naming_symbols.unity_serialized_field_symbols_1.resharper_applicable_kinds = unity_serialised_field
-dotnet_naming_symbols.unity_serialized_field_symbols_1.resharper_required_modifiers = instance
-dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:warning
-dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:warning
-dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:warning
-dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
-dotnet_style_predefined_type_for_member_access = true:suggestion
-dotnet_style_qualification_for_event = false:suggestion
-dotnet_style_qualification_for_field = false:suggestion
-dotnet_style_qualification_for_method = false:suggestion
-dotnet_style_qualification_for_property = false:suggestion
-dotnet_style_require_accessibility_modifiers = never:suggestion
+csharp_preferred_modifier_order = public, private, protected, internal, file, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async, required:suggestion
+csharp_space_after_keywords_in_control_flow_statements = false
+csharp_style_namespace_declarations = file_scoped:warning
+csharp_style_prefer_utf8_string_literals = true:warning
+csharp_style_var_elsewhere = false:suggestion
+csharp_style_var_for_built_in_types = false:suggestion
+csharp_style_var_when_type_is_apparent = true:suggestion
+csharp_using_directive_placement = outside_namespace:silent
+dotnet_naming_rule.constants_rule.import_to_resharper = True
+dotnet_naming_rule.constants_rule.resharper_description = Constant fields (not private)
+dotnet_naming_rule.constants_rule.resharper_guid = 669e5282-fb4b-4e90-91e7-07d269d04b60
+dotnet_naming_rule.constants_rule.severity = warning
+dotnet_naming_rule.constants_rule.style = upper_camel_case_style
+dotnet_naming_rule.constants_rule.symbols = constants_symbols
+dotnet_naming_rule.private_constants_rule.import_to_resharper = True
+dotnet_naming_rule.private_constants_rule.resharper_description = Constant fields (private)
+dotnet_naming_rule.private_constants_rule.resharper_guid = 236f7aa5-7b06-43ca-bf2a-9b31bfcff09a
+dotnet_naming_rule.private_constants_rule.severity = warning
+dotnet_naming_rule.private_constants_rule.style = all_upper_style
+dotnet_naming_rule.private_constants_rule.symbols = private_constants_symbols
+dotnet_naming_rule.public_static_fields_rule.import_to_resharper = True
+dotnet_naming_rule.public_static_fields_rule.resharper_description = Static fields (not private)
+dotnet_naming_rule.public_static_fields_rule.resharper_guid = 70345118-4b40-4ece-937c-bbeb7a0b2e70
+dotnet_naming_rule.public_static_fields_rule.severity = warning
+dotnet_naming_rule.public_static_fields_rule.style = lower_camel_case_style_1
+dotnet_naming_rule.public_static_fields_rule.symbols = public_static_fields_symbols
+dotnet_naming_rule.static_readonly_rule.import_to_resharper = True
+dotnet_naming_rule.static_readonly_rule.resharper_description = Static readonly fields (not private)
+dotnet_naming_rule.static_readonly_rule.resharper_guid = c873eafb-d57f-481d-8c93-77f6863c2f88
+dotnet_naming_rule.static_readonly_rule.severity = warning
+dotnet_naming_rule.static_readonly_rule.style = upper_camel_case_style
+dotnet_naming_rule.static_readonly_rule.symbols = static_readonly_symbols
+dotnet_naming_rule.unity_serialized_field_rule.import_to_resharper = True
+dotnet_naming_rule.unity_serialized_field_rule.resharper_description = Unity serialized field
+dotnet_naming_rule.unity_serialized_field_rule.resharper_guid = 5f0fdb63-c892-4d2c-9324-15c80b22a7ef
+dotnet_naming_rule.unity_serialized_field_rule.severity = warning
+dotnet_naming_rule.unity_serialized_field_rule.style = lower_camel_case_style
+dotnet_naming_rule.unity_serialized_field_rule.symbols = unity_serialized_field_symbols
+dotnet_naming_rule.unity_serialized_field_rule_1.import_to_resharper = True
+dotnet_naming_rule.unity_serialized_field_rule_1.resharper_description = Unity serialized field
+dotnet_naming_rule.unity_serialized_field_rule_1.resharper_guid = 5f0fdb63-c892-4d2c-9324-15c80b22a7ef
+dotnet_naming_rule.unity_serialized_field_rule_1.severity = warning
+dotnet_naming_rule.unity_serialized_field_rule_1.style = lower_camel_case_style
+dotnet_naming_rule.unity_serialized_field_rule_1.symbols = unity_serialized_field_symbols_1
+dotnet_naming_style.all_upper_style.capitalization = all_upper
+dotnet_naming_style.all_upper_style.word_separator = _
+dotnet_naming_style.lower_camel_case_style.capitalization = camel_case
+dotnet_naming_style.lower_camel_case_style_1.capitalization = camel_case
+dotnet_naming_style.lower_camel_case_style_1.required_prefix = _
+dotnet_naming_style.upper_camel_case_style.capitalization = pascal_case
+dotnet_naming_symbols.constants_symbols.applicable_accessibilities = public, internal, protected, protected_internal, private_protected
+dotnet_naming_symbols.constants_symbols.applicable_kinds = field
+dotnet_naming_symbols.constants_symbols.required_modifiers = const
+dotnet_naming_symbols.constants_symbols.resharper_applicable_kinds = constant_field
+dotnet_naming_symbols.constants_symbols.resharper_required_modifiers = any
+dotnet_naming_symbols.private_constants_symbols.applicable_accessibilities = private
+dotnet_naming_symbols.private_constants_symbols.applicable_kinds = field
+dotnet_naming_symbols.private_constants_symbols.required_modifiers = const
+dotnet_naming_symbols.public_static_fields_symbols.applicable_accessibilities = public, internal, protected, protected_internal, private_protected
+dotnet_naming_symbols.public_static_fields_symbols.applicable_kinds = field
+dotnet_naming_symbols.public_static_fields_symbols.required_modifiers = static
+dotnet_naming_symbols.public_static_fields_symbols.resharper_applicable_kinds = field
+dotnet_naming_symbols.public_static_fields_symbols.resharper_required_modifiers = static
+dotnet_naming_symbols.static_readonly_symbols.applicable_accessibilities = public, internal, protected, protected_internal, private_protected
+dotnet_naming_symbols.static_readonly_symbols.applicable_kinds = field
+dotnet_naming_symbols.static_readonly_symbols.required_modifiers = readonly, static
+dotnet_naming_symbols.static_readonly_symbols.resharper_applicable_kinds = readonly_field
+dotnet_naming_symbols.static_readonly_symbols.resharper_required_modifiers = static
+dotnet_naming_symbols.unity_serialized_field_symbols.applicable_accessibilities = *
+dotnet_naming_symbols.unity_serialized_field_symbols.applicable_kinds =
+dotnet_naming_symbols.unity_serialized_field_symbols.resharper_applicable_kinds = unity_serialised_field
+dotnet_naming_symbols.unity_serialized_field_symbols.resharper_required_modifiers = instance
+dotnet_naming_symbols.unity_serialized_field_symbols_1.applicable_accessibilities = *
+dotnet_naming_symbols.unity_serialized_field_symbols_1.applicable_kinds =
+dotnet_naming_symbols.unity_serialized_field_symbols_1.resharper_applicable_kinds = unity_serialised_field
+dotnet_naming_symbols.unity_serialized_field_symbols_1.resharper_required_modifiers = instance
+dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:warning
+dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:warning
+dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:warning
+dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
+dotnet_style_predefined_type_for_member_access = true:suggestion
+dotnet_style_qualification_for_event = false:suggestion
+dotnet_style_qualification_for_field = false:suggestion
+dotnet_style_qualification_for_method = false:suggestion
+dotnet_style_qualification_for_property = false:suggestion
+dotnet_style_require_accessibility_modifiers = never:suggestion
# ReSharper properties
-resharper_align_first_arg_by_paren = true
-resharper_align_linq_query = true
-resharper_align_multiline_argument = true
-resharper_align_multiline_binary_expressions_chain = true
-resharper_align_multiline_binary_patterns = true
-resharper_align_multiline_calls_chain = true
-resharper_align_multiline_expression = true
-resharper_align_multiline_extends_list = true
-resharper_align_multiline_for_stmt = true
-resharper_align_multiline_parameter = true
-resharper_align_multiline_property_pattern = true
-resharper_align_multiline_switch_expression = true
-resharper_align_multiple_declaration = true
-resharper_align_multline_type_parameter_constrains = true
-resharper_align_multline_type_parameter_list = true
-resharper_align_tuple_components = true
-resharper_attribute_indent = align_by_first_attribute
-resharper_attribute_style = on_single_line
-resharper_autodetect_indent_settings = true
-resharper_constructor_or_destructor_body = expression_body
-resharper_cpp_brace_style = next_line
-resharper_csharp_outdent_commas = true
-resharper_default_value_when_type_not_evident = default_expression
-resharper_empty_block_style = together_same_line
-resharper_force_attribute_style = join
-resharper_force_chop_compound_do_expression = true
-resharper_force_chop_compound_if_expression = true
-resharper_force_chop_compound_while_expression = true
-resharper_for_built_in_types = use_var_when_evident
-resharper_fsharp_type_declaration_braces = next_line
-resharper_indent_nested_fixed_stmt = true
-resharper_indent_nested_foreach_stmt = true
-resharper_indent_nested_for_stmt = true
-resharper_indent_nested_lock_stmt = true
-resharper_indent_nested_usings_stmt = true
-resharper_indent_nested_while_stmt = true
-resharper_indent_preprocessor_if = outdent
-resharper_indent_preprocessor_other = usual_indent
-resharper_indent_switch_labels = true
-resharper_int_align_assignments = true
-resharper_int_align_binary_expressions = true
-resharper_int_align_comments = true
-resharper_int_align_fields = true
-resharper_int_align_methods = true
-resharper_int_align_nested_ternary = true
-resharper_int_align_properties = true
-resharper_int_align_property_patterns = true
-resharper_int_align_switch_expressions = true
-resharper_int_align_switch_sections = true
-resharper_int_align_variables = true
-resharper_keep_existing_arrangement = false
-resharper_keep_user_linebreaks = false
-resharper_linebreak_before_all_elements = true
-resharper_local_function_body = expression_body
-resharper_max_blank_lines_between_tags = 0
-resharper_max_enum_members_on_line = 1
-resharper_method_or_operator_body = expression_body
-resharper_nested_ternary_style = expanded
-resharper_new_line_before_while = false
-resharper_normalize_tag_names = true
-resharper_outdent_binary_ops = true
-resharper_outdent_binary_pattern_ops = true
-resharper_outdent_dots = true
-resharper_outdent_statement_labels = true
-resharper_place_attribute_on_same_line = false
-resharper_place_expr_accessor_on_single_line = true
-resharper_place_expr_method_on_single_line = true
-resharper_place_expr_property_on_single_line = true
-resharper_place_linq_into_on_new_line = false
-resharper_place_simple_anonymousmethod_on_single_line = false
-resharper_place_simple_case_statement_on_same_line = true
-resharper_place_simple_embedded_statement_on_same_line = false
-resharper_place_simple_initializer_on_single_line = false
-resharper_place_simple_switch_expression_on_single_line = true
-resharper_prefer_explicit_discard_declaration = true
-resharper_qualified_using_at_nested_scope = true
-resharper_show_autodetect_configure_formatting_tip = false
-resharper_sort_attributes = true
-resharper_sort_class_selectors = true
-resharper_space_after_keywords_in_control_flow_statements = false
-resharper_space_after_last_pi_attribute = true
-resharper_space_after_unary_operator = false
-resharper_space_around_binary_operator = true
-resharper_space_before_self_closing = true
-resharper_space_within_empty_braces = false
-resharper_stick_comment = false
-resharper_use_indent_from_vs = false
-resharper_wrap_after_dot_in_method_calls = true
-resharper_wrap_before_first_type_parameter_constraint = true
-resharper_wrap_before_type_parameter_langle = true
-resharper_wrap_enum_declaration = wrap_if_long
-resharper_wrap_for_stmt_header_style = wrap_if_long
-resharper_wrap_lines = true
-resharper_wrap_multiple_declaration_style = wrap_if_long
-resharper_wrap_multiple_type_parameter_constraints_style = wrap_if_long
-resharper_wrap_object_and_collection_initializer_style = chop_always
-resharper_wrap_ternary_expr_style = wrap_if_long
-resharper_wrap_verbatim_interpolated_strings = wrap_if_long
+resharper_align_first_arg_by_paren = false
+resharper_align_linq_query = true
+resharper_align_multiline_argument = true
+resharper_align_multiline_array_and_object_initializer = false
+resharper_align_multiline_binary_expressions_chain = true
+resharper_align_multiline_binary_patterns = true
+resharper_align_multiline_calls_chain = true
+resharper_align_multiline_expression = true
+resharper_align_multiline_expression_braces = true
+resharper_align_multiline_extends_list = true
+resharper_align_multiline_for_stmt = true
+resharper_align_multiline_list_pattern = true
+resharper_align_multiline_parameter = true
+resharper_align_multiline_property_pattern = true
+resharper_align_multiline_switch_expression = true
+resharper_align_multiple_declaration = true
+resharper_align_multline_type_parameter_constrains = true
+resharper_align_multline_type_parameter_list = true
+resharper_align_ternary = align_all
+resharper_align_tuple_components = true
+resharper_autodetect_indent_settings = true
+resharper_blank_lines_after_multiline_statements = 1
+resharper_blank_lines_around_auto_property = 0
+resharper_blank_lines_before_block_statements = 1
+resharper_blank_lines_before_control_transfer_statements = 1
+resharper_blank_lines_before_multiline_statements = 1
+resharper_blank_lines_before_single_line_comment = 1
+resharper_braces_for_for = required_for_multiline
+resharper_braces_for_foreach = required_for_multiline
+resharper_braces_for_ifelse = required_for_multiline
+resharper_braces_for_while = required_for_multiline
+resharper_builtin_type_apply_to_native_integer = false
+resharper_constructor_or_destructor_body = expression_body
+resharper_continuous_indent_multiplier = 1
+resharper_cpp_allow_comment_after_lbrace = true
+resharper_cpp_keep_blank_lines_in_code = 1
+resharper_cpp_keep_blank_lines_in_declarations = 1
+resharper_cpp_keep_user_linebreaks = false
+resharper_cpp_wrap_parameters_style = chop_if_long
+resharper_csharp_align_first_arg_by_paren = true
+resharper_csharp_blank_lines_around_field = 0
+resharper_csharp_continuous_indent_multiplier = 1
+resharper_csharp_empty_block_style = together_same_line
+resharper_csharp_int_align_fix_in_adjacent = true
+resharper_csharp_place_comments_at_first_column = true
+resharper_csharp_prefer_qualified_reference = false
+resharper_csharp_wrap_arguments_style = chop_if_long
+resharper_csharp_wrap_extends_list_style = chop_if_long
+resharper_default_value_when_type_not_evident = default_expression
+resharper_empty_block_style = together_same_line
+resharper_enforce_line_ending_style = true
+resharper_formatter_off_tag = @formatter:off
+resharper_formatter_on_tag = @formatter:on
+resharper_formatter_tags_enabled = true
+resharper_for_built_in_types = use_var_when_evident
+resharper_function_declaration_return_type_style = on_single_line
+resharper_function_definition_return_type_style = on_single_line
+resharper_html_attribute_style = on_single_line
+resharper_html_max_blank_lines_between_tags = 1
+resharper_html_pi_attribute_style = first_attribute_on_single_line
+resharper_indent_anonymous_method_block = false
+resharper_indent_goto_labels = false
+resharper_indent_nested_fixed_stmt = true
+resharper_indent_nested_foreach_stmt = true
+resharper_indent_nested_for_stmt = true
+resharper_indent_nested_lock_stmt = true
+resharper_indent_nested_usings_stmt = true
+resharper_indent_nested_while_stmt = true
+resharper_indent_preprocessor_if = no_indent
+resharper_indent_preprocessor_other = no_indent
+resharper_indent_preprocessor_region = no_indent
+resharper_indent_primary_constructor_decl_pars = inside
+resharper_indent_switch_labels = true
+resharper_int_align = true
+resharper_int_align_bitfield_sizes = true
+resharper_int_align_comments = true
+resharper_int_align_declaration_names = true
+resharper_int_align_enum_initializers = true
+resharper_int_align_eq = true
+resharper_int_align_fix_in_adjacent = true
+resharper_keep_existing_declaration_parens_arrangement = false
+resharper_keep_existing_embedded_arrangement = false
+resharper_keep_existing_enum_arrangement = false
+resharper_keep_existing_expr_member_arrangement = false
+resharper_keep_existing_initializer_arrangement = false
+resharper_keep_existing_linebreaks = false
+resharper_keep_existing_list_patterns_arrangement = false
+resharper_keep_existing_primary_constructor_declaration_parens_arrangement = false
+resharper_keep_existing_property_patterns_arrangement = false
+resharper_keep_existing_switch_expression_arrangement = false
+resharper_line_break_after_colon_in_member_initializer_lists = on_single_line
+resharper_line_break_after_deref_in_trailing_return_types = on_single_line
+resharper_line_break_before_deref_in_trailing_return_types = on_single_line
+resharper_line_break_before_requires_clause = on_single_line
+resharper_linkage_specification_braces = next_line
+resharper_linkage_specification_indentation = all
+resharper_local_function_body = expression_body
+resharper_max_enum_members_on_line = 1
+resharper_max_initializer_elements_on_line = 1
+resharper_member_initializer_list_style = on_single_line
+resharper_method_or_operator_body = expression_body
+resharper_nested_ternary_style = expanded
+resharper_normalize_tag_names = true
+resharper_outdent_binary_ops = true
+resharper_outdent_binary_pattern_ops = true
+resharper_outdent_commas = true
+resharper_outdent_dots = true
+resharper_outdent_statement_labels = true
+resharper_parentheses_redundancy_style = remove
+resharper_place_attribute_on_same_line = false
+resharper_place_expr_accessor_on_single_line = true
+resharper_place_expr_method_on_single_line = true
+resharper_place_expr_property_on_single_line = true
+resharper_place_simple_embedded_statement_on_same_line = if_owner_is_single_line
+resharper_place_simple_initializer_on_single_line = false
+resharper_qualified_using_at_nested_scope = true
+resharper_show_autodetect_configure_formatting_tip = false
+resharper_simple_block_style = on_single_line
+resharper_simple_case_statement_style = line_break
+resharper_simple_embedded_statement_style = on_single_line
+resharper_sort_attributes = true
+resharper_sort_class_selectors = true
+resharper_space_after_keywords_in_control_flow_statements = false
+resharper_space_after_ptr_in_data_member = false
+resharper_space_after_ptr_in_method = false
+resharper_space_after_ref_in_data_member = false
+resharper_space_after_ref_in_method = false
+resharper_space_before_ptr_in_data_member = true
+resharper_space_before_ptr_in_method = true
+resharper_space_before_ref_in_data_member = true
+resharper_space_before_ref_in_method = true
+resharper_space_before_template_params = false
+resharper_space_within_empty_braces = false
+resharper_toplevel_function_declaration_return_type_style = on_single_line
+resharper_toplevel_function_definition_return_type_style = on_single_line
+resharper_use_continuous_indent_inside_initializer_braces = false
+resharper_use_continuous_indent_inside_parens = false
+resharper_use_indent_from_vs = false
+resharper_wrap_after_dot_in_method_calls = false
+resharper_wrap_base_clause_style = chop_if_long
+resharper_wrap_before_primary_constructor_declaration_lpar = true
+resharper_wrap_before_primary_constructor_declaration_rpar = true
+resharper_wrap_braced_init_list_style = chop_if_long
+resharper_wrap_chained_binary_expressions = chop_if_long
+resharper_wrap_chained_binary_patterns = chop_if_long
+resharper_wrap_chained_method_calls = chop_if_long
+resharper_wrap_ctor_initializer_style = chop_if_long
+resharper_wrap_enum_declaration = chop_if_long
+resharper_wrap_lines = true
+resharper_xmldoc_attribute_indent = align_by_first_attribute
+resharper_xmldoc_attribute_style = first_attribute_on_single_line
+resharper_xmldoc_pi_attribute_style = first_attribute_on_single_line
+resharper_xml_attribute_style = first_attribute_on_single_line
+resharper_xml_keep_user_linebreaks = false
+resharper_xml_pi_attribute_style = first_attribute_on_single_line
# ReSharper inspection severities
-resharper_annotate_can_be_null_parameter_highlighting = warning
-resharper_annotate_can_be_null_type_member_highlighting = warning
-resharper_annotate_not_null_parameter_highlighting = warning
-resharper_annotate_not_null_type_member_highlighting = warning
-resharper_arrange_attributes_highlighting = hint
-resharper_arrange_constructor_or_destructor_body_highlighting = warning
-resharper_arrange_default_value_when_type_evident_highlighting = warning
-resharper_arrange_default_value_when_type_not_evident_highlighting = warning
-resharper_arrange_local_function_body_highlighting = warning
-resharper_arrange_method_or_operator_body_highlighting = warning
-resharper_arrange_object_creation_when_type_evident_highlighting = warning
-resharper_arrange_object_creation_when_type_not_evident_highlighting = warning
-resharper_arrange_redundant_parentheses_highlighting = hint
-resharper_arrange_this_qualifier_highlighting = hint
-resharper_arrange_type_member_modifiers_highlighting = hint
-resharper_arrange_type_modifiers_highlighting = hint
-resharper_async_void_method_highlighting = warning
-resharper_built_in_type_reference_style_for_member_access_highlighting = hint
-resharper_built_in_type_reference_style_highlighting = hint
-resharper_compare_non_constrained_generic_with_null_highlighting = warning
-resharper_heap_view_boxing_allocation_highlighting = none
-resharper_heap_view_delegate_allocation_highlighting = none
-resharper_heap_view_object_allocation_evident_highlighting = none
-resharper_heap_view_object_allocation_highlighting = none
-resharper_inheritdoc_consider_usage_highlighting = warning
-resharper_local_function_can_be_made_static_highlighting = warning
-resharper_loop_can_be_partly_converted_to_query_highlighting = warning
-resharper_member_can_be_internal_highlighting = warning
-resharper_nullable_warning_suppression_is_used_highlighting = warning
-resharper_redundant_base_qualifier_highlighting = warning
-resharper_remove_constructor_invocation_highlighting = warning
-resharper_separate_control_transfer_statement_highlighting = warning
-resharper_string_ends_with_is_culture_specific_highlighting = warning
-resharper_string_starts_with_is_culture_specific_highlighting = warning
-resharper_struct_member_can_be_made_read_only_highlighting = warning
-resharper_suggest_var_or_type_built_in_types_highlighting = hint
-resharper_suggest_var_or_type_elsewhere_highlighting = hint
-resharper_suggest_var_or_type_simple_types_highlighting = hint
-resharper_tabs_are_disallowed_highlighting = warning
-resharper_unnecessary_whitespace_highlighting = warning
-resharper_use_nameof_expression_for_part_of_the_string_highlighting = warning
-resharper_use_positional_deconstruction_pattern_highlighting = warning
-resharper_web_config_module_not_resolved_highlighting = warning
-resharper_web_config_type_not_resolved_highlighting = warning
-resharper_web_config_wrong_module_highlighting = warning
+resharper_annotate_can_be_null_parameter_highlighting = warning
+resharper_annotate_can_be_null_type_member_highlighting = warning
+resharper_annotate_not_null_parameter_highlighting = warning
+resharper_annotate_not_null_type_member_highlighting = warning
+resharper_arguments_style_anonymous_function_highlighting = warning
+resharper_arguments_style_literal_highlighting = warning
+resharper_arguments_style_named_expression_highlighting = warning
+resharper_arguments_style_other_highlighting = warning
+resharper_arguments_style_string_literal_highlighting = warning
+resharper_arrange_accessor_owner_body_highlighting = warning
+resharper_arrange_constructor_or_destructor_body_highlighting = warning
+resharper_arrange_local_function_body_highlighting = warning
+resharper_arrange_method_or_operator_body_highlighting = warning
+resharper_arrange_redundant_parentheses_highlighting = hint
+resharper_arrange_static_member_qualifier_highlighting = warning
+resharper_arrange_this_qualifier_highlighting = hint
+resharper_arrange_trailing_comma_in_multiline_lists_highlighting = warning
+resharper_arrange_trailing_comma_in_singleline_lists_highlighting = warning
+resharper_arrange_type_member_modifiers_highlighting = hint
+resharper_arrange_type_modifiers_highlighting = hint
+resharper_arrange_var_keywords_in_deconstructing_declaration_highlighting = warning
+resharper_async_void_method_highlighting = warning
+resharper_auto_property_can_be_made_get_only_global_highlighting = warning
+resharper_auto_property_can_be_made_get_only_local_highlighting = warning
+resharper_bad_attribute_brackets_spaces_highlighting = warning
+resharper_bad_braces_spaces_highlighting = warning
+resharper_bad_colon_spaces_highlighting = warning
+resharper_bad_comma_spaces_highlighting = warning
+resharper_bad_control_braces_indent_highlighting = warning
+resharper_bad_control_braces_line_breaks_highlighting = warning
+resharper_bad_declaration_braces_indent_highlighting = warning
+resharper_bad_declaration_braces_line_breaks_highlighting = warning
+resharper_bad_empty_braces_line_breaks_highlighting = warning
+resharper_bad_expression_braces_indent_highlighting = warning
+resharper_bad_expression_braces_line_breaks_highlighting = warning
+resharper_bad_generic_brackets_spaces_highlighting = warning
+resharper_bad_indent_highlighting = warning
+resharper_bad_linq_line_breaks_highlighting = warning
+resharper_bad_member_access_spaces_highlighting = warning
+resharper_bad_namespace_braces_indent_highlighting = warning
+resharper_bad_parens_line_breaks_highlighting = warning
+resharper_bad_parens_spaces_highlighting = warning
+resharper_bad_preprocessor_indent_highlighting = warning
+resharper_bad_semicolon_spaces_highlighting = warning
+resharper_bad_spaces_after_keyword_highlighting = warning
+resharper_bad_square_brackets_spaces_highlighting = warning
+resharper_bad_switch_braces_indent_highlighting = warning
+resharper_bad_symbol_spaces_highlighting = warning
+resharper_built_in_type_reference_style_for_member_access_highlighting = hint
+resharper_built_in_type_reference_style_highlighting = hint
+resharper_check_for_reference_equality_instead_1_highlighting = warning
+resharper_check_for_reference_equality_instead_2_highlighting = warning
+resharper_check_for_reference_equality_instead_3_highlighting = warning
+resharper_check_for_reference_equality_instead_4_highlighting = warning
+resharper_class_can_be_sealed_global_highlighting = warning
+resharper_class_can_be_sealed_local_highlighting = warning
+resharper_class_never_instantiated_global_highlighting = warning
+resharper_class_never_instantiated_local_highlighting = warning
+resharper_class_with_virtual_members_never_inherited_global_highlighting = warning
+resharper_class_with_virtual_members_never_inherited_local_highlighting = warning
+resharper_comment_typo_highlighting = none
+resharper_compare_non_constrained_generic_with_null_highlighting = warning
+resharper_convert_closure_to_method_group_highlighting = warning
+resharper_convert_conditional_ternary_expression_to_switch_expression_highlighting = warning
+resharper_convert_if_do_to_while_highlighting = warning
+resharper_convert_if_statement_to_conditional_ternary_expression_highlighting = warning
+resharper_convert_if_statement_to_null_coalescing_assignment_highlighting = warning
+resharper_convert_if_statement_to_null_coalescing_expression_highlighting = warning
+resharper_convert_if_statement_to_return_statement_highlighting = warning
+resharper_convert_if_statement_to_switch_statement_highlighting = warning
+resharper_convert_if_to_or_expression_highlighting = warning
+resharper_convert_nullable_to_short_form_highlighting = warning
+resharper_convert_switch_statement_to_switch_expression_highlighting = warning
+resharper_convert_to_auto_property_highlighting = warning
+resharper_convert_to_auto_property_when_possible_highlighting = warning
+resharper_convert_to_auto_property_with_private_setter_highlighting = warning
+resharper_convert_to_compound_assignment_highlighting = warning
+resharper_convert_to_constant_global_highlighting = warning
+resharper_convert_to_constant_local_highlighting = warning
+resharper_convert_to_lambda_expression_highlighting = warning
+resharper_convert_to_local_function_highlighting = warning
+resharper_convert_to_null_coalescing_compound_assignment_highlighting = warning
+resharper_convert_to_primary_constructor_highlighting = warning
+resharper_convert_to_static_class_highlighting = warning
+resharper_convert_to_using_declaration_highlighting = warning
+resharper_cpp_enforce_cv_qualifiers_order_highlighting = hint
+resharper_cpp_enforce_cv_qualifiers_placement_highlighting = hint
+resharper_cpp_enforce_do_statement_braces_highlighting = hint
+resharper_cpp_enforce_for_statement_braces_highlighting = hint
+resharper_cpp_enforce_function_declaration_style_highlighting = hint
+resharper_cpp_enforce_if_statement_braces_highlighting = hint
+resharper_cpp_enforce_type_alias_code_style_highlighting = hint
+resharper_cpp_enforce_while_statement_braces_highlighting = hint
+resharper_cpp_remove_redundant_braces_highlighting = hint
+resharper_double_negation_in_pattern_highlighting = warning
+resharper_double_negation_operator_highlighting = warning
+resharper_event_never_invoked_global_highlighting = warning
+resharper_event_never_subscribed_to_global_highlighting = warning
+resharper_event_never_subscribed_to_local_highlighting = warning
+resharper_field_can_be_made_read_only_global_highlighting = warning
+resharper_field_can_be_made_read_only_local_highlighting = warning
+resharper_foreach_can_be_converted_to_query_using_another_get_enumerator_highlighting = warning
+resharper_foreach_can_be_partly_converted_to_query_using_another_get_enumerator_highlighting = none
+resharper_for_can_be_converted_to_foreach_highlighting = warning
+resharper_heap_view_boxing_allocation_highlighting = none
+resharper_heap_view_closure_allocation_highlighting = none
+resharper_heap_view_delegate_allocation_highlighting = none
+resharper_heap_view_object_allocation_evident_highlighting = none
+resharper_heap_view_object_allocation_highlighting = none
+resharper_identifier_typo_highlighting = none
+resharper_incorrect_blank_lines_near_braces_highlighting = warning
+resharper_inheritdoc_consider_usage_highlighting = warning
+resharper_inline_out_variable_declaration_highlighting = warning
+resharper_inline_temporary_variable_highlighting = warning
+resharper_introduce_optional_parameters_global_highlighting = warning
+resharper_introduce_optional_parameters_local_highlighting = warning
+resharper_invert_condition_1_highlighting = warning
+resharper_invert_if_highlighting = warning
+resharper_invocation_is_skipped_highlighting = warning
+resharper_invoke_as_extension_method_highlighting = warning
+resharper_join_declaration_and_initializer_highlighting = warning
+resharper_join_null_check_with_usage_highlighting = warning
+resharper_lambda_expression_must_be_static_highlighting = warning
+resharper_localizable_element_highlighting = error
+resharper_local_function_can_be_made_static_highlighting = warning
+resharper_loop_can_be_converted_to_query_highlighting = warning
+resharper_loop_can_be_partly_converted_to_query_highlighting = warning
+resharper_member_can_be_file_local_highlighting = warning
+resharper_member_can_be_internal_highlighting = warning
+resharper_member_can_be_made_static_global_highlighting = warning
+resharper_member_can_be_made_static_local_highlighting = warning
+resharper_member_can_be_private_global_highlighting = warning
+resharper_member_can_be_private_local_highlighting = warning
+resharper_member_can_be_protected_global_highlighting = warning
+resharper_member_can_be_protected_local_highlighting = warning
+resharper_merge_and_pattern_highlighting = warning
+resharper_merge_cast_with_type_check_highlighting = warning
+resharper_merge_conditional_expression_highlighting = warning
+resharper_merge_into_logical_pattern_highlighting = warning
+resharper_merge_into_negated_pattern_highlighting = warning
+resharper_merge_into_pattern_highlighting = warning
+resharper_merge_nested_property_patterns_highlighting = warning
+resharper_merge_sequential_checks_highlighting = warning
+resharper_method_has_async_overload_highlighting = warning
+resharper_method_has_async_overload_with_cancellation_highlighting = warning
+resharper_method_supports_cancellation_highlighting = warning
+resharper_missing_blank_lines_highlighting = warning
+resharper_missing_linebreak_highlighting = warning
+resharper_missing_space_highlighting = warning
+resharper_more_specific_foreach_variable_type_available_highlighting = warning
+resharper_move_to_existing_positional_deconstruction_pattern_highlighting = warning
+resharper_move_variable_declaration_inside_loop_condition_highlighting = warning
+resharper_multiple_spaces_highlighting = warning
+resharper_multiple_statements_on_one_line_highlighting = warning
+resharper_multiple_type_members_on_one_line_highlighting = warning
+resharper_negation_of_relational_pattern_highlighting = warning
+resharper_negative_equality_expression_highlighting = warning
+resharper_nested_string_interpolation_highlighting = warning
+resharper_not_accessed_field_global_highlighting = warning
+resharper_nullable_warning_suppression_is_used_highlighting = warning
+resharper_outdent_is_off_prev_level_highlighting = warning
+resharper_out_parameter_value_is_always_discarded_global_highlighting = warning
+resharper_parameter_only_used_for_precondition_check_global_highlighting = warning
+resharper_parameter_type_can_be_enumerable_global_highlighting = warning
+resharper_parameter_type_can_be_enumerable_local_highlighting = warning
+resharper_pass_string_interpolation_highlighting = warning
+resharper_possible_unintended_queryable_as_enumerable_highlighting = warning
+resharper_property_can_be_made_init_only_global_highlighting = warning
+resharper_property_can_be_made_init_only_local_highlighting = warning
+resharper_public_constructor_in_abstract_class_highlighting = warning
+resharper_raw_string_can_be_simplified_highlighting = warning
+resharper_razor_assembly_not_resolved_highlighting = warning
+resharper_redundant_accessor_body_highlighting = warning
+resharper_redundant_always_match_subpattern_highlighting = warning
+resharper_redundant_array_creation_expression_highlighting = warning
+resharper_redundant_attribute_parentheses_highlighting = warning
+resharper_redundant_attribute_usage_property_highlighting = warning
+resharper_redundant_base_qualifier_highlighting = warning
+resharper_redundant_blank_lines_highlighting = warning
+resharper_redundant_collection_initializer_element_braces_highlighting = warning
+resharper_redundant_configure_await_highlighting = warning
+resharper_redundant_declaration_semicolon_highlighting = warning
+resharper_redundant_discard_designation_highlighting = warning
+resharper_redundant_empty_object_creation_argument_list_highlighting = warning
+resharper_redundant_enum_case_label_for_default_section_highlighting = warning
+resharper_redundant_explicit_params_array_creation_highlighting = warning
+resharper_redundant_fixed_pointer_declaration_highlighting = warning
+resharper_redundant_if_else_block_highlighting = warning
+resharper_redundant_immediate_delegate_invocation_highlighting = warning
+resharper_redundant_is_before_relational_pattern_highlighting = warning
+resharper_redundant_lambda_signature_parentheses_highlighting = warning
+resharper_redundant_overload_global_highlighting = warning
+resharper_redundant_overload_local_highlighting = warning
+resharper_redundant_pattern_parentheses_highlighting = warning
+resharper_redundant_property_pattern_clause_highlighting = warning
+resharper_redundant_query_order_by_ascending_keyword_highlighting = warning
+resharper_redundant_range_bound_highlighting = warning
+resharper_redundant_readonly_modifier_highlighting = warning
+resharper_redundant_space_highlighting = warning
+resharper_redundant_string_interpolation_highlighting = warning
+resharper_redundant_to_string_call_for_value_type_highlighting = warning
+resharper_redundant_verbatim_prefix_highlighting = warning
+resharper_redundant_verbatim_string_prefix_highlighting = warning
+resharper_redundant_with_expression_highlighting = warning
+resharper_remove_constructor_invocation_highlighting = warning
+resharper_remove_redundant_braces_highlighting = warning
+resharper_remove_redundant_or_statement_false_highlighting = warning
+resharper_remove_redundant_or_statement_true_highlighting = warning
+resharper_remove_to_list_1_highlighting = warning
+resharper_remove_to_list_2_highlighting = warning
+resharper_replace_auto_property_with_computed_property_highlighting = warning
+resharper_replace_conditional_expression_with_null_coalescing_highlighting = warning
+resharper_replace_object_pattern_with_var_pattern_highlighting = warning
+resharper_replace_slice_with_range_indexer_highlighting = warning
+resharper_replace_substring_with_range_indexer_highlighting = warning
+resharper_replace_with_field_keyword_highlighting = warning
+resharper_replace_with_first_or_default_1_highlighting = warning
+resharper_replace_with_first_or_default_2_highlighting = warning
+resharper_replace_with_first_or_default_3_highlighting = warning
+resharper_replace_with_first_or_default_4_highlighting = warning
+resharper_replace_with_last_or_default_1_highlighting = warning
+resharper_replace_with_last_or_default_2_highlighting = warning
+resharper_replace_with_last_or_default_3_highlighting = warning
+resharper_replace_with_last_or_default_4_highlighting = warning
+resharper_replace_with_of_type_1_highlighting = warning
+resharper_replace_with_of_type_2_highlighting = warning
+resharper_replace_with_of_type_3_highlighting = warning
+resharper_replace_with_of_type_any_1_highlighting = warning
+resharper_replace_with_of_type_any_2_highlighting = warning
+resharper_replace_with_of_type_count_1_highlighting = warning
+resharper_replace_with_of_type_count_2_highlighting = warning
+resharper_replace_with_of_type_first_1_highlighting = warning
+resharper_replace_with_of_type_first_2_highlighting = warning
+resharper_replace_with_of_type_first_or_default_1_highlighting = warning
+resharper_replace_with_of_type_first_or_default_2_highlighting = warning
+resharper_replace_with_of_type_last_1_highlighting = warning
+resharper_replace_with_of_type_last_2_highlighting = warning
+resharper_replace_with_of_type_last_or_default_1_highlighting = warning
+resharper_replace_with_of_type_last_or_default_2_highlighting = warning
+resharper_replace_with_of_type_long_count_highlighting = warning
+resharper_replace_with_of_type_single_1_highlighting = warning
+resharper_replace_with_of_type_single_2_highlighting = warning
+resharper_replace_with_of_type_single_or_default_1_highlighting = warning
+resharper_replace_with_of_type_single_or_default_2_highlighting = warning
+resharper_replace_with_of_type_where_highlighting = warning
+resharper_replace_with_simple_assignment_false_highlighting = warning
+resharper_replace_with_simple_assignment_true_highlighting = warning
+resharper_replace_with_single_assignment_false_highlighting = warning
+resharper_replace_with_single_assignment_true_highlighting = warning
+resharper_replace_with_single_call_to_any_highlighting = warning
+resharper_replace_with_single_call_to_count_highlighting = warning
+resharper_replace_with_single_call_to_first_highlighting = warning
+resharper_replace_with_single_call_to_first_or_default_highlighting = warning
+resharper_replace_with_single_call_to_last_highlighting = warning
+resharper_replace_with_single_call_to_last_or_default_highlighting = warning
+resharper_replace_with_single_call_to_single_highlighting = warning
+resharper_replace_with_single_call_to_single_or_default_highlighting = warning
+resharper_replace_with_single_or_default_1_highlighting = warning
+resharper_replace_with_single_or_default_2_highlighting = warning
+resharper_replace_with_single_or_default_3_highlighting = warning
+resharper_replace_with_single_or_default_4_highlighting = warning
+resharper_replace_with_string_is_null_or_empty_highlighting = warning
+resharper_return_type_can_be_enumerable_global_highlighting = warning
+resharper_return_type_can_be_enumerable_local_highlighting = warning
+resharper_safe_cast_is_used_as_type_check_highlighting = warning
+resharper_separate_control_transfer_statement_highlighting = warning
+resharper_similar_anonymous_type_nearby_highlighting = warning
+resharper_simplify_conditional_ternary_expression_highlighting = warning
+resharper_simplify_linq_expression_use_all_highlighting = warning
+resharper_simplify_linq_expression_use_any_highlighting = warning
+resharper_simplify_linq_expression_use_min_by_and_max_by_highlighting = warning
+resharper_simplify_string_interpolation_highlighting = warning
+resharper_specify_string_comparison_highlighting = warning
+resharper_string_ends_with_is_culture_specific_highlighting = warning
+resharper_string_literal_as_interpolation_argument_highlighting = warning
+resharper_string_literal_typo_highlighting = warning
+resharper_string_starts_with_is_culture_specific_highlighting = warning
+resharper_struct_can_be_made_read_only_highlighting = warning
+resharper_struct_member_can_be_made_read_only_highlighting = warning
+resharper_suggest_base_type_for_parameter_highlighting = none
+resharper_suggest_base_type_for_parameter_in_constructor_highlighting = warning
+resharper_suggest_discard_declaration_var_style_highlighting = hint
+resharper_suggest_var_or_type_built_in_types_highlighting = hint
+resharper_suggest_var_or_type_deconstruction_declarations_highlighting = warning
+resharper_suggest_var_or_type_elsewhere_highlighting = hint
+resharper_suggest_var_or_type_simple_types_highlighting = hint
+resharper_swap_via_deconstruction_highlighting = warning
+resharper_switch_expression_handles_some_known_enum_values_with_exception_in_default_highlighting = warning
+resharper_switch_statement_handles_some_known_enum_values_with_default_highlighting = none
+resharper_switch_statement_missing_some_enum_cases_no_default_highlighting = none
+resharper_tabs_and_spaces_mismatch_highlighting = warning
+resharper_tabs_are_disallowed_highlighting = warning
+resharper_tabs_outside_indent_highlighting = warning
+resharper_tail_recursive_call_highlighting = warning
+resharper_too_wide_local_variable_scope_highlighting = warning
+resharper_try_cast_always_succeeds_highlighting = warning
+resharper_try_statements_can_be_merged_highlighting = warning
+resharper_type_parameter_can_be_variant_highlighting = warning
+resharper_unnecessary_whitespace_highlighting = warning
+resharper_unused_member_global_highlighting = warning
+resharper_unused_member_hierarchy_global_highlighting = warning
+resharper_unused_member_in_super_global_highlighting = warning
+resharper_unused_method_return_value_global_highlighting = warning
+resharper_unused_parameter_global_highlighting = warning
+resharper_unused_type_global_highlighting = warning
+resharper_use_array_creation_expression_1_highlighting = warning
+resharper_use_array_creation_expression_2_highlighting = warning
+resharper_use_array_empty_method_highlighting = warning
+resharper_use_await_using_highlighting = warning
+resharper_use_cancellation_token_for_i_async_enumerable_highlighting = warning
+resharper_use_collection_count_property_highlighting = warning
+resharper_use_configure_await_false_highlighting = warning
+resharper_use_deconstruction_highlighting = warning
+resharper_use_empty_types_field_highlighting = warning
+resharper_use_event_args_empty_field_highlighting = warning
+resharper_use_format_specifier_in_format_string_highlighting = warning
+resharper_use_indexed_property_highlighting = warning
+resharper_use_index_from_end_expression_highlighting = warning
+resharper_use_is_operator_1_highlighting = warning
+resharper_use_is_operator_2_highlighting = warning
+resharper_use_method_any_0_highlighting = warning
+resharper_use_method_any_1_highlighting = warning
+resharper_use_method_any_2_highlighting = warning
+resharper_use_method_any_3_highlighting = warning
+resharper_use_method_any_4_highlighting = warning
+resharper_use_method_is_instance_of_type_highlighting = warning
+resharper_use_nameof_expression_for_part_of_the_string_highlighting = warning
+resharper_use_nameof_expression_highlighting = warning
+resharper_use_nameof_for_dependency_property_highlighting = warning
+resharper_use_name_of_instead_of_type_of_highlighting = warning
+resharper_use_negated_pattern_in_is_expression_highlighting = warning
+resharper_use_negated_pattern_matching_highlighting = warning
+resharper_use_nullable_annotation_instead_of_attribute_highlighting = warning
+resharper_use_nullable_attributes_supported_by_compiler_highlighting = warning
+resharper_use_null_propagation_highlighting = warning
+resharper_use_object_or_collection_initializer_highlighting = warning
+resharper_use_pattern_matching_highlighting = warning
+resharper_use_positional_deconstruction_pattern_highlighting = warning
+resharper_use_raw_string_highlighting = warning
+resharper_use_string_interpolation_highlighting = warning
+resharper_use_switch_case_pattern_variable_highlighting = warning
+resharper_use_throw_if_null_method_highlighting = warning
+resharper_use_unsigned_right_shift_operator_highlighting = warning
+resharper_use_verbatim_string_highlighting = warning
+resharper_use_with_expression_to_copy_anonymous_object_highlighting = warning
+resharper_use_with_expression_to_copy_record_highlighting = warning
+resharper_use_with_expression_to_copy_struct_highlighting = warning
+resharper_use_with_expression_to_copy_tuple_highlighting = warning
+resharper_virtual_member_never_overridden_global_highlighting = warning
+resharper_virtual_member_never_overridden_local_highlighting = warning
+resharper_web_config_module_not_resolved_highlighting = warning
+resharper_web_config_type_not_resolved_highlighting = warning
+resharper_web_config_wrong_module_highlighting = warning
+resharper_with_expression_instead_of_initializer_highlighting = warning
+resharper_wrong_indent_size_highlighting = warning
-[{*.har,*.inputactions,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,jest.config}]
-indent_style = space
-indent_size = 2
-
-[{*.yaml,*.yml,.analysis_options}]
-indent_style = space
-indent_size = 2
+[*.css]
+ij_css_align_closing_brace_with_properties = false
+ij_css_blank_lines_around_nested_selector = 1
+ij_css_blank_lines_between_blocks = 1
+ij_css_block_comment_add_space = false
+ij_css_brace_placement = end_of_line
+ij_css_enforce_quotes_on_format = false
+ij_css_hex_color_long_format = false
+ij_css_hex_color_lower_case = false
+ij_css_hex_color_short_format = false
+ij_css_hex_color_upper_case = false
+ij_css_keep_blank_lines_in_code = 2
+ij_css_keep_indents_on_empty_lines = false
+ij_css_keep_single_line_blocks = false
+ij_css_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow
+ij_css_space_after_colon = true
+ij_css_space_before_opening_brace = true
+ij_css_use_double_quotes = true
+ij_css_value_alignment = do_not_align
[*.csv]
-indent_style = tab
-tab_width = 1
+max_line_length = 2147483647
+ij_csv_wrap_long_lines = false
+indent_style = tab
+tab_width = 1
-[{*.bash,*.sh,*.tool,*.zsh}]
-indent_style = space
-indent_size = 2
+[*.dart]
+max_line_length = 80
-[*.{appxmanifest,asax,ascx,aspx,axaml,build,cg,cginc,compute,cs,cshtml,dtd,fs,fsi,fsscript,fsx,hlsl,hlsli,hlslinc,master,ml,mli,nuspec,paml,razor,resw,resx,shader,skin,usf,ush,vb,xaml,xamlx,xoml,xsd}]
+[*.less]
+indent_size = 2
+ij_less_align_closing_brace_with_properties = false
+ij_less_blank_lines_around_nested_selector = 1
+ij_less_blank_lines_between_blocks = 1
+ij_less_block_comment_add_space = false
+ij_less_brace_placement = 0
+ij_less_enforce_quotes_on_format = false
+ij_less_hex_color_long_format = false
+ij_less_hex_color_lower_case = false
+ij_less_hex_color_short_format = false
+ij_less_hex_color_upper_case = false
+ij_less_keep_blank_lines_in_code = 2
+ij_less_keep_indents_on_empty_lines = false
+ij_less_keep_single_line_blocks = false
+ij_less_line_comment_add_space = false
+ij_less_line_comment_at_first_column = false
+ij_less_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow
+ij_less_space_after_colon = true
+ij_less_space_before_opening_brace = true
+ij_less_use_double_quotes = true
+ij_less_value_alignment = 0
+
+[*.pp]
+indent_size = 2
+tab_width = 2
+ij_continuation_indent_size = 2
+ij_puppet_keep_indents_on_empty_lines = false
+
+[*.properties]
+ij_properties_align_group_field_declarations = true
+ij_properties_keep_blank_lines = false
+ij_properties_key_value_delimiter = equals
+ij_properties_spaces_around_key_value_delimiter = true
+
+[*.sass]
+indent_size = 2
+ij_sass_align_closing_brace_with_properties = false
+ij_sass_blank_lines_around_nested_selector = 1
+ij_sass_blank_lines_between_blocks = 1
+ij_sass_brace_placement = 0
+ij_sass_enforce_quotes_on_format = false
+ij_sass_hex_color_long_format = false
+ij_sass_hex_color_lower_case = false
+ij_sass_hex_color_short_format = false
+ij_sass_hex_color_upper_case = false
+ij_sass_keep_blank_lines_in_code = 2
+ij_sass_keep_indents_on_empty_lines = false
+ij_sass_keep_single_line_blocks = false
+ij_sass_line_comment_add_space = false
+ij_sass_line_comment_at_first_column = false
+ij_sass_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow
+ij_sass_space_after_colon = true
+ij_sass_space_before_opening_brace = true
+ij_sass_use_double_quotes = true
+ij_sass_value_alignment = 0
+
+[*.scss]
+indent_size = 2
+ij_scss_align_closing_brace_with_properties = false
+ij_scss_blank_lines_around_nested_selector = 1
+ij_scss_blank_lines_between_blocks = 1
+ij_scss_block_comment_add_space = false
+ij_scss_brace_placement = 0
+ij_scss_enforce_quotes_on_format = false
+ij_scss_hex_color_long_format = false
+ij_scss_hex_color_lower_case = false
+ij_scss_hex_color_short_format = false
+ij_scss_hex_color_upper_case = false
+ij_scss_keep_blank_lines_in_code = 2
+ij_scss_keep_indents_on_empty_lines = false
+ij_scss_keep_single_line_blocks = false
+ij_scss_line_comment_add_space = false
+ij_scss_line_comment_at_first_column = false
+ij_scss_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow
+ij_scss_space_after_colon = true
+ij_scss_space_before_opening_brace = true
+ij_scss_use_double_quotes = true
+ij_scss_value_alignment = 0
+
+[*.slim]
+indent_size = 2
+ij_slim_keep_indents_on_empty_lines = false
+
+[*.twig]
+ij_twig_keep_indents_on_empty_lines = false
+ij_twig_spaces_inside_comments_delimiters = true
+ij_twig_spaces_inside_delimiters = true
+ij_twig_spaces_inside_variable_delimiters = true
+
+[*.vue]
+indent_size = 2
+tab_width = 2
+ij_continuation_indent_size = 4
+ij_vue_indent_children_of_top_level = template
+ij_vue_interpolation_new_line_after_start_delimiter = true
+ij_vue_interpolation_new_line_before_end_delimiter = true
+ij_vue_interpolation_wrap = off
+ij_vue_keep_indents_on_empty_lines = false
+ij_vue_spaces_within_interpolation_expressions = true
+
+[.editorconfig]
+ij_editorconfig_align_group_field_declarations = true
+ij_editorconfig_space_after_colon = false
+ij_editorconfig_space_after_comma = true
+ij_editorconfig_space_before_colon = false
+ij_editorconfig_space_before_comma = false
+ij_editorconfig_spaces_around_assignment_operators = true
+
+[{*.ad,*.adoc,*.asciidoc,.asciidoctorconfig}]
+ij_asciidoc_blank_lines_after_header = 1
+ij_asciidoc_blank_lines_keep_after_header = 1
+ij_asciidoc_formatting_enabled = true
+ij_asciidoc_one_sentence_per_line = true
+
+[{*.ant,*.appxmanifest,*.axml,*.cscfg,*.csdef,*.disco,*.dotsettings,*.filelayout,*.fxml,*.jhm,*.jnlp,*.jrxml,*.manifest,*.myapp,*.nuspec,*.rng,*.sdef,*.stylecop,*.svcmap,*.tld,*.wadcfgx,*.webref,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul,StyleCop.Cache}]
+ij_xml_align_attributes = true
+ij_xml_align_text = false
+ij_xml_attribute_wrap = on_every_item
+ij_xml_block_comment_add_space = false
+ij_xml_block_comment_at_first_column = true
+ij_xml_keep_blank_lines = 2
+ij_xml_keep_indents_on_empty_lines = false
+ij_xml_keep_line_breaks = true
+ij_xml_keep_line_breaks_in_text = true
+ij_xml_keep_whitespaces = false
+ij_xml_keep_whitespaces_around_cdata = preserve
+ij_xml_keep_whitespaces_inside_cdata = false
+ij_xml_line_comment_at_first_column = true
+ij_xml_space_after_tag_name = false
+ij_xml_space_around_equals_in_attribute = false
+ij_xml_space_inside_empty_tag = false
+ij_xml_text_wrap = normal
+ij_xml_use_custom_settings = false
+indent_size = 2
+tab_width = 2
+ij_continuation_indent_size = 4
+
+[{*.applescript,*.scpt}]
+indent_size = 2
+tab_width = 2
+ij_continuation_indent_size = 4
+ij_applescript_align_multiline_binary_operation = true
+ij_applescript_align_multiline_parameters = true
+ij_applescript_align_multiline_parameters_in_calls = true
+ij_applescript_binary_operation_sign_on_next_line = false
+ij_applescript_binary_operation_wrap = off
+ij_applescript_block_brace_style = next_line
+ij_applescript_call_parameters_new_line_after_left_paren = false
+ij_applescript_call_parameters_right_paren_on_new_line = false
+ij_applescript_call_parameters_wrap = off
+ij_applescript_else_on_new_line = true
+ij_applescript_keep_blank_lines_in_code = 2
+ij_applescript_keep_first_column_comment = true
+ij_applescript_keep_indents_on_empty_lines = false
+ij_applescript_keep_line_breaks = true
+ij_applescript_method_brace_style = next_line
+ij_applescript_method_parameters_new_line_after_left_paren = false
+ij_applescript_method_parameters_right_paren_on_new_line = false
+ij_applescript_method_parameters_wrap = off
+ij_applescript_parentheses_expression_new_line_after_left_paren = false
+ij_applescript_parentheses_expression_right_paren_on_new_line = false
+ij_applescript_space_after_colon = true
+ij_applescript_space_after_comma = true
+ij_applescript_space_after_comma_in_type_arguments = true
+ij_applescript_space_before_colon = true
+ij_applescript_space_before_comma = false
+ij_applescript_space_before_else_keyword = true
+ij_applescript_space_before_else_left_brace = true
+ij_applescript_space_before_if_parentheses = false
+ij_applescript_space_before_method_call_parentheses = false
+ij_applescript_space_before_method_left_brace = true
+ij_applescript_space_before_method_parentheses = false
+ij_applescript_space_before_while_keyword = true
+ij_applescript_spaces_around_additive_operators = true
+ij_applescript_spaces_around_assignment_operators = true
+ij_applescript_spaces_around_equality_operators = true
+ij_applescript_spaces_around_logical_operators = true
+ij_applescript_spaces_around_multiplicative_operators = true
+ij_applescript_spaces_around_relational_operators = true
+ij_applescript_spaces_around_shift_operators = true
+ij_applescript_spaces_around_unary_operator = false
+ij_applescript_spaces_within_if_parentheses = false
+ij_applescript_spaces_within_method_call_parentheses = false
+ij_applescript_spaces_within_method_parentheses = false
+ij_applescript_special_else_if_treatment = true
+
+[{*.ats,*.cts,*.mts,*.ts}]
+ij_continuation_indent_size = 4
+ij_typescript_align_imports = true
+ij_typescript_align_multiline_array_initializer_expression = true
+ij_typescript_align_multiline_binary_operation = true
+ij_typescript_align_multiline_chained_methods = true
+ij_typescript_align_multiline_extends_list = false
+ij_typescript_align_multiline_for = true
+ij_typescript_align_multiline_parameters = true
+ij_typescript_align_multiline_parameters_in_calls = true
+ij_typescript_align_multiline_ternary_operation = true
+ij_typescript_align_object_properties = 1
+ij_typescript_align_union_types = true
+ij_typescript_align_var_statements = 2
+ij_typescript_array_initializer_new_line_after_left_brace = false
+ij_typescript_array_initializer_right_brace_on_new_line = false
+ij_typescript_array_initializer_wrap = on_every_item
+ij_typescript_assignment_wrap = on_every_item
+ij_typescript_binary_operation_sign_on_next_line = false
+ij_typescript_binary_operation_wrap = on_every_item
+ij_typescript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/**
+ij_typescript_blank_lines_after_imports = 1
+ij_typescript_blank_lines_around_class = 1
+ij_typescript_blank_lines_around_field = 0
+ij_typescript_blank_lines_around_field_in_interface = 0
+ij_typescript_blank_lines_around_function = 1
+ij_typescript_blank_lines_around_method = 1
+ij_typescript_blank_lines_around_method_in_interface = 1
+ij_typescript_block_brace_style = next_line
+ij_typescript_block_comment_add_space = false
+ij_typescript_block_comment_at_first_column = true
+ij_typescript_call_parameters_new_line_after_left_paren = false
+ij_typescript_call_parameters_right_paren_on_new_line = false
+ij_typescript_call_parameters_wrap = on_every_item
+ij_typescript_catch_on_new_line = true
+ij_typescript_chained_call_dot_on_new_line = true
+ij_typescript_class_brace_style = next_line
+ij_typescript_comma_on_new_line = false
+ij_typescript_do_while_brace_force = always
+ij_typescript_else_on_new_line = false
+ij_typescript_enforce_trailing_comma = keep
+ij_typescript_enum_constants_wrap = on_every_item
+ij_typescript_extends_keyword_wrap = normal
+ij_typescript_extends_list_wrap = on_every_item
+ij_typescript_field_prefix = _
+ij_typescript_file_name_style = relaxed
+ij_typescript_finally_on_new_line = true
+ij_typescript_for_brace_force = if_multiline
+ij_typescript_for_statement_new_line_after_left_paren = false
+ij_typescript_for_statement_right_paren_on_new_line = false
+ij_typescript_for_statement_wrap = on_every_item
+ij_typescript_force_quote_style = true
+ij_typescript_force_semicolon_style = true
+ij_typescript_function_expression_brace_style = next_line
+ij_typescript_if_brace_force = never
+ij_typescript_import_merge_members = global
+ij_typescript_import_prefer_absolute_path = true
+ij_typescript_import_sort_members = true
+ij_typescript_import_sort_module_name = true
+ij_typescript_import_use_node_resolution = true
+ij_typescript_imports_wrap = on_every_item
+ij_typescript_indent_case_from_switch = true
+ij_typescript_indent_chained_calls = true
+ij_typescript_indent_package_children = 0
+ij_typescript_jsdoc_include_types = false
+ij_typescript_jsx_attribute_value = braces
+ij_typescript_keep_blank_lines_in_code = 2
+ij_typescript_keep_first_column_comment = true
+ij_typescript_keep_indents_on_empty_lines = false
+ij_typescript_keep_line_breaks = true
+ij_typescript_keep_simple_blocks_in_one_line = false
+ij_typescript_keep_simple_methods_in_one_line = false
+ij_typescript_line_comment_add_space = true
+ij_typescript_line_comment_at_first_column = false
+ij_typescript_method_brace_style = next_line
+ij_typescript_method_call_chain_wrap = on_every_item
+ij_typescript_method_parameters_new_line_after_left_paren = false
+ij_typescript_method_parameters_right_paren_on_new_line = false
+ij_typescript_method_parameters_wrap = on_every_item
+ij_typescript_object_literal_wrap = on_every_item
+ij_typescript_object_types_wrap = on_every_item
+ij_typescript_parentheses_expression_new_line_after_left_paren = false
+ij_typescript_parentheses_expression_right_paren_on_new_line = false
+ij_typescript_place_assignment_sign_on_next_line = false
+ij_typescript_prefer_as_type_cast = false
+ij_typescript_prefer_explicit_types_function_expression_returns = false
+ij_typescript_prefer_explicit_types_function_returns = false
+ij_typescript_prefer_explicit_types_vars_fields = false
+ij_typescript_prefer_parameters_wrap = false
+ij_typescript_property_prefix =
+ij_typescript_reformat_c_style_comments = false
+ij_typescript_space_after_colon = true
+ij_typescript_space_after_comma = true
+ij_typescript_space_after_dots_in_rest_parameter = false
+ij_typescript_space_after_generator_mult = true
+ij_typescript_space_after_property_colon = true
+ij_typescript_space_after_quest = true
+ij_typescript_space_after_type_colon = true
+ij_typescript_space_after_unary_not = false
+ij_typescript_space_before_async_arrow_lparen = false
+ij_typescript_space_before_catch_keyword = true
+ij_typescript_space_before_catch_left_brace = false
+ij_typescript_space_before_catch_parentheses = false
+ij_typescript_space_before_class_lbrace = false
+ij_typescript_space_before_class_left_brace = true
+ij_typescript_space_before_colon = true
+ij_typescript_space_before_comma = false
+ij_typescript_space_before_do_left_brace = false
+ij_typescript_space_before_else_keyword = true
+ij_typescript_space_before_else_left_brace = false
+ij_typescript_space_before_finally_keyword = true
+ij_typescript_space_before_finally_left_brace = false
+ij_typescript_space_before_for_left_brace = false
+ij_typescript_space_before_for_parentheses = false
+ij_typescript_space_before_for_semicolon = false
+ij_typescript_space_before_function_left_parenth = false
+ij_typescript_space_before_generator_mult = false
+ij_typescript_space_before_if_left_brace = false
+ij_typescript_space_before_if_parentheses = false
+ij_typescript_space_before_method_call_parentheses = false
+ij_typescript_space_before_method_left_brace = false
+ij_typescript_space_before_method_parentheses = false
+ij_typescript_space_before_property_colon = false
+ij_typescript_space_before_quest = true
+ij_typescript_space_before_switch_left_brace = false
+ij_typescript_space_before_switch_parentheses = false
+ij_typescript_space_before_try_left_brace = false
+ij_typescript_space_before_type_colon = false
+ij_typescript_space_before_unary_not = false
+ij_typescript_space_before_while_keyword = true
+ij_typescript_space_before_while_left_brace = false
+ij_typescript_space_before_while_parentheses = false
+ij_typescript_spaces_around_additive_operators = true
+ij_typescript_spaces_around_arrow_function_operator = true
+ij_typescript_spaces_around_assignment_operators = true
+ij_typescript_spaces_around_bitwise_operators = true
+ij_typescript_spaces_around_equality_operators = true
+ij_typescript_spaces_around_logical_operators = true
+ij_typescript_spaces_around_multiplicative_operators = true
+ij_typescript_spaces_around_relational_operators = true
+ij_typescript_spaces_around_shift_operators = true
+ij_typescript_spaces_around_unary_operator = false
+ij_typescript_spaces_within_array_initializer_brackets = false
+ij_typescript_spaces_within_brackets = false
+ij_typescript_spaces_within_catch_parentheses = false
+ij_typescript_spaces_within_for_parentheses = false
+ij_typescript_spaces_within_if_parentheses = false
+ij_typescript_spaces_within_imports = false
+ij_typescript_spaces_within_interpolation_expressions = false
+ij_typescript_spaces_within_method_call_parentheses = false
+ij_typescript_spaces_within_method_parentheses = false
+ij_typescript_spaces_within_object_literal_braces = false
+ij_typescript_spaces_within_object_type_braces = true
+ij_typescript_spaces_within_parentheses = false
+ij_typescript_spaces_within_switch_parentheses = false
+ij_typescript_spaces_within_type_assertion = false
+ij_typescript_spaces_within_union_types = true
+ij_typescript_spaces_within_while_parentheses = false
+ij_typescript_special_else_if_treatment = true
+ij_typescript_ternary_operation_signs_on_next_line = false
+ij_typescript_ternary_operation_wrap = on_every_item
+ij_typescript_union_types_wrap = on_every_item
+ij_typescript_use_chained_calls_group_indents = false
+ij_typescript_use_double_quotes = true
+ij_typescript_use_explicit_js_extension = auto
+ij_typescript_use_path_mapping = always
+ij_typescript_use_public_modifier = false
+ij_typescript_use_semicolon_after_statement = true
+ij_typescript_var_declaration_wrap = normal
+ij_typescript_while_brace_force = always
+ij_typescript_while_on_new_line = false
+ij_typescript_wrap_comments = false
+
+[{*.bash,*.sh,*.zsh}]
+indent_size = 2
+tab_width = 2
+ij_shell_binary_ops_start_line = false
+ij_shell_keep_column_alignment_padding = false
+ij_shell_minify_program = false
+ij_shell_redirect_followed_by_space = false
+ij_shell_switch_cases_indented = true
+ij_shell_use_unix_line_separator = true
+indent_style = space
+
+[{*.cjs,*.js}]
+ij_continuation_indent_size = 4
+ij_javascript_align_imports = true
+ij_javascript_align_multiline_array_initializer_expression = true
+ij_javascript_align_multiline_binary_operation = true
+ij_javascript_align_multiline_chained_methods = false
+ij_javascript_align_multiline_extends_list = true
+ij_javascript_align_multiline_for = true
+ij_javascript_align_multiline_parameters = true
+ij_javascript_align_multiline_parameters_in_calls = true
+ij_javascript_align_multiline_ternary_operation = true
+ij_javascript_align_object_properties = 1
+ij_javascript_align_union_types = false
+ij_javascript_align_var_statements = 2
+ij_javascript_array_initializer_new_line_after_left_brace = false
+ij_javascript_array_initializer_right_brace_on_new_line = false
+ij_javascript_array_initializer_wrap = on_every_item
+ij_javascript_assignment_wrap = on_every_item
+ij_javascript_binary_operation_sign_on_next_line = false
+ij_javascript_binary_operation_wrap = on_every_item
+ij_javascript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/**
+ij_javascript_blank_lines_after_imports = 1
+ij_javascript_blank_lines_around_class = 1
+ij_javascript_blank_lines_around_field = 0
+ij_javascript_blank_lines_around_function = 1
+ij_javascript_blank_lines_around_method = 1
+ij_javascript_block_brace_style = next_line
+ij_javascript_block_comment_add_space = false
+ij_javascript_block_comment_at_first_column = true
+ij_javascript_call_parameters_new_line_after_left_paren = false
+ij_javascript_call_parameters_right_paren_on_new_line = false
+ij_javascript_call_parameters_wrap = on_every_item
+ij_javascript_catch_on_new_line = true
+ij_javascript_chained_call_dot_on_new_line = true
+ij_javascript_class_brace_style = next_line
+ij_javascript_comma_on_new_line = false
+ij_javascript_do_while_brace_force = always
+ij_javascript_else_on_new_line = true
+ij_javascript_enforce_trailing_comma = remove
+ij_javascript_extends_keyword_wrap = normal
+ij_javascript_extends_list_wrap = on_every_item
+ij_javascript_field_prefix = _
+ij_javascript_file_name_style = relaxed
+ij_javascript_finally_on_new_line = true
+ij_javascript_for_brace_force = if_multiline
+ij_javascript_for_statement_new_line_after_left_paren = false
+ij_javascript_for_statement_right_paren_on_new_line = false
+ij_javascript_for_statement_wrap = on_every_item
+ij_javascript_force_quote_style = true
+ij_javascript_force_semicolon_style = true
+ij_javascript_function_expression_brace_style = next_line
+ij_javascript_if_brace_force = if_multiline
+ij_javascript_import_merge_members = global
+ij_javascript_import_prefer_absolute_path = true
+ij_javascript_import_sort_members = true
+ij_javascript_import_sort_module_name = true
+ij_javascript_import_use_node_resolution = true
+ij_javascript_imports_wrap = on_every_item
+ij_javascript_indent_case_from_switch = true
+ij_javascript_indent_chained_calls = true
+ij_javascript_indent_package_children = 0
+ij_javascript_jsx_attribute_value = braces
+ij_javascript_keep_blank_lines_in_code = 2
+ij_javascript_keep_first_column_comment = true
+ij_javascript_keep_indents_on_empty_lines = false
+ij_javascript_keep_line_breaks = true
+ij_javascript_keep_simple_blocks_in_one_line = false
+ij_javascript_keep_simple_methods_in_one_line = false
+ij_javascript_line_comment_add_space = true
+ij_javascript_line_comment_at_first_column = false
+ij_javascript_method_brace_style = next_line
+ij_javascript_method_call_chain_wrap = on_every_item
+ij_javascript_method_parameters_new_line_after_left_paren = false
+ij_javascript_method_parameters_right_paren_on_new_line = false
+ij_javascript_method_parameters_wrap = on_every_item
+ij_javascript_object_literal_wrap = on_every_item
+ij_javascript_object_types_wrap = on_every_item
+ij_javascript_parentheses_expression_new_line_after_left_paren = false
+ij_javascript_parentheses_expression_right_paren_on_new_line = false
+ij_javascript_place_assignment_sign_on_next_line = true
+ij_javascript_prefer_as_type_cast = false
+ij_javascript_prefer_explicit_types_function_expression_returns = false
+ij_javascript_prefer_explicit_types_function_returns = false
+ij_javascript_prefer_explicit_types_vars_fields = false
+ij_javascript_prefer_parameters_wrap = false
+ij_javascript_property_prefix =
+ij_javascript_reformat_c_style_comments = true
+ij_javascript_space_after_colon = true
+ij_javascript_space_after_comma = true
+ij_javascript_space_after_dots_in_rest_parameter = false
+ij_javascript_space_after_generator_mult = true
+ij_javascript_space_after_property_colon = true
+ij_javascript_space_after_quest = true
+ij_javascript_space_after_type_colon = true
+ij_javascript_space_after_unary_not = false
+ij_javascript_space_before_async_arrow_lparen = false
+ij_javascript_space_before_catch_keyword = true
+ij_javascript_space_before_catch_left_brace = false
+ij_javascript_space_before_catch_parentheses = false
+ij_javascript_space_before_class_lbrace = false
+ij_javascript_space_before_class_left_brace = true
+ij_javascript_space_before_colon = true
+ij_javascript_space_before_comma = false
+ij_javascript_space_before_do_left_brace = false
+ij_javascript_space_before_else_keyword = true
+ij_javascript_space_before_else_left_brace = false
+ij_javascript_space_before_finally_keyword = true
+ij_javascript_space_before_finally_left_brace = false
+ij_javascript_space_before_for_left_brace = false
+ij_javascript_space_before_for_parentheses = false
+ij_javascript_space_before_for_semicolon = false
+ij_javascript_space_before_function_left_parenth = false
+ij_javascript_space_before_generator_mult = false
+ij_javascript_space_before_if_left_brace = false
+ij_javascript_space_before_if_parentheses = false
+ij_javascript_space_before_method_call_parentheses = false
+ij_javascript_space_before_method_left_brace = false
+ij_javascript_space_before_method_parentheses = false
+ij_javascript_space_before_property_colon = false
+ij_javascript_space_before_quest = true
+ij_javascript_space_before_switch_left_brace = false
+ij_javascript_space_before_switch_parentheses = false
+ij_javascript_space_before_try_left_brace = false
+ij_javascript_space_before_type_colon = false
+ij_javascript_space_before_unary_not = false
+ij_javascript_space_before_while_keyword = true
+ij_javascript_space_before_while_left_brace = false
+ij_javascript_space_before_while_parentheses = false
+ij_javascript_spaces_around_additive_operators = true
+ij_javascript_spaces_around_arrow_function_operator = true
+ij_javascript_spaces_around_assignment_operators = true
+ij_javascript_spaces_around_bitwise_operators = true
+ij_javascript_spaces_around_equality_operators = true
+ij_javascript_spaces_around_logical_operators = true
+ij_javascript_spaces_around_multiplicative_operators = true
+ij_javascript_spaces_around_relational_operators = true
+ij_javascript_spaces_around_shift_operators = true
+ij_javascript_spaces_around_unary_operator = false
+ij_javascript_spaces_within_array_initializer_brackets = false
+ij_javascript_spaces_within_brackets = false
+ij_javascript_spaces_within_catch_parentheses = false
+ij_javascript_spaces_within_for_parentheses = false
+ij_javascript_spaces_within_if_parentheses = false
+ij_javascript_spaces_within_imports = false
+ij_javascript_spaces_within_interpolation_expressions = false
+ij_javascript_spaces_within_method_call_parentheses = false
+ij_javascript_spaces_within_method_parentheses = false
+ij_javascript_spaces_within_object_literal_braces = false
+ij_javascript_spaces_within_object_type_braces = true
+ij_javascript_spaces_within_parentheses = false
+ij_javascript_spaces_within_switch_parentheses = false
+ij_javascript_spaces_within_type_assertion = false
+ij_javascript_spaces_within_union_types = true
+ij_javascript_spaces_within_while_parentheses = false
+ij_javascript_special_else_if_treatment = true
+ij_javascript_ternary_operation_signs_on_next_line = false
+ij_javascript_ternary_operation_wrap = on_every_item
+ij_javascript_union_types_wrap = on_every_item
+ij_javascript_use_chained_calls_group_indents = true
+ij_javascript_use_double_quotes = true
+ij_javascript_use_explicit_js_extension = auto
+ij_javascript_use_path_mapping = always
+ij_javascript_use_public_modifier = false
+ij_javascript_use_semicolon_after_statement = true
+ij_javascript_var_declaration_wrap = normal
+ij_javascript_while_brace_force = always
+ij_javascript_while_on_new_line = false
+ij_javascript_wrap_comments = false
+
+[{*.comp,*.frag,*.fsh,*.geom,*.glsl,*.tesc,*.tese,*.vert,*.vsh}]
+ij_glsl_keep_indents_on_empty_lines = false
+
+[{*.har,*.jsb2,*.jsb3,*.json,*.jsonc,.babelrc,.eslintrc,.prettierrc,.stylelintrc,bowerrc,jest.config}]
+indent_size = 2
+ij_json_array_wrapping = normal
+ij_json_keep_blank_lines_in_code = 0
+ij_json_keep_indents_on_empty_lines = false
+ij_json_keep_line_breaks = true
+ij_json_keep_trailing_comma = false
+ij_json_object_wrapping = normal
+ij_json_property_alignment = align_on_value
+ij_json_space_after_colon = true
+ij_json_space_after_comma = true
+ij_json_space_before_colon = false
+ij_json_space_before_comma = false
+ij_json_spaces_within_braces = false
+ij_json_spaces_within_brackets = false
+ij_json_wrap_long_lines = false
+indent_style = space
+
+[{*.htm,*.html,*.ng,*.sht,*.shtm,*.shtml}]
+ij_html_add_new_line_before_tags = body, div, p, form, h1, h2, h3
+ij_html_align_attributes = true
+ij_html_align_text = false
+ij_html_attribute_wrap = normal
+ij_html_block_comment_add_space = false
+ij_html_block_comment_at_first_column = true
+ij_html_do_not_align_children_of_min_lines = 0
+ij_html_do_not_break_if_inline_tags = title, h1, h2, h3, h4, h5, h6, p
+ij_html_do_not_indent_children_of_tags = html, body, thead, tbody, tfoot
+ij_html_enforce_quotes = false
+ij_html_inline_tags = a, abbr, acronym, b, basefont, bdo, big, br, cite, cite, code, dfn, em, font, i, img, input, kbd, label, q, s, samp, select, small, span, strike, strong, sub, sup, textarea, tt, u, var
+ij_html_keep_blank_lines = 2
+ij_html_keep_indents_on_empty_lines = false
+ij_html_keep_line_breaks = true
+ij_html_keep_line_breaks_in_text = true
+ij_html_keep_whitespaces = false
+ij_html_keep_whitespaces_inside = span, pre, textarea
+ij_html_line_comment_at_first_column = true
+ij_html_new_line_after_last_attribute = never
+ij_html_new_line_before_first_attribute = never
+ij_html_quote_style = double
+ij_html_remove_new_line_before_tags = br
+ij_html_space_after_tag_name = false
+ij_html_space_around_equality_in_attribute = false
+ij_html_space_inside_empty_tag = false
+ij_html_text_wrap = normal
+
+[{*.http,*.rest}]
+indent_size = 0
+ij_continuation_indent_size = 4
+ij_http-request_call_parameters_wrap = normal
+ij_http-request_method_parameters_wrap = split_into_lines
+ij_http-request_space_before_comma = true
+ij_http-request_spaces_around_assignment_operators = true
+
+[{*.markdown,*.md}]
+ij_markdown_force_one_space_after_blockquote_symbol = true
+ij_markdown_force_one_space_after_header_symbol = true
+ij_markdown_force_one_space_after_list_bullet = true
+ij_markdown_force_one_space_between_words = true
+ij_markdown_format_tables = true
+ij_markdown_insert_quote_arrows_on_wrap = true
+ij_markdown_keep_indents_on_empty_lines = false
+ij_markdown_keep_line_breaks_inside_text_blocks = true
+ij_markdown_max_lines_around_block_elements = 1
+ij_markdown_max_lines_around_header = 1
+ij_markdown_max_lines_between_paragraphs = 1
+ij_markdown_min_lines_around_block_elements = 1
+ij_markdown_min_lines_around_header = 1
+ij_markdown_min_lines_between_paragraphs = 1
+ij_markdown_wrap_text_if_long = true
+ij_markdown_wrap_text_inside_blockquotes = true
+
+[{*.ps1,*.psd1,*.psm1}]
+max_line_length = 115
+ij_powershell_align_multiline_binary_operation = true
+ij_powershell_align_multiline_chained_methods = false
+ij_powershell_align_multiline_for = true
+ij_powershell_align_multiline_parameters = true
+ij_powershell_align_multiline_parameters_in_calls = false
+ij_powershell_binary_operation_wrap = on_every_item
+ij_powershell_block_brace_style = next_line
+ij_powershell_call_parameters_new_line_after_left_paren = false
+ij_powershell_call_parameters_right_paren_on_new_line = false
+ij_powershell_call_parameters_wrap = on_every_item
+ij_powershell_catch_on_new_line = true
+ij_powershell_class_annotation_wrap = split_into_lines
+ij_powershell_class_brace_style = next_line
+ij_powershell_else_on_new_line = true
+ij_powershell_field_annotation_wrap = off
+ij_powershell_finally_on_new_line = true
+ij_powershell_for_statement_new_line_after_left_paren = false
+ij_powershell_for_statement_right_paren_on_new_line = false
+ij_powershell_for_statement_wrap = on_every_item
+ij_powershell_keep_blank_lines_in_code = 2
+ij_powershell_keep_first_column_comment = true
+ij_powershell_keep_line_breaks = true
+ij_powershell_keep_simple_blocks_in_one_line = true
+ij_powershell_keep_simple_classes_in_one_line = false
+ij_powershell_keep_simple_lambdas_in_one_line = true
+ij_powershell_keep_simple_methods_in_one_line = true
+ij_powershell_method_annotation_wrap = split_into_lines
+ij_powershell_method_brace_style = next_line
+ij_powershell_method_call_chain_wrap = on_every_item
+ij_powershell_method_parameters_new_line_after_left_paren = false
+ij_powershell_method_parameters_right_paren_on_new_line = false
+ij_powershell_method_parameters_wrap = on_every_item
+ij_powershell_parameter_annotation_wrap = off
+ij_powershell_parentheses_expression_new_line_after_left_paren = false
+ij_powershell_parentheses_expression_right_paren_on_new_line = false
+ij_powershell_space_after_colon = true
+ij_powershell_space_after_comma = true
+ij_powershell_space_after_for_semicolon = true
+ij_powershell_space_after_type_cast = false
+ij_powershell_space_before_annotation_parameter_list = false
+ij_powershell_space_before_array_initializer_left_brace = false
+ij_powershell_space_before_catch_keyword = true
+ij_powershell_space_before_catch_left_brace = false
+ij_powershell_space_before_class_left_brace = false
+ij_powershell_space_before_colon = true
+ij_powershell_space_before_comma = false
+ij_powershell_space_before_do_left_brace = false
+ij_powershell_space_before_else_keyword = true
+ij_powershell_space_before_else_left_brace = false
+ij_powershell_space_before_finally_keyword = true
+ij_powershell_space_before_finally_left_brace = false
+ij_powershell_space_before_for_left_brace = false
+ij_powershell_space_before_for_parentheses = false
+ij_powershell_space_before_for_semicolon = false
+ij_powershell_space_before_if_left_brace = false
+ij_powershell_space_before_if_parentheses = false
+ij_powershell_space_before_method_call_parentheses = false
+ij_powershell_space_before_method_left_brace = false
+ij_powershell_space_before_method_parentheses = false
+ij_powershell_space_before_switch_left_brace = false
+ij_powershell_space_before_switch_parentheses = false
+ij_powershell_space_before_try_left_brace = false
+ij_powershell_space_before_while_keyword = true
+ij_powershell_space_before_while_left_brace = false
+ij_powershell_space_before_while_parentheses = false
+ij_powershell_space_within_empty_method_call_parentheses = false
+ij_powershell_space_within_empty_method_parentheses = false
+ij_powershell_spaces_around_additive_operators = true
+ij_powershell_spaces_around_assignment_operators = true
+ij_powershell_spaces_around_bitwise_operators = true
+ij_powershell_spaces_around_logical_operators = true
+ij_powershell_spaces_around_method_ref_dbl_colon = false
+ij_powershell_spaces_around_multiplicative_operators = true
+ij_powershell_spaces_around_relational_operators = true
+ij_powershell_spaces_around_unary_operator = false
+ij_powershell_spaces_within_annotation_parentheses = false
+ij_powershell_spaces_within_braces = true
+ij_powershell_spaces_within_brackets = false
+ij_powershell_spaces_within_cast_parentheses = false
+ij_powershell_spaces_within_for_parentheses = false
+ij_powershell_spaces_within_if_parentheses = false
+ij_powershell_spaces_within_method_call_parentheses = false
+ij_powershell_spaces_within_method_parentheses = false
+ij_powershell_spaces_within_parentheses = false
+ij_powershell_spaces_within_switch_parentheses = false
+ij_powershell_spaces_within_while_parentheses = false
+ij_powershell_special_else_if_treatment = true
+ij_powershell_while_on_new_line = false
+ij_powershell_wrap_first_method_in_call_chain = false
+ij_powershell_wrap_long_lines = false
+
+[{*.py,*.pyw}]
+ij_python_align_collections_and_comprehensions = true
+ij_python_align_multiline_imports = true
+ij_python_align_multiline_parameters = true
+ij_python_align_multiline_parameters_in_calls = true
+ij_python_blank_line_at_file_end = false
+ij_python_blank_lines_after_imports = 1
+ij_python_blank_lines_after_local_imports = 0
+ij_python_blank_lines_around_class = 1
+ij_python_blank_lines_around_method = 1
+ij_python_blank_lines_around_top_level_classes_functions = 2
+ij_python_blank_lines_before_first_method = 0
+ij_python_call_parameters_new_line_after_left_paren = false
+ij_python_call_parameters_right_paren_on_new_line = false
+ij_python_call_parameters_wrap = on_every_item
+ij_python_dict_alignment = 0
+ij_python_dict_new_line_after_left_brace = false
+ij_python_dict_new_line_before_right_brace = false
+ij_python_dict_wrapping = 5
+ij_python_from_import_new_line_after_left_parenthesis = false
+ij_python_from_import_new_line_before_right_parenthesis = false
+ij_python_from_import_parentheses_force_if_multiline = false
+ij_python_from_import_trailing_comma_if_multiline = false
+ij_python_from_import_wrapping = 5
+ij_python_hang_closing_brackets = true
+ij_python_keep_blank_lines_in_code = 1
+ij_python_keep_blank_lines_in_declarations = 1
+ij_python_keep_indents_on_empty_lines = false
+ij_python_keep_line_breaks = true
+ij_python_method_parameters_new_line_after_left_paren = false
+ij_python_method_parameters_right_paren_on_new_line = false
+ij_python_method_parameters_wrap = on_every_item
+ij_python_new_line_after_colon = false
+ij_python_new_line_after_colon_multi_clause = true
+ij_python_optimize_imports_always_split_from_imports = false
+ij_python_optimize_imports_case_insensitive_order = true
+ij_python_optimize_imports_join_from_imports_with_same_source = false
+ij_python_optimize_imports_sort_by_type_first = true
+ij_python_optimize_imports_sort_imports = true
+ij_python_optimize_imports_sort_names_in_from_imports = true
+ij_python_space_after_comma = true
+ij_python_space_after_number_sign = true
+ij_python_space_after_py_colon = true
+ij_python_space_before_backslash = true
+ij_python_space_before_comma = false
+ij_python_space_before_for_semicolon = false
+ij_python_space_before_lbracket = false
+ij_python_space_before_method_call_parentheses = false
+ij_python_space_before_method_parentheses = false
+ij_python_space_before_number_sign = true
+ij_python_space_before_py_colon = false
+ij_python_space_within_empty_method_call_parentheses = false
+ij_python_space_within_empty_method_parentheses = false
+ij_python_spaces_around_additive_operators = true
+ij_python_spaces_around_assignment_operators = true
+ij_python_spaces_around_bitwise_operators = true
+ij_python_spaces_around_eq_in_keyword_argument = false
+ij_python_spaces_around_eq_in_named_parameter = false
+ij_python_spaces_around_equality_operators = true
+ij_python_spaces_around_multiplicative_operators = true
+ij_python_spaces_around_power_operator = true
+ij_python_spaces_around_relational_operators = true
+ij_python_spaces_around_shift_operators = true
+ij_python_spaces_within_braces = false
+ij_python_spaces_within_brackets = false
+ij_python_spaces_within_method_call_parentheses = false
+ij_python_spaces_within_method_parentheses = false
+ij_python_use_continuation_indent_for_arguments = false
+ij_python_use_continuation_indent_for_collection_and_comprehensions = false
+ij_python_use_continuation_indent_for_parameters = true
+ij_python_wrap_long_lines = false
+
+[{*.toml,Cargo.lock,Cargo.toml.orig,Gopkg.lock,Pipfile,poetry.lock}]
+ij_toml_keep_indents_on_empty_lines = false
+
+[{*.yaml,*.yml,pubspec.lock}]
+indent_size = 2
+ij_yaml_align_values_properties = on_value
+ij_yaml_autoinsert_sequence_marker = true
+ij_yaml_block_mapping_on_new_line = false
+ij_yaml_indent_sequence_value = true
+ij_yaml_keep_indents_on_empty_lines = false
+ij_yaml_keep_line_breaks = true
+ij_yaml_sequence_on_new_line = false
+ij_yaml_space_before_colon = false
+ij_yaml_spaces_within_braces = true
+ij_yaml_spaces_within_brackets = true
+indent_style = space
+
+[*.{appxmanifest,asax,ascx,aspx,axaml,build,c,c++,cc,cginc,compute,cp,cpp,cppm,cs,cshtml,cu,cuh,cxx,dtd,fs,fsi,fsscript,fsx,fx,fxh,h,hh,hlsl,hlsli,hlslinc,hpp,hxx,inc,inl,ino,ipp,ixx,master,ml,mli,mpp,mq4,mq5,mqh,nuspec,paml,razor,resw,resx,shader,skin,tpp,usf,ush,uxml,vb,xaml,xamlx,xoml,xsd}]
indent_style = space
-indent_size = 4
-tab_width = 4
+indent_size = 4
+tab_width = 4
+
+[*.{appxmanifest,asax,ascx,aspx,axaml,build,c,c++,c++m,cc,ccm,cginc,compute,cp,cpp,cppm,cs,cshtml,cu,cuh,cxx,cxxm,dtd,fs,fsi,fsscript,fsx,fx,fxh,h,hh,hlsl,hlsli,hlslinc,hpp,hxx,inc,inl,ino,ipp,ixx,master,ml,mli,mpp,mq4,mq5,mqh,mxx,nuspec,paml,razor,resw,resx,shader,skin,tpp,usf,ush,uxml,vb,xaml,xamlx,xoml,xsd}]
+indent_style = space
+indent_size = 4
+tab_width = 4
+
+[*.{cs,vb}]
+dotnet_diagnostic.ph2006.severity = none
+dotnet_diagnostic.ph2021.severity = none
+dotnet_diagnostic.ph2026.severity = none
+dotnet_diagnostic.ph2028.severity = none
+dotnet_diagnostic.ph2029.severity = none
+dotnet_diagnostic.ph2031.severity = warning
+dotnet_diagnostic.ph2045.severity = none
+dotnet_diagnostic.ph2067.severity = none
+dotnet_diagnostic.ph2068.severity = none
+dotnet_diagnostic.ph2069.severity = warning
+dotnet_diagnostic.ph2075.severity = none
+dotnet_diagnostic.ph2079.severity = none
+dotnet_diagnostic.ph2081.severity = none
+dotnet_diagnostic.ph2082.severity = suggestion
+dotnet_diagnostic.ph2083.severity = warning
+dotnet_diagnostic.ph2086.severity = warning
+dotnet_diagnostic.ph2089.severity = warning
+dotnet_diagnostic.ph2096.severity = warning
+dotnet_diagnostic.ph2097.severity = warning
+dotnet_diagnostic.ph2098.severity = warning
+dotnet_diagnostic.ph2101.severity = warning
+dotnet_diagnostic.ph2102.severity = none
+dotnet_diagnostic.mt1001.severity = warning
+
+[*.{razor}]
+resharper_normalize_tag_names = false
\ No newline at end of file
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index d1436e196..b5d985a2f 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,6 +1,6 @@
# These are supported funding model platforms
# github: claunia
-patreon: claunia
-ko_fi: claunia
+patreon: claunia
+ko_fi: claunia
open_collective: aaru
diff --git a/.github/ISSUE_TEMPLATE/bug_report_general.yaml b/.github/ISSUE_TEMPLATE/bug_report_general.yaml
index 9cd28c50b..bf2ddf4a5 100644
--- a/.github/ISSUE_TEMPLATE/bug_report_general.yaml
+++ b/.github/ISSUE_TEMPLATE/bug_report_general.yaml
@@ -1,13 +1,13 @@
-name: General Bug Report
+name: General Bug Report
description: Bugs report on other commands. Use this to submit device reports.
-labels: ["bug", "needs triage"]
+labels: [ "bug", "needs triage" ]
assignees:
- silaslaspada
body:
- type: dropdown
- id: version
+ id: version
attributes:
- label: Version
+ label: Version
description: What version of Aaru are you running?
options:
- 5.3.0
@@ -18,22 +18,22 @@ body:
validations:
required: true
- type: input
- id: commit
+ id: commit
attributes:
- label: Commit hash
+ label: Commit hash
description: If using a developmen commit, which one
- type: checkboxes
- id: debug
+ id: debug
attributes:
- label: Tested debug version?
+ label: Tested debug version?
description: Have you reproduced the problem using the debug version?
options:
- - label: "Yes"
+ - label: "Yes"
required: true
- type: checkboxes
- id: os
+ id: os
attributes:
- label: Which operating systems have you used?
+ label: Which operating systems have you used?
description: You may select more than one.
options:
- label: Windows
@@ -41,56 +41,56 @@ body:
- label: macOS
- label: Other
- type: checkboxes
- id: bitsize
+ id: bitsize
attributes:
- label: What is the architectural bit size you're using?
+ label: What is the architectural bit size you're using?
description: You may select more than one.
options:
- label: 32-bit
- label: 64-bit
- label: Unsure or unknown
- type: checkboxes
- id: cpu
+ id: cpu
attributes:
- label: What processor are you using?
+ label: What processor are you using?
description: You may select more than one.
options:
- label: An Intel or AMD
- label: An ARM or Apple Silicon
- label: Unsure or unknown
- type: textarea
- id: description
+ id: description
attributes:
- label: Description
+ label: Description
description: Description of the bug
validations:
required: true
- type: input
- id: command_line
+ id: command_line
attributes:
- label: Exact command line used
+ label: Exact command line used
placeholder: "`Aaru [command] [parameters]`"
validations:
required: true
- type: textarea
- id: expected
+ id: expected
attributes:
- label: Expected behavior
+ label: Expected behavior
description: What did you expect to happen
validations:
required: true
- type: textarea
- id: actual
+ id: actual
attributes:
- label: Actual behavior
+ label: Actual behavior
description: What actually happened
validations:
required: true
- type: textarea
- id: output
+ id: output
attributes:
- label: Output of command execution with debug output enabled
+ label: Output of command execution with debug output enabled
placeholder: Paste the whole output of the executed command when you append '-d' to your command line parameters here
- render: shell
+ render: shell
validations:
required: true
diff --git a/.github/ISSUE_TEMPLATE/bug_report_image.yaml b/.github/ISSUE_TEMPLATE/bug_report_image.yaml
index 69fc93f2e..b8a0d3d00 100644
--- a/.github/ISSUE_TEMPLATE/bug_report_image.yaml
+++ b/.github/ISSUE_TEMPLATE/bug_report_image.yaml
@@ -1,13 +1,13 @@
-name: Image Bug Report
+name: Image Bug Report
description: Bugs report on commands that handle images, like converting or extracting.
-labels: ["bug", "needs triage", "dump image format"]
+labels: [ "bug", "needs triage", "dump image format" ]
assignees:
- silaslaspada
body:
- type: dropdown
- id: version
+ id: version
attributes:
- label: Version
+ label: Version
description: What version of Aaru are you running?
options:
- 5.3.0
@@ -18,22 +18,22 @@ body:
validations:
required: true
- type: input
- id: commit
+ id: commit
attributes:
- label: Commit hash
+ label: Commit hash
description: If using a developmen commit, which one
- type: checkboxes
- id: debug
+ id: debug
attributes:
- label: Tested debug version?
+ label: Tested debug version?
description: Have you reproduced the problem using the debug version?
options:
- - label: "Yes"
+ - label: "Yes"
required: true
- type: checkboxes
- id: os
+ id: os
attributes:
- label: Which operating systems have you used?
+ label: Which operating systems have you used?
description: You may select more than one.
options:
- label: Windows
@@ -41,39 +41,39 @@ body:
- label: macOS
- label: Other
- type: checkboxes
- id: bitsize
+ id: bitsize
attributes:
- label: What is the architectural bit size you're using?
+ label: What is the architectural bit size you're using?
description: You may select more than one.
options:
- label: 32-bit
- label: 64-bit
- label: Unsure or unknown
- type: checkboxes
- id: cpu
+ id: cpu
attributes:
- label: What processor are you using?
+ label: What processor are you using?
description: You may select more than one.
options:
- label: An Intel or AMD
- label: An ARM or Apple Silicon
- label: Unsure or unknown
- type: input
- id: format
+ id: format
attributes:
label: Image format
validations:
required: true
- type: input
- id: application
+ id: application
attributes:
label: Application that created the image
validations:
required: true
- type: checkboxes
- id: action
+ id: action
attributes:
- label: What were you doing when it failed?
+ label: What were you doing when it failed?
description: Choose all that apply
options:
- label: I was converting the image to another format...
@@ -86,54 +86,54 @@ body:
- label: I was verifying the image...
- label: I was calculating the image entropy...
- type: input
- id: target_format
+ id: target_format
attributes:
- label: Destination image format
+ label: Destination image format
description: If you were converting the image format, what format were you trying to convert it into
- type: input
- id: filesystem
+ id: filesystem
attributes:
- label: Filesystem
+ label: Filesystem
description: If you were listing information, contents, or extracting the contents of a filesystem, which filesystem is it? (leave empty if unknown)
- type: textarea
- id: description
+ id: description
attributes:
- label: Description
+ label: Description
description: Description of the bug
validations:
required: true
- type: input
- id: command_line
+ id: command_line
attributes:
- label: Exact command line used
+ label: Exact command line used
placeholder: "`Aaru [command] [parameters]`"
validations:
required: true
- type: textarea
- id: expected
+ id: expected
attributes:
- label: Expected behavior
+ label: Expected behavior
description: What did you expect to happen
validations:
required: true
- type: textarea
- id: actual
+ id: actual
attributes:
- label: Actual behavior
+ label: Actual behavior
description: What actually happened
validations:
required: true
- type: textarea
- id: output
+ id: output
attributes:
- label: Output of command execution with debug output enabled
+ label: Output of command execution with debug output enabled
placeholder: Paste the whole output of the executed command when you append '-d' to your command line parameters here
- render: shell
+ render: shell
validations:
required: true
- type: textarea
- id: image
+ id: image
attributes:
- label: Affected image
+ label: Affected image
placeholder: Upload the image, compressed and with the number of this issue.
If the image contains personal data contact the project lead, and the image contents will be handled confidentially under the GDPR requirements.
diff --git a/.github/ISSUE_TEMPLATE/bug_report_media.yaml b/.github/ISSUE_TEMPLATE/bug_report_media.yaml
index cb643343c..457281083 100644
--- a/.github/ISSUE_TEMPLATE/bug_report_media.yaml
+++ b/.github/ISSUE_TEMPLATE/bug_report_media.yaml
@@ -1,13 +1,13 @@
-name: Media Bug Report
+name: Media Bug Report
description: Bugs report on commands that handle media, like dumping or retrieving information.
-labels: ["bug", "needs triage", "media"]
+labels: [ "bug", "needs triage", "media" ]
assignees:
- silaslaspada
body:
- type: dropdown
- id: version
+ id: version
attributes:
- label: Version
+ label: Version
description: What version of Aaru are you running?
options:
- 5.3.0
@@ -18,22 +18,22 @@ body:
validations:
required: true
- type: input
- id: commit
+ id: commit
attributes:
- label: Commit hash
+ label: Commit hash
description: If using a developmen commit, which one
- type: checkboxes
- id: debug
+ id: debug
attributes:
- label: Tested debug version?
+ label: Tested debug version?
description: Have you reproduced the problem using the debug version?
options:
- - label: "Yes"
+ - label: "Yes"
required: true
- type: checkboxes
- id: os
+ id: os
attributes:
- label: Which operating systems have you used?
+ label: Which operating systems have you used?
description: You may select more than one.
options:
- label: Windows
@@ -41,39 +41,39 @@ body:
- label: macOS
- label: Other
- type: checkboxes
- id: bitsize
+ id: bitsize
attributes:
- label: What is the architectural bit size you're using?
+ label: What is the architectural bit size you're using?
description: You may select more than one.
options:
- label: 32-bit
- label: 64-bit
- label: Unsure or unknown
- type: checkboxes
- id: cpu
+ id: cpu
attributes:
- label: What processor are you using?
+ label: What processor are you using?
description: You may select more than one.
options:
- label: An Intel or AMD
- label: An ARM or Apple Silicon
- label: Unsure or unknown
- type: input
- id: manufacturer
+ id: manufacturer
attributes:
label: Device manufacturer
validations:
required: true
- type: input
- id: model
+ id: model
attributes:
label: Device model
validations:
required: true
- type: checkboxes
- id: bus
+ id: bus
attributes:
- label: Bus the device uses to attach to the computer
+ label: Bus the device uses to attach to the computer
description: Select the physical drive bus as well as the bus you're using if using a cable or card reader
options:
- label: Parallel ATA
@@ -86,19 +86,19 @@ body:
- label: SecureDigital
- label: MultiMediaCard
- type: input
- id: usb_manufacturer
+ id: usb_manufacturer
attributes:
- label: USB cable or card reader manufacturer
+ label: USB cable or card reader manufacturer
description: Fill if using a USB cable or a USB card reader
- type: input
- id: usb_model
+ id: usb_model
attributes:
- label: USB cable or card reader model
+ label: USB cable or card reader model
description: Fill if using a USB cable or a USB card reader
- type: checkboxes
- id: action
+ id: action
attributes:
- label: What were you doing when it failed?
+ label: What were you doing when it failed?
description: Choose all that apply
options:
- label: I was dumping media (disk, tape, etc)...
@@ -106,43 +106,43 @@ body:
- label: I was scanning media (disk, tape, etc)...
- label: I was retrieving device information...
- type: textarea
- id: description
+ id: description
attributes:
- label: Description
+ label: Description
description: Description of the bug
validations:
required: true
- type: input
- id: command_line
+ id: command_line
attributes:
- label: Exact command line used
+ label: Exact command line used
placeholder: "`Aaru [command] [parameters]`"
validations:
required: true
- type: textarea
- id: expected
+ id: expected
attributes:
- label: Expected behavior
+ label: Expected behavior
description: What did you expect to happen
validations:
required: true
- type: textarea
- id: actual
+ id: actual
attributes:
- label: Actual behavior
+ label: Actual behavior
description: What actually happened
validations:
required: true
- type: textarea
- id: output
+ id: output
attributes:
- label: Output of command execution with debug output enabled
+ label: Output of command execution with debug output enabled
placeholder: Paste the whole output of the executed command when you append '-d' to your command line parameters here
- render: shell
+ render: shell
validations:
required: true
- type: textarea
- id: details
+ id: details
attributes:
- label: Media details
+ label: Media details
placeholder: Photo, EAN-13, if possible eBay link
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml
index 73c24c194..9cb175346 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.yaml
+++ b/.github/ISSUE_TEMPLATE/feature_request.yaml
@@ -1,14 +1,14 @@
-name: Feature Request
+name: Feature Request
description: For feature requests. Please search for existing issues first. Also see CONTRIBUTING.
-title: "[Feature request] "
-labels: [feature request, needs triage]
-assignees:
+title: "[Feature request] "
+labels: [ feature request, needs triage ]
+assignees:
- claunia
body:
- type: dropdown
attributes:
description: Type of feture you're requesting
- label: Type
+ label: Type
options:
- Support for a new media image format...
- Support for identifying a new filesystem...
@@ -21,19 +21,19 @@ body:
- type: textarea
attributes:
description: Detailed Description
- label: Description
+ label: Description
placeholder: Provide a detailed description of the change or addition you are proposing
validations:
required: true
- type: textarea
attributes:
description: Context
- label: Context
+ label: Context
placeholder: Why is this change important to you? How would you use it? How can it benefit other users?
validations:
required: true
- type: textarea
attributes:
description: Known documentation
- label: Documentation
+ label: Documentation
placeholder: Attach documentation, links to specifications or existing source code
\ No newline at end of file
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index ae91a9c81..09a19f463 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -1,67 +1,52 @@
-# For most projects, this workflow file will not need changing; you simply need
-# to commit it to your repository.
-#
-# You may wish to alter this file to override the set of languages analyzed,
-# or to provide custom queries or build logic.
-#
-# ******** NOTE ********
-# We have attempted to detect the languages in your repository. Please check
-# the `language` matrix defined below to confirm you have the correct set of
-# supported CodeQL languages.
-#
name: "CodeQL"
-on:
- push:
- branches: [ master ]
- pull_request:
- # The branches below must be a subset of the branches above
- branches: [ master ]
- schedule:
- - cron: '29 15 * * 2'
+on: [ push, pull_request ]
jobs:
- analyze:
- name: Analyze
- runs-on: ubuntu-latest
+ CodeQL-Build:
+ # CodeQL runs on ubuntu-latest, windows-latest, and macos-latest
+ runs-on: windows-latest
- strategy:
- fail-fast: false
- matrix:
- language: [ 'csharp' ]
- # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
- # Learn more:
- # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
+ permissions:
+ # required for all workflows
+ security-events: write
+
+ # only required for workflows in private repositories
+ actions: read
+ contents: read
steps:
- - name: Checkout repository
- uses: actions/checkout@v2
+ - name: Checkout repository
+ uses: actions/checkout@v3
+ with:
+ submodules: recursive
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: |
+ 8.0.x
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v2
+ # Override language selection by uncommenting this and choosing your languages
+ with:
+ languages: csharp
- # Initializes the CodeQL tools for scanning.
- - name: Initialize CodeQL
- uses: github/codeql-action/init@v1
- with:
- languages: ${{ matrix.language }}
- # If you wish to specify custom queries, you can do so here or in a config file.
- # By default, queries listed here will override any specified in a config file.
- # Prefix the list here with "+" to use these queries and those in the config file.
- # queries: ./path/to/local/query, your-org/your-repo/queries@main
+ # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
+ # If this step fails, then you should remove it and run the build manually (see below).
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v2
- # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
- # If this step fails, then you should remove it and run the build manually (see below)
- - name: Autobuild
- uses: github/codeql-action/autobuild@v1
+ # ℹ️ Command-line programs to run using the OS shell.
+ # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
- # ℹ️ Command-line programs to run using the OS shell.
- # 📚 https://git.io/JvXDl
+ # ✏️ If the Autobuild fails above, remove it and uncomment the following
+ # three lines and modify them (or add more) to build your code if your
+ # project uses a compiled language
- # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
- # and modify them (or add more) to build your code if your project
- # uses a compiled language
+ #- run: |
+ # make bootstrap
+ # make release
- #- run: |
- # make bootstrap
- # make release
-
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v1
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v2
diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index ef97e09ca..44f660e08 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -1,10 +1,6 @@
name: .NET
-on:
- push:
- branches: [ master ]
- pull_request:
- branches: [ master ]
+on: [ push, pull_request ]
jobs:
build:
@@ -12,14 +8,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
- - name: Checking submodules
- uses: textbook/git-checkout-submodule-action@2.1.1
- - name: Setup .NET
- uses: actions/setup-dotnet@v1
- with:
- dotnet-version: 3.1.301
- - name: Restore dependencies
- run: dotnet restore Aaru.sln
- - name: Build
- run: dotnet build --no-restore Aaru.sln
+ - uses: actions/checkout@v3
+ with:
+ submodules: recursive
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: 8.0
+ - name: Restore dependencies
+ run: dotnet restore Aaru.sln
+ - name: Build
+ run: dotnet build --no-restore Aaru.sln
diff --git a/.gitmodules b/.gitmodules
index 0a8499607..e69de29bb 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,27 +0,0 @@
-[submodule "CICMMetadata"]
- path = CICMMetadata
- url = https://github.com/claunia/CICMMetadata
-[submodule "Aaru.Checksums"]
- path = Aaru.Checksums
- url = https://github.com/aaru-dps/Aaru.Checksums
-[submodule "Aaru.CommonTypes"]
- path = Aaru.CommonTypes
- url = https://github.com/aaru-dps/Aaru.CommonTypes
-[submodule "Aaru.Console"]
- path = Aaru.Console
- url = https://github.com/aaru-dps/Aaru.Console
-[submodule "Aaru.Decoders"]
- path = Aaru.Decoders
- url = https://github.com/aaru-dps/Aaru.Decoders
-[submodule "Aaru.Dto"]
- path = Aaru.Dto
- url = https://github.com/aaru-dps/Aaru.Dto
-[submodule "Aaru.Helpers"]
- path = Aaru.Helpers
- url = https://github.com/aaru-dps/Aaru.Helpers
-[submodule "cuetools.net"]
- path = Aaru.Compression/cuetools.net
- url = https://github.com/gchudov/cuetools.net
-[submodule "Aaru.Decryption"]
- path = Aaru.Decryption
- url = https://github.com/aaru-dps/Aaru.Decryption
diff --git a/.globalconfig b/.globalconfig
new file mode 100644
index 000000000..f06bb062e
--- /dev/null
+++ b/.globalconfig
@@ -0,0 +1,2 @@
+is_global = true
+dotnet_diagnostic.PH2075.severity = none
diff --git a/.idea/.idea.Aaru/.idea/codeStyles/Project.xml b/.idea/.idea.Aaru/.idea/codeStyles/Project.xml
new file mode 100644
index 000000000..2e7707de6
--- /dev/null
+++ b/.idea/.idea.Aaru/.idea/codeStyles/Project.xml
@@ -0,0 +1,213 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.Aaru/.idea/codeStyles/codeStyleConfig.xml b/.idea/.idea.Aaru/.idea/codeStyles/codeStyleConfig.xml
index a55e7a179..6e6eec114 100644
--- a/.idea/.idea.Aaru/.idea/codeStyles/codeStyleConfig.xml
+++ b/.idea/.idea.Aaru/.idea/codeStyles/codeStyleConfig.xml
@@ -1,5 +1,6 @@
+
\ No newline at end of file
diff --git a/.idea/.idea.Aaru/.idea/runConfigurations/Aaru.xml b/.idea/.idea.Aaru/.idea/runConfigurations/Aaru.xml
index 441ef3f56..9fdac204a 100644
--- a/.idea/.idea.Aaru/.idea/runConfigurations/Aaru.xml
+++ b/.idea/.idea.Aaru/.idea/runConfigurations/Aaru.xml
@@ -1,8 +1,8 @@
-
-
-
+
+
+
@@ -12,7 +12,7 @@
-
+
diff --git a/.idea/.idea.Aaru/.idea/vcs.xml b/.idea/.idea.Aaru/.idea/vcs.xml
index 361dcec1e..3e61b707a 100644
--- a/.idea/.idea.Aaru/.idea/vcs.xml
+++ b/.idea/.idea.Aaru/.idea/vcs.xml
@@ -9,12 +9,10 @@
-
-
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index c26513d81..b885216e2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,7 @@
language: csharp
solution: Aaru.sln
-mono: none
-dotnet: 6.0.100
+mono: none
+dotnet: 6.0.100
script:
- dotnet restore Aaru.sln
- dotnet build Aaru.sln
diff --git a/Aaru.Archives/Aaru.Archives.csproj b/Aaru.Archives/Aaru.Archives.csproj
index 907f36b79..177ef038b 100644
--- a/Aaru.Archives/Aaru.Archives.csproj
+++ b/Aaru.Archives/Aaru.Archives.csproj
@@ -1,108 +1,119 @@
-
- Debug
- AnyCPU
- 2.0
- {282271D0-CCC2-4ED7-BA38-EC06A84BB974}
- Library
- Aaru.Archives
- Aaru.Archives
- $(Version)
- false
- true
- 6.0.0-alpha8
- Claunia.com
- Copyright © 2011-2022 Natalia Portillo
- Aaru Data Preservation Suite
- Aaru.Archives
- $(Version)
- net6.0
- 10
- Archive implementations used by the Aaru Data Preservation Suite.
- https://github.com/aaru-dps/
- LGPL-2.1-only
- https://github.com/aaru-dps/Aaru.Archives
- true
- en-US
- true
- true
- snupkg
- Natalia Portillo <claunia@claunia.com>
- true
-
-
- $(Version)+{chash:8}
- true
- true
-
-
- true
- full
- false
- bin\Debug
- DEBUG;
- prompt
- 4
- false
-
-
- true
- bin\Release
- prompt
- 4
- false
-
-
-
-
-
-
- LICENSE.LGPL
-
-
-
-
-
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /Library/Frameworks/Mono.framework/Versions/Current/lib/mono
- /usr/lib/mono
- /usr/local/lib/mono
-
- $(BaseFrameworkPathOverrideForMono)/4.0-api
- $(BaseFrameworkPathOverrideForMono)/4.5-api
- $(BaseFrameworkPathOverrideForMono)/4.5.1-api
- $(BaseFrameworkPathOverrideForMono)/4.5.2-api
- $(BaseFrameworkPathOverrideForMono)/4.6-api
- $(BaseFrameworkPathOverrideForMono)/4.6.1-api
- $(BaseFrameworkPathOverrideForMono)/4.6.2-api
- $(BaseFrameworkPathOverrideForMono)/4.7-api
- $(BaseFrameworkPathOverrideForMono)/4.7.1-api
- true
-
- $(FrameworkPathOverride)/Facades;$(AssemblySearchPaths)
-
+
+ 2.0
+ {282271D0-CCC2-4ED7-BA38-EC06A84BB974}
+ Library
+ Aaru.Archives
+ Aaru.Archives
+ $(Version)
+ true
+ 6.0.0-alpha9
+ Claunia.com
+ Copyright © 2011-2024 Natalia Portillo
+ Aaru Data Preservation Suite
+ Aaru.Archives
+ $(Version)
+ net8.0
+ 12
+ Archive implementations used by the Aaru Data Preservation Suite.
+ https://github.com/aaru-dps/
+ LGPL-2.1-only
+ https://github.com/aaru-dps/Aaru.Archives
+ true
+ en-US
+ true
+ true
+ snupkg
+ Natalia Portillo <claunia@claunia.com>
+ true
+ true
+ true
+
+
+ CS1591;CS1574
+
+
+
+
+
+
+ $(Version)+{chash:8}
+ true
+ true
+
+
+
+ LICENSE.LGPL
+
+
+ ResXFileCodeGenerator
+ Localization.Designer.cs
+
+
+ ResXFileCodeGenerator
+ Localization.Designer.cs
+
+
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+ True
+ True
+ Localization.resx
+
+
diff --git a/Aaru.Archives/Aaru.Archives.csproj.DotSettings b/Aaru.Archives/Aaru.Archives.csproj.DotSettings
new file mode 100644
index 000000000..45681b16d
--- /dev/null
+++ b/Aaru.Archives/Aaru.Archives.csproj.DotSettings
@@ -0,0 +1,6 @@
+
+ True
+ True
\ No newline at end of file
diff --git a/Aaru.Archives/Authors.cs b/Aaru.Archives/Authors.cs
new file mode 100644
index 000000000..9f350cfff
--- /dev/null
+++ b/Aaru.Archives/Authors.cs
@@ -0,0 +1,37 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Authors.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Aaru.Filesystems.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System.Diagnostics.CodeAnalysis;
+
+namespace Aaru.Archives;
+
+[SuppressMessage("ReSharper", "InconsistentNaming")]
+static class Authors
+{
+ internal const string NataliaPortillo = "Natalia Portillo";
+}
\ No newline at end of file
diff --git a/Aaru.Archives/Localization/Localization.Designer.cs b/Aaru.Archives/Localization/Localization.Designer.cs
new file mode 100644
index 000000000..229a2d7ca
--- /dev/null
+++ b/Aaru.Archives/Localization/Localization.Designer.cs
@@ -0,0 +1,728 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace Aaru.Archives {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Localization {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Localization() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Aaru.Archives.Localization.Localization", typeof(Localization).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Application ID: 0x{0:X8}.
+ ///
+ internal static string Application_ID_0 {
+ get {
+ return ResourceManager.GetString("Application_ID_0", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Archive options: {0}.
+ ///
+ internal static string Archive_options_0 {
+ get {
+ return ResourceManager.GetString("Archive_options_0", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Capabilities:.
+ ///
+ internal static string Capabilities {
+ get {
+ return ResourceManager.GetString("Capabilities", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Component name for language with code {0}: {1}.
+ ///
+ internal static string Component_name_for_language_with_code_0_1 {
+ get {
+ return ResourceManager.GetString("Component_name_for_language_with_code_0_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Component version: {0}.{1}.
+ ///
+ internal static string Component_version_0_1 {
+ get {
+ return ResourceManager.GetString("Component_version_0_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to CRC16 of header: 0x{0:X4}.
+ ///
+ internal static string CRC16_of_header_0 {
+ get {
+ return ResourceManager.GetString("CRC16_of_header_0", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Archive contains {0} files (pointer: {1}).
+ ///
+ internal static string File_contains_0_files_pointer_1 {
+ get {
+ return ResourceManager.GetString("File_contains_0_files_pointer_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Archive contains {0} languages:.
+ ///
+ internal static string File_contains_0_languages {
+ get {
+ return ResourceManager.GetString("File_contains_0_languages", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Archive contains {0} requisites.
+ ///
+ internal static string File_contains_0_requisites {
+ get {
+ return ResourceManager.GetString("File_contains_0_requisites", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Files for `{0}` language:.
+ ///
+ internal static string Files_for_0_language {
+ get {
+ return ResourceManager.GetString("Files_for_0_language", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Files for all languages:.
+ ///
+ internal static string Files_for_all_languages {
+ get {
+ return ResourceManager.GetString("Files_for_all_languages", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Name for language {0}: {1}.
+ ///
+ internal static string Name_for_language_0_1 {
+ get {
+ return ResourceManager.GetString("Name_for_language_0_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Option {0}:.
+ ///
+ internal static string Option_0 {
+ get {
+ return ResourceManager.GetString("Option_0", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Required {0} version {1}.{2}.
+ ///
+ internal static string Required_UID_0_version_1_2 {
+ get {
+ return ResourceManager.GetString("Required_UID_0_version_1_2", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Required variant: {0}.
+ ///
+ internal static string Required_variant_0 {
+ get {
+ return ResourceManager.GetString("Required_variant_0", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Requisite #{0}:.
+ ///
+ internal static string Requisite_0 {
+ get {
+ return ResourceManager.GetString("Requisite_0", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Requisite for language {0}: {1}.
+ ///
+ internal static string Requisite_for_language_0_1 {
+ get {
+ return ResourceManager.GetString("Requisite_for_language_0_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to SIS contains an application.
+ ///
+ internal static string SIS_contains_an_application {
+ get {
+ return ResourceManager.GetString("SIS_contains_an_application", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to UID 0x{0:X8}.
+ ///
+ internal static string SIS_Platform_UID_0 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_0", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia 3230.
+ ///
+ internal static string SIS_Platform_UID_Nokia_3230 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_3230", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia 3250.
+ ///
+ internal static string SIS_Platform_UID_Nokia_3250 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_3250", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia 3650.
+ ///
+ internal static string SIS_Platform_UID_Nokia_3650 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_3650", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia 6260.
+ ///
+ internal static string SIS_Platform_UID_Nokia_6260 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_6260", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia 6600.
+ ///
+ internal static string SIS_Platform_UID_Nokia_6600 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_6600", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia 6620.
+ ///
+ internal static string SIS_Platform_UID_Nokia_6620 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_6620", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia 6630.
+ ///
+ internal static string SIS_Platform_UID_Nokia_6630 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_6630", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia 6670.
+ ///
+ internal static string SIS_Platform_UID_Nokia_6670 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_6670", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia 6680.
+ ///
+ internal static string SIS_Platform_UID_Nokia_6680 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_6680", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia 6681.
+ ///
+ internal static string SIS_Platform_UID_Nokia_6681 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_6681", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia 6682.
+ ///
+ internal static string SIS_Platform_UID_Nokia_6682 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_6682", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia 7610.
+ ///
+ internal static string SIS_Platform_UID_Nokia_7610 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_7610", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia 7650.
+ ///
+ internal static string SIS_Platform_UID_Nokia_7650 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_7650", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia 7710 (Series 90).
+ ///
+ internal static string SIS_Platform_UID_Nokia_7710_Series_90 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_7710_Series_90", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia 9300.
+ ///
+ internal static string SIS_Platform_UID_Nokia_9300 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_9300", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia 9500.
+ ///
+ internal static string SIS_Platform_UID_Nokia_9500 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_9500", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia Belle.
+ ///
+ internal static string SIS_Platform_UID_Nokia_Belle {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_Belle", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia E60.
+ ///
+ internal static string SIS_Platform_UID_Nokia_E60 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_E60", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia E61.
+ ///
+ internal static string SIS_Platform_UID_Nokia_E61 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_E61", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia E70.
+ ///
+ internal static string SIS_Platform_UID_Nokia_E70 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_E70", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia N-Gage.
+ ///
+ internal static string SIS_Platform_UID_Nokia_N_Gage {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_N_Gage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia N70.
+ ///
+ internal static string SIS_Platform_UID_Nokia_N70 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_N70", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia N71.
+ ///
+ internal static string SIS_Platform_UID_Nokia_N71 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_N71", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia N73.
+ ///
+ internal static string SIS_Platform_UID_Nokia_N73 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_N73", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia N80.
+ ///
+ internal static string SIS_Platform_UID_Nokia_N80 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_N80", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia N90.
+ ///
+ internal static string SIS_Platform_UID_Nokia_N90 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_N90", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia N91.
+ ///
+ internal static string SIS_Platform_UID_Nokia_N91 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_N91", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Nokia N92.
+ ///
+ internal static string SIS_Platform_UID_Nokia_N92 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Nokia_N92", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Series 60 1st Edition.
+ ///
+ internal static string SIS_Platform_UID_Series_60_1st_Edition {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Series_60_1st_Edition", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Series 60 1st Edition, Feature Pack 1.
+ ///
+ internal static string SIS_Platform_UID_Series_60_1st_Edition_Feature_Pack_1 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Series_60_1st_Edition_Feature_Pack_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Series 60 2nd Edition.
+ ///
+ internal static string SIS_Platform_UID_Series_60_2nd_Edition {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Series_60_2nd_Edition", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Series 60 2nd Edition, Feature Pack 1.
+ ///
+ internal static string SIS_Platform_UID_Series_60_2nd_Edition_Feature_Pack_1 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Series_60_2nd_Edition_Feature_Pack_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Series 60 2nd Edition, Feature Pack 2.
+ ///
+ internal static string SIS_Platform_UID_Series_60_2nd_Edition_Feature_Pack_2 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Series_60_2nd_Edition_Feature_Pack_2", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Series 60 2nd Edition, Feature Pack 3.
+ ///
+ internal static string SIS_Platform_UID_Series_60_2nd_Edition_Feature_Pack_3 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Series_60_2nd_Edition_Feature_Pack_3", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Series 60 3rd Edition.
+ ///
+ internal static string SIS_Platform_UID_Series_60_3rd_Edition {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Series_60_3rd_Edition", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Series 60 3rd Edition, Feature Pack 1.
+ ///
+ internal static string SIS_Platform_UID_Series_60_3rd_Edition_Feature_Pack_1 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Series_60_3rd_Edition_Feature_Pack_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Series 60 3rd Edition, Feature Pack 2.
+ ///
+ internal static string SIS_Platform_UID_Series_60_3rd_Edition_Feature_Pack_2 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Series_60_3rd_Edition_Feature_Pack_2", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Series 60 5th Edition.
+ ///
+ internal static string SIS_Platform_UID_Series_60_5th_Edition {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Series_60_5th_Edition", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Series 60 v1.0.
+ ///
+ internal static string SIS_Platform_UID_Series_60_v1_0 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Series_60_v1_0", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Series 60 v1.1.
+ ///
+ internal static string SIS_Platform_UID_Series_60_v1_1 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Series_60_v1_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Series 80 2nd Edition.
+ ///
+ internal static string SIS_Platform_UID_Series_80_2nd_edition {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Series_80_2nd_edition", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Siemens SX1.
+ ///
+ internal static string SIS_Platform_UID_Siemens_SX1 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Siemens_SX1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to SonyEricsson P80x.
+ ///
+ internal static string SIS_Platform_UID_SonyEricsson_P80x {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_SonyEricsson_P80x", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to SonyEricsson P90x.
+ ///
+ internal static string SIS_Platform_UID_SonyEricsson_P90x {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_SonyEricsson_P90x", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Symbian^3.
+ ///
+ internal static string SIS_Platform_UID_Symbian_3 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_Symbian_3", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to UIQ v2.0.
+ ///
+ internal static string SIS_Platform_UID_UIQ_20 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_UIQ_20", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to UIQ v2.1.
+ ///
+ internal static string SIS_Platform_UID_UIQ_21 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_UIQ_21", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to UIQ v3.0.
+ ///
+ internal static string SIS_Platform_UID_UIQ_30 {
+ get {
+ return ResourceManager.GetString("SIS_Platform_UID_UIQ_30", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to SymbianOS 3 or later.
+ ///
+ internal static string Symbian_3_or_later {
+ get {
+ return ResourceManager.GetString("Symbian_3_or_later", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to SymbianOS 6 or later.
+ ///
+ internal static string Symbian_6_or_later {
+ get {
+ return ResourceManager.GetString("Symbian_6_or_later", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to SymbianOS 9.1 or later.
+ ///
+ internal static string Symbian_9_1_or_later {
+ get {
+ return ResourceManager.GetString("Symbian_9_1_or_later", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Symbian Installation File.
+ ///
+ internal static string Symbian_Installation_File {
+ get {
+ return ResourceManager.GetString("Symbian_Installation_File", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Symbian Installation File.
+ ///
+ internal static string Symbian_Name {
+ get {
+ return ResourceManager.GetString("Symbian_Name", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to UIDs checksum: 0x{0:X8}.
+ ///
+ internal static string UIDs_checksum_0 {
+ get {
+ return ResourceManager.GetString("UIDs_checksum_0", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Unknown EPOC magic 0x{0:X8}.
+ ///
+ internal static string Unknown_EPOC_magic_0 {
+ get {
+ return ResourceManager.GetString("Unknown_EPOC_magic_0", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/Aaru.Archives/Localization/Localization.es.resx b/Aaru.Archives/Localization/Localization.es.resx
new file mode 100644
index 000000000..c2d248cc1
--- /dev/null
+++ b/Aaru.Archives/Localization/Localization.es.resx
@@ -0,0 +1,240 @@
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
+ PublicKeyToken=b77a5c561934e089
+
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
+ PublicKeyToken=b77a5c561934e089
+
+
+
+ Fichero de Instalación de Symbian
+
+
+ ID de aplicación: 0x{0:X8}
+
+
+ Capacidades:
+
+
+ CRC16 de la cabecera: 0x{0:X4}
+
+
+ El archivo contiene {0} ficheros (pointer: {1})
+
+
+ El archivo contiene {0} idiomas:
+
+
+ El archivo contiene {0} requisitos:
+
+
+ El archivo contiene una aplicación
+
+
+ SymbianOS 3 o superior
+
+
+ SymbianOS 6 o superior
+
+
+ SymbianOS 9.1 o superior
+
+
+ Fichero de Instalación de Symbian
+
+
+ Checksum de los UIDs: 0x{0:X8}
+
+
+ Mágica EPOC 0x{0:X8} desconocida
+
+
+ Nombre del componente para el idioma con código {0}: {1}
+
+
+ Versión del componente: {0}.{1}
+
+
+ Ficheros para el idioma `{0}`:
+
+
+ Ficheros para todos los idiomas:
+
+
+ Requerida {0} versión {1}.{2}
+
+
+ Variante requerida: {0}
+
+
+ Requisito nº {0}:
+
+
+ Requisito para el idioma {0}: {1}
+
+
+ Nokia Belle
+
+
+ Series 60 1ª Edición
+
+
+ Series 60 1ª Edición, Feature Pack 1
+
+
+ Series 60 2ª Edición
+
+
+ Series 60 2ª Edición, Feature Pack 1
+
+
+ Series 60 2ª Edición, Feature Pack 2
+
+
+ Series 60 2ª Edición, Feature Pack 3
+
+
+ Series 60 3ª Edición
+
+
+ Series 60 3ª Edición, Feature Pack 1
+
+
+ Series 60 3ª Edición, Feature Pack 2
+
+
+ Series 60 5ª Edición
+
+
+ Symbian^3
+
+
+ UID 0x{0:X8}
+
+
+ Opciones del archivo: {0}
+
+
+ UIQ v2.1
+
+
+ UIQ v3.0
+
+
+ Nokia 7650
+
+
+ Series 60 v1.0
+
+
+ Nokia 3650
+
+
+ Nokia 6600
+
+
+ Nokia 6630
+
+
+ SonyEricsson P80x
+
+
+ Series 60 v1.1
+
+
+ Nokia N-Gage
+
+
+ Nokia 9500
+
+
+ Nokia 9300
+
+
+ Series 80 2ª Edición
+
+
+ Siemens SX1
+
+
+ Nokia 6260
+
+
+ SonyEricsson P90x
+
+
+ Nokia 7710 (Series 90)
+
+
+ Nokia 7610
+
+
+ Nokia 6670
+
+
+ UIQ v2.0
+
+
+ Nokia 3230
+
+
+ Nokia N90
+
+
+ Nokia N70
+
+
+ Nokia 6680
+
+
+ Nokia 6620
+
+
+ Nokia 6682
+
+
+ Nokia 6681
+
+
+ Nokia 3250
+
+
+ Nokia N80
+
+
+ Nokia N92
+
+
+ Nokia N73
+
+
+ Nokia N91
+
+
+ Nokia N71
+
+
+ Nokia E60
+
+
+ Nokia E70
+
+
+ Nokia E61
+
+
+ Opción {0}:
+
+
+ Nombre para el idioma {0}: {1}
+
+
\ No newline at end of file
diff --git a/Aaru.Archives/Localization/Localization.resx b/Aaru.Archives/Localization/Localization.resx
new file mode 100644
index 000000000..906e7a6fa
--- /dev/null
+++ b/Aaru.Archives/Localization/Localization.resx
@@ -0,0 +1,248 @@
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
+ PublicKeyToken=b77a5c561934e089
+
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
+ PublicKeyToken=b77a5c561934e089
+
+
+
+ Symbian Installation File
+
+
+ Symbian Installation File
+
+
+ SymbianOS 9.1 or later
+
+
+ Application ID: 0x{0:X8}
+
+
+ UIDs checksum: 0x{0:X8}
+
+
+ SymbianOS 3 or later
+
+
+ SymbianOS 6 or later
+
+
+ Unknown EPOC magic 0x{0:X8}
+
+
+ CRC16 of header: 0x{0:X4}
+
+
+ SIS contains an application
+
+
+ Archive contains {0} languages:
+
+
+ Archive contains {0} files (pointer: {1})
+
+
+ Archive contains {0} requisites
+
+
+ Capabilities:
+
+
+ Component version: {0}.{1}
+
+
+ Component name for language with code {0}: {1}
+
+
+ Files for all languages:
+
+
+ Files for `{0}` language:
+
+
+ Requisite #{0}:
+
+
+ Required {0} version {1}.{2}
+
+
+ Required variant: {0}
+
+
+ Requisite for language {0}: {1}
+
+
+ Series 60 1st Edition
+
+
+ Series 60 1st Edition, Feature Pack 1
+
+
+ Series 60 2nd Edition
+
+
+ Series 60 2nd Edition, Feature Pack 1
+
+
+ Series 60 2nd Edition, Feature Pack 2
+
+
+ Series 60 2nd Edition, Feature Pack 3
+
+
+ Series 60 3rd Edition
+
+
+ Series 60 3rd Edition, Feature Pack 1
+
+
+ Series 60 3rd Edition, Feature Pack 2
+
+
+ Series 60 5th Edition
+
+
+ Symbian^3
+
+
+ Nokia Belle
+
+
+ UID 0x{0:X8}
+
+
+ Archive options: {0}
+
+
+ UIQ v2.1
+
+
+ UIQ v3.0
+
+
+ Nokia 7650
+
+
+ Series 60 v1.0
+
+
+ Nokia 3650
+
+
+ Nokia 6600
+
+
+ Nokia 6630
+
+
+ SonyEricsson P80x
+
+
+ Series 60 v1.1
+
+
+ Nokia N-Gage
+
+
+ Nokia 9500
+
+
+ Nokia 9300
+
+
+ Series 80 2nd Edition
+
+
+ Siemens SX1
+
+
+ Nokia 6260
+
+
+ SonyEricsson P90x
+
+
+ Nokia 7710 (Series 90)
+
+
+ Nokia 7610
+
+
+ Nokia 6670
+
+
+ UIQ v2.0
+
+
+ Nokia 3230
+
+
+ Nokia N90
+
+
+ Nokia N70
+
+
+ Nokia 6680
+
+
+ Nokia 6620
+
+
+ Nokia 6682
+
+
+ Nokia 6681
+
+
+ Nokia 3250
+
+
+ Nokia N80
+
+
+ Nokia N92
+
+
+ Nokia N73
+
+
+ Nokia N91
+
+
+ Nokia N71
+
+
+ Nokia E60
+
+
+ Nokia E70
+
+
+ Nokia E61
+
+
+ Option {0}:
+
+
+ Name for language {0}: {1}
+
+
\ No newline at end of file
diff --git a/Aaru.Archives/Register.cs b/Aaru.Archives/Register.cs
index f5c059114..2c6ac1a12 100644
--- a/Aaru.Archives/Register.cs
+++ b/Aaru.Archives/Register.cs
@@ -1,4 +1,4 @@
-// /***************************************************************************
+// /***************************************************************************
// Aaru Data Preservation Suite
// ----------------------------------------------------------------------------
//
@@ -34,53 +34,15 @@
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// ----------------------------------------------------------------------------
-// Copyright © 2021-2022 Michael Drüing
-// Copyright © 2011-2022 Natalia Portillo
+// Copyright © 2021-2024 Michael Drüing
+// Copyright © 2011-2024 Natalia Portillo
// ****************************************************************************/
+using Aaru.CommonTypes.Interfaces;
+
namespace Aaru.Archives;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using Aaru.CommonTypes.Interfaces;
-
+// Needs to have the interface here so the source generator knows THIS IS the class
+// ReSharper disable once RedundantExtendsListEntry
///
-public sealed class Register : IPluginRegister
-{
- ///
- public List GetAllChecksumPlugins() => null;
-
- ///
- public List GetAllFilesystemPlugins() => null;
-
- ///
- public List GetAllFilterPlugins() => null;
-
- ///
- public List GetAllFloppyImagePlugins() => null;
-
- ///
- public List GetAllMediaImagePlugins() => null;
-
- ///
- public List GetAllPartitionPlugins() => null;
-
- ///
- public List GetAllReadOnlyFilesystemPlugins() => null;
-
- ///
- public List GetAllWritableFloppyImagePlugins() => null;
-
- ///
- public List GetAllWritableImagePlugins() => null;
-
- ///
- public List GetAllArchivePlugins() => Assembly.GetExecutingAssembly().GetTypes().
- Where(t => t.GetInterfaces().Contains(typeof(IArchive))).
- Where(t => t.IsClass).ToList();
-
- ///
- public List GetAllByteAddressablePlugins() => null;
-}
\ No newline at end of file
+public sealed partial class Register : IPluginRegister;
\ No newline at end of file
diff --git a/Aaru.Archives/Symbian/Conditions.cs b/Aaru.Archives/Symbian/Conditions.cs
new file mode 100644
index 000000000..1647b1aab
--- /dev/null
+++ b/Aaru.Archives/Symbian/Conditions.cs
@@ -0,0 +1,327 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Symbian.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Symbian plugin.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Identifies Symbian installer (.sis) packages and shows information.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace Aaru.Archives;
+
+public sealed partial class Symbian
+{
+ ConditionalExpression ParseConditionalExpression(BinaryReader br, uint maxOffset, StringBuilder sb,
+ ref Attribute? attribute)
+ {
+ if(br.BaseStream.Position >= maxOffset) return null;
+
+ var type = (ConditionalType)br.ReadUInt32();
+ var operatorString = "";
+
+ SubConditionalExpression subExpression;
+ TwoSubsConditionalExpression twoSubsConditionalExpression;
+
+ switch(type)
+ {
+ case ConditionalType.Equals:
+ if(type == ConditionalType.Equals) operatorString = " == ";
+
+ twoSubsConditionalExpression = new TwoSubsConditionalExpression
+ {
+ type = type
+ };
+
+ sb.Append("(");
+ twoSubsConditionalExpression.leftOperand = ParseConditionalExpression(br, maxOffset, sb, ref attribute);
+ sb.Append(operatorString);
+
+ twoSubsConditionalExpression.rightOperand =
+ ParseConditionalExpression(br, maxOffset, sb, ref attribute);
+
+ sb.Append(")");
+
+ attribute = null;
+
+ return twoSubsConditionalExpression;
+ case ConditionalType.Differs:
+ operatorString = " != ";
+ goto case ConditionalType.Equals;
+ case ConditionalType.GreaterThan:
+ operatorString = " > ";
+ goto case ConditionalType.Equals;
+ case ConditionalType.LessThan:
+ operatorString = " < ";
+ goto case ConditionalType.Equals;
+ case ConditionalType.GreaterOrEqualThan:
+ operatorString = " >= ";
+ goto case ConditionalType.Equals;
+ case ConditionalType.LessOrEqualThan:
+ operatorString = " <= ";
+ goto case ConditionalType.Equals;
+ case ConditionalType.And:
+ operatorString = " && ";
+ goto case ConditionalType.Equals;
+ case ConditionalType.Or:
+ operatorString = " || ";
+ goto case ConditionalType.Equals;
+ case ConditionalType.Exists:
+ sb.Append("exists(");
+
+ subExpression = new SubConditionalExpression
+ {
+ type = type,
+ subExpression = ParseConditionalExpression(br, maxOffset, sb, ref attribute)
+ };
+
+ sb.Append(")");
+
+ attribute = null;
+
+ return subExpression;
+ case ConditionalType.DeviceCapability:
+ sb.Append("devcap(");
+
+ subExpression = new SubConditionalExpression
+ {
+ type = type,
+ subExpression = ParseConditionalExpression(br, maxOffset, sb, ref attribute)
+ };
+
+ sb.Append(')');
+
+ attribute = null;
+
+ return subExpression;
+ case ConditionalType.ApplicationCapability:
+ twoSubsConditionalExpression = new TwoSubsConditionalExpression
+ {
+ type = type
+ };
+
+ sb.Append("appcap(");
+ twoSubsConditionalExpression.leftOperand = ParseConditionalExpression(br, maxOffset, sb, ref attribute);
+ sb.Append(", ");
+
+ twoSubsConditionalExpression.rightOperand =
+ ParseConditionalExpression(br, maxOffset, sb, ref attribute);
+
+ sb.Append(')');
+
+ attribute = null;
+
+ return twoSubsConditionalExpression;
+ case ConditionalType.Not:
+ sb.Append('!');
+
+ subExpression = new SubConditionalExpression
+ {
+ type = type,
+ subExpression = ParseConditionalExpression(br, maxOffset, sb, ref attribute)
+ };
+
+ attribute = null;
+
+ return subExpression;
+ case ConditionalType.String:
+ var stringExpression = new StringConditionalExpression
+ {
+ type = type,
+ length = br.ReadUInt32(),
+ pointer = br.ReadUInt32()
+ };
+
+ long position = br.BaseStream.Position;
+
+ br.BaseStream.Seek(stringExpression.pointer, SeekOrigin.Begin);
+ byte[] buffer = br.ReadBytes((int)stringExpression.length);
+ stringExpression.@string = _encoding.GetString(buffer);
+
+ br.BaseStream.Seek(position, SeekOrigin.Begin);
+
+ sb.Append($"\"{stringExpression.@string}\"");
+
+ attribute = null;
+
+ break;
+ case ConditionalType.Attribute:
+ var attributeExpression = new AttributeConditionalExpression
+ {
+ type = type,
+ attribute = (Attribute)br.ReadUInt32(),
+ unused = br.ReadUInt32()
+ };
+
+ if((int)attributeExpression.attribute > 0x2000)
+ {
+ int optionIndex = (int)attributeExpression.attribute - 0x2000;
+
+ if(optionIndex <= _options.Count)
+ {
+ OptionRecord option = _options[optionIndex - 1];
+ option.names.TryGetValue("EN", out string optionName);
+ optionName ??= option.names.Values.FirstOrDefault() ?? optionIndex.ToString();
+ sb.Append($"option(\"{optionName}\", ENABLED)");
+ }
+ else
+ sb.Append($"option({optionIndex}, ENABLED");
+ }
+ else
+ sb.Append($"{attributeExpression.attribute}");
+
+ attribute = attributeExpression.attribute;
+
+ return attributeExpression;
+ case ConditionalType.Number:
+ var numberExpression = new NumberConditionalExpression
+ {
+ type = type,
+ number = br.ReadUInt32(),
+ unused = br.ReadUInt32()
+ };
+
+ if(attribute is null)
+ sb.Append($"0x{numberExpression.number:X8}");
+ else if((uint)attribute.Value < 0x2000)
+ {
+ switch(attribute)
+ {
+ case Attribute.Manufacturer:
+ sb.Append($"{(ManufacturerCode)numberExpression.number}");
+
+ break;
+ case Attribute.ManufacturerHardwareRev:
+ case Attribute.ManufacturerSoftwareRev:
+ case Attribute.DeviceFamilyRev:
+ sb.Append($"{numberExpression.number >> 8}.{numberExpression.number & 0xFF}");
+
+ break;
+ case Attribute.MachineUid:
+ sb.Append($"{DecodeMachineUid(numberExpression.number)}");
+
+ break;
+ case Attribute.DeviceFamily:
+ sb.Append($"{(DeviceFamilyCode)numberExpression.number}");
+
+ break;
+ case Attribute.CPU:
+ sb.Append($"{(CpuCode)numberExpression.number}");
+
+ break;
+ case Attribute.CPUArch:
+ sb.Append($"{(CpuArchitecture)numberExpression.number}");
+
+ break;
+ case Attribute.CPUABI:
+ sb.Append($"{(CpuAbiCode)numberExpression.number}");
+
+ break;
+ case Attribute.CPUSpeed:
+ sb.Append($"{numberExpression.number / 1024}MHz");
+
+ break;
+ case Attribute.SystemTickPeriod:
+ sb.Append($"{numberExpression.number}μs");
+
+ break;
+ case Attribute.MemoryRAM:
+ case Attribute.MemoryRAMFree:
+ case Attribute.MemoryROM:
+ case Attribute.MemoryPageSize:
+ case Attribute.Keyboard:
+ case Attribute.KeyboardDeviceKeys:
+ case Attribute.KeyboardAppKeys:
+ case Attribute.KeyboardClickVolumeMax:
+ case Attribute.DisplayXPixels:
+ case Attribute.DisplayYPixels:
+ case Attribute.DisplayXTwips:
+ case Attribute.DisplayYTwips:
+ case Attribute.DisplayColors:
+ case Attribute.DisplayContrastMax:
+ case Attribute.PenX:
+ case Attribute.PenY:
+ case Attribute.PenClickVolumeMax:
+ case Attribute.MouseX:
+ case Attribute.MouseY:
+ case Attribute.MouseButtons:
+ case Attribute.LEDs:
+ case Attribute.DisplayBrightnessMax:
+ case Attribute.KeyboardBacklightState:
+ case Attribute.AccessoryPower:
+ case Attribute.NumHalAttributes:
+ case Attribute.Language:
+ sb.Append($"{numberExpression.number}");
+
+ break;
+ case Attribute.PowerBackup:
+ case Attribute.KeyboardClick:
+ case Attribute.Backlight:
+ case Attribute.Pen:
+ case Attribute.PenDisplayOn:
+ case Attribute.PenClick:
+ case Attribute.Mouse:
+ case Attribute.CaseSwitch:
+ case Attribute.IntegratedPhone:
+ case Attribute.RemoteInstall:
+ sb.Append(numberExpression.number == 0 ? "false" : "true");
+
+ break;
+ default:
+ sb.Append($"0x{numberExpression.number:X8}");
+
+ break;
+ }
+ }
+ else
+ {
+ int optionIndex = (int)attribute - 0x2000;
+
+ if(optionIndex <= _options.Count)
+ {
+ OptionRecord option = _options[optionIndex - 1];
+ option.names.TryGetValue("EN", out string optionName);
+ optionName ??= option.names.Values.FirstOrDefault() ?? optionIndex.ToString();
+ sb.Append($"option(\"{optionName}\", {(numberExpression.number == 0 ? "DISABLED" : "ENABLED")})");
+ }
+ else
+ sb.Append($"option({optionIndex}, {(numberExpression.number == 0 ? "DISABLED" : "ENABLED")}");
+ }
+
+ attribute = null;
+
+ return numberExpression;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/Aaru.Archives/Symbian/Consts.cs b/Aaru.Archives/Symbian/Consts.cs
new file mode 100644
index 000000000..2429d7b96
--- /dev/null
+++ b/Aaru.Archives/Symbian/Consts.cs
@@ -0,0 +1,46 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Symbian.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Symbian plugin.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Identifies Symbian installer (.sis) packages and shows information.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System.Diagnostics.CodeAnalysis;
+
+namespace Aaru.Archives;
+
+[SuppressMessage("ReSharper", "UnusedType.Global")]
+[SuppressMessage("ReSharper", "UnusedMember.Local")]
+public sealed partial class Symbian
+{
+ // Magics
+ const uint SYMBIAN_MAGIC = 0x10000419;
+ const uint EPOC_MAGIC = 0x1000006D;
+ const uint EPOC6_MAGIC = 0x10003A12;
+ const uint SYMBIAN9_MAGIC = 0x10201A7A;
+}
\ No newline at end of file
diff --git a/Aaru.Archives/Symbian/Enums.cs b/Aaru.Archives/Symbian/Enums.cs
new file mode 100644
index 000000000..571c47ae0
--- /dev/null
+++ b/Aaru.Archives/Symbian/Enums.cs
@@ -0,0 +1,637 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Symbian.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Symbian plugin.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Identifies Symbian installer (.sis) packages and shows information.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Aaru.Archives;
+
+[SuppressMessage("ReSharper", "UnusedMember.Local")]
+[SuppressMessage("ReSharper", "UnusedType.Local")]
+[SuppressMessage("ReSharper", "UnusedType.Global")]
+[SuppressMessage("ReSharper", "InconsistentNaming")]
+public sealed partial class Symbian
+{
+#region Nested type: Attribute
+
+ enum Attribute : uint
+ {
+ ///
+ ///
+ ///
+ Manufacturer = 0x00000000,
+ ///
+ /// 0x0100 = 1.00
+ ///
+ ManufacturerHardwareRev = 0x00000001,
+ ///
+ /// 0x0100 = 1.00
+ ///
+ ManufacturerSoftwareRev = 0x00000002,
+ ///
+ /// Manufacturer specific
+ ///
+ ManufacturerSoftwareBuild = 0x00000003,
+ Model = 0x00000004,
+ ///
+ /// Device specific values for products as defined in epoc32\include\hal_data.h
+ ///
+ MachineUid = 0x00000005,
+ ///
+ ///
+ ///
+ DeviceFamily = 0x00000006,
+ ///
+ /// 0x0100 = 1.00
+ ///
+ DeviceFamilyRev = 0x00000007,
+ ///
+ ///
+ ///
+ CPU = 0x00000008,
+ ///
+ ///
+ ///
+ CPUArch = 0x00000009,
+ ///
+ ///
+ ///
+ CPUABI = 0x0000000a,
+ ///
+ /// CPU clock speed / 1024, e.g. 36864=36MHz
+ ///
+ CPUSpeed = 0x0000000b,
+ ///
+ /// Tick period in microseconds
+ ///
+ SystemTickPeriod = 0x0000000e,
+ ///
+ /// Approximate speed relative to Psion Series 5 = 100
+ ///
+ SystemSpeed = 0x0000000e,
+ ///
+ /// Total RAM size in bytes
+ ///
+ MemoryRAM = 0x0000000f,
+ ///
+ /// Free RAM size in bytes
+ ///
+ MemoryRAMFree = 0x00000010,
+ ///
+ /// Total ROM size
+ ///
+ MemoryROM = 0x00000011,
+ ///
+ /// Size of memory management unit pages
+ ///
+ MemoryPageSize = 0x00000012,
+ ///
+ /// 0=none, 1=supported
+ ///
+ PowerBackup = 0x00000015,
+ ///
+ /// 0=none, 1=keypad, 2=full, 3=both
+ ///
+ Keyboard = 0x00000018,
+ ///
+ /// Number of device specific keys
+ ///
+ KeyboardDeviceKeys = 0x00000019,
+ ///
+ /// Number of application keys
+ ///
+ KeyboardAppKeys = 0x0000001a,
+ ///
+ /// 0=none, 1=supported
+ ///
+ KeyboardClick = 0x0000001b,
+ KeyboardClickVolumeMax = 0x0000001e,
+ ///
+ /// Screen width in pixels
+ ///
+ DisplayXPixels = 0x0000001f,
+ ///
+ /// Screen height in pixels
+ ///
+ DisplayYPixels = 0x00000020,
+ ///
+ /// Screen width in twips (1/1440 inch)
+ ///
+ DisplayXTwips = 0x00000021,
+ ///
+ /// Screen height in twips (1/1440 inch)
+ ///
+ DisplayYTwips = 0x00000022,
+ ///
+ /// 2, 4, 16, 256, 65536, etc
+ ///
+ DisplayColors = 0x00000023,
+ DisplayContrastMax = 0x00000026,
+ ///
+ /// 0=none, 1=supported
+ ///
+ Backlight = 0x00000027,
+ ///
+ /// 0=none, 1=supported
+ ///
+ Pen = 0x00000029,
+ ///
+ /// Pen horizontal resolution
+ ///
+ PenX = 0x0000002a,
+ ///
+ /// Pen vertical resolution
+ ///
+ PenY = 0x0000002b,
+ ///
+ /// 0=no 1=yes
+ ///
+ PenDisplayOn = 0x0000002c,
+ ///
+ /// 0=none, 1=supported
+ ///
+ PenClick = 0x0000002d,
+ PenClickVolumeMax = 0x00000030,
+ ///
+ /// 0=none, 1=supported
+ ///
+ Mouse = 0x00000031,
+ ///
+ /// Mouse horizontal resolution
+ ///
+ MouseX = 0x00000032,
+ ///
+ /// Mouse vertical resolution
+ ///
+ MouseY = 0x00000033,
+ ///
+ /// Number of mouse buttons
+ ///
+ MouseButtons = 0x00000037,
+ ///
+ /// 0=none, 1=supported
+ ///
+ CaseSwitch = 0x0000003a,
+ ///
+ /// Number of LEDs
+ ///
+ LEDs = 0x0000003d,
+ ///
+ /// 0=none, 1=supported
+ ///
+ IntegratedPhone = 0x0000003f,
+ DisplayBrightnessMax = 0x00000041,
+ KeyboardBacklightState = 0x00000042,
+ AccessoryPower = 0x00000043,
+ ///
+ /// Number of supported HAL attributes
+ ///
+ NumHalAttributes = 0x00000059,
+ ///
+ /// Machine language
+ ///
+ Language = 0x00001000,
+ ///
+ /// 0=Symbian OS based install, 1=installation via a PC
+ ///
+ RemoteInstall = 0x00001001
+ }
+
+#endregion
+
+#region Nested type: ConditionalType
+
+ enum ConditionalType : uint
+ {
+ ///
+ /// a == b
+ ///
+ Equals,
+ ///
+ /// a != b
+ ///
+ Differs,
+ ///
+ /// a > b
+ ///
+ GreaterThan,
+ ///
+ /// a < b
+ ///
+ LessThan,
+ ///
+ /// a >= b
+ ///
+ GreaterOrEqualThan,
+ ///
+ /// a <= b
+ ///
+ LessOrEqualThan,
+ ///
+ /// a AND b
+ ///
+ And,
+ ///
+ /// a OR b
+ ///
+ Or,
+ ///
+ /// exists(filename)
+ ///
+ Exists,
+ ///
+ /// devcap(capability)
+ ///
+ DeviceCapability,
+ ///
+ /// appcap(uid, capability)
+ ///
+ ApplicationCapability,
+ ///
+ /// NOT a
+ ///
+ Not,
+ ///
+ /// String
+ ///
+ String,
+ ///
+ /// Attribute
+ ///
+ Attribute,
+ ///
+ /// Number
+ ///
+ Number
+ }
+
+#endregion
+
+#region Nested type: CpuAbiCode
+
+ enum CpuAbiCode
+ {
+ ARM4 = 0,
+ ARMI = 1,
+ Thumb = 2,
+ MCORE = 3,
+ MSVC = 4
+ }
+
+#endregion
+
+#region Nested type: CpuArchitecture
+
+ enum CpuArchitecture
+ {
+ ARM4 = 0x400,
+ ARM4T = 0x410,
+ ARM5 = 0x500,
+ M340 = 0x300
+ }
+
+#endregion
+
+#region Nested type: CpuCode
+
+ enum CpuCode
+ {
+ ARM = 0,
+ MCORE = 1,
+ x86 = 2
+ }
+
+#endregion
+
+#region Nested type: DeviceFamilyCode
+
+ enum DeviceFamilyCode
+ {
+ Crystal = 0,
+ Pearl = 1,
+ Quartz = 2
+ }
+
+#endregion
+
+#region Nested type: FileDetails
+
+ ///
+ /// Gives some specific details about how to handle some special files
+ ///
+ enum FileDetails : uint
+ {
+ ///
+ /// Show the continue button and continue installing
+ ///
+ TextContinue = 0,
+ ///
+ /// Show a yes and a no button and skip next file on no
+ ///
+ TextSkip = 1,
+ ///
+ /// Show a yes and a no button and abort installation on no
+ ///
+ TextAbort = 2,
+ ///
+ /// Show a yes and a no button and abort and undo installation on no
+ ///
+ TextExit = 3,
+ ///
+ /// Run during installation
+ ///
+ RunInstall = 0,
+ ///
+ /// Run during uninstallation
+ ///
+ RunRemove = 1,
+ ///
+ /// Run during both installation and uninstallation
+ ///
+ RunBoth = 2,
+ ///
+ /// Works as a flag. Close when installation is complete.
+ ///
+ RunsEnd = 0x100,
+ ///
+ /// Works as a flag. Wait for it to close before continuing.
+ ///
+ RunWait = 0x200,
+ ///
+ /// Works as a flag. Close when installation is complete.
+ ///
+ OpenClose = 0x100,
+ ///
+ /// Works as a flag. Wait for it to close before continuing.
+ ///
+ OpenWait = 0x200
+ }
+
+#endregion
+
+#region Nested type: FileRecordType
+
+ ///
+ /// Define the file record type and therefore its structure
+ ///
+ enum FileRecordType : uint
+ {
+ ///
+ /// Points to a single file
+ ///
+ SimpleFile = 0,
+ ///
+ /// Points to an array of files sorted by the language codes
+ ///
+ MultipleLanguageFiles = 1,
+ ///
+ /// Points to an array of option strings
+ ///
+ Options = 2,
+ If = 3,
+ ElseIf = 4,
+ Else = 5,
+ EndIf = 6,
+ ///
+ /// Found in the wild, doesn't seem to contain any data, and doesn't count like a file entry either
+ ///
+ Skip = 0xFFFFFFFF
+ }
+
+#endregion
+
+#region Nested type: FileType
+
+ ///
+ /// Defines the file type
+ ///
+ enum FileType : uint
+ {
+ ///
+ /// Standard file
+ ///
+ File = 0,
+ ///
+ /// Text file to show during installation
+ ///
+ FileText = 1,
+ ///
+ /// SIS component
+ ///
+ Component = 2,
+ ///
+ /// File to run during installation
+ ///
+ FileRun = 3,
+ ///
+ /// File does not exist in SIS, will be created when application runs
+ ///
+ FileNull = 4,
+ ///
+ /// Open file using whatever app is associated with its MIME type
+ ///
+ FileMime = 5
+ }
+
+#endregion
+
+#region Nested type: LanguageCodes
+
+ [SuppressMessage("ReSharper", "InconsistentNaming")]
+ enum LanguageCodes
+ {
+ Test = 0,
+ EN,
+ FR,
+ GE,
+ SP,
+ IT,
+ SW,
+ DA,
+ NO,
+ FI,
+ AM,
+ SF,
+ SG,
+ PO,
+ TU,
+ IC,
+ RU,
+ HU,
+ DU,
+ BL,
+ AU,
+ BF,
+ AS,
+ NZ,
+ IF,
+ CS,
+ SK,
+ PL,
+ SL,
+ TC,
+ HK,
+ ZH,
+ JA,
+ TH,
+ AF,
+ SQ,
+ AH,
+ AR,
+ HY,
+ TL,
+ BE,
+ BN,
+ BG,
+ MY,
+ CA,
+ HR,
+ CE,
+ IE,
+ ZA,
+ ET,
+ FA,
+ CF,
+ GD,
+ KA,
+ EL,
+ CG,
+ GU,
+ HE,
+ HI,
+ IN,
+ GA,
+ SZ,
+ KN,
+ KK,
+ KM,
+ KO,
+ LO,
+ LV,
+ LT,
+ MK,
+ MS,
+ ML,
+ MR,
+ MO,
+ MN,
+ NN,
+ BP,
+ PA,
+ RO,
+ SR,
+ SI,
+ SO,
+ OS,
+ LS,
+ SH,
+ FS,
+ TA,
+ TE,
+ BO,
+ TI,
+ CT,
+ TK,
+ UK,
+ UR,
+ VI,
+ CY,
+ ZU
+ }
+
+#endregion
+
+#region Nested type: ManufacturerCode
+
+ enum ManufacturerCode
+ {
+ Ericsson = 0,
+ Motorola = 1,
+ Nokia = 2,
+ Panasonic = 3,
+ Psion = 4,
+ Intel = 5,
+ Cogent = 6,
+ Cirrus = 7
+ }
+
+#endregion
+
+#region Nested type: SymbianOptions
+
+ ///
+ /// Options
+ ///
+ [Flags]
+ enum SymbianOptions : ushort
+ {
+ IsUnicode = 0x0001,
+ IsDistributable = 0x0002,
+ NoCompress = 0x0008,
+ ShutdownApps = 0x0010
+ }
+
+#endregion
+
+#region Nested type: SymbianType
+
+ // Types
+ enum SymbianType : ushort
+ {
+ ///
+ /// Application
+ ///
+ Application = 0x0000,
+ ///
+ /// System component (library)
+ ///
+ SystemComponent = 0x0001,
+ ///
+ /// Optional component
+ ///
+ OptionalComponent = 0x0002,
+ ///
+ /// Configures an application
+ ///
+ Configurator = 0x0003,
+ ///
+ /// Patch
+ ///
+ Patch = 0x0004,
+ ///
+ /// Upgrade
+ ///
+ Upgrade = 0x0005
+ }
+
+#endregion
+}
\ No newline at end of file
diff --git a/Aaru.Archives/Symbian/Files.cs b/Aaru.Archives/Symbian/Files.cs
new file mode 100644
index 000000000..fca292e10
--- /dev/null
+++ b/Aaru.Archives/Symbian/Files.cs
@@ -0,0 +1,182 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Symbian.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Symbian plugin.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Identifies Symbian installer (.sis) packages and shows information.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.IO;
+using System.IO.Compression;
+using Aaru.CommonTypes.Enums;
+using Aaru.CommonTypes.Interfaces;
+using Aaru.CommonTypes.Structs;
+using Aaru.Filters;
+using Aaru.Helpers.IO;
+using FileAttributes = System.IO.FileAttributes;
+
+namespace Aaru.Archives;
+
+public sealed partial class Symbian
+{
+#region IArchive Members
+
+ ///
+ public int NumberOfEntries => Opened ? _files.Count : -1;
+
+ ///
+ public ErrorNumber GetFilename(int entryNumber, out string fileName)
+ {
+ fileName = null;
+
+ if(!Opened) return ErrorNumber.NotOpened;
+
+ if(entryNumber < 0 || entryNumber >= _files.Count) return ErrorNumber.OutOfRange;
+
+ fileName = _files[entryNumber].destinationName;
+
+ return ErrorNumber.NoError;
+ }
+
+ ///
+ public ErrorNumber GetEntryNumber(string fileName, bool caseInsensitiveMatch, out int entryNumber)
+ {
+ entryNumber = -1;
+
+ if(!Opened) return ErrorNumber.NotOpened;
+
+ if(string.IsNullOrEmpty(fileName)) return ErrorNumber.InvalidArgument;
+
+ entryNumber = _files.FindIndex(x => caseInsensitiveMatch
+ ? x.destinationName.Equals(fileName,
+ StringComparison.CurrentCultureIgnoreCase)
+ : x.destinationName.Equals(fileName, StringComparison.CurrentCulture));
+
+ return entryNumber < 0 ? ErrorNumber.NoSuchFile : ErrorNumber.NoError;
+ }
+
+ ///
+ public ErrorNumber GetCompressedSize(int entryNumber, out long length)
+ {
+ length = -1;
+
+ if(!Opened) return ErrorNumber.NotOpened;
+
+ if(entryNumber < 0 || entryNumber >= _files.Count) return ErrorNumber.OutOfRange;
+
+ length = _files[entryNumber].length;
+
+ return ErrorNumber.NoError;
+ }
+
+ ///
+ public ErrorNumber GetUncompressedSize(int entryNumber, out long length)
+ {
+ length = -1;
+
+ if(!Opened) return ErrorNumber.NotOpened;
+
+ if(entryNumber < 0 || entryNumber >= _files.Count) return ErrorNumber.OutOfRange;
+
+ length = _compressed ? _files[entryNumber].originalLength : _files[entryNumber].length;
+
+ return ErrorNumber.NoError;
+ }
+
+ ///
+ public ErrorNumber GetAttributes(int entryNumber, out FileAttributes attributes)
+ {
+ attributes = FileAttributes.None;
+
+ if(!Opened) return ErrorNumber.NotOpened;
+
+ if(entryNumber < 0 || entryNumber >= _files.Count) return ErrorNumber.OutOfRange;
+
+ attributes = FileAttributes.Normal;
+
+ return ErrorNumber.NoError;
+ }
+
+ ///
+ public ErrorNumber Stat(int entryNumber, out FileEntryInfo stat)
+ {
+ stat = null;
+
+ if(!Opened) return ErrorNumber.NotOpened;
+
+ if(entryNumber < 0 || entryNumber >= _files.Count) return ErrorNumber.OutOfRange;
+
+ stat = new FileEntryInfo
+ {
+ Length = _compressed ? _files[entryNumber].originalLength : _files[entryNumber].length,
+ Attributes = CommonTypes.Structs.FileAttributes.File,
+ Inode = (ulong)entryNumber
+ };
+
+ return ErrorNumber.NoError;
+ }
+
+ ///
+ public ErrorNumber GetEntry(int entryNumber, out IFilter filter)
+ {
+ filter = null;
+
+ if(!Opened) return ErrorNumber.NotOpened;
+
+ if(entryNumber < 0 || entryNumber >= _files.Count) return ErrorNumber.OutOfRange;
+
+ Stream stream = new OffsetStream(new NonClosableStream(_stream),
+ _files[entryNumber].pointer,
+ _files[entryNumber].pointer + _files[entryNumber].length);
+
+ ErrorNumber errno;
+
+ if(_compressed)
+ {
+ if(_files[entryNumber].originalLength == 0)
+ stream = new MemoryStream([]);
+ else
+ {
+ stream = new ForcedSeekStream(_files[entryNumber].originalLength,
+ stream,
+ CompressionMode.Decompress);
+ }
+ }
+
+ filter = new ZZZNoFilter();
+ errno = filter.Open(stream);
+
+ if(errno == ErrorNumber.NoError) return ErrorNumber.NoError;
+
+ stream.Close();
+
+ return errno;
+ }
+
+#endregion
+}
\ No newline at end of file
diff --git a/Aaru.Archives/Symbian/Info.cs b/Aaru.Archives/Symbian/Info.cs
new file mode 100644
index 000000000..0c26390f6
--- /dev/null
+++ b/Aaru.Archives/Symbian/Info.cs
@@ -0,0 +1,390 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Symbian.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Symbian plugin.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Identifies Symbian installer (.sis) packages and shows information.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using Aaru.CommonTypes.Interfaces;
+using Aaru.Console;
+using Aaru.Helpers;
+using Marshal = Aaru.Helpers.Marshal;
+
+namespace Aaru.Archives;
+
+public sealed partial class Symbian
+{
+#region IArchive Members
+
+ ///
+ public bool Identify(IFilter filter)
+ {
+ if(filter.DataForkLength < Marshal.SizeOf()) return false;
+
+ Stream stream = filter.GetDataForkStream();
+
+ var hdr = new byte[Marshal.SizeOf()];
+
+ stream.EnsureRead(hdr, 0, hdr.Length);
+
+ SymbianHeader header = Marshal.ByteArrayToStructureLittleEndian(hdr);
+
+ if(header.uid1 == SYMBIAN9_MAGIC) return true;
+
+ if(header.uid3 != SYMBIAN_MAGIC) return false;
+
+ return header.uid2 is EPOC_MAGIC or EPOC6_MAGIC;
+ }
+
+ public void GetInformation(IFilter filter, Encoding encoding, out string information)
+ {
+ information = "";
+ var description = new StringBuilder();
+ var languages = new List();
+ var capabilities = new Dictionary();
+ Stream stream = filter.GetDataForkStream();
+
+ if(stream.Length < Marshal.SizeOf()) return;
+
+ var buffer = new byte[Marshal.SizeOf()];
+
+ stream.Seek(0, SeekOrigin.Begin);
+ stream.EnsureRead(buffer, 0, buffer.Length);
+ SymbianHeader sh = Marshal.ByteArrayToStructureLittleEndian(buffer);
+
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.uid1 = {0}", sh.uid1);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.uid2 = {0}", sh.uid2);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.uid3 = {0}", sh.uid3);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.uid4 = {0}", sh.uid4);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.crc16 = {0}", sh.crc16);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.languages = {0}", sh.languages);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.files = {0}", sh.files);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.requisites = {0}", sh.requisites);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.inst_lang = {0}", sh.inst_lang);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.inst_files = {0}", sh.inst_files);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.inst_drive = {0}", sh.inst_drive);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.capabilities = {0}", sh.capabilities);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.inst_version = {0}", sh.inst_version);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.options = {0}", sh.options);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.type = {0}", sh.type);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.major = {0}", sh.major);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.minor = {0}", sh.minor);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.variant = {0}", sh.variant);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.lang_ptr = {0}", sh.lang_ptr);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.files_ptr = {0}", sh.files_ptr);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.reqs_ptr = {0}", sh.reqs_ptr);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.certs_ptr = {0}", sh.certs_ptr);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.comp_ptr = {0}", sh.comp_ptr);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.sig_ptr = {0}", sh.sig_ptr);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.caps_ptr = {0}", sh.caps_ptr);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.instspace = {0}", sh.instspace);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.maxinsspc = {0}", sh.maxinsspc);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.reserved1 = {0}", sh.reserved1);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.reserved2 = {0}", sh.reserved2);
+
+ _release6 = false;
+
+ if(sh.uid1 == SYMBIAN9_MAGIC)
+ {
+ description.AppendLine(Localization.Symbian_Installation_File);
+ description.AppendLine(Localization.Symbian_9_1_or_later);
+ description.AppendFormat(Localization.Application_ID_0, sh.uid3).AppendLine();
+ _release6 = true;
+
+ description.AppendLine();
+ description.AppendLine("This file format is not yet implemented, no more information can be decoded.");
+
+ information = description.ToString();
+
+ return;
+ }
+
+ if(sh.uid3 == SYMBIAN_MAGIC)
+ {
+ description.AppendLine(Localization.Symbian_Installation_File);
+
+ switch(sh.uid2)
+ {
+ case EPOC_MAGIC:
+ description.AppendLine(Localization.Symbian_3_or_later);
+
+ break;
+ case EPOC6_MAGIC:
+ description.AppendLine(Localization.Symbian_6_or_later);
+ _release6 = true;
+
+ break;
+ default:
+ description.AppendFormat(Localization.Unknown_EPOC_magic_0, sh.uid2).AppendLine();
+
+ break;
+ }
+
+ description.AppendFormat(Localization.Application_ID_0, sh.uid1).AppendLine();
+ }
+
+ if(sh.options.HasFlag(SymbianOptions.IsUnicode))
+ _encoding = Encoding.Unicode;
+ else
+ _encoding = encoding ?? Encoding.GetEncoding("windows-1252");
+
+ var br = new BinaryReader(stream);
+
+ // Go to enumerate languages
+ br.BaseStream.Seek(sh.lang_ptr, SeekOrigin.Begin);
+ for(var i = 0; i < sh.languages; i++) languages.Add(((LanguageCodes)br.ReadUInt16()).ToString("G"));
+
+ // Go to component record
+ br.BaseStream.Seek(sh.comp_ptr, SeekOrigin.Begin);
+
+ var componentRecord = new ComponentRecord
+ {
+ names = new string[languages.Count]
+ };
+
+ buffer = new byte[sizeof(uint) * languages.Count];
+
+ // Read the component string lenghts
+ stream.EnsureRead(buffer, 0, buffer.Length);
+ ReadOnlySpan span = buffer;
+ componentRecord.namesLengths = MemoryMarshal.Cast(span)[..languages.Count].ToArray();
+
+ // Read the component string pointers
+ stream.EnsureRead(buffer, 0, buffer.Length);
+ span = buffer;
+ componentRecord.namesPointers = MemoryMarshal.Cast(span)[..languages.Count].ToArray();
+
+ for(var i = 0; i < sh.languages; i++)
+ {
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ "Found component name for language {0} at {1} with a length of {2} bytes",
+ languages[i],
+ componentRecord.namesPointers[i],
+ componentRecord.namesLengths[i]);
+
+ br.BaseStream.Seek(componentRecord.namesPointers[i], SeekOrigin.Begin);
+ buffer = br.ReadBytes((int)componentRecord.namesLengths[i]);
+ componentRecord.names[i] = _encoding.GetString(buffer);
+ }
+
+ // Go to capabilities (???)
+ br.BaseStream.Seek(sh.caps_ptr, SeekOrigin.Begin);
+
+ for(var i = 0; i < sh.capabilities; i++)
+ {
+ uint cap_Key = br.ReadUInt32();
+ uint cap_Value = br.ReadUInt32();
+ capabilities.Add(cap_Key, cap_Value);
+ }
+
+ description.AppendFormat(Localization.UIDs_checksum_0, sh.uid4).AppendLine();
+ description.AppendFormat(Localization.Archive_options_0, sh.options).AppendLine();
+ description.AppendFormat(Localization.CRC16_of_header_0, sh.crc16).AppendLine();
+ description.AppendLine();
+
+ switch(sh.type)
+ {
+ case SymbianType.Application:
+ description.AppendLine(Localization.SIS_contains_an_application);
+
+ break;
+ }
+
+ description.AppendFormat(Localization.Component_version_0_1, sh.major, sh.minor).AppendLine();
+
+ description.AppendLine();
+
+ description.AppendFormat(Localization.File_contains_0_languages, sh.languages).AppendLine();
+
+ for(var i = 0; i < languages.Count; i++)
+ {
+ if(i > 0) description.Append(", ");
+ description.Append($"{languages[i]}");
+ }
+
+ description.AppendLine();
+ description.AppendLine();
+
+ for(var i = 0; i < languages.Count; i++)
+ {
+ description.AppendFormat(Localization.Component_name_for_language_with_code_0_1,
+ languages[i],
+ componentRecord.names[i])
+ .AppendLine();
+ }
+
+ description.AppendLine();
+
+ description.AppendFormat(Localization.File_contains_0_files_pointer_1, sh.files, sh.files_ptr).AppendLine();
+ description.AppendFormat(Localization.File_contains_0_requisites, sh.requisites).AppendLine();
+
+ uint offset = sh.reqs_ptr;
+
+ if(sh.requisites > 0)
+ {
+ for(var r = 0; r < sh.requisites; r++)
+ {
+ br.BaseStream.Seek(offset, SeekOrigin.Begin);
+
+ var requisiteRecord = new RequisiteRecord
+ {
+ uid = br.ReadUInt32(),
+ majorVersion = br.ReadUInt16(),
+ minorVersion = br.ReadUInt16(),
+ variant = br.ReadUInt32()
+ };
+
+ buffer = br.ReadBytes(sizeof(uint) * languages.Count);
+ span = buffer;
+ requisiteRecord.namesLengths = MemoryMarshal.Cast(span)[..languages.Count].ToArray();
+
+ buffer = br.ReadBytes(sizeof(uint) * languages.Count);
+ span = buffer;
+ requisiteRecord.namesPointers = MemoryMarshal.Cast(span)[..languages.Count].ToArray();
+
+ description.AppendFormat(Localization.Requisite_0, r).AppendLine();
+
+ description.AppendFormat("\t" + Localization.Required_UID_0_version_1_2,
+ DecodePlatformUid(requisiteRecord.uid),
+ requisiteRecord.majorVersion,
+ requisiteRecord.minorVersion)
+ .AppendLine();
+
+ description.AppendFormat("\t" + Localization.Required_variant_0, requisiteRecord.variant).AppendLine();
+
+ offset = (uint)br.BaseStream.Position;
+
+ for(var i = 0; i < languages.Count; i++)
+ {
+ br.BaseStream.Seek(requisiteRecord.namesPointers[i], SeekOrigin.Begin);
+ buffer = br.ReadBytes((int)requisiteRecord.namesLengths[i]);
+
+ description.AppendFormat("\t" + Localization.Requisite_for_language_0_1,
+ languages[i],
+ _encoding.GetString(buffer))
+ .AppendLine();
+ }
+
+ description.AppendLine();
+ }
+ }
+
+// description.AppendLine(Localization.Capabilities);
+// foreach(KeyValuePair kvp in capabilities)
+// description.AppendFormat("{0} = {1}", kvp.Key, kvp.Value).AppendLine();
+
+ // Set instance values
+ _files = [];
+ _conditions = [];
+
+ uint currentFile = 0;
+ offset = sh.files_ptr;
+ var conditionLevel = 0;
+ _options = [];
+
+ // Get only the options records
+ do
+ {
+ Parse(br, ref offset, ref currentFile, sh.files, languages, ref conditionLevel, true);
+ } while(currentFile < sh.files);
+
+ // Get all other records
+ offset = sh.files_ptr;
+ currentFile = 0;
+ conditionLevel = 0;
+
+ do
+ {
+ Parse(br, ref offset, ref currentFile, sh.files, languages, ref conditionLevel, false);
+ } while(currentFile < sh.files);
+
+ description.AppendLine();
+
+ // Files appear on .sis in the reverse order they should be processed
+ _files.Reverse();
+
+ // Conditions do as well
+ _conditions.Reverse();
+
+ if(_files.Any(t => t.language is null))
+ {
+ description.AppendLine(Localization.Files_for_all_languages);
+
+ foreach(DecodedFileRecord file in _files.Where(t => t.language is null))
+ description.AppendLine($"{file.destinationName}");
+
+ description.AppendLine();
+ }
+
+ foreach(string lang in languages)
+ {
+ if(_files.All(t => t.language != lang)) continue;
+
+ description.AppendFormat(Localization.Files_for_0_language, lang).AppendLine();
+
+ foreach(DecodedFileRecord file in _files.Where(t => t.language == lang))
+ description.AppendLine($"{file.destinationName}");
+
+ description.AppendLine();
+ }
+
+ if(_options.Count > 0)
+ {
+ for(var i = 0; i < _options.Count; i++)
+ {
+ OptionRecord option = _options[i];
+
+ description.AppendFormat(Localization.Option_0, i + 1).AppendLine();
+
+ foreach(KeyValuePair kvp in option.names)
+ {
+ description.AppendFormat("\t" + Localization.Name_for_language_0_1, kvp.Key, kvp.Value)
+ .AppendLine();
+ }
+ }
+
+ description.AppendLine();
+ }
+
+ if(_conditions.Count > 0)
+ {
+ description.AppendLine("Conditions:");
+ foreach(string condition in _conditions) description.AppendLine(condition);
+ }
+
+ information = description.ToString();
+ }
+
+#endregion
+}
\ No newline at end of file
diff --git a/Aaru.Archives/Symbian/Open.cs b/Aaru.Archives/Symbian/Open.cs
new file mode 100644
index 000000000..a556c4215
--- /dev/null
+++ b/Aaru.Archives/Symbian/Open.cs
@@ -0,0 +1,201 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Symbian.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Symbian plugin.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Identifies Symbian installer (.sis) packages and shows information.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Aaru.CommonTypes.Enums;
+using Aaru.CommonTypes.Interfaces;
+using Aaru.Console;
+using Aaru.Helpers;
+
+namespace Aaru.Archives;
+
+public sealed partial class Symbian
+{
+#region IArchive Members
+
+ ///
+ public ErrorNumber Open(IFilter filter, Encoding encoding)
+ {
+ // Already opened!
+ if(Opened) return ErrorNumber.InvalidArgument;
+
+ var languages = new List();
+ _stream = filter.GetDataForkStream();
+
+ if(_stream.Length < Marshal.SizeOf()) return ErrorNumber.InvalidArgument;
+
+ var buffer = new byte[Marshal.SizeOf()];
+
+ _stream.Seek(0, SeekOrigin.Begin);
+ _stream.EnsureRead(buffer, 0, buffer.Length);
+ SymbianHeader sh = Marshal.ByteArrayToStructureLittleEndian(buffer);
+
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.uid1 = {0}", sh.uid1);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.uid2 = {0}", sh.uid2);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.uid3 = {0}", sh.uid3);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.uid4 = {0}", sh.uid4);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.crc16 = {0}", sh.crc16);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.languages = {0}", sh.languages);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.files = {0}", sh.files);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.requisites = {0}", sh.requisites);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.inst_lang = {0}", sh.inst_lang);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.inst_files = {0}", sh.inst_files);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.inst_drive = {0}", sh.inst_drive);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.capabilities = {0}", sh.capabilities);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.inst_version = {0}", sh.inst_version);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.options = {0}", sh.options);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.type = {0}", sh.type);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.major = {0}", sh.major);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.minor = {0}", sh.minor);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.variant = {0}", sh.variant);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.lang_ptr = {0}", sh.lang_ptr);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.files_ptr = {0}", sh.files_ptr);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.reqs_ptr = {0}", sh.reqs_ptr);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.certs_ptr = {0}", sh.certs_ptr);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.comp_ptr = {0}", sh.comp_ptr);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.sig_ptr = {0}", sh.sig_ptr);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.caps_ptr = {0}", sh.caps_ptr);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.instspace = {0}", sh.instspace);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.maxinsspc = {0}", sh.maxinsspc);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.reserved1 = {0}", sh.reserved1);
+ AaruConsole.DebugWriteLine(MODULE_NAME, "sh.reserved2 = {0}", sh.reserved2);
+
+ _release6 = false;
+
+ if(sh.uid1 == SYMBIAN9_MAGIC)
+ {
+ AaruConsole.ErrorWriteLine("Symbian Installation Files from Symbian OS 9 or later are not yet supported.");
+
+ return ErrorNumber.NotSupported;
+ }
+
+ if(sh.uid3 == SYMBIAN_MAGIC)
+ {
+ switch(sh.uid2)
+ {
+ case EPOC_MAGIC:
+ break;
+ case EPOC6_MAGIC:
+ _release6 = true;
+
+ break;
+ }
+ }
+
+ if(sh.options.HasFlag(SymbianOptions.IsUnicode))
+ _encoding = Encoding.Unicode;
+ else
+ _encoding = encoding ?? Encoding.GetEncoding("windows-1252");
+
+ var br = new BinaryReader(_stream);
+
+ // Go to enumerate languages
+ br.BaseStream.Seek(sh.lang_ptr, SeekOrigin.Begin);
+ for(var i = 0; i < sh.languages; i++) languages.Add(((LanguageCodes)br.ReadUInt16()).ToString("G"));
+
+ _files = [];
+ _conditions = [];
+ _options = [];
+
+ uint currentFile = 0;
+ uint offset = sh.files_ptr;
+ var conditionLevel = 0;
+
+ // Get only the options records
+ do
+ {
+ Parse(br, ref offset, ref currentFile, sh.files, languages, ref conditionLevel, true);
+ } while(currentFile < sh.files);
+
+ // Get all other records
+ offset = sh.files_ptr;
+ currentFile = 0;
+ conditionLevel = 0;
+
+ do
+ {
+ Parse(br, ref offset, ref currentFile, sh.files, languages, ref conditionLevel, false);
+ } while(currentFile < sh.files);
+
+ // Files appear on .sis in the reverse order they should be processed
+ _files.Reverse();
+
+ List filesWithFixedFilenames = [];
+
+ foreach(DecodedFileRecord f in _files)
+ {
+ DecodedFileRecord file = f;
+
+ if(file.destinationName.Length > 3 && file.destinationName[1] == ':' && file.destinationName[2] == '\\')
+ file.destinationName = file.destinationName[3..];
+
+ file.destinationName = file.destinationName.Replace('\\', '/');
+
+ if(file.language != null) file.destinationName = $"{file.language}/{file.destinationName}";
+
+ filesWithFixedFilenames.Add(file);
+ }
+
+ _files = filesWithFixedFilenames;
+
+ _features = ArchiveSupportedFeature.SupportsFilenames | ArchiveSupportedFeature.SupportsSubdirectories;
+
+ if(_release6 && !sh.options.HasFlag(SymbianOptions.NoCompress))
+ {
+ _features |= ArchiveSupportedFeature.SupportsCompression;
+ _compressed = true;
+ }
+
+ if(_files.Any(t => t.mime is not null)) _features |= ArchiveSupportedFeature.SupportsXAttrs;
+
+ Opened = true;
+
+ return ErrorNumber.NoError;
+ }
+
+ ///
+ public void Close()
+ {
+ // Already closed
+ if(!Opened) return;
+
+ _stream?.Close();
+
+ _stream = null;
+ Opened = false;
+ }
+
+#endregion
+}
\ No newline at end of file
diff --git a/Aaru.Archives/Symbian/Parser.cs b/Aaru.Archives/Symbian/Parser.cs
new file mode 100644
index 000000000..0d6af29ef
--- /dev/null
+++ b/Aaru.Archives/Symbian/Parser.cs
@@ -0,0 +1,608 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Symbian.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Symbian plugin.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Identifies Symbian installer (.sis) packages and shows information.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+using Aaru.Console;
+using Marshal = Aaru.Helpers.Marshal;
+
+namespace Aaru.Archives;
+
+[SuppressMessage("ReSharper", "UnusedMember.Local")]
+public sealed partial class Symbian
+{
+ void Parse(BinaryReader br, ref uint offset, ref uint currentFile, uint maxFiles, List languages,
+ ref int conditionLevel, bool optionsOnly)
+ {
+ currentFile++;
+
+ if(currentFile > maxFiles) return;
+
+ var tabulationChars = new char[conditionLevel];
+ for(var i = 0; i < conditionLevel; i++) tabulationChars[i] = '\t';
+ string tabulation = new(tabulationChars);
+
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ "Seeking to {0} for parsing of file {1} of {2}",
+ offset,
+ currentFile,
+ maxFiles);
+
+ br.BaseStream.Seek(offset, SeekOrigin.Begin);
+ var recordType = (FileRecordType)br.ReadUInt32();
+
+ AaruConsole.DebugWriteLine(MODULE_NAME, "Found record with type {0}", recordType);
+
+ br.BaseStream.Seek(-sizeof(FileRecordType), SeekOrigin.Current);
+
+ byte[] buffer;
+ ConditionalRecord conditionalRecord;
+
+ StringBuilder conditionSb;
+ Attribute? nullAttribute;
+
+ switch(recordType)
+ {
+ case FileRecordType.SimpleFile:
+ buffer = br.ReadBytes(Marshal.SizeOf());
+ SimpleFileRecord simpleFileRecord = Marshal.ByteArrayToStructureLittleEndian(buffer);
+
+ offset = (uint)br.BaseStream.Position;
+
+ // Remove the 3 fields that exist only on >= ER6
+ if(!_release6) offset -= sizeof(uint) * 3;
+
+ if(optionsOnly) break;
+
+ var decodedFileRecord = new DecodedFileRecord
+ {
+ type = simpleFileRecord.record.type,
+ details = simpleFileRecord.record.details,
+ length = simpleFileRecord.length,
+ pointer = simpleFileRecord.pointer
+ };
+
+ br.BaseStream.Seek(simpleFileRecord.record.sourceNamePtr, SeekOrigin.Begin);
+ buffer = br.ReadBytes((int)simpleFileRecord.record.sourceNameLen);
+ decodedFileRecord.sourceName = _encoding.GetString(buffer);
+
+ // Files that are not written to disk but shown or installed components do not have a destination name.
+ if(simpleFileRecord.record.destinationNameLen > 0)
+ {
+ br.BaseStream.Seek(simpleFileRecord.record.destinationNamePtr, SeekOrigin.Begin);
+ buffer = br.ReadBytes((int)simpleFileRecord.record.destinationNameLen);
+ decodedFileRecord.destinationName = _encoding.GetString(buffer);
+ }
+ else
+ decodedFileRecord.destinationName = decodedFileRecord.sourceName;
+
+ if(_release6)
+ {
+ decodedFileRecord.originalLength = simpleFileRecord.originalLength;
+
+ br.BaseStream.Seek(simpleFileRecord.mimePtr, SeekOrigin.Begin);
+ buffer = br.ReadBytes((int)simpleFileRecord.mimeLen);
+ decodedFileRecord.mime = _encoding.GetString(buffer);
+ }
+
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ "Found file for \"{0}\" with length {1} at {2}",
+ decodedFileRecord.destinationName,
+ decodedFileRecord.length,
+ decodedFileRecord.pointer);
+
+ _files.Add(decodedFileRecord);
+
+ if(conditionLevel > 0)
+ {
+ bool wait, close;
+
+ switch(decodedFileRecord.type)
+ {
+ case FileType.File:
+ _conditions.Add(tabulation + $"InstallFileTo(\"{decodedFileRecord.destinationName}\")");
+
+ break;
+ case FileType.FileText:
+ switch((FileDetails)((uint)decodedFileRecord.details & 0xFF))
+ {
+ case FileDetails.TextContinue:
+ _conditions.Add(tabulation +
+ $"ShowText(\"{decodedFileRecord.sourceName}\", BUTTONS_CONTINUE, ACTION_CONTINUE)");
+
+ break;
+ case FileDetails.TextSkip:
+ _conditions.Add(tabulation +
+ $"ShowText(\"{decodedFileRecord.sourceName}\", BUTTONS_YES_NO, ACTION_SKIP)");
+
+ break;
+ case FileDetails.TextAbort:
+ _conditions.Add(tabulation +
+ $"ShowText(\"{decodedFileRecord.sourceName}\", BUTTONS_YES_NO, ACTION_ABORT)");
+
+ break;
+ case FileDetails.TextExit:
+ _conditions.Add(tabulation +
+ $"ShowText(\"{decodedFileRecord.sourceName}\", BUTTONS_YES_NO, ACTION_EXIT)");
+
+ break;
+ }
+
+ break;
+ case FileType.FileRun:
+ // ReSharper disable BitwiseOperatorOnEnumWithoutFlags
+ wait = (decodedFileRecord.details & FileDetails.RunWait) != 0;
+ close = (decodedFileRecord.details & FileDetails.RunsEnd) != 0;
+
+ // ReSharper restore BitwiseOperatorOnEnumWithoutFlags
+
+ switch((FileDetails)((uint)decodedFileRecord.details & 0xFF))
+ {
+ case FileDetails.RunInstall:
+ if(wait && close)
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecord.sourceName}\", ON_INSTALL, WAIT | CLOSE)");
+ }
+ else if(close)
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecord.sourceName}\", ON_INSTALL, CLOSE)");
+ }
+ else if(wait)
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecord.sourceName}\", ON_INSTALL, WAIT)");
+ }
+ else
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecord.sourceName}\", ON_INSTALL, 0)");
+ }
+
+ break;
+ case FileDetails.RunRemove:
+ if(wait && close)
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecord.sourceName}\", ON_REMOVE, WAIT | CLOSE)");
+ }
+ else if(close)
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecord.sourceName}\", ON_REMOVE, CLOSE)");
+ }
+ else if(wait)
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecord.sourceName}\", ON_REMOVE, WAIT)");
+ }
+ else
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecord.sourceName}\", ON_REMOVE, 0)");
+ }
+
+ break;
+ case FileDetails.RunBoth:
+ if(wait && close)
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecord.sourceName}\", ON_INSTALL | ON_REMOVE, WAIT | CLOSE)");
+ }
+ else if(close)
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecord.sourceName}\", ON_INSTALL | ON_REMOVE, CLOSE)");
+ }
+ else if(wait)
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecord.sourceName}\", ON_INSTALL | ON_REMOVE, WAIT)");
+ }
+ else
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecord.sourceName}\", ON_INSTALL | ON_REMOVE, 0)");
+ }
+
+ break;
+ }
+
+ break;
+ case FileType.FileMime:
+ // ReSharper disable BitwiseOperatorOnEnumWithoutFlags
+ wait = (decodedFileRecord.details & FileDetails.RunWait) != 0;
+ close = (decodedFileRecord.details & FileDetails.RunsEnd) != 0;
+
+ // ReSharper restore BitwiseOperatorOnEnumWithoutFlags
+
+ if(wait && close)
+ _conditions.Add(tabulation + $"Open(\"{decodedFileRecord.sourceName}\", WAIT | CLOSE)");
+ else if(close)
+ _conditions.Add(tabulation + $"Open(\"{decodedFileRecord.sourceName}\", CLOSE)");
+ else if(wait)
+ _conditions.Add(tabulation + $"Open(\"{decodedFileRecord.sourceName}\", WAIT)");
+ else
+ _conditions.Add(tabulation + $"Open(\"{decodedFileRecord.sourceName}\", 0)");
+
+ break;
+ }
+ }
+
+ break;
+ case FileRecordType.MultipleLanguageFiles:
+ MultipleFileRecord multipleFileRecord = new();
+
+ // Read common file record fields
+ buffer = br.ReadBytes(Marshal.SizeOf());
+ multipleFileRecord.record = Marshal.ByteArrayToStructureLittleEndian(buffer);
+
+ buffer = br.ReadBytes(sizeof(uint) * languages.Count);
+ ReadOnlySpan span = buffer;
+ multipleFileRecord.lengths = MemoryMarshal.Cast(span)[..languages.Count].ToArray();
+
+ buffer = br.ReadBytes(sizeof(uint) * languages.Count);
+ span = buffer;
+ multipleFileRecord.pointers = MemoryMarshal.Cast(span)[..languages.Count].ToArray();
+
+ if(_release6)
+ {
+ buffer = br.ReadBytes(sizeof(uint) * languages.Count);
+ span = buffer;
+
+ multipleFileRecord.originalLengths =
+ MemoryMarshal.Cast(span)[..languages.Count].ToArray();
+
+ multipleFileRecord.mimeLen = br.ReadUInt32();
+ multipleFileRecord.mimePtr = br.ReadUInt32();
+ }
+ else
+ multipleFileRecord.originalLengths = multipleFileRecord.lengths;
+
+ offset = (uint)br.BaseStream.Position;
+
+ if(optionsOnly) break;
+
+ br.BaseStream.Seek(multipleFileRecord.record.sourceNamePtr, SeekOrigin.Begin);
+ buffer = br.ReadBytes((int)multipleFileRecord.record.sourceNameLen);
+ string sourceName = _encoding.GetString(buffer);
+ string destinationName;
+
+ // Files that are not written to disk but shown or installed components do not have a destination name.
+ if(multipleFileRecord.record.destinationNameLen > 0)
+ {
+ br.BaseStream.Seek(multipleFileRecord.record.destinationNamePtr, SeekOrigin.Begin);
+ buffer = br.ReadBytes((int)multipleFileRecord.record.destinationNameLen);
+ destinationName = _encoding.GetString(buffer);
+ }
+ else
+ destinationName = sourceName;
+
+ string mimeType = null;
+
+ if(_release6)
+ {
+ br.BaseStream.Seek(multipleFileRecord.mimePtr, SeekOrigin.Begin);
+ buffer = br.ReadBytes((int)multipleFileRecord.mimeLen);
+ mimeType = _encoding.GetString(buffer);
+ }
+
+ var decodedFileRecords = new DecodedFileRecord[languages.Count];
+
+ for(var i = 0; i < languages.Count; i++)
+ {
+ decodedFileRecords[i].type = multipleFileRecord.record.type;
+ decodedFileRecords[i].details = multipleFileRecord.record.details;
+ decodedFileRecords[i].sourceName = sourceName;
+ decodedFileRecords[i].destinationName = destinationName;
+ decodedFileRecords[i].length = multipleFileRecord.lengths[i];
+ decodedFileRecords[i].pointer = multipleFileRecord.pointers[i];
+ decodedFileRecords[i].originalLength = multipleFileRecord.originalLengths[i];
+ decodedFileRecords[i].mime = mimeType;
+ decodedFileRecords[i].language = languages[i];
+ }
+
+ _files.AddRange(decodedFileRecords);
+
+ if(conditionLevel > 0)
+ {
+ bool wait, close;
+
+ switch(decodedFileRecords[0].type)
+ {
+ case FileType.File:
+ _conditions.Add(tabulation + $"InstallFileTo(\"{decodedFileRecords[0].destinationName}\")");
+
+ break;
+ case FileType.FileText:
+ switch((FileDetails)((uint)decodedFileRecords[0].details & 0xFF))
+ {
+ case FileDetails.TextContinue:
+ _conditions.Add(tabulation +
+ $"ShowText(\"{decodedFileRecords[0].sourceName}\", BUTTONS_CONTINUE, ACTION_CONTINUE)");
+
+ break;
+ case FileDetails.TextSkip:
+ _conditions.Add(tabulation +
+ $"ShowText(\"{decodedFileRecords[0].sourceName}\", BUTTONS_YES_NO, ACTION_SKIP)");
+
+ break;
+ case FileDetails.TextAbort:
+ _conditions.Add(tabulation +
+ $"ShowText(\"{decodedFileRecords[0].sourceName}\", BUTTONS_YES_NO, ACTION_ABORT)");
+
+ break;
+ case FileDetails.TextExit:
+ _conditions.Add(tabulation +
+ $"ShowText(\"{decodedFileRecords[0].sourceName}\", BUTTONS_YES_NO, ACTION_EXIT)");
+
+ break;
+ }
+
+ break;
+ case FileType.FileRun:
+ // ReSharper disable BitwiseOperatorOnEnumWithoutFlags
+ wait = (decodedFileRecords[0].details & FileDetails.RunWait) != 0;
+ close = (decodedFileRecords[0].details & FileDetails.RunsEnd) != 0;
+
+ // ReSharper restore BitwiseOperatorOnEnumWithoutFlags
+
+ switch((FileDetails)((uint)decodedFileRecords[0].details & 0xFF))
+ {
+ case FileDetails.RunInstall:
+ if(wait && close)
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecords[0].sourceName}\", ON_INSTALL, WAIT | CLOSE)");
+ }
+ else if(close)
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecords[0].sourceName}\", ON_INSTALL, CLOSE)");
+ }
+ else if(wait)
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecords[0].sourceName}\", ON_INSTALL, WAIT)");
+ }
+ else
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecords[0].sourceName}\", ON_INSTALL, 0)");
+ }
+
+ break;
+ case FileDetails.RunRemove:
+ if(wait && close)
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecords[0].sourceName}\", ON_REMOVE, WAIT | CLOSE)");
+ }
+ else if(close)
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecords[0].sourceName}\", ON_REMOVE, CLOSE)");
+ }
+ else if(wait)
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecords[0].sourceName}\", ON_REMOVE, WAIT)");
+ }
+ else
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecords[0].sourceName}\", ON_REMOVE, 0)");
+ }
+
+ break;
+ case FileDetails.RunBoth:
+ if(wait && close)
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecords[0].sourceName}\", ON_INSTALL | ON_REMOVE, WAIT | CLOSE)");
+ }
+ else if(close)
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecords[0].sourceName}\", ON_INSTALL | ON_REMOVE, CLOSE)");
+ }
+ else if(wait)
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecords[0].sourceName}\", ON_INSTALL | ON_REMOVE, WAIT)");
+ }
+ else
+ {
+ _conditions.Add(tabulation +
+ $"Run(\"{decodedFileRecords[0].sourceName}\", ON_INSTALL | ON_REMOVE, 0)");
+ }
+
+ break;
+ }
+
+ break;
+ case FileType.FileMime:
+ // ReSharper disable BitwiseOperatorOnEnumWithoutFlags
+ wait = (decodedFileRecords[0].details & FileDetails.RunWait) != 0;
+ close = (decodedFileRecords[0].details & FileDetails.RunsEnd) != 0;
+
+ // ReSharper restore BitwiseOperatorOnEnumWithoutFlags
+
+ if(wait && close)
+ {
+ _conditions.Add(tabulation +
+ $"Open(\"{decodedFileRecords[0].sourceName}\", WAIT | CLOSE)");
+ }
+ else if(close)
+ _conditions.Add(tabulation + $"Open(\"{decodedFileRecords[0].sourceName}\", CLOSE)");
+ else if(wait)
+ _conditions.Add(tabulation + $"Open(\"{decodedFileRecords[0].sourceName}\", WAIT)");
+ else
+ _conditions.Add(tabulation + $"Open(\"{decodedFileRecords[0].sourceName}\", 0)");
+
+ break;
+ }
+ }
+
+ break;
+ case FileRecordType.Options:
+ OptionsLineRecord optionsLineRecord = new()
+ {
+ recordType = (FileRecordType)br.ReadUInt32(),
+ numberOfOptions = br.ReadUInt32()
+ };
+
+ optionsLineRecord.options = new OptionRecord[(int)optionsLineRecord.numberOfOptions];
+
+ for(var i = 0; i < optionsLineRecord.numberOfOptions; i++)
+ {
+ optionsLineRecord.options[i] = new OptionRecord();
+
+ buffer = br.ReadBytes(sizeof(uint) * languages.Count);
+ span = buffer;
+
+ optionsLineRecord.options[i].lengths =
+ MemoryMarshal.Cast(span)[..languages.Count].ToArray();
+
+ buffer = br.ReadBytes(sizeof(uint) * languages.Count);
+ span = buffer;
+
+ optionsLineRecord.options[i].pointers =
+ MemoryMarshal.Cast(span)[..languages.Count].ToArray();
+
+ optionsLineRecord.options[i].names = new Dictionary();
+
+ offset = (uint)br.BaseStream.Position;
+
+ for(var j = 0; j < languages.Count; j++)
+ {
+ br.BaseStream.Seek(optionsLineRecord.options[i].pointers[j], SeekOrigin.Begin);
+ buffer = br.ReadBytes((int)optionsLineRecord.options[i].lengths[j]);
+ optionsLineRecord.options[i].names.Add(languages[j], _encoding.GetString(buffer));
+ }
+
+ br.BaseStream.Seek(offset, SeekOrigin.Begin);
+
+ if(optionsOnly) _options.Add(optionsLineRecord.options[i]);
+ }
+
+ offset = (uint)br.BaseStream.Position;
+
+ break;
+ case FileRecordType.If:
+ conditionLevel--;
+
+ tabulationChars = new char[conditionLevel];
+ for(var i = 0; i < conditionLevel; i++) tabulationChars[i] = '\t';
+ tabulation = new string(tabulationChars);
+
+ conditionalRecord = new ConditionalRecord
+ {
+ recordType = (FileRecordType)br.ReadUInt32(),
+ length = br.ReadUInt32()
+ };
+
+ offset = (uint)(br.BaseStream.Position + conditionalRecord.length);
+
+ if(optionsOnly) break;
+
+ conditionSb = new StringBuilder();
+ nullAttribute = null;
+
+ conditionSb.Append(tabulation + "if(");
+ ParseConditionalExpression(br, offset, conditionSb, ref nullAttribute);
+ conditionSb.Append(")");
+
+ _conditions.Add(conditionSb.ToString());
+
+ break;
+ case FileRecordType.ElseIf:
+ tabulationChars = new char[conditionLevel - 1];
+ for(var i = 0; i < conditionLevel - 1; i++) tabulationChars[i] = '\t';
+ tabulation = new string(tabulationChars);
+
+ conditionalRecord = new ConditionalRecord
+ {
+ recordType = (FileRecordType)br.ReadUInt32(),
+ length = br.ReadUInt32()
+ };
+
+ offset = (uint)(br.BaseStream.Position + conditionalRecord.length);
+
+ if(optionsOnly) break;
+
+ conditionSb = new StringBuilder();
+ nullAttribute = null;
+
+ conditionSb.Append(tabulation + "else if(");
+ ParseConditionalExpression(br, offset, conditionSb, ref nullAttribute);
+ conditionSb.Append(")");
+
+ _conditions.Add(conditionSb.ToString());
+
+ break;
+ case FileRecordType.Else:
+ tabulationChars = new char[conditionLevel - 1];
+ for(var i = 0; i < conditionLevel - 1; i++) tabulationChars[i] = '\t';
+ tabulation = new string(tabulationChars);
+
+ offset = (uint)(br.BaseStream.Position + Marshal.SizeOf());
+
+ if(optionsOnly) break;
+
+ _conditions.Add(tabulation + "else");
+
+ break;
+ case FileRecordType.EndIf:
+ conditionLevel++;
+ offset = (uint)(br.BaseStream.Position + Marshal.SizeOf());
+
+ if(optionsOnly) break;
+
+ _conditions.Add(tabulation + "endif()" + Environment.NewLine);
+
+ break;
+ case FileRecordType.Skip:
+ offset = (uint)br.BaseStream.Seek(sizeof(FileRecordType), SeekOrigin.Current);
+ currentFile--;
+
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Aaru.Archives/Symbian/Structs.cs b/Aaru.Archives/Symbian/Structs.cs
new file mode 100644
index 000000000..18d3b4b0c
--- /dev/null
+++ b/Aaru.Archives/Symbian/Structs.cs
@@ -0,0 +1,593 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Symbian.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Symbian plugin.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Identifies Symbian installer (.sis) packages and shows information.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.InteropServices;
+
+#pragma warning disable CS0169 // Field is never used
+
+#pragma warning disable CS0649 // Field is never assigned to, and will always have its default value
+
+namespace Aaru.Archives;
+
+[SuppressMessage("ReSharper", "UnusedType.Global")]
+[SuppressMessage("ReSharper", "UnusedType.Local")]
+[SuppressMessage("ReSharper", "InconsistentNaming")]
+[SuppressMessage("ReSharper", "InheritdocConsiderUsage")]
+[SuppressMessage("ReSharper", "NotAccessedField.Local")]
+[SuppressMessage("ReSharper", "ClassCanBeSealed.Local")]
+public sealed partial class Symbian
+{
+#region Nested type: AttributeConditionalExpression
+
+ ///
+ /// Contains an attribute to be used as a parameter in a conditional expression
+ ///
+ class AttributeConditionalExpression : ConditionalExpression
+ {
+ public Attribute attribute;
+ public uint unused;
+ }
+
+#endregion
+
+#region Nested type: BaseFileRecord
+
+ ///
+ /// Common fields to simple file record and multiple file record
+ ///
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ struct BaseFileRecord
+ {
+ ///
+ /// File record type, in this case or
+ ///
+ ///
+ public FileRecordType recordType;
+ ///
+ /// File type
+ ///
+ public FileType type;
+ ///
+ /// File details
+ ///
+ public FileDetails details;
+ ///
+ /// Length in bytes of the source name (filename on the machine that built the SIS)
+ ///
+ public uint sourceNameLen;
+ ///
+ /// Pointer to the source name
+ ///
+ public uint sourceNamePtr;
+ ///
+ /// Length in bytes of the destination name (filename+path it will be installed to. '!:' for drive means allow the user
+ /// to pick destination drive)
+ ///
+ public uint destinationNameLen;
+ ///
+ /// Pointer to the destination name
+ ///
+ public uint destinationNamePtr;
+ }
+
+#endregion
+
+#region Nested type: CapabilitiesRecord
+
+ ///
+ /// TODO: Unclear, check on real files
+ ///
+ struct CapabilitiesRecord
+ {
+ public uint[] keys;
+ public uint[] values;
+ }
+
+#endregion
+
+#region Nested type: CertificatesRecord
+
+ ///
+ /// Holds signature certifications, but the exact distribution of them is unclear
+ ///
+ struct CertificatesRecord
+ {
+ public ushort year;
+ public ushort month;
+ public ushort day;
+ public ushort hour;
+ public ushort minute;
+ public ushort second;
+ public uint numberOfCertificates;
+ }
+
+#endregion
+
+#region Nested type: ComponentRecord
+
+ ///
+ /// Component record as pointed by the header
+ ///
+ struct ComponentRecord
+ {
+ ///
+ /// Lengths of the component names, array sorted as language records
+ ///
+ public uint[] namesLengths;
+ ///
+ /// Pointers to the component names, array sorted as language records
+ ///
+ public uint[] namesPointers;
+ ///
+ /// Decoded names, not on-disk
+ ///
+ public string[] names;
+ }
+
+#endregion
+
+#region Nested type: ConditionalEndRecord
+
+ ///
+ /// Contains an 'else' or 'endif' expression
+ ///
+ struct ConditionalEndRecord
+ {
+ ///
+ /// File record type in this case or
+ ///
+ public FileRecordType recordType;
+ }
+
+#endregion
+
+#region Nested type: ConditionalExpression
+
+ ///
+ /// Conditional expression base
+ ///
+ class ConditionalExpression
+ {
+ ///
+ /// Conditional type
+ ///
+ public ConditionalType type;
+ }
+
+#endregion
+
+#region Nested type: ConditionalRecord
+
+ ///
+ /// Contains an 'if' or 'else if' condition
+ ///
+ struct ConditionalRecord
+ {
+ ///
+ /// File record type in this case or
+ ///
+ public FileRecordType recordType;
+ ///
+ /// Length in bytes of the record and all contained expressions
+ ///
+ public uint length;
+ ///
+ /// Conditional expression(s) (chain)
+ ///
+ public ConditionalExpression expression;
+ }
+
+#endregion
+
+#region Nested type: DecodedFileRecord
+
+ ///
+ /// On-memory structure
+ ///
+ struct DecodedFileRecord
+ {
+ ///
+ /// File type
+ ///
+ public FileType type;
+ ///
+ /// File details
+ ///
+ public FileDetails details;
+ ///
+ /// Source name (filename on the machine that built the SIS)
+ ///
+ public string sourceName;
+ ///
+ /// Destination name (filename+path it will be installed to. '!:' for drive means allow the user
+ /// to pick destination drive)
+ ///
+ public string destinationName;
+ ///
+ /// Length in bytes of the (compressed or uncompressed) file
+ ///
+ public uint length;
+ ///
+ /// Pointer to the (compressed or uncompressed) file data
+ ///
+ public uint pointer;
+ ///
+ /// EPOC Release >= 6, uncompressed file length
+ ///
+ public uint originalLength;
+ ///
+ /// EPOC Release >= 6, MIME type string
+ ///
+ public string mime;
+ ///
+ /// Language, or null for no language
+ ///
+ public string language;
+ }
+
+#endregion
+
+#region Nested type: MultipleFileRecord
+
+ ///
+ /// Multiple language file record, cannot be marshalled
+ ///
+ struct MultipleFileRecord
+ {
+ ///
+ /// Common fields to simple file record and multiple file record
+ ///
+ public BaseFileRecord record;
+ ///
+ /// Lengths in bytes of the (compressed or uncompressed) files, array sorted as language records
+ ///
+ public uint[] lengths;
+ ///
+ /// Pointers to the (compressed or uncompressed) files data, array sorted as language records
+ ///
+ public uint[] pointers;
+ ///
+ /// EPOC Release >= 6, uncompressed files lengths, array sorted as language records
+ ///
+ public uint[] originalLengths;
+ ///
+ /// EPOC Release >= 6, length in bytes of MIME type string
+ ///
+ public uint mimeLen;
+ ///
+ /// EPOC Release >= 6, pointer to MIME type string
+ ///
+ public uint mimePtr;
+ }
+
+#endregion
+
+#region Nested type: NumberConditionalExpression
+
+ ///
+ /// Contains a number to be used as a parameter in a conditional expression
+ ///
+ class NumberConditionalExpression : ConditionalExpression
+ {
+ public uint number;
+ public uint unused;
+ }
+
+#endregion
+
+#region Nested type: OptionRecord
+
+ struct OptionRecord
+ {
+ ///
+ /// Pointer to the option name lengths, array sorted as language records
+ ///
+ public uint[] lengths;
+ ///
+ /// Pointer to the option names, array sorted as language records
+ ///
+ public uint[] pointers;
+ public Dictionary names;
+ }
+
+#endregion
+
+#region Nested type: OptionsLineRecord
+
+ struct OptionsLineRecord
+ {
+ ///
+ /// File record type in this case
+ ///
+ public FileRecordType recordType;
+ ///
+ /// How many options follow
+ ///
+ public uint numberOfOptions;
+ ///
+ /// Option records
+ ///
+ public OptionRecord[] options;
+ ///
+ /// 128-bit bitmap of selected options
+ ///
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
+ public ulong[] selectedOptions;
+ }
+
+#endregion
+
+#region Nested type: RequisiteRecord
+
+ struct RequisiteRecord
+ {
+ ///
+ /// UID of the required component
+ ///
+ public uint uid;
+ ///
+ /// Major version of the required component
+ ///
+ public ushort majorVersion;
+ ///
+ /// Minor version of the required component
+ ///
+ public ushort minorVersion;
+ ///
+ /// Variant of the required component, usually set to 0 and not checked by installer
+ ///
+ public uint variant;
+ ///
+ /// Lengths of the requisite names, array sorted as language records
+ ///
+ public uint[] namesLengths;
+ ///
+ /// Pointers to the requisite names, array sorted as language records
+ ///
+ public uint[] namesPointers;
+ }
+
+#endregion
+
+#region Nested type: SimpleFileRecord
+
+ ///
+ /// Simple file record, can be marshalled
+ ///
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ struct SimpleFileRecord
+ {
+ ///
+ /// Common fields to simple file record and multiple file record
+ ///
+ public BaseFileRecord record;
+ ///
+ /// Length in bytes of the (compressed or uncompressed) file
+ ///
+ public uint length;
+ ///
+ /// Pointer to the (compressed or uncompressed) file data
+ ///
+ public uint pointer;
+ ///
+ /// EPOC Release >= 6, uncompressed file length
+ ///
+ public uint originalLength;
+ ///
+ /// EPOC Release >= 6, length in bytes of MIME type string
+ ///
+ public uint mimeLen;
+ ///
+ /// EPOC Release >= 6, pointer to MIME type string
+ ///
+ public uint mimePtr;
+ }
+
+#endregion
+
+#region Nested type: StringConditionalExpression
+
+ ///
+ /// Points to a string used as a parameter in a conditional expression
+ ///
+ class StringConditionalExpression : ConditionalExpression
+ {
+ public uint length;
+ public uint pointer;
+ public string @string;
+ }
+
+#endregion
+
+#region Nested type: SubConditionalExpression
+
+ ///
+ /// Conditional expression that contains a single sub-expression
+ ///
+ class SubConditionalExpression : ConditionalExpression
+ {
+ ///
+ /// Sub-expression
+ ///
+ public ConditionalExpression subExpression;
+ }
+
+#endregion
+
+#region Nested type: SymbianHeader
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ struct SymbianHeader
+ {
+ ///
+ /// Application UID before SymbianOS 9, magic after
+ ///
+ public uint uid1;
+ ///
+ /// EPOC release magic before SOS 9, NULLs after
+ ///
+ public uint uid2;
+ ///
+ /// Application UID after SOS 9, magic before
+ ///
+ public uint uid3;
+ ///
+ /// Checksum of UIDs 1 to 3
+ ///
+ public uint uid4;
+ ///
+ /// CRC16 of all header
+ ///
+ public ushort crc16;
+ ///
+ /// Number of languages
+ ///
+ public ushort languages;
+ ///
+ /// Number of files
+ ///
+ public ushort files;
+ ///
+ /// Number of requisites
+ ///
+ public ushort requisites;
+ ///
+ /// Installed language (only residual SIS)
+ ///
+ public ushort inst_lang;
+ ///
+ /// Installed files (only residual SIS)
+ ///
+ public ushort inst_files;
+ ///
+ /// Installed drive (only residual SIS), NULL or 0x0021
+ ///
+ public ushort inst_drive;
+ ///
+ /// Number of capabilities
+ ///
+ public ushort capabilities;
+ ///
+ /// Version of Symbian Installer required
+ ///
+ public uint inst_version;
+ ///
+ /// Option flags
+ ///
+ public SymbianOptions options;
+ ///
+ /// Type
+ ///
+ public SymbianType type;
+ ///
+ /// Major version of application
+ ///
+ public ushort major;
+ ///
+ /// Minor version of application
+ ///
+ public ushort minor;
+ ///
+ /// Variant when SIS is a prerequisite for other SISs
+ ///
+ public uint variant;
+ ///
+ /// Pointer to language records
+ ///
+ public uint lang_ptr;
+ ///
+ /// Pointer to file records
+ ///
+ public uint files_ptr;
+ ///
+ /// Pointer to requisite records
+ ///
+ public uint reqs_ptr;
+ ///
+ /// Pointer to certificate records
+ ///
+ public uint certs_ptr;
+ ///
+ /// Pointer to component name record
+ ///
+ public uint comp_ptr;
+
+ // From EPOC Release 6
+ ///
+ /// Pointer to signature record
+ ///
+ public uint sig_ptr;
+ ///
+ /// Pointer to capability records
+ ///
+ public uint caps_ptr;
+ ///
+ /// Installed space (only residual SIS)
+ ///
+ public uint instspace;
+ ///
+ /// Space required
+ ///
+ public uint maxinsspc;
+ ///
+ /// Reserved
+ ///
+ public ulong reserved1;
+ ///
+ /// Reserved
+ ///
+ public ulong reserved2;
+ }
+
+#endregion
+
+#region Nested type: TwoSubsConditionalExpression
+
+ ///
+ /// Conditional expression that contains two sub-expressions
+ ///
+ class TwoSubsConditionalExpression : ConditionalExpression
+ {
+ ///
+ /// Left hand side sub-expression
+ ///
+ public ConditionalExpression leftOperand;
+ ///
+ /// Right hand side sub-expression
+ ///
+ public ConditionalExpression rightOperand;
+ }
+
+#endregion
+}
\ No newline at end of file
diff --git a/Aaru.Archives/Symbian/Symbian.cs b/Aaru.Archives/Symbian/Symbian.cs
new file mode 100644
index 000000000..3c2daf801
--- /dev/null
+++ b/Aaru.Archives/Symbian/Symbian.cs
@@ -0,0 +1,73 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Symbian.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Symbian plugin.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Identifies Symbian installer (.sis) packages and shows information.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Aaru.CommonTypes.Interfaces;
+
+namespace Aaru.Archives;
+
+// Information from https://thoukydides.github.io/riscos-psifs/sis.html
+public sealed partial class Symbian : IArchive
+{
+ const string MODULE_NAME = "Symbian Installation File Plugin";
+ bool _compressed;
+ List _conditions;
+ Encoding _encoding;
+ ArchiveSupportedFeature _features;
+ List _files;
+ List _options;
+ bool _release6;
+ Stream _stream;
+
+#region IArchive Members
+
+ ///
+ public bool Opened { get; private set; }
+
+ public string Author => Authors.NataliaPortillo;
+
+ public string Name => Localization.Symbian_Name;
+ public Guid Id => new("0EC84EC7-EAE6-4196-83FE-943B3FE48DBD");
+
+ ///
+ public ArchiveSupportedFeature ArchiveFeatures => !Opened
+ ? ArchiveSupportedFeature.SupportsFilenames |
+ ArchiveSupportedFeature.SupportsCompression |
+ ArchiveSupportedFeature.SupportsSubdirectories |
+ ArchiveSupportedFeature.SupportsXAttrs
+ : _features;
+
+#endregion
+}
\ No newline at end of file
diff --git a/Aaru.Archives/Symbian/UID.cs b/Aaru.Archives/Symbian/UID.cs
new file mode 100644
index 000000000..c6c0cf8d2
--- /dev/null
+++ b/Aaru.Archives/Symbian/UID.cs
@@ -0,0 +1,229 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Symbian.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Symbian plugin.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Identifies Symbian installer (.sis) packages and shows information.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+namespace Aaru.Archives;
+
+public sealed partial class Symbian
+{
+ static string DecodePlatformUid(uint uid) => uid switch
+ {
+ 0x101F61CE => Localization.SIS_Platform_UID_UIQ_21,
+ 0x101F6300 => Localization.SIS_Platform_UID_UIQ_30,
+ 0x101F6F87 => Localization.SIS_Platform_UID_Nokia_7650,
+ 0x101F6F88 => Localization.SIS_Platform_UID_Series_60_1st_Edition,
+ 0x101F795F => Localization.SIS_Platform_UID_Series_60_v1_0,
+ 0x101F7960 => Localization.SIS_Platform_UID_Series_60_2nd_Edition,
+ 0x101F7961 => Localization.SIS_Platform_UID_Series_60_3rd_Edition,
+ 0x101F7962 => Localization.SIS_Platform_UID_Nokia_3650,
+ 0x101F7963 => Localization.SIS_Platform_UID_Nokia_6600,
+ 0x101F7964 => Localization.SIS_Platform_UID_Nokia_6630,
+ 0x101F80BE => Localization.SIS_Platform_UID_SonyEricsson_P80x,
+ 0x101F8201 => Localization.SIS_Platform_UID_Series_60_v1_1,
+ 0x101F8202 => Localization
+ .SIS_Platform_UID_Series_60_1st_Edition_Feature_Pack_1,
+ 0x101F8A64 => Localization.SIS_Platform_UID_Nokia_N_Gage,
+ 0x101F8DDB => Localization.SIS_Platform_UID_Nokia_9500,
+ 0x101F8ED1 => Localization.SIS_Platform_UID_Nokia_9300,
+ 0x101F8ED2 => Localization.SIS_Platform_UID_Series_80_2nd_edition,
+ 0x101F9071 => Localization.SIS_Platform_UID_Siemens_SX1,
+ 0x101F9115 => Localization
+ .SIS_Platform_UID_Series_60_2nd_Edition_Feature_Pack_1,
+ 0x101FB3F4 => Localization.SIS_Platform_UID_Nokia_6260,
+ 0x101FBB35 => Localization.SIS_Platform_UID_SonyEricsson_P90x,
+ 0x101FBE05 => Localization.SIS_Platform_UID_Nokia_7710_Series_90,
+ 0x101FD5DB => Localization.SIS_Platform_UID_Nokia_7610,
+ 0x101FD5DC => Localization.SIS_Platform_UID_Nokia_6670,
+ 0x101f617b => Localization.SIS_Platform_UID_UIQ_20,
+ 0x10200BAB => Localization
+ .SIS_Platform_UID_Series_60_2nd_Edition_Feature_Pack_2,
+ 0x10200F97 => Localization.SIS_Platform_UID_Nokia_3230,
+ 0x10200F98 => Localization.SIS_Platform_UID_Nokia_N90,
+ 0x10200F9A => Localization.SIS_Platform_UID_Nokia_N70,
+ 0x10200f99 => Localization.SIS_Platform_UID_Nokia_6680,
+ 0x1020216B => Localization.SIS_Platform_UID_Nokia_6620,
+ 0x102032BD => Localization
+ .SIS_Platform_UID_Series_60_2nd_Edition_Feature_Pack_3,
+ 0x102032BE => Localization
+ .SIS_Platform_UID_Series_60_3rd_Edition_Feature_Pack_1,
+ 0x102078CF => Localization.SIS_Platform_UID_Nokia_6682,
+ 0x102078D0 => Localization.SIS_Platform_UID_Nokia_6681,
+ 0x102752AE => Localization
+ .SIS_Platform_UID_Series_60_3rd_Edition_Feature_Pack_2,
+ 0x1028315F => Localization.SIS_Platform_UID_Series_60_5th_Edition,
+ 0x200005F8 => Localization.SIS_Platform_UID_Nokia_3250,
+ 0x200005F9 => Localization.SIS_Platform_UID_Nokia_N80,
+ 0x200005FA => Localization.SIS_Platform_UID_Nokia_N92,
+ 0x200005FB => Localization.SIS_Platform_UID_Nokia_N73,
+ 0x200005FC => Localization.SIS_Platform_UID_Nokia_N91,
+ 0x200005FF => Localization.SIS_Platform_UID_Nokia_N71,
+ 0x20001856 => Localization.SIS_Platform_UID_Nokia_E60,
+ 0x20001857 => Localization.SIS_Platform_UID_Nokia_E70,
+ 0x20001858 => Localization.SIS_Platform_UID_Nokia_E61,
+ 0x20022E6D => Localization.SIS_Platform_UID_Symbian_3,
+ 0x2003A678 => Localization.SIS_Platform_UID_Nokia_Belle,
+ _ => string.Format(Localization.SIS_Platform_UID_0, uid)
+ };
+
+ static string DecodeMachineUid(uint uid) => uid switch
+ {
+ 0x200005f8 => "UID_NOKIA_3250",
+ 0x20024104 => "UID_NOKIA_5228",
+ 0x20023763 => "UID_NOKIA_5230",
+ 0x20023764 => "UID_NOKIA_5230a",
+ 0x2002376b => "UID_NOKIA_5230_NURON",
+ 0x20024105 => "UID_NOKIA_5235",
+ 0x2002bf93 => "UID_NOKIA_5250",
+ 0x2000da5a => "UID_NOKIA_5320",
+ 0x20000602 => "UID_NOKIA_5500",
+ 0x2001de9d => "UID_NOKIA_5530",
+ 0x2001de9e => "UID_NOKIA_5530_chinese",
+ 0x2000da61 => "UID_NOKIA_5630",
+ 0x20002d7c => "UID_NOKIA_5700",
+ 0x20014dd3 => "UID_NOKIA_5730",
+ 0x2000da56 => "UID_NOKIA_5800",
+ 0x20002d7b => "UID_NOKIA_6110",
+ 0x20002d7e => "UID_NOKIA_6120",
+ 0x2000da55 => "UID_NOKIA_6124",
+ 0x2000da54 => "UID_NOKIA_6210",
+ 0x2000da52 => "UID_NOKIA_6220",
+ 0x2000da53 => "UID_NOKIA_6220_cn",
+ 0x20000606 => "UID_NOKIA_6290",
+ 0x2000da57 => "UID_NOKIA_6650",
+ 0x2001de9b => "UID_NOKIA_6700",
+ 0x20014dd1 => "UID_NOKIA_6710",
+ 0x20014dcd => "UID_NOKIA_6720",
+ 0x2001de9a => "UID_NOKIA_6730",
+ 0x200227e2 => "UID_NOKIA_6760",
+ 0x200227e6 => "UID_NOKIA_6788",
+ 0x2001de98 => "UID_NOKIA_6790",
+ 0x20024107 => "UID_NOKIA_C5_00",
+ 0x20029a75 => "UID_NOKIA_C5_01",
+ 0x2002bf91 => "UID_NOKIA_C6_00",
+ 0x2002376a => "UID_NOKIA_C6_01",
+ 0x2002bf92 => "UID_NOKIA_C7_00",
+ 0x20002495 => "UID_NOKIA_E50",
+ 0x20002498 => "UID_NOKIA_E51",
+ 0x20014dcc => "UID_NOKIA_E52",
+ 0x20014dcf => "UID_NOKIA_E55",
+ 0x20001856 => "UID_NOKIA_E60",
+ 0x20001858 => "UID_NOKIA_E61",
+ 0x20002d7f => "UID_NOKIA_E61i",
+ 0x20001859 => "UID_NOKIA_E62",
+ 0x200025c3 => "UID_NOKIA_E63",
+ 0x20000604 => "UID_NOKIA_E65",
+ 0x2000249c => "UID_NOKIA_E66",
+ 0x2002bf96 => "UID_NOKIA_E7_00",
+ 0x20001857 => "UID_NOKIA_E70",
+ 0x2000249b => "UID_NOKIA_E71",
+ 0x20014dd8 => "UID_NOKIA_E71x",
+ 0x20014dd0 => "UID_NOKIA_E72",
+ 0x20029a6d => "UID_NOKIA_E73",
+ 0x2000249d => "UID_NOKIA_E75",
+ 0x20002496 => "UID_NOKIA_E90",
+ 0x20024100 => "UID_NOKIA_E5_00",
+ 0x10200f9a => "UID_NOKIA_N70",
+ 0x200005ff => "UID_NOKIA_N71",
+ 0x200005fb => "UID_NOKIA_N73",
+ 0x200005fe => "UID_NOKIA_N75",
+ 0x2000060a => "UID_NOKIA_N76",
+ 0x20000601 => "UID_NOKIA_N77",
+ 0x20002d81 => "UID_NOKIA_N78",
+ 0x2000da64 => "UID_NOKIA_N79",
+ 0x20029a73 => "UID_NOKIA_N8_00",
+ 0x200005f9 => "UID_NOKIA_N80",
+ 0x20002d83 => "UID_NOKIA_N81",
+ 0x20002d85 => "UID_NOKIA_N82",
+ 0x20002d86 => "UID_NOKIA_N85",
+ 0x20014dd2 => "UID_NOKIA_N86",
+ 0x200005fc => "UID_NOKIA_N91",
+ 0x200005fa => "UID_NOKIA_N92",
+ 0x20000600 => "UID_NOKIA_N93",
+ 0x20000605 => "UID_NOKIA_N93i",
+ 0x2000060b => "UID_NOKIA_N95",
+ 0x20002d84 => "UID_NOKIA_N95_8GB",
+ 0x20002d82 => "UID_NOKIA_N96",
+ 0x20014ddd => "UID_NOKIA_N97",
+ 0x20014dde => "UID_NOKIA_N97a",
+ 0x20023766 => "UID_NOKIA_N97_mini",
+ 0x20029a76 => "UID_NOKIA_X5_00",
+ 0x20024101 => "UID_NOKIA_X5_01",
+ 0x200227dd => "UID_NOKIA_X6",
+ 0x20008610 => "UID_SAMSUNG_I400",
+ 0x2000a677 => "UID_SAMSUNG_I450",
+ 0x20003abd => "UID_SAMSUNG_I520",
+ 0x2000a678 => "UID_SAMSUNG_I550",
+ 0x2000c51c => "UID_SAMSUNG_I560",
+ 0x2000a679 => "UID_SAMSUNG_I590",
+ 0x2000c51f => "UID_SAMSUNG_I7110",
+ 0x2000c51e => "UID_SAMSUNG_I8510",
+ 0x2000c520 => "UID_SAMSUNG_I8910",
+ 0x2001f0a1 => "UID_SONYERICSSON_SATIO",
+ 0x10274bf9 => "UID_SONYERICSSON_M600",
+ 0x10274bfa => "UID_SONYERICSSON_W950",
+ 0x20002e6a => "UID_SONYERICSSON_W960",
+ 0x1020e285 => "UID_SONYERICSSON_P990",
+ 0x20002e69 => "UID_SONYERICSSON_P1",
+ 0x2000cc70 => "UID_SONYERICSSON_G700",
+ 0x2000cc6c => "UID_SONYERICSSON_G900",
+ 0x20024eec => "UID_SONYERICSSON_VIVAZ_U5i",
+ 0x20024eed => "UID_SONYERICSSON_VIVAZ_U8",
+ 0x1027400d => "UID_MOTOROLA_Z8",
+ 0x101ff809 => "UID_LG_KT610",
+ 0x10200f97 => "UID_NOKIA_3230",
+ 0x101f466a => "UID_NOKIA_3650",
+ 0x101f8c19 => "UID_NOKIA_NGAGE",
+ 0x101fb2b1 => "UID_NOKIA_NGAGE_QD",
+ 0x101fb3f4 => "UID_NOKIA_6260",
+ 0x101fb3dd => "UID_NOKIA_6600",
+ 0x101f3ee3 => "UID_NOKIA_6620",
+ 0x101fbb55 => "UID_NOKIA_6630",
+ 0x101fb3f3 => "UID_NOKIA_6670",
+ 0x10200f99 => "UID_NOKIA_6680",
+ 0x10200f9c => "UID_NOKIA_6681",
+ 0x10200f9b => "UID_NOKIA_6682",
+ 0x101f4fc3 => "UID_NOKIA_7650",
+ 0x10005e33 => "UID_NOKIA_92XX",
+ 0x101f8ddb => "UID_NOKIA_9x00",
+ 0x1020e048 => "UID_NOKIA_9300i",
+ 0x10200f98 => "UID_NOKIA_N90",
+ 0x101fbe09 => "UID_NOKIA_7710",
+ 0x101fa031 => "UID_SENDO_X",
+ 0x101f9071 => "UID_SIEMENS_SX1",
+ 0x101fe7b7 => "SAMSUNG_SGH_D730",
+ 0x101f408b => "UID_SONYERICSSON_P800",
+ 0x101fb2ae => "UID_SONYERICSSON_P900",
+ 0x10200ac6 => "UID_SONYERICSSON_P910",
+ 0x101f6b26 => "UID_MOTOROLA_A9XX",
+ 0x101f6b27 => "UID_MOTOROLA_A1000",
+ _ => $"{uid:X8}"
+ };
+}
\ No newline at end of file
diff --git a/Aaru.Archives/Symbian/Xattrs.cs b/Aaru.Archives/Symbian/Xattrs.cs
new file mode 100644
index 000000000..e70a2595a
--- /dev/null
+++ b/Aaru.Archives/Symbian/Xattrs.cs
@@ -0,0 +1,77 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Symbian.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Symbian plugin.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Identifies Symbian installer (.sis) packages and shows information.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System.Collections.Generic;
+using System.Text;
+using Aaru.CommonTypes.Enums;
+
+namespace Aaru.Archives;
+
+public sealed partial class Symbian
+{
+#region IArchive Members
+
+ ///
+ public ErrorNumber ListXAttr(int entryNumber, out List xattrs)
+ {
+ xattrs = null;
+
+ if(!Opened) return ErrorNumber.NotOpened;
+
+ if(entryNumber < 0 || entryNumber >= _files.Count) return ErrorNumber.OutOfRange;
+
+ xattrs = [];
+
+ if(_files[entryNumber].mime is not null) xattrs.Add("org.iana.mime_type");
+
+ return ErrorNumber.NoError;
+ }
+
+ ///
+ public ErrorNumber GetXattr(int entryNumber, string xattr, ref byte[] buffer)
+ {
+ buffer = null;
+
+ if(!Opened) return ErrorNumber.NotOpened;
+
+ if(entryNumber < 0 || entryNumber >= _files.Count) return ErrorNumber.OutOfRange;
+
+ if(xattr != "org.iana.mime_type" || _files[entryNumber].mime is null)
+ return ErrorNumber.NoSuchExtendedAttribute;
+
+ buffer = Encoding.ASCII.GetBytes(_files[entryNumber].mime);
+
+ return ErrorNumber.NoError;
+ }
+
+#endregion
+}
\ No newline at end of file
diff --git a/Aaru.Checksums b/Aaru.Checksums
deleted file mode 160000
index 3362cdcd7..000000000
--- a/Aaru.Checksums
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 3362cdcd74318e4fb51779f88579fddfa7ddd8cc
diff --git a/Aaru.Checksums/.gitignore b/Aaru.Checksums/.gitignore
new file mode 100644
index 000000000..05c540d38
--- /dev/null
+++ b/Aaru.Checksums/.gitignore
@@ -0,0 +1,595 @@
+### VisualStudio template
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# CodeRush
+.cr/
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+### Linux template
+
+# temporary files which can be created if a process still has a handle open of a deleted file
+.fuse_hidden*
+
+# KDE directory preferences
+.directory
+
+# Linux trash folder which might appear on any partition or disk
+.Trash-*
+
+# .nfs files are created when an open file is removed but is still being accessed
+.nfs*
+### Xcode template
+# Xcode
+#
+# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
+
+## User settings
+xcuserdata/
+
+## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
+*.xcscmblueprint
+*.xccheckout
+
+## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
+build/
+DerivedData/
+*.moved-aside
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+### VisualStudioCode template
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+### C++ template
+# Prerequisites
+*.d
+
+# Compiled Object files
+*.slo
+*.lo
+*.o
+
+# Precompiled Headers
+*.gch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+*.smod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
+### MonoDevelop template
+#User Specific
+*.usertasks
+
+#Mono Project Files
+*.resources
+test-results/
+### GPG template
+secring.*
+
+### JetBrains template
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+### CMake template
+CMakeCache.txt
+CMakeFiles
+CMakeScripts
+Testing
+Makefile
+cmake_install.cmake
+install_manifest.txt
+compile_commands.json
+CTestTestfile.cmake
+### C template
+# Object files
+*.ko
+*.elf
+
+# Linker output
+*.map
+*.exp
+
+*.so.*
+
+# Executables
+*.i*86
+*.x86_64
+*.hex
+
+# Debug files
+*.dSYM/
+*.su
+*.idb
+
+# Kernel Module Compile Results
+*.mod*
+*.cmd
+.tmp_versions/
+modules.order
+Module.symvers
+Mkfile.old
+dkms.conf
+### Windows template
+# Windows thumbnail cache files
+Thumbs.db
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# NuGet Packages Directory
+packages/
+## TODO: If the tool you use requires repositories.config uncomment the next line
+#!packages/repositories.config
+
+# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
+# This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented)
+!packages/build/
+
+
+# Others
+sql/
+*.Cache
+
+# Visual Studio 2017
+.vs
+
+workspace.xml
+cmake-build-debug
+### macOS template
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+pkg/**/pkg
+pkg/**/src
+pkg/**/*.asc
+pkg/**/*.sig
+pkg/**/*.tar.xz
+pkg/**/*.zip
+pkg/**/aaru
+
+.sonarqube
\ No newline at end of file
diff --git a/Aaru.Checksums/Aaru.Checksums.csproj b/Aaru.Checksums/Aaru.Checksums.csproj
new file mode 100644
index 000000000..549091c54
--- /dev/null
+++ b/Aaru.Checksums/Aaru.Checksums.csproj
@@ -0,0 +1,108 @@
+
+
+
+ 2.0
+ {CC48B324-A532-4A45-87A6-6F91F7141E8D}
+ Library
+ Aaru.Checksums
+ Aaru.Checksums
+ $(Version)
+ true
+ 6.0.0-alpha9
+ Claunia.com
+ Copyright © 2011-2024 Natalia Portillo
+ Aaru Data Preservation Suite
+ Aaru.Checksums
+ $(Version)
+ net8.0
+ 12
+ C# implementation of CRC16, CRC32, CRC64, Fletcher, MD5, SHA1, SHA2 and SpamSum.
+ https://github.com/aaru-dps/
+ LGPL-2.1-only
+ https://github.com/aaru-dps/Aaru.Checksums
+ true
+ en-US
+ true
+ true
+ snupkg
+ Natalia Portillo <claunia@claunia.com>
+ true
+ true
+ true
+ true
+
+
+ CS1591;CS1574
+
+
+
+
+
+
+ $(Version)+{chash:8}
+ true
+ true
+
+
+
+
+
+
+
+
+ LICENSE.LGPL
+
+
+ LICENSE
+
+
+ ResXFileCodeGenerator
+ Localization.Designer.cs
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Aaru.Checksums/Aaru.Checksums.csproj.DotSettings b/Aaru.Checksums/Aaru.Checksums.csproj.DotSettings
new file mode 100644
index 000000000..50c5847b4
--- /dev/null
+++ b/Aaru.Checksums/Aaru.Checksums.csproj.DotSettings
@@ -0,0 +1,6 @@
+
+ True
\ No newline at end of file
diff --git a/Aaru.Checksums/Adler32/neon.cs b/Aaru.Checksums/Adler32/neon.cs
new file mode 100644
index 000000000..2057f373a
--- /dev/null
+++ b/Aaru.Checksums/Adler32/neon.cs
@@ -0,0 +1,242 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : neon.cs
+// Author(s) : Natalia Portillo
+// The Chromium Authors
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Compute Adler32 checksum using NEON vectorization.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// ****************************************************************************/
+
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.Arm;
+
+namespace Aaru.Checksums.Adler32;
+
+static class Neon
+{
+ internal static void Step(ref ushort preSum1, ref ushort preSum2, byte[] buf, uint len)
+ {
+ /*
+ * Split Adler-32 into component sums.
+ */
+ uint s1 = preSum1;
+ uint s2 = preSum2;
+
+ var bufPos = 0;
+
+ /*
+ * Process the data in blocks.
+ */
+ const uint blockSize = 1 << 5;
+ uint blocks = len / blockSize;
+ len -= blocks * blockSize;
+
+ while(blocks != 0)
+ {
+ uint n = Adler32Context.NMax / blockSize; /* The NMAX constraint. */
+
+ if(n > blocks) n = blocks;
+
+ blocks -= n;
+ /*
+ * Process n blocks of data. At most NMAX data bytes can be
+ * processed before s2 must be reduced modulo ADLER_MODULE.
+ */
+ var vS2 = Vector128.Create(s1 * n, 0, 0, 0);
+ var vS1 = Vector128.Create(0u, 0, 0, 0);
+ Vector128 vColumnSum1 = AdvSimd.DuplicateToVector128((ushort)0);
+ Vector128 vColumnSum2 = AdvSimd.DuplicateToVector128((ushort)0);
+ Vector128 vColumnSum3 = AdvSimd.DuplicateToVector128((ushort)0);
+ Vector128 vColumnSum4 = AdvSimd.DuplicateToVector128((ushort)0);
+
+ do
+ {
+ /*
+ * Load 32 input bytes.
+ */
+ var bytes1 = Vector128.Create(buf[bufPos],
+ buf[bufPos + 1],
+ buf[bufPos + 2],
+ buf[bufPos + 3],
+ buf[bufPos + 4],
+ buf[bufPos + 5],
+ buf[bufPos + 6],
+ buf[bufPos + 7],
+ buf[bufPos + 8],
+ buf[bufPos + 9],
+ buf[bufPos + 10],
+ buf[bufPos + 11],
+ buf[bufPos + 12],
+ buf[bufPos + 13],
+ buf[bufPos + 14],
+ buf[bufPos + 15]);
+
+ bufPos += 16;
+
+ var bytes2 = Vector128.Create(buf[bufPos],
+ buf[bufPos + 1],
+ buf[bufPos + 2],
+ buf[bufPos + 3],
+ buf[bufPos + 4],
+ buf[bufPos + 5],
+ buf[bufPos + 6],
+ buf[bufPos + 7],
+ buf[bufPos + 8],
+ buf[bufPos + 9],
+ buf[bufPos + 10],
+ buf[bufPos + 11],
+ buf[bufPos + 12],
+ buf[bufPos + 13],
+ buf[bufPos + 14],
+ buf[bufPos + 15]);
+
+ bufPos += 16;
+ /*
+ * Add previous block byte sum to v_s2.
+ */
+ vS2 = AdvSimd.Add(vS2, vS1);
+
+ /*
+ * Horizontally add the bytes for s1.
+ */
+ vS1 = AdvSimd.AddPairwiseWideningAndAdd(vS1,
+ AdvSimd
+ .AddPairwiseWideningAndAdd(AdvSimd
+ .AddPairwiseWidening(bytes1),
+ bytes2));
+
+ /*
+ * Vertically add the bytes for s2.
+ */
+ vColumnSum1 = AdvSimd.AddWideningLower(vColumnSum1, bytes1.GetLower());
+ vColumnSum2 = AdvSimd.AddWideningLower(vColumnSum2, bytes1.GetUpper());
+ vColumnSum3 = AdvSimd.AddWideningLower(vColumnSum3, bytes2.GetLower());
+ vColumnSum4 = AdvSimd.AddWideningLower(vColumnSum4, bytes2.GetUpper());
+ } while(--n != 0);
+
+ vS2 = AdvSimd.ShiftLeftLogical(vS2, 5);
+
+ /*
+ * Multiply-add bytes by [ 32, 31, 30, ... ] for s2.
+ */
+ vS2 = AdvSimd.MultiplyWideningLowerAndAdd(vS2,
+ vColumnSum1.GetLower(),
+ Vector64.Create((ushort)32, 31, 30, 29));
+
+ vS2 = AdvSimd.MultiplyWideningLowerAndAdd(vS2,
+ vColumnSum1.GetUpper(),
+ Vector64.Create((ushort)28, 27, 26, 25));
+
+ vS2 = AdvSimd.MultiplyWideningLowerAndAdd(vS2,
+ vColumnSum2.GetLower(),
+ Vector64.Create((ushort)24, 23, 22, 21));
+
+ vS2 = AdvSimd.MultiplyWideningLowerAndAdd(vS2,
+ vColumnSum2.GetUpper(),
+ Vector64.Create((ushort)20, 19, 18, 17));
+
+ vS2 = AdvSimd.MultiplyWideningLowerAndAdd(vS2,
+ vColumnSum3.GetLower(),
+ Vector64.Create((ushort)16, 15, 14, 13));
+
+ vS2 = AdvSimd.MultiplyWideningLowerAndAdd(vS2,
+ vColumnSum3.GetUpper(),
+ Vector64.Create((ushort)12, 11, 10, 9));
+
+ vS2 = AdvSimd.MultiplyWideningLowerAndAdd(vS2, vColumnSum4.GetLower(), Vector64.Create((ushort)8, 7, 6, 5));
+
+ vS2 = AdvSimd.MultiplyWideningLowerAndAdd(vS2, vColumnSum4.GetUpper(), Vector64.Create((ushort)4, 3, 2, 1));
+
+ /*
+ * Sum epi32 ints v_s1(s2) and accumulate in s1(s2).
+ */
+ Vector64 sum1 = AdvSimd.AddPairwise(vS1.GetLower(), vS1.GetUpper());
+ Vector64 sum2 = AdvSimd.AddPairwise(vS2.GetLower(), vS2.GetUpper());
+ Vector64 s1S2 = AdvSimd.AddPairwise(sum1, sum2);
+ s1 += AdvSimd.Extract(s1S2, 0);
+ s2 += AdvSimd.Extract(s1S2, 1);
+ /*
+ * Reduce.
+ */
+ s1 %= Adler32Context.AdlerModule;
+ s2 %= Adler32Context.AdlerModule;
+ }
+
+ /*
+ * Handle leftover data.
+ */
+ if(len != 0)
+ {
+ if(len >= 16)
+ {
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ len -= 16;
+ }
+
+ while(len-- != 0) s2 += s1 += buf[bufPos++];
+
+ if(s1 >= Adler32Context.AdlerModule) s1 -= Adler32Context.AdlerModule;
+
+ s2 %= Adler32Context.AdlerModule;
+ }
+
+ /*
+ * Return the recombined sums.
+ */
+ preSum1 = (ushort)(s1 & 0xFFFF);
+ preSum2 = (ushort)(s2 & 0xFFFF);
+ }
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/Adler32/ssse3.cs b/Aaru.Checksums/Adler32/ssse3.cs
new file mode 100644
index 000000000..e03300cd5
--- /dev/null
+++ b/Aaru.Checksums/Adler32/ssse3.cs
@@ -0,0 +1,188 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : ssse3.cs
+// Author(s) : Natalia Portillo
+// The Chromium Authors
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Compute Adler32 checksum using SSSE3 vectorization.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// ****************************************************************************/
+
+using System;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace Aaru.Checksums.Adler32;
+
+static class Ssse3
+{
+ internal static void Step(ref ushort sum1, ref ushort sum2, byte[] buf, uint len)
+ {
+ uint s1 = sum1;
+ uint s2 = sum2;
+ var bufPos = 0;
+
+ /*
+ * Process the data in blocks.
+ */
+ const uint blockSize = 1 << 5;
+ uint blocks = len / blockSize;
+ len -= blocks * blockSize;
+
+ while(blocks != 0)
+ {
+ uint n = Adler32Context.NMax / blockSize; /* The NMAX constraint. */
+
+ if(n > blocks) n = blocks;
+
+ blocks -= n;
+
+ Vector128 tap1 = Vector128.Create(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17)
+ .AsByte();
+
+ Vector128 tap2 = Vector128.Create(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1).AsByte();
+ Vector128 zero = Vector128.Create(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).AsByte();
+ var ones = Vector128.Create(1, 1, 1, 1, 1, 1, 1, 1);
+ /*
+ * Process n blocks of data. At most NMAX data bytes can be
+ * processed before s2 must be reduced modulo BASE.
+ */
+ var vPs = Vector128.Create(s1 * n, 0, 0, 0);
+ var vS2 = Vector128.Create(s2, 0, 0, 0);
+ var vS1 = Vector128.Create(0u, 0, 0, 0);
+
+ do
+ {
+ /*
+ * Load 32 input bytes.
+ */
+ var bytes1 = Vector128.Create(BitConverter.ToUInt32(buf, bufPos),
+ BitConverter.ToUInt32(buf, bufPos + 4),
+ BitConverter.ToUInt32(buf, bufPos + 8),
+ BitConverter.ToUInt32(buf, bufPos + 12));
+
+ bufPos += 16;
+
+ var bytes2 = Vector128.Create(BitConverter.ToUInt32(buf, bufPos),
+ BitConverter.ToUInt32(buf, bufPos + 4),
+ BitConverter.ToUInt32(buf, bufPos + 8),
+ BitConverter.ToUInt32(buf, bufPos + 12));
+
+ bufPos += 16;
+
+ /*
+ * Add previous block byte sum to v_ps.
+ */
+ vPs = Sse2.Add(vPs, vS1);
+ /*
+ * Horizontally add the bytes for s1, multiply-adds the
+ * bytes by [ 32, 31, 30, ... ] for s2.
+ */
+ vS1 = Sse2.Add(vS1, Sse2.SumAbsoluteDifferences(bytes1.AsByte(), zero).AsUInt32());
+
+ Vector128 mad1 =
+ System.Runtime.Intrinsics.X86.Ssse3.MultiplyAddAdjacent(bytes1.AsByte(), tap1.AsSByte());
+
+ vS2 = Sse2.Add(vS2, Sse2.MultiplyAddAdjacent(mad1.AsInt16(), ones.AsInt16()).AsUInt32());
+ vS1 = Sse2.Add(vS1, Sse2.SumAbsoluteDifferences(bytes2.AsByte(), zero).AsUInt32());
+
+ Vector128 mad2 =
+ System.Runtime.Intrinsics.X86.Ssse3.MultiplyAddAdjacent(bytes2.AsByte(), tap2.AsSByte());
+
+ vS2 = Sse2.Add(vS2, Sse2.MultiplyAddAdjacent(mad2.AsInt16(), ones.AsInt16()).AsUInt32());
+ } while(--n != 0);
+
+ vS2 = Sse2.Add(vS2, Sse2.ShiftLeftLogical(vPs, 5));
+ /*
+ * Sum epi32 ints v_s1(s2) and accumulate in s1(s2).
+ */
+ vS1 = Sse2.Add(vS1, Sse2.Shuffle(vS1, 177));
+ vS1 = Sse2.Add(vS1, Sse2.Shuffle(vS1, 78));
+ s1 += (uint)Sse2.ConvertToInt32(vS1.AsInt32());
+ vS2 = Sse2.Add(vS2, Sse2.Shuffle(vS2, 177));
+ vS2 = Sse2.Add(vS2, Sse2.Shuffle(vS2, 78));
+ s2 = (uint)Sse2.ConvertToInt32(vS2.AsInt32());
+ /*
+ * Reduce.
+ */
+ s1 %= Adler32Context.AdlerModule;
+ s2 %= Adler32Context.AdlerModule;
+ }
+
+ /*
+ * Handle leftover data.
+ */
+ if(len != 0)
+ {
+ if(len >= 16)
+ {
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ len -= 16;
+ }
+
+ while(len-- != 0) s2 += s1 += buf[bufPos++];
+
+ if(s1 >= Adler32Context.AdlerModule) s1 -= Adler32Context.AdlerModule;
+
+ s2 %= Adler32Context.AdlerModule;
+ }
+
+ /*
+ * Return the recombined sums.
+ */
+ sum1 = (ushort)(s1 & 0xFFFF);
+ sum2 = (ushort)(s2 & 0xFFFF);
+ }
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/Adler32Context.cs b/Aaru.Checksums/Adler32Context.cs
new file mode 100644
index 000000000..cb9837330
--- /dev/null
+++ b/Aaru.Checksums/Adler32Context.cs
@@ -0,0 +1,415 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Adler32Context.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Implements an Adler-32 algorithm.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// Copyright (C) 1995-2011 Mark Adler
+// Copyright (C) Jean-loup Gailly
+// ****************************************************************************/
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.Arm;
+using System.Text;
+using Aaru.Checksums.Adler32;
+using Aaru.CommonTypes.Interfaces;
+using Aaru.Helpers;
+using Ssse3 = System.Runtime.Intrinsics.X86.Ssse3;
+
+namespace Aaru.Checksums;
+
+///
+/// Implements the Adler-32 algorithm
+[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
+public sealed partial class Adler32Context : IChecksum
+{
+ internal const ushort AdlerModule = 65521;
+ internal const uint NMax = 5552;
+ readonly IntPtr _nativeContext;
+ readonly bool _useNative;
+ ushort _sum1, _sum2;
+
+ /// Initializes the Adler-32 sums
+ public Adler32Context()
+ {
+ _sum1 = 1;
+ _sum2 = 0;
+
+ if(!Native.IsSupported) return;
+
+ _nativeContext = adler32_init();
+ _useNative = _nativeContext != IntPtr.Zero;
+ }
+
+#region IChecksum Members
+
+ ///
+ public string Name => Localization.Adler32_Name;
+
+ ///
+ public Guid Id => new("D69CF1E7-4A7B-4605-9291-3A1BE4C2951F");
+
+ ///
+ public string Author => Authors.NataliaPortillo;
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ /// Length of buffer to hash.
+ public void Update(byte[] data, uint len) => Step(ref _sum1, ref _sum2, data, len, _useNative, _nativeContext);
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ public void Update(byte[] data) => Update(data, (uint)data.Length);
+
+ ///
+ /// Returns a byte array of the hash value.
+ public byte[] Final()
+ {
+ var finalSum = (uint)(_sum2 << 16 | _sum1);
+
+ if(!_useNative) return BigEndianBitConverter.GetBytes(finalSum);
+
+ adler32_final(_nativeContext, ref finalSum);
+ adler32_free(_nativeContext);
+
+ return BigEndianBitConverter.GetBytes(finalSum);
+ }
+
+ ///
+ /// Returns a hexadecimal representation of the hash value.
+ public string End()
+ {
+ var finalSum = (uint)(_sum2 << 16 | _sum1);
+
+ if(_useNative)
+ {
+ adler32_final(_nativeContext, ref finalSum);
+ adler32_free(_nativeContext);
+ }
+
+ var adlerOutput = new StringBuilder();
+
+ for(var i = 0; i < BigEndianBitConverter.GetBytes(finalSum).Length; i++)
+ adlerOutput.Append(BigEndianBitConverter.GetBytes(finalSum)[i].ToString("x2"));
+
+ return adlerOutput.ToString();
+ }
+
+#endregion
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial IntPtr adler32_init();
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial int adler32_update(IntPtr ctx, byte[] data, uint len);
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial int adler32_final(IntPtr ctx, ref uint checksum);
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial void adler32_free(IntPtr ctx);
+
+ static void Step(ref ushort preSum1, ref ushort preSum2, byte[] data, uint len, bool useNative,
+ IntPtr nativeContext)
+ {
+ if(useNative)
+ {
+ adler32_update(nativeContext, data, len);
+
+ return;
+ }
+
+ if(Ssse3.IsSupported)
+ {
+ Adler32.Ssse3.Step(ref preSum1, ref preSum2, data, len);
+
+ return;
+ }
+
+ if(AdvSimd.IsSupported)
+ {
+ Neon.Step(ref preSum1, ref preSum2, data, len);
+
+ return;
+ }
+
+ uint sum1 = preSum1;
+ uint sum2 = preSum2;
+ var dataOff = 0;
+
+ switch(len)
+ {
+ /* in case user likes doing a byte at a time, keep it fast */
+ case 1:
+ {
+ sum1 += data[dataOff];
+
+ if(sum1 >= AdlerModule) sum1 -= AdlerModule;
+
+ sum2 += sum1;
+
+ if(sum2 >= AdlerModule) sum2 -= AdlerModule;
+
+ preSum1 = (ushort)(sum1 & 0xFFFF);
+ preSum2 = (ushort)(sum2 & 0xFFFF);
+
+ return;
+ }
+ /* in case short lengths are provided, keep it somewhat fast */
+ case < 16:
+ {
+ while(len-- > 0)
+ {
+ sum1 += data[dataOff++];
+ sum2 += sum1;
+ }
+
+ if(sum1 >= AdlerModule) sum1 -= AdlerModule;
+
+ sum2 %= AdlerModule; /* only added so many ADLER_MODULE's */
+ preSum1 = (ushort)(sum1 & 0xFFFF);
+ preSum2 = (ushort)(sum2 & 0xFFFF);
+
+ return;
+ }
+ }
+
+ /* do length NMAX blocks -- requires just one modulo operation */
+ while(len >= NMax)
+ {
+ len -= NMax;
+ uint n = NMax / 16;
+
+ do
+ {
+ sum1 += data[dataOff];
+ sum2 += sum1;
+ sum1 += data[dataOff + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 2 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4 + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4 + 2 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 2 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 4];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 4 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 4 + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 4 + 2 + 1];
+ sum2 += sum1;
+
+ /* 16 sums unrolled */
+ dataOff += 16;
+ } while(--n != 0);
+
+ sum1 %= AdlerModule;
+ sum2 %= AdlerModule;
+ }
+
+ /* do remaining bytes (less than NMAX, still just one modulo) */
+ if(len != 0)
+ {
+ /* avoid modulos if none remaining */
+ while(len >= 16)
+ {
+ len -= 16;
+ sum1 += data[dataOff];
+ sum2 += sum1;
+ sum1 += data[dataOff + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 2 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4 + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4 + 2 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 2 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 4];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 4 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 4 + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 4 + 2 + 1];
+ sum2 += sum1;
+
+ dataOff += 16;
+ }
+
+ while(len-- != 0)
+ {
+ sum1 += data[dataOff++];
+ sum2 += sum1;
+ }
+
+ sum1 %= AdlerModule;
+ sum2 %= AdlerModule;
+ }
+
+ preSum1 = (ushort)(sum1 & 0xFFFF);
+ preSum2 = (ushort)(sum2 & 0xFFFF);
+ }
+
+ /// Gets the hash of a file
+ /// File path.
+ public static byte[] File(string filename)
+ {
+ File(filename, out byte[] hash);
+
+ return hash;
+ }
+
+ /// Gets the hash of a file in hexadecimal and as a byte array.
+ /// File path.
+ /// Byte array of the hash value.
+ public static string File(string filename, out byte[] hash)
+ {
+ bool useNative = Native.IsSupported;
+ IntPtr nativeContext = IntPtr.Zero;
+
+ if(useNative)
+ {
+ nativeContext = adler32_init();
+
+ if(nativeContext == IntPtr.Zero) useNative = false;
+ }
+
+ var fileStream = new FileStream(filename, FileMode.Open);
+
+ ushort localSum1 = 1;
+ ushort localSum2 = 0;
+
+ var buffer = new byte[65536];
+ int read = fileStream.EnsureRead(buffer, 0, 65536);
+
+ while(read > 0)
+ {
+ Step(ref localSum1, ref localSum2, buffer, (uint)read, useNative, nativeContext);
+ read = fileStream.EnsureRead(buffer, 0, 65536);
+ }
+
+ var finalSum = (uint)(localSum2 << 16 | localSum1);
+
+ if(useNative)
+ {
+ adler32_final(nativeContext, ref finalSum);
+ adler32_free(nativeContext);
+ }
+
+ hash = BigEndianBitConverter.GetBytes(finalSum);
+
+ var adlerOutput = new StringBuilder();
+
+ foreach(byte h in hash) adlerOutput.Append(h.ToString("x2"));
+
+ fileStream.Close();
+
+ return adlerOutput.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Length of the data buffer to hash.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, uint len, out byte[] hash)
+ {
+ bool useNative = Native.IsSupported;
+ IntPtr nativeContext = IntPtr.Zero;
+
+ if(useNative)
+ {
+ nativeContext = adler32_init();
+
+ if(nativeContext == IntPtr.Zero) useNative = false;
+ }
+
+ ushort localSum1 = 1;
+ ushort localSum2 = 0;
+
+ Step(ref localSum1, ref localSum2, data, len, useNative, nativeContext);
+
+ var finalSum = (uint)(localSum2 << 16 | localSum1);
+
+ if(useNative)
+ {
+ adler32_final(nativeContext, ref finalSum);
+ adler32_free(nativeContext);
+ }
+
+ hash = BigEndianBitConverter.GetBytes(finalSum);
+
+ var adlerOutput = new StringBuilder();
+
+ foreach(byte h in hash) adlerOutput.Append(h.ToString("x2"));
+
+ return adlerOutput.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/Authors.cs b/Aaru.Checksums/Authors.cs
new file mode 100644
index 000000000..ee56b2442
--- /dev/null
+++ b/Aaru.Checksums/Authors.cs
@@ -0,0 +1,37 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Authors.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Aaru.Checksums.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System.Diagnostics.CodeAnalysis;
+
+namespace Aaru.Checksums;
+
+[SuppressMessage("ReSharper", "InconsistentNaming")]
+static class Authors
+{
+ internal const string NataliaPortillo = "Natalia Portillo";
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/CDChecksums.cs b/Aaru.Checksums/CDChecksums.cs
new file mode 100644
index 000000000..891f4c063
--- /dev/null
+++ b/Aaru.Checksums/CDChecksums.cs
@@ -0,0 +1,673 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : CDChecksums.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Implements CD checksums.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program.If not, see.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ECC algorithm from ECM(c) 2002-2011 Neill Corlett
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using Aaru.Console;
+using Aaru.Helpers;
+
+namespace Aaru.Checksums;
+
+/// Implements ReedSolomon and CRC32 algorithms as used by CD-ROM
+public static class CdChecksums
+{
+ const string MODULE_NAME = "CD checksums";
+ static byte[] _eccFTable;
+ static byte[] _eccBTable;
+ static uint[] _edcTable;
+
+ /// Checks the EDC and ECC of a CD sector
+ /// CD sector
+ ///
+ /// true if all checks were correct, false if any of them weren't, and null if none of them
+ /// are present.
+ ///
+ public static bool? CheckCdSector(byte[] buffer) => CheckCdSector(buffer, out _, out _, out _);
+
+ /// Checks the EDC and ECC of a CD sector
+ /// CD sector
+ ///
+ /// true if ECC P is correct, false if it isn't, and null if there is no ECC
+ /// P in sector.
+ ///
+ ///
+ /// true if ECC Q is correct, false if it isn't, and null if there is no ECC
+ /// Q in sector.
+ ///
+ ///
+ /// true if EDC is correct, false if it isn't, and null if there is no EDC in
+ /// sector.
+ ///
+ ///
+ /// true if all checks were correct, false if any of them weren't, and null if none of them
+ /// are present.
+ ///
+ public static bool? CheckCdSector(byte[] buffer, out bool? correctEccP, out bool? correctEccQ, out bool? correctEdc)
+ {
+ correctEccP = null;
+ correctEccQ = null;
+ correctEdc = null;
+
+ switch(buffer.Length)
+ {
+ case 2448:
+ {
+ var subchannel = new byte[96];
+ var channel = new byte[2352];
+
+ Array.Copy(buffer, 0, channel, 0, 2352);
+ Array.Copy(buffer, 2352, subchannel, 0, 96);
+
+ bool? channelStatus = CheckCdSectorChannel(channel, out correctEccP, out correctEccQ, out correctEdc);
+
+ bool? subchannelStatus = CheckCdSectorSubChannel(subchannel);
+ bool? status = null;
+
+ if(channelStatus == false || subchannelStatus == false) status = false;
+
+ status = channelStatus switch
+ {
+ null when subchannelStatus == true => true,
+ true when subchannelStatus == null => true,
+ _ => status
+ };
+
+ return status;
+ }
+
+ case 2352:
+ return CheckCdSectorChannel(buffer, out correctEccP, out correctEccQ, out correctEdc);
+ default:
+ return null;
+ }
+ }
+
+ static void EccInit()
+ {
+ _eccFTable = new byte[256];
+ _eccBTable = new byte[256];
+ _edcTable = new uint[256];
+
+ for(uint i = 0; i < 256; i++)
+ {
+ uint edc = i;
+ var j = (uint)(i << 1 ^ ((i & 0x80) == 0x80 ? 0x11D : 0));
+ _eccFTable[i] = (byte)j;
+ _eccBTable[i ^ j] = (byte)i;
+
+ for(j = 0; j < 8; j++) edc = edc >> 1 ^ ((edc & 1) > 0 ? 0xD8018001 : 0);
+
+ _edcTable[i] = edc;
+ }
+ }
+
+ static bool CheckEcc(byte[] address, byte[] data, uint majorCount, uint minorCount, uint majorMult, uint minorInc,
+ byte[] ecc)
+ {
+ uint size = majorCount * minorCount;
+ uint major;
+
+ for(major = 0; major < majorCount; major++)
+ {
+ uint index = (major >> 1) * majorMult + (major & 1);
+ byte eccA = 0;
+ byte eccB = 0;
+ uint minor;
+
+ for(minor = 0; minor < minorCount; minor++)
+ {
+ byte temp = index < 4 ? address[index] : data[index - 4];
+ index += minorInc;
+
+ if(index >= size) index -= size;
+
+ eccA ^= temp;
+ eccB ^= temp;
+ eccA = _eccFTable[eccA];
+ }
+
+ eccA = _eccBTable[_eccFTable[eccA] ^ eccB];
+
+ if(ecc[major] != eccA || ecc[major + majorCount] != (eccA ^ eccB)) return false;
+ }
+
+ return true;
+ }
+
+ static bool? CheckCdSectorChannel(byte[] channel, out bool? correctEccP, out bool? correctEccQ,
+ out bool? correctEdc)
+ {
+ EccInit();
+
+ correctEccP = null;
+ correctEccQ = null;
+ correctEdc = null;
+
+ if(channel[0x000] != 0x00 ||
+ channel[0x001] != 0xFF ||
+ channel[0x002] != 0xFF ||
+ channel[0x003] != 0xFF ||
+ channel[0x004] != 0xFF ||
+ channel[0x005] != 0xFF ||
+ channel[0x006] != 0xFF ||
+ channel[0x007] != 0xFF ||
+ channel[0x008] != 0xFF ||
+ channel[0x009] != 0xFF ||
+ channel[0x00A] != 0xFF ||
+ channel[0x00B] != 0x00)
+ return null;
+
+ //AaruConsole.DebugWriteLine(MODULE_NAME, "Data sector, address {0:X2}:{1:X2}:{2:X2}", channel[0x00C],
+ // channel[0x00D], channel[0x00E]);
+
+ switch(channel[0x00F] & 0x03)
+ {
+ // mode (1 byte)
+ case 0x00:
+ {
+ //AaruConsole.DebugWriteLine(MODULE_NAME, "Mode 0 sector at address {0:X2}:{1:X2}:{2:X2}",
+ // channel[0x00C], channel[0x00D], channel[0x00E]);
+ for(var i = 0x010; i < 0x930; i++)
+ {
+ if(channel[i] == 0x00) continue;
+
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ "Mode 0 sector with error at address: {0:X2}:{1:X2}:{2:X2}",
+ channel[0x00C],
+ channel[0x00D],
+ channel[0x00E]);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ // mode (1 byte)
+ //AaruConsole.DebugWriteLine(MODULE_NAME, "Mode 1 sector at address {0:X2}:{1:X2}:{2:X2}",
+ // channel[0x00C], channel[0x00D], channel[0x00E]);
+ case 0x01 when channel[0x814] != 0x00 || // reserved (8 bytes)
+ channel[0x815] != 0x00 ||
+ channel[0x816] != 0x00 ||
+ channel[0x817] != 0x00 ||
+ channel[0x818] != 0x00 ||
+ channel[0x819] != 0x00 ||
+ channel[0x81A] != 0x00 ||
+ channel[0x81B] != 0x00:
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ "Mode 1 sector with data in reserved bytes at address: {0:X2}:{1:X2}:{2:X2}",
+ channel[0x00C],
+ channel[0x00D],
+ channel[0x00E]);
+
+ return false;
+ case 0x01:
+ {
+ var address = new byte[4];
+ var data = new byte[2060];
+ var data2 = new byte[2232];
+ var eccP = new byte[172];
+ var eccQ = new byte[104];
+
+ Array.Copy(channel, 0x0C, address, 0, 4);
+ Array.Copy(channel, 0x10, data, 0, 2060);
+ Array.Copy(channel, 0x10, data2, 0, 2232);
+ Array.Copy(channel, 0x81C, eccP, 0, 172);
+ Array.Copy(channel, 0x8C8, eccQ, 0, 104);
+
+ bool failedEccP = !CheckEcc(address, data, 86, 24, 2, 86, eccP);
+ bool failedEccQ = !CheckEcc(address, data2, 52, 43, 86, 88, eccQ);
+
+ correctEccP = !failedEccP;
+ correctEccQ = !failedEccQ;
+
+ if(failedEccP)
+ {
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ "Mode 1 sector at address: {0:X2}:{1:X2}:{2:X2}, fails ECC P check",
+ channel[0x00C],
+ channel[0x00D],
+ channel[0x00E]);
+ }
+
+ if(failedEccQ)
+ {
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ "Mode 1 sector at address: {0:X2}:{1:X2}:{2:X2}, fails ECC Q check",
+ channel[0x00C],
+ channel[0x00D],
+ channel[0x00E]);
+ }
+
+ var storedEdc = BitConverter.ToUInt32(channel, 0x810);
+ uint calculatedEdc = ComputeEdc(0, channel, 0x810);
+
+ correctEdc = calculatedEdc == storedEdc;
+
+ if(calculatedEdc == storedEdc) return !failedEccP && !failedEccQ;
+
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ "Mode 1 sector at address: {0:X2}:{1:X2}:{2:X2}, got CRC 0x{3:X8} expected 0x{4:X8}",
+ channel[0x00C],
+ channel[0x00D],
+ channel[0x00E],
+ calculatedEdc,
+ storedEdc);
+
+ return false;
+ }
+
+ // mode (1 byte)
+ case 0x02:
+ {
+ //AaruConsole.DebugWriteLine(MODULE_NAME, "Mode 2 sector at address {0:X2}:{1:X2}:{2:X2}",
+ // channel[0x00C], channel[0x00D], channel[0x00E]);
+ var mode2Sector = new byte[channel.Length - 0x10];
+ Array.Copy(channel, 0x10, mode2Sector, 0, mode2Sector.Length);
+
+ if((channel[0x012] & 0x20) == 0x20) // mode 2 form 2
+ {
+ if(channel[0x010] != channel[0x014] ||
+ channel[0x011] != channel[0x015] ||
+ channel[0x012] != channel[0x016] ||
+ channel[0x013] != channel[0x017])
+ {
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ "Subheader copies differ in mode 2 form 2 sector at address: {0:X2}:{1:X2}:{2:X2}",
+ channel[0x00C],
+ channel[0x00D],
+ channel[0x00E]);
+ }
+
+ var storedEdc = BitConverter.ToUInt32(mode2Sector, 0x91C);
+
+ // No CRC stored!
+ if(storedEdc == 0x00000000) return true;
+
+ uint calculatedEdc = ComputeEdc(0, mode2Sector, 0x91C);
+
+ correctEdc = calculatedEdc == storedEdc;
+
+ if(calculatedEdc == storedEdc) return true;
+
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ "Mode 2 form 2 sector at address: {0:X2}:{1:X2}:{2:X2}, got CRC 0x{3:X8} expected 0x{4:X8}",
+ channel[0x00C],
+ channel[0x00D],
+ channel[0x00E],
+ calculatedEdc,
+ storedEdc);
+
+ return false;
+ }
+ else
+ {
+ if(channel[0x010] != channel[0x014] ||
+ channel[0x011] != channel[0x015] ||
+ channel[0x012] != channel[0x016] ||
+ channel[0x013] != channel[0x017])
+ {
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ "Subheader copies differ in mode 2 form 1 sector at address: {0:X2}:{1:X2}:{2:X2}",
+ channel[0x00C],
+ channel[0x00D],
+ channel[0x00E]);
+ }
+
+ var address = new byte[4];
+ var eccP = new byte[172];
+ var eccQ = new byte[104];
+
+ Array.Copy(mode2Sector, 0x80C, eccP, 0, 172);
+ Array.Copy(mode2Sector, 0x8B8, eccQ, 0, 104);
+
+ bool failedEccP = !CheckEcc(address, mode2Sector, 86, 24, 2, 86, eccP);
+ bool failedEccQ = !CheckEcc(address, mode2Sector, 52, 43, 86, 88, eccQ);
+
+ correctEccP = !failedEccP;
+ correctEccQ = !failedEccQ;
+
+ if(failedEccP)
+ {
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ "Mode 2 form 1 sector at address: {0:X2}:{1:X2}:{2:X2}, fails ECC P check",
+ channel[0x00C],
+ channel[0x00D],
+ channel[0x00E]);
+ }
+
+ if(failedEccQ)
+ {
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ "Mode 2 form 1 sector at address: {0:X2}:{1:X2}:{2:X2}, fails ECC Q check",
+ channel[0x00C],
+ channel[0x00D],
+ channel[0x00E]);
+ }
+
+ var storedEdc = BitConverter.ToUInt32(mode2Sector, 0x808);
+ uint calculatedEdc = ComputeEdc(0, mode2Sector, 0x808);
+
+ correctEdc = calculatedEdc == storedEdc;
+
+ if(calculatedEdc == storedEdc) return !failedEccP && !failedEccQ;
+
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ "Mode 2 sector at address: {0:X2}:{1:X2}:{2:X2}, got CRC 0x{3:X8} expected 0x{4:X8}",
+ channel[0x00C],
+ channel[0x00D],
+ channel[0x00E],
+ calculatedEdc,
+ storedEdc);
+
+ return false;
+ }
+ }
+ default:
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ "Unknown mode {0} sector at address: {1:X2}:{2:X2}:{3:X2}",
+ channel[0x00F],
+ channel[0x00C],
+ channel[0x00D],
+ channel[0x00E]);
+
+ return null;
+ }
+ }
+
+ static uint ComputeEdc(uint edc, IReadOnlyList src, int size)
+ {
+ var pos = 0;
+
+ for(; size > 0; size--) edc = edc >> 8 ^ _edcTable[(edc ^ src[pos++]) & 0xFF];
+
+ return edc;
+ }
+
+ static bool? CheckCdSectorSubChannel(IReadOnlyList subchannel)
+ {
+ bool? status = true;
+ var qSubChannel = new byte[12];
+ var cdTextPack1 = new byte[18];
+ var cdTextPack2 = new byte[18];
+ var cdTextPack3 = new byte[18];
+ var cdTextPack4 = new byte[18];
+ var cdSubRwPack1 = new byte[24];
+ var cdSubRwPack2 = new byte[24];
+ var cdSubRwPack3 = new byte[24];
+ var cdSubRwPack4 = new byte[24];
+
+ var i = 0;
+
+ for(var j = 0; j < 12; j++) qSubChannel[j] = 0;
+
+ for(var j = 0; j < 18; j++)
+ {
+ cdTextPack1[j] = 0;
+ cdTextPack2[j] = 0;
+ cdTextPack3[j] = 0;
+ cdTextPack4[j] = 0;
+ }
+
+ for(var j = 0; j < 24; j++)
+ {
+ cdSubRwPack1[j] = 0;
+ cdSubRwPack2[j] = 0;
+ cdSubRwPack3[j] = 0;
+ cdSubRwPack4[j] = 0;
+ }
+
+ for(var j = 0; j < 12; j++)
+ {
+ qSubChannel[j] = (byte)(qSubChannel[j] | (subchannel[i++] & 0x40) << 1);
+ qSubChannel[j] = (byte)(qSubChannel[j] | subchannel[i++] & 0x40);
+ qSubChannel[j] = (byte)(qSubChannel[j] | (subchannel[i++] & 0x40) >> 1);
+ qSubChannel[j] = (byte)(qSubChannel[j] | (subchannel[i++] & 0x40) >> 2);
+ qSubChannel[j] = (byte)(qSubChannel[j] | (subchannel[i++] & 0x40) >> 3);
+ qSubChannel[j] = (byte)(qSubChannel[j] | (subchannel[i++] & 0x40) >> 4);
+ qSubChannel[j] = (byte)(qSubChannel[j] | (subchannel[i++] & 0x40) >> 5);
+ qSubChannel[j] = (byte)(qSubChannel[j] | (subchannel[i++] & 0x40) >> 6);
+ }
+
+ i = 0;
+
+ for(var j = 0; j < 18; j++)
+ {
+ cdTextPack1[j] = (byte)(cdTextPack1[j] | (subchannel[i++] & 0x3F) << 2);
+
+ if(j < 17) cdTextPack1[j] = (byte)(cdTextPack1[j++] | (subchannel[i] & 0xC0) >> 4);
+
+ cdTextPack1[j] = (byte)(cdTextPack1[j] | (subchannel[i++] & 0x0F) << 4);
+
+ if(j < 17) cdTextPack1[j] = (byte)(cdTextPack1[j++] | (subchannel[i] & 0x3C) >> 2);
+
+ cdTextPack1[j] = (byte)(cdTextPack1[j] | (subchannel[i++] & 0x03) << 6);
+
+ cdTextPack1[j] = (byte)(cdTextPack1[j] | subchannel[i++] & 0x3F);
+ }
+
+ for(var j = 0; j < 18; j++)
+ {
+ cdTextPack2[j] = (byte)(cdTextPack2[j] | (subchannel[i++] & 0x3F) << 2);
+
+ if(j < 17) cdTextPack2[j] = (byte)(cdTextPack2[j++] | (subchannel[i] & 0xC0) >> 4);
+
+ cdTextPack2[j] = (byte)(cdTextPack2[j] | (subchannel[i++] & 0x0F) << 4);
+
+ if(j < 17) cdTextPack2[j] = (byte)(cdTextPack2[j++] | (subchannel[i] & 0x3C) >> 2);
+
+ cdTextPack2[j] = (byte)(cdTextPack2[j] | (subchannel[i++] & 0x03) << 6);
+
+ cdTextPack2[j] = (byte)(cdTextPack2[j] | subchannel[i++] & 0x3F);
+ }
+
+ for(var j = 0; j < 18; j++)
+ {
+ cdTextPack3[j] = (byte)(cdTextPack3[j] | (subchannel[i++] & 0x3F) << 2);
+
+ if(j < 17) cdTextPack3[j] = (byte)(cdTextPack3[j++] | (subchannel[i] & 0xC0) >> 4);
+
+ cdTextPack3[j] = (byte)(cdTextPack3[j] | (subchannel[i++] & 0x0F) << 4);
+
+ if(j < 17) cdTextPack3[j] = (byte)(cdTextPack3[j++] | (subchannel[i] & 0x3C) >> 2);
+
+ cdTextPack3[j] = (byte)(cdTextPack3[j] | (subchannel[i++] & 0x03) << 6);
+
+ cdTextPack3[j] = (byte)(cdTextPack3[j] | subchannel[i++] & 0x3F);
+ }
+
+ for(var j = 0; j < 18; j++)
+ {
+ cdTextPack4[j] = (byte)(cdTextPack4[j] | (subchannel[i++] & 0x3F) << 2);
+
+ if(j < 17) cdTextPack4[j] = (byte)(cdTextPack4[j++] | (subchannel[i] & 0xC0) >> 4);
+
+ cdTextPack4[j] = (byte)(cdTextPack4[j] | (subchannel[i++] & 0x0F) << 4);
+
+ if(j < 17) cdTextPack4[j] = (byte)(cdTextPack4[j++] | (subchannel[i] & 0x3C) >> 2);
+
+ cdTextPack4[j] = (byte)(cdTextPack4[j] | (subchannel[i++] & 0x03) << 6);
+
+ cdTextPack4[j] = (byte)(cdTextPack4[j] | subchannel[i++] & 0x3F);
+ }
+
+ i = 0;
+
+ for(var j = 0; j < 24; j++) cdSubRwPack1[j] = (byte)(subchannel[i++] & 0x3F);
+
+ for(var j = 0; j < 24; j++) cdSubRwPack2[j] = (byte)(subchannel[i++] & 0x3F);
+
+ for(var j = 0; j < 24; j++) cdSubRwPack3[j] = (byte)(subchannel[i++] & 0x3F);
+
+ for(var j = 0; j < 24; j++) cdSubRwPack4[j] = (byte)(subchannel[i++] & 0x3F);
+
+ switch(cdSubRwPack1[0])
+ {
+ case 0x00:
+ AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Detected_Zero_Pack_in_subchannel);
+
+ break;
+ case 0x08:
+ AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Detected_Line_Graphics_Pack_in_subchannel);
+
+ break;
+ case 0x09:
+ AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Detected_CD_G_Pack_in_subchannel);
+
+ break;
+ case 0x0A:
+ AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Detected_CD_EG_Pack_in_subchannel);
+
+ break;
+ case 0x14:
+ AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Detected_CD_TEXT_Pack_in_subchannel);
+
+ break;
+ case 0x18:
+ AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Detected_CD_MIDI_Pack_in_subchannel);
+
+ break;
+ case 0x38:
+ AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Detected_User_Pack_in_subchannel);
+
+ break;
+ default:
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ Localization.Detected_unknown_Pack_type_in_subchannel_mode_0_item_1,
+ Convert.ToString(cdSubRwPack1[0] & 0x38, 2),
+ Convert.ToString(cdSubRwPack1[0] & 0x07, 2));
+
+ break;
+ }
+
+ var qSubChannelCrc = BigEndianBitConverter.ToUInt16(qSubChannel, 10);
+ var qSubChannelForCrc = new byte[10];
+ Array.Copy(qSubChannel, 0, qSubChannelForCrc, 0, 10);
+ ushort calculatedQcrc = CRC16CcittContext.Calculate(qSubChannelForCrc);
+
+ if(qSubChannelCrc != calculatedQcrc)
+ {
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ Localization.Q_subchannel_CRC_0_expected_1,
+ calculatedQcrc,
+ qSubChannelCrc);
+
+ status = false;
+ }
+
+ if((cdTextPack1[0] & 0x80) == 0x80)
+ {
+ var cdTextPack1Crc = BigEndianBitConverter.ToUInt16(cdTextPack1, 16);
+ var cdTextPack1ForCrc = new byte[16];
+ Array.Copy(cdTextPack1, 0, cdTextPack1ForCrc, 0, 16);
+ ushort calculatedCdtp1Crc = CRC16CcittContext.Calculate(cdTextPack1ForCrc);
+
+ if(cdTextPack1Crc != calculatedCdtp1Crc && cdTextPack1Crc != 0)
+ {
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ Localization.CD_Text_Pack_one_CRC_0_expected_1,
+ cdTextPack1Crc,
+ calculatedCdtp1Crc);
+
+ status = false;
+ }
+ }
+
+ if((cdTextPack2[0] & 0x80) == 0x80)
+ {
+ var cdTextPack2Crc = BigEndianBitConverter.ToUInt16(cdTextPack2, 16);
+ var cdTextPack2ForCrc = new byte[16];
+ Array.Copy(cdTextPack2, 0, cdTextPack2ForCrc, 0, 16);
+ ushort calculatedCdtp2Crc = CRC16CcittContext.Calculate(cdTextPack2ForCrc);
+
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ Localization.Cyclic_CDTP2_0_Calc_CDTP2_1,
+ cdTextPack2Crc,
+ calculatedCdtp2Crc);
+
+ if(cdTextPack2Crc != calculatedCdtp2Crc && cdTextPack2Crc != 0)
+ {
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ Localization.CD_Text_Pack_two_CRC_0_expected_1,
+ cdTextPack2Crc,
+ calculatedCdtp2Crc);
+
+ status = false;
+ }
+ }
+
+ if((cdTextPack3[0] & 0x80) == 0x80)
+ {
+ var cdTextPack3Crc = BigEndianBitConverter.ToUInt16(cdTextPack3, 16);
+ var cdTextPack3ForCrc = new byte[16];
+ Array.Copy(cdTextPack3, 0, cdTextPack3ForCrc, 0, 16);
+ ushort calculatedCdtp3Crc = CRC16CcittContext.Calculate(cdTextPack3ForCrc);
+
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ Localization.Cyclic_CDTP3_0_Calc_CDTP3_1,
+ cdTextPack3Crc,
+ calculatedCdtp3Crc);
+
+ if(cdTextPack3Crc != calculatedCdtp3Crc && cdTextPack3Crc != 0)
+ {
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ Localization.CD_Text_Pack_three_CRC_0_expected_1,
+ cdTextPack3Crc,
+ calculatedCdtp3Crc);
+
+ status = false;
+ }
+ }
+
+ if((cdTextPack4[0] & 0x80) != 0x80) return status;
+
+ var cdTextPack4Crc = BigEndianBitConverter.ToUInt16(cdTextPack4, 16);
+ var cdTextPack4ForCrc = new byte[16];
+ Array.Copy(cdTextPack4, 0, cdTextPack4ForCrc, 0, 16);
+ ushort calculatedCdtp4Crc = CRC16CcittContext.Calculate(cdTextPack4ForCrc);
+
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ Localization.Cyclic_CDTP4_0_Calc_CDTP4_1,
+ cdTextPack4Crc,
+ calculatedCdtp4Crc);
+
+ if(cdTextPack4Crc == calculatedCdtp4Crc || cdTextPack4Crc == 0) return status;
+
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ Localization.CD_Text_Pack_four_CRC_0_expected_1,
+ cdTextPack4Crc,
+ calculatedCdtp4Crc);
+
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/CRC16CCITTContext.cs b/Aaru.Checksums/CRC16CCITTContext.cs
new file mode 100644
index 000000000..4762c6d7a
--- /dev/null
+++ b/Aaru.Checksums/CRC16CCITTContext.cs
@@ -0,0 +1,266 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : CRC16CCITTContext.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Implements a CRC16 algorithm with the CCITT polynomial.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Aaru.Checksums;
+
+///
+/// Implements the CRC16 algorithm with CCITT polynomial and seed
+[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
+public sealed class CRC16CcittContext : Crc16Context
+{
+ /// CCITT CRC16 polynomial
+ public const ushort CRC16CcittPoly = 0x8408;
+ /// CCITT CRC16 seed
+ public const ushort CRC16CcittSeed = 0x0000;
+ static readonly ushort[][] _ccittCrc16Table =
+ [
+ [
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C,
+ 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318,
+ 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4,
+ 0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, 0x3653, 0x2672, 0x1611, 0x0630,
+ 0x76D7, 0x66F6, 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, 0x48C4,
+ 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969,
+ 0xA90A, 0xB92B, 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC, 0xFBBF,
+ 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
+ 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13,
+ 0x2E32, 0x1E51, 0x0E70, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, 0x9188, 0x81A9,
+ 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046,
+ 0x6067, 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x02B1, 0x1290, 0x22F3, 0x32D2,
+ 0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0x34E2,
+ 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E,
+ 0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, 0xD94C, 0xC96D, 0xF90E,
+ 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
+ 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1,
+ 0x1AD0, 0x2AB3, 0x3A92, 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07,
+ 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9,
+ 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
+ ],
+ [
+ 0x0000, 0x3331, 0x6662, 0x5553, 0xCCC4, 0xFFF5, 0xAAA6, 0x9997, 0x89A9, 0xBA98, 0xEFCB, 0xDCFA, 0x456D,
+ 0x765C, 0x230F, 0x103E, 0x0373, 0x3042, 0x6511, 0x5620, 0xCFB7, 0xFC86, 0xA9D5, 0x9AE4, 0x8ADA, 0xB9EB,
+ 0xECB8, 0xDF89, 0x461E, 0x752F, 0x207C, 0x134D, 0x06E6, 0x35D7, 0x6084, 0x53B5, 0xCA22, 0xF913, 0xAC40,
+ 0x9F71, 0x8F4F, 0xBC7E, 0xE92D, 0xDA1C, 0x438B, 0x70BA, 0x25E9, 0x16D8, 0x0595, 0x36A4, 0x63F7, 0x50C6,
+ 0xC951, 0xFA60, 0xAF33, 0x9C02, 0x8C3C, 0xBF0D, 0xEA5E, 0xD96F, 0x40F8, 0x73C9, 0x269A, 0x15AB, 0x0DCC,
+ 0x3EFD, 0x6BAE, 0x589F, 0xC108, 0xF239, 0xA76A, 0x945B, 0x8465, 0xB754, 0xE207, 0xD136, 0x48A1, 0x7B90,
+ 0x2EC3, 0x1DF2, 0x0EBF, 0x3D8E, 0x68DD, 0x5BEC, 0xC27B, 0xF14A, 0xA419, 0x9728, 0x8716, 0xB427, 0xE174,
+ 0xD245, 0x4BD2, 0x78E3, 0x2DB0, 0x1E81, 0x0B2A, 0x381B, 0x6D48, 0x5E79, 0xC7EE, 0xF4DF, 0xA18C, 0x92BD,
+ 0x8283, 0xB1B2, 0xE4E1, 0xD7D0, 0x4E47, 0x7D76, 0x2825, 0x1B14, 0x0859, 0x3B68, 0x6E3B, 0x5D0A, 0xC49D,
+ 0xF7AC, 0xA2FF, 0x91CE, 0x81F0, 0xB2C1, 0xE792, 0xD4A3, 0x4D34, 0x7E05, 0x2B56, 0x1867, 0x1B98, 0x28A9,
+ 0x7DFA, 0x4ECB, 0xD75C, 0xE46D, 0xB13E, 0x820F, 0x9231, 0xA100, 0xF453, 0xC762, 0x5EF5, 0x6DC4, 0x3897,
+ 0x0BA6, 0x18EB, 0x2BDA, 0x7E89, 0x4DB8, 0xD42F, 0xE71E, 0xB24D, 0x817C, 0x9142, 0xA273, 0xF720, 0xC411,
+ 0x5D86, 0x6EB7, 0x3BE4, 0x08D5, 0x1D7E, 0x2E4F, 0x7B1C, 0x482D, 0xD1BA, 0xE28B, 0xB7D8, 0x84E9, 0x94D7,
+ 0xA7E6, 0xF2B5, 0xC184, 0x5813, 0x6B22, 0x3E71, 0x0D40, 0x1E0D, 0x2D3C, 0x786F, 0x4B5E, 0xD2C9, 0xE1F8,
+ 0xB4AB, 0x879A, 0x97A4, 0xA495, 0xF1C6, 0xC2F7, 0x5B60, 0x6851, 0x3D02, 0x0E33, 0x1654, 0x2565, 0x7036,
+ 0x4307, 0xDA90, 0xE9A1, 0xBCF2, 0x8FC3, 0x9FFD, 0xACCC, 0xF99F, 0xCAAE, 0x5339, 0x6008, 0x355B, 0x066A,
+ 0x1527, 0x2616, 0x7345, 0x4074, 0xD9E3, 0xEAD2, 0xBF81, 0x8CB0, 0x9C8E, 0xAFBF, 0xFAEC, 0xC9DD, 0x504A,
+ 0x637B, 0x3628, 0x0519, 0x10B2, 0x2383, 0x76D0, 0x45E1, 0xDC76, 0xEF47, 0xBA14, 0x8925, 0x991B, 0xAA2A,
+ 0xFF79, 0xCC48, 0x55DF, 0x66EE, 0x33BD, 0x008C, 0x13C1, 0x20F0, 0x75A3, 0x4692, 0xDF05, 0xEC34, 0xB967,
+ 0x8A56, 0x9A68, 0xA959, 0xFC0A, 0xCF3B, 0x56AC, 0x659D, 0x30CE, 0x03FF
+ ],
+ [
+ 0x0000, 0x3730, 0x6E60, 0x5950, 0xDCC0, 0xEBF0, 0xB2A0, 0x8590, 0xA9A1, 0x9E91, 0xC7C1, 0xF0F1, 0x7561,
+ 0x4251, 0x1B01, 0x2C31, 0x4363, 0x7453, 0x2D03, 0x1A33, 0x9FA3, 0xA893, 0xF1C3, 0xC6F3, 0xEAC2, 0xDDF2,
+ 0x84A2, 0xB392, 0x3602, 0x0132, 0x5862, 0x6F52, 0x86C6, 0xB1F6, 0xE8A6, 0xDF96, 0x5A06, 0x6D36, 0x3466,
+ 0x0356, 0x2F67, 0x1857, 0x4107, 0x7637, 0xF3A7, 0xC497, 0x9DC7, 0xAAF7, 0xC5A5, 0xF295, 0xABC5, 0x9CF5,
+ 0x1965, 0x2E55, 0x7705, 0x4035, 0x6C04, 0x5B34, 0x0264, 0x3554, 0xB0C4, 0x87F4, 0xDEA4, 0xE994, 0x1DAD,
+ 0x2A9D, 0x73CD, 0x44FD, 0xC16D, 0xF65D, 0xAF0D, 0x983D, 0xB40C, 0x833C, 0xDA6C, 0xED5C, 0x68CC, 0x5FFC,
+ 0x06AC, 0x319C, 0x5ECE, 0x69FE, 0x30AE, 0x079E, 0x820E, 0xB53E, 0xEC6E, 0xDB5E, 0xF76F, 0xC05F, 0x990F,
+ 0xAE3F, 0x2BAF, 0x1C9F, 0x45CF, 0x72FF, 0x9B6B, 0xAC5B, 0xF50B, 0xC23B, 0x47AB, 0x709B, 0x29CB, 0x1EFB,
+ 0x32CA, 0x05FA, 0x5CAA, 0x6B9A, 0xEE0A, 0xD93A, 0x806A, 0xB75A, 0xD808, 0xEF38, 0xB668, 0x8158, 0x04C8,
+ 0x33F8, 0x6AA8, 0x5D98, 0x71A9, 0x4699, 0x1FC9, 0x28F9, 0xAD69, 0x9A59, 0xC309, 0xF439, 0x3B5A, 0x0C6A,
+ 0x553A, 0x620A, 0xE79A, 0xD0AA, 0x89FA, 0xBECA, 0x92FB, 0xA5CB, 0xFC9B, 0xCBAB, 0x4E3B, 0x790B, 0x205B,
+ 0x176B, 0x7839, 0x4F09, 0x1659, 0x2169, 0xA4F9, 0x93C9, 0xCA99, 0xFDA9, 0xD198, 0xE6A8, 0xBFF8, 0x88C8,
+ 0x0D58, 0x3A68, 0x6338, 0x5408, 0xBD9C, 0x8AAC, 0xD3FC, 0xE4CC, 0x615C, 0x566C, 0x0F3C, 0x380C, 0x143D,
+ 0x230D, 0x7A5D, 0x4D6D, 0xC8FD, 0xFFCD, 0xA69D, 0x91AD, 0xFEFF, 0xC9CF, 0x909F, 0xA7AF, 0x223F, 0x150F,
+ 0x4C5F, 0x7B6F, 0x575E, 0x606E, 0x393E, 0x0E0E, 0x8B9E, 0xBCAE, 0xE5FE, 0xD2CE, 0x26F7, 0x11C7, 0x4897,
+ 0x7FA7, 0xFA37, 0xCD07, 0x9457, 0xA367, 0x8F56, 0xB866, 0xE136, 0xD606, 0x5396, 0x64A6, 0x3DF6, 0x0AC6,
+ 0x6594, 0x52A4, 0x0BF4, 0x3CC4, 0xB954, 0x8E64, 0xD734, 0xE004, 0xCC35, 0xFB05, 0xA255, 0x9565, 0x10F5,
+ 0x27C5, 0x7E95, 0x49A5, 0xA031, 0x9701, 0xCE51, 0xF961, 0x7CF1, 0x4BC1, 0x1291, 0x25A1, 0x0990, 0x3EA0,
+ 0x67F0, 0x50C0, 0xD550, 0xE260, 0xBB30, 0x8C00, 0xE352, 0xD462, 0x8D32, 0xBA02, 0x3F92, 0x08A2, 0x51F2,
+ 0x66C2, 0x4AF3, 0x7DC3, 0x2493, 0x13A3, 0x9633, 0xA103, 0xF853, 0xCF63
+ ],
+ [
+ 0x0000, 0x76B4, 0xED68, 0x9BDC, 0xCAF1, 0xBC45, 0x2799, 0x512D, 0x85C3, 0xF377, 0x68AB, 0x1E1F, 0x4F32,
+ 0x3986, 0xA25A, 0xD4EE, 0x1BA7, 0x6D13, 0xF6CF, 0x807B, 0xD156, 0xA7E2, 0x3C3E, 0x4A8A, 0x9E64, 0xE8D0,
+ 0x730C, 0x05B8, 0x5495, 0x2221, 0xB9FD, 0xCF49, 0x374E, 0x41FA, 0xDA26, 0xAC92, 0xFDBF, 0x8B0B, 0x10D7,
+ 0x6663, 0xB28D, 0xC439, 0x5FE5, 0x2951, 0x787C, 0x0EC8, 0x9514, 0xE3A0, 0x2CE9, 0x5A5D, 0xC181, 0xB735,
+ 0xE618, 0x90AC, 0x0B70, 0x7DC4, 0xA92A, 0xDF9E, 0x4442, 0x32F6, 0x63DB, 0x156F, 0x8EB3, 0xF807, 0x6E9C,
+ 0x1828, 0x83F4, 0xF540, 0xA46D, 0xD2D9, 0x4905, 0x3FB1, 0xEB5F, 0x9DEB, 0x0637, 0x7083, 0x21AE, 0x571A,
+ 0xCCC6, 0xBA72, 0x753B, 0x038F, 0x9853, 0xEEE7, 0xBFCA, 0xC97E, 0x52A2, 0x2416, 0xF0F8, 0x864C, 0x1D90,
+ 0x6B24, 0x3A09, 0x4CBD, 0xD761, 0xA1D5, 0x59D2, 0x2F66, 0xB4BA, 0xC20E, 0x9323, 0xE597, 0x7E4B, 0x08FF,
+ 0xDC11, 0xAAA5, 0x3179, 0x47CD, 0x16E0, 0x6054, 0xFB88, 0x8D3C, 0x4275, 0x34C1, 0xAF1D, 0xD9A9, 0x8884,
+ 0xFE30, 0x65EC, 0x1358, 0xC7B6, 0xB102, 0x2ADE, 0x5C6A, 0x0D47, 0x7BF3, 0xE02F, 0x969B, 0xDD38, 0xAB8C,
+ 0x3050, 0x46E4, 0x17C9, 0x617D, 0xFAA1, 0x8C15, 0x58FB, 0x2E4F, 0xB593, 0xC327, 0x920A, 0xE4BE, 0x7F62,
+ 0x09D6, 0xC69F, 0xB02B, 0x2BF7, 0x5D43, 0x0C6E, 0x7ADA, 0xE106, 0x97B2, 0x435C, 0x35E8, 0xAE34, 0xD880,
+ 0x89AD, 0xFF19, 0x64C5, 0x1271, 0xEA76, 0x9CC2, 0x071E, 0x71AA, 0x2087, 0x5633, 0xCDEF, 0xBB5B, 0x6FB5,
+ 0x1901, 0x82DD, 0xF469, 0xA544, 0xD3F0, 0x482C, 0x3E98, 0xF1D1, 0x8765, 0x1CB9, 0x6A0D, 0x3B20, 0x4D94,
+ 0xD648, 0xA0FC, 0x7412, 0x02A6, 0x997A, 0xEFCE, 0xBEE3, 0xC857, 0x538B, 0x253F, 0xB3A4, 0xC510, 0x5ECC,
+ 0x2878, 0x7955, 0x0FE1, 0x943D, 0xE289, 0x3667, 0x40D3, 0xDB0F, 0xADBB, 0xFC96, 0x8A22, 0x11FE, 0x674A,
+ 0xA803, 0xDEB7, 0x456B, 0x33DF, 0x62F2, 0x1446, 0x8F9A, 0xF92E, 0x2DC0, 0x5B74, 0xC0A8, 0xB61C, 0xE731,
+ 0x9185, 0x0A59, 0x7CED, 0x84EA, 0xF25E, 0x6982, 0x1F36, 0x4E1B, 0x38AF, 0xA373, 0xD5C7, 0x0129, 0x779D,
+ 0xEC41, 0x9AF5, 0xCBD8, 0xBD6C, 0x26B0, 0x5004, 0x9F4D, 0xE9F9, 0x7225, 0x0491, 0x55BC, 0x2308, 0xB8D4,
+ 0xCE60, 0x1A8E, 0x6C3A, 0xF7E6, 0x8152, 0xD07F, 0xA6CB, 0x3D17, 0x4BA3
+ ],
+ [
+ 0x0000, 0xAA51, 0x4483, 0xEED2, 0x8906, 0x2357, 0xCD85, 0x67D4, 0x022D, 0xA87C, 0x46AE, 0xECFF, 0x8B2B,
+ 0x217A, 0xCFA8, 0x65F9, 0x045A, 0xAE0B, 0x40D9, 0xEA88, 0x8D5C, 0x270D, 0xC9DF, 0x638E, 0x0677, 0xAC26,
+ 0x42F4, 0xE8A5, 0x8F71, 0x2520, 0xCBF2, 0x61A3, 0x08B4, 0xA2E5, 0x4C37, 0xE666, 0x81B2, 0x2BE3, 0xC531,
+ 0x6F60, 0x0A99, 0xA0C8, 0x4E1A, 0xE44B, 0x839F, 0x29CE, 0xC71C, 0x6D4D, 0x0CEE, 0xA6BF, 0x486D, 0xE23C,
+ 0x85E8, 0x2FB9, 0xC16B, 0x6B3A, 0x0EC3, 0xA492, 0x4A40, 0xE011, 0x87C5, 0x2D94, 0xC346, 0x6917, 0x1168,
+ 0xBB39, 0x55EB, 0xFFBA, 0x986E, 0x323F, 0xDCED, 0x76BC, 0x1345, 0xB914, 0x57C6, 0xFD97, 0x9A43, 0x3012,
+ 0xDEC0, 0x7491, 0x1532, 0xBF63, 0x51B1, 0xFBE0, 0x9C34, 0x3665, 0xD8B7, 0x72E6, 0x171F, 0xBD4E, 0x539C,
+ 0xF9CD, 0x9E19, 0x3448, 0xDA9A, 0x70CB, 0x19DC, 0xB38D, 0x5D5F, 0xF70E, 0x90DA, 0x3A8B, 0xD459, 0x7E08,
+ 0x1BF1, 0xB1A0, 0x5F72, 0xF523, 0x92F7, 0x38A6, 0xD674, 0x7C25, 0x1D86, 0xB7D7, 0x5905, 0xF354, 0x9480,
+ 0x3ED1, 0xD003, 0x7A52, 0x1FAB, 0xB5FA, 0x5B28, 0xF179, 0x96AD, 0x3CFC, 0xD22E, 0x787F, 0x22D0, 0x8881,
+ 0x6653, 0xCC02, 0xABD6, 0x0187, 0xEF55, 0x4504, 0x20FD, 0x8AAC, 0x647E, 0xCE2F, 0xA9FB, 0x03AA, 0xED78,
+ 0x4729, 0x268A, 0x8CDB, 0x6209, 0xC858, 0xAF8C, 0x05DD, 0xEB0F, 0x415E, 0x24A7, 0x8EF6, 0x6024, 0xCA75,
+ 0xADA1, 0x07F0, 0xE922, 0x4373, 0x2A64, 0x8035, 0x6EE7, 0xC4B6, 0xA362, 0x0933, 0xE7E1, 0x4DB0, 0x2849,
+ 0x8218, 0x6CCA, 0xC69B, 0xA14F, 0x0B1E, 0xE5CC, 0x4F9D, 0x2E3E, 0x846F, 0x6ABD, 0xC0EC, 0xA738, 0x0D69,
+ 0xE3BB, 0x49EA, 0x2C13, 0x8642, 0x6890, 0xC2C1, 0xA515, 0x0F44, 0xE196, 0x4BC7, 0x33B8, 0x99E9, 0x773B,
+ 0xDD6A, 0xBABE, 0x10EF, 0xFE3D, 0x546C, 0x3195, 0x9BC4, 0x7516, 0xDF47, 0xB893, 0x12C2, 0xFC10, 0x5641,
+ 0x37E2, 0x9DB3, 0x7361, 0xD930, 0xBEE4, 0x14B5, 0xFA67, 0x5036, 0x35CF, 0x9F9E, 0x714C, 0xDB1D, 0xBCC9,
+ 0x1698, 0xF84A, 0x521B, 0x3B0C, 0x915D, 0x7F8F, 0xD5DE, 0xB20A, 0x185B, 0xF689, 0x5CD8, 0x3921, 0x9370,
+ 0x7DA2, 0xD7F3, 0xB027, 0x1A76, 0xF4A4, 0x5EF5, 0x3F56, 0x9507, 0x7BD5, 0xD184, 0xB650, 0x1C01, 0xF2D3,
+ 0x5882, 0x3D7B, 0x972A, 0x79F8, 0xD3A9, 0xB47D, 0x1E2C, 0xF0FE, 0x5AAF
+ ],
+ [
+ 0x0000, 0x45A0, 0x8B40, 0xCEE0, 0x06A1, 0x4301, 0x8DE1, 0xC841, 0x0D42, 0x48E2, 0x8602, 0xC3A2, 0x0BE3,
+ 0x4E43, 0x80A3, 0xC503, 0x1A84, 0x5F24, 0x91C4, 0xD464, 0x1C25, 0x5985, 0x9765, 0xD2C5, 0x17C6, 0x5266,
+ 0x9C86, 0xD926, 0x1167, 0x54C7, 0x9A27, 0xDF87, 0x3508, 0x70A8, 0xBE48, 0xFBE8, 0x33A9, 0x7609, 0xB8E9,
+ 0xFD49, 0x384A, 0x7DEA, 0xB30A, 0xF6AA, 0x3EEB, 0x7B4B, 0xB5AB, 0xF00B, 0x2F8C, 0x6A2C, 0xA4CC, 0xE16C,
+ 0x292D, 0x6C8D, 0xA26D, 0xE7CD, 0x22CE, 0x676E, 0xA98E, 0xEC2E, 0x246F, 0x61CF, 0xAF2F, 0xEA8F, 0x6A10,
+ 0x2FB0, 0xE150, 0xA4F0, 0x6CB1, 0x2911, 0xE7F1, 0xA251, 0x6752, 0x22F2, 0xEC12, 0xA9B2, 0x61F3, 0x2453,
+ 0xEAB3, 0xAF13, 0x7094, 0x3534, 0xFBD4, 0xBE74, 0x7635, 0x3395, 0xFD75, 0xB8D5, 0x7DD6, 0x3876, 0xF696,
+ 0xB336, 0x7B77, 0x3ED7, 0xF037, 0xB597, 0x5F18, 0x1AB8, 0xD458, 0x91F8, 0x59B9, 0x1C19, 0xD2F9, 0x9759,
+ 0x525A, 0x17FA, 0xD91A, 0x9CBA, 0x54FB, 0x115B, 0xDFBB, 0x9A1B, 0x459C, 0x003C, 0xCEDC, 0x8B7C, 0x433D,
+ 0x069D, 0xC87D, 0x8DDD, 0x48DE, 0x0D7E, 0xC39E, 0x863E, 0x4E7F, 0x0BDF, 0xC53F, 0x809F, 0xD420, 0x9180,
+ 0x5F60, 0x1AC0, 0xD281, 0x9721, 0x59C1, 0x1C61, 0xD962, 0x9CC2, 0x5222, 0x1782, 0xDFC3, 0x9A63, 0x5483,
+ 0x1123, 0xCEA4, 0x8B04, 0x45E4, 0x0044, 0xC805, 0x8DA5, 0x4345, 0x06E5, 0xC3E6, 0x8646, 0x48A6, 0x0D06,
+ 0xC547, 0x80E7, 0x4E07, 0x0BA7, 0xE128, 0xA488, 0x6A68, 0x2FC8, 0xE789, 0xA229, 0x6CC9, 0x2969, 0xEC6A,
+ 0xA9CA, 0x672A, 0x228A, 0xEACB, 0xAF6B, 0x618B, 0x242B, 0xFBAC, 0xBE0C, 0x70EC, 0x354C, 0xFD0D, 0xB8AD,
+ 0x764D, 0x33ED, 0xF6EE, 0xB34E, 0x7DAE, 0x380E, 0xF04F, 0xB5EF, 0x7B0F, 0x3EAF, 0xBE30, 0xFB90, 0x3570,
+ 0x70D0, 0xB891, 0xFD31, 0x33D1, 0x7671, 0xB372, 0xF6D2, 0x3832, 0x7D92, 0xB5D3, 0xF073, 0x3E93, 0x7B33,
+ 0xA4B4, 0xE114, 0x2FF4, 0x6A54, 0xA215, 0xE7B5, 0x2955, 0x6CF5, 0xA9F6, 0xEC56, 0x22B6, 0x6716, 0xAF57,
+ 0xEAF7, 0x2417, 0x61B7, 0x8B38, 0xCE98, 0x0078, 0x45D8, 0x8D99, 0xC839, 0x06D9, 0x4379, 0x867A, 0xC3DA,
+ 0x0D3A, 0x489A, 0x80DB, 0xC57B, 0x0B9B, 0x4E3B, 0x91BC, 0xD41C, 0x1AFC, 0x5F5C, 0x971D, 0xD2BD, 0x1C5D,
+ 0x59FD, 0x9CFE, 0xD95E, 0x17BE, 0x521E, 0x9A5F, 0xDFFF, 0x111F, 0x54BF
+ ],
+ [
+ 0x0000, 0xB861, 0x60E3, 0xD882, 0xC1C6, 0x79A7, 0xA125, 0x1944, 0x93AD, 0x2BCC, 0xF34E, 0x4B2F, 0x526B,
+ 0xEA0A, 0x3288, 0x8AE9, 0x377B, 0x8F1A, 0x5798, 0xEFF9, 0xF6BD, 0x4EDC, 0x965E, 0x2E3F, 0xA4D6, 0x1CB7,
+ 0xC435, 0x7C54, 0x6510, 0xDD71, 0x05F3, 0xBD92, 0x6EF6, 0xD697, 0x0E15, 0xB674, 0xAF30, 0x1751, 0xCFD3,
+ 0x77B2, 0xFD5B, 0x453A, 0x9DB8, 0x25D9, 0x3C9D, 0x84FC, 0x5C7E, 0xE41F, 0x598D, 0xE1EC, 0x396E, 0x810F,
+ 0x984B, 0x202A, 0xF8A8, 0x40C9, 0xCA20, 0x7241, 0xAAC3, 0x12A2, 0x0BE6, 0xB387, 0x6B05, 0xD364, 0xDDEC,
+ 0x658D, 0xBD0F, 0x056E, 0x1C2A, 0xA44B, 0x7CC9, 0xC4A8, 0x4E41, 0xF620, 0x2EA2, 0x96C3, 0x8F87, 0x37E6,
+ 0xEF64, 0x5705, 0xEA97, 0x52F6, 0x8A74, 0x3215, 0x2B51, 0x9330, 0x4BB2, 0xF3D3, 0x793A, 0xC15B, 0x19D9,
+ 0xA1B8, 0xB8FC, 0x009D, 0xD81F, 0x607E, 0xB31A, 0x0B7B, 0xD3F9, 0x6B98, 0x72DC, 0xCABD, 0x123F, 0xAA5E,
+ 0x20B7, 0x98D6, 0x4054, 0xF835, 0xE171, 0x5910, 0x8192, 0x39F3, 0x8461, 0x3C00, 0xE482, 0x5CE3, 0x45A7,
+ 0xFDC6, 0x2544, 0x9D25, 0x17CC, 0xAFAD, 0x772F, 0xCF4E, 0xD60A, 0x6E6B, 0xB6E9, 0x0E88, 0xABF9, 0x1398,
+ 0xCB1A, 0x737B, 0x6A3F, 0xD25E, 0x0ADC, 0xB2BD, 0x3854, 0x8035, 0x58B7, 0xE0D6, 0xF992, 0x41F3, 0x9971,
+ 0x2110, 0x9C82, 0x24E3, 0xFC61, 0x4400, 0x5D44, 0xE525, 0x3DA7, 0x85C6, 0x0F2F, 0xB74E, 0x6FCC, 0xD7AD,
+ 0xCEE9, 0x7688, 0xAE0A, 0x166B, 0xC50F, 0x7D6E, 0xA5EC, 0x1D8D, 0x04C9, 0xBCA8, 0x642A, 0xDC4B, 0x56A2,
+ 0xEEC3, 0x3641, 0x8E20, 0x9764, 0x2F05, 0xF787, 0x4FE6, 0xF274, 0x4A15, 0x9297, 0x2AF6, 0x33B2, 0x8BD3,
+ 0x5351, 0xEB30, 0x61D9, 0xD9B8, 0x013A, 0xB95B, 0xA01F, 0x187E, 0xC0FC, 0x789D, 0x7615, 0xCE74, 0x16F6,
+ 0xAE97, 0xB7D3, 0x0FB2, 0xD730, 0x6F51, 0xE5B8, 0x5DD9, 0x855B, 0x3D3A, 0x247E, 0x9C1F, 0x449D, 0xFCFC,
+ 0x416E, 0xF90F, 0x218D, 0x99EC, 0x80A8, 0x38C9, 0xE04B, 0x582A, 0xD2C3, 0x6AA2, 0xB220, 0x0A41, 0x1305,
+ 0xAB64, 0x73E6, 0xCB87, 0x18E3, 0xA082, 0x7800, 0xC061, 0xD925, 0x6144, 0xB9C6, 0x01A7, 0x8B4E, 0x332F,
+ 0xEBAD, 0x53CC, 0x4A88, 0xF2E9, 0x2A6B, 0x920A, 0x2F98, 0x97F9, 0x4F7B, 0xF71A, 0xEE5E, 0x563F, 0x8EBD,
+ 0x36DC, 0xBC35, 0x0454, 0xDCD6, 0x64B7, 0x7DF3, 0xC592, 0x1D10, 0xA571
+ ],
+ [
+ 0x0000, 0x47D3, 0x8FA6, 0xC875, 0x0F6D, 0x48BE, 0x80CB, 0xC718, 0x1EDA, 0x5909, 0x917C, 0xD6AF, 0x11B7,
+ 0x5664, 0x9E11, 0xD9C2, 0x3DB4, 0x7A67, 0xB212, 0xF5C1, 0x32D9, 0x750A, 0xBD7F, 0xFAAC, 0x236E, 0x64BD,
+ 0xACC8, 0xEB1B, 0x2C03, 0x6BD0, 0xA3A5, 0xE476, 0x7B68, 0x3CBB, 0xF4CE, 0xB31D, 0x7405, 0x33D6, 0xFBA3,
+ 0xBC70, 0x65B2, 0x2261, 0xEA14, 0xADC7, 0x6ADF, 0x2D0C, 0xE579, 0xA2AA, 0x46DC, 0x010F, 0xC97A, 0x8EA9,
+ 0x49B1, 0x0E62, 0xC617, 0x81C4, 0x5806, 0x1FD5, 0xD7A0, 0x9073, 0x576B, 0x10B8, 0xD8CD, 0x9F1E, 0xF6D0,
+ 0xB103, 0x7976, 0x3EA5, 0xF9BD, 0xBE6E, 0x761B, 0x31C8, 0xE80A, 0xAFD9, 0x67AC, 0x207F, 0xE767, 0xA0B4,
+ 0x68C1, 0x2F12, 0xCB64, 0x8CB7, 0x44C2, 0x0311, 0xC409, 0x83DA, 0x4BAF, 0x0C7C, 0xD5BE, 0x926D, 0x5A18,
+ 0x1DCB, 0xDAD3, 0x9D00, 0x5575, 0x12A6, 0x8DB8, 0xCA6B, 0x021E, 0x45CD, 0x82D5, 0xC506, 0x0D73, 0x4AA0,
+ 0x9362, 0xD4B1, 0x1CC4, 0x5B17, 0x9C0F, 0xDBDC, 0x13A9, 0x547A, 0xB00C, 0xF7DF, 0x3FAA, 0x7879, 0xBF61,
+ 0xF8B2, 0x30C7, 0x7714, 0xAED6, 0xE905, 0x2170, 0x66A3, 0xA1BB, 0xE668, 0x2E1D, 0x69CE, 0xFD81, 0xBA52,
+ 0x7227, 0x35F4, 0xF2EC, 0xB53F, 0x7D4A, 0x3A99, 0xE35B, 0xA488, 0x6CFD, 0x2B2E, 0xEC36, 0xABE5, 0x6390,
+ 0x2443, 0xC035, 0x87E6, 0x4F93, 0x0840, 0xCF58, 0x888B, 0x40FE, 0x072D, 0xDEEF, 0x993C, 0x5149, 0x169A,
+ 0xD182, 0x9651, 0x5E24, 0x19F7, 0x86E9, 0xC13A, 0x094F, 0x4E9C, 0x8984, 0xCE57, 0x0622, 0x41F1, 0x9833,
+ 0xDFE0, 0x1795, 0x5046, 0x975E, 0xD08D, 0x18F8, 0x5F2B, 0xBB5D, 0xFC8E, 0x34FB, 0x7328, 0xB430, 0xF3E3,
+ 0x3B96, 0x7C45, 0xA587, 0xE254, 0x2A21, 0x6DF2, 0xAAEA, 0xED39, 0x254C, 0x629F, 0x0B51, 0x4C82, 0x84F7,
+ 0xC324, 0x043C, 0x43EF, 0x8B9A, 0xCC49, 0x158B, 0x5258, 0x9A2D, 0xDDFE, 0x1AE6, 0x5D35, 0x9540, 0xD293,
+ 0x36E5, 0x7136, 0xB943, 0xFE90, 0x3988, 0x7E5B, 0xB62E, 0xF1FD, 0x283F, 0x6FEC, 0xA799, 0xE04A, 0x2752,
+ 0x6081, 0xA8F4, 0xEF27, 0x7039, 0x37EA, 0xFF9F, 0xB84C, 0x7F54, 0x3887, 0xF0F2, 0xB721, 0x6EE3, 0x2930,
+ 0xE145, 0xA696, 0x618E, 0x265D, 0xEE28, 0xA9FB, 0x4D8D, 0x0A5E, 0xC22B, 0x85F8, 0x42E0, 0x0533, 0xCD46,
+ 0x8A95, 0x5357, 0x1484, 0xDCF1, 0x9B22, 0x5C3A, 0x1BE9, 0xD39C, 0x944F
+ ]
+ ];
+
+ /// Initializes an instance of the CRC16 with CCITT polynomial and seed.
+ ///
+ public CRC16CcittContext() : base(CRC16CcittPoly, CRC16CcittSeed, _ccittCrc16Table, true) {}
+
+ public new string Name => Localization.CRC16_CCITT_Name;
+ public new Guid Id => new("4C3BD0D5-24BD-4D45-BC19-A90A5AA5CC9D");
+ public new string Author => Authors.NataliaPortillo;
+
+ /// Gets the hash of a file
+ /// File path.
+ public static byte[] File(string filename)
+ {
+ File(filename, out byte[] hash);
+
+ return hash;
+ }
+
+ /// Gets the hash of a file in hexadecimal and as a byte array.
+ /// File path.
+ /// Byte array of the hash value.
+ public static string File(string filename, out byte[] hash) =>
+ File(filename, out hash, CRC16CcittPoly, CRC16CcittSeed, _ccittCrc16Table, true);
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Length of the data buffer to hash.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, uint len, out byte[] hash) =>
+ Data(data, len, out hash, CRC16CcittPoly, CRC16CcittSeed, _ccittCrc16Table, true);
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
+
+ /// Calculates the CCITT CRC16 of the specified buffer with the specified parameters
+ /// Buffer
+ public static ushort Calculate(byte[] buffer) =>
+ Calculate(buffer, CRC16CcittPoly, CRC16CcittSeed, _ccittCrc16Table, true);
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/CRC16Context.cs b/Aaru.Checksums/CRC16Context.cs
new file mode 100644
index 000000000..f35c15ab9
--- /dev/null
+++ b/Aaru.Checksums/CRC16Context.cs
@@ -0,0 +1,635 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : CRC16Context.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Implements a CRC16 algorithm.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+using Aaru.CommonTypes.Interfaces;
+using Aaru.Helpers;
+
+namespace Aaru.Checksums;
+
+///
+/// Implements a CRC16 algorithm
+public partial class Crc16Context : IChecksum
+{
+ readonly ushort _finalSeed;
+ readonly bool _inverse;
+ readonly IntPtr _nativeContext;
+ readonly ushort[][] _table;
+ readonly bool _useCcitt;
+ readonly bool _useIbm;
+ readonly bool _useNative;
+ ushort _hashInt;
+
+ /// Initializes the CRC16 table with a custom polynomial and seed
+ public Crc16Context(ushort polynomial, ushort seed, ushort[][] table, bool inverse)
+ {
+ _hashInt = seed;
+ _finalSeed = seed;
+ _inverse = inverse;
+
+ _useNative = Native.IsSupported;
+
+ _useCcitt = polynomial == CRC16CcittContext.CRC16CcittPoly &&
+ seed == CRC16CcittContext.CRC16CcittSeed &&
+ inverse;
+
+ _useIbm = polynomial == CRC16IbmContext.CRC16IbmPoly && seed == CRC16IbmContext.CRC16IbmSeed && !inverse;
+
+ if(_useCcitt && _useNative)
+ {
+ _nativeContext = crc16_ccitt_init();
+ _useNative = _nativeContext != IntPtr.Zero;
+ }
+ else if(_useIbm && _useNative)
+ {
+ _nativeContext = crc16_init();
+ _useNative = _nativeContext != IntPtr.Zero;
+ }
+ else
+ _useNative = false;
+
+ if(!_useNative) _table = table ?? GenerateTable(polynomial, inverse);
+ }
+
+#region IChecksum Members
+
+ ///
+ public string Name => "Adler-32";
+
+ ///
+ public Guid Id => new("D69CF1E7-4A7B-4605-9291-3A1BE4C2951F");
+
+ ///
+ public string Author => Authors.NataliaPortillo;
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ /// Length of buffer to hash.
+ public void Update(byte[] data, uint len)
+ {
+ switch(_useNative)
+ {
+ case true when _useCcitt:
+ crc16_ccitt_update(_nativeContext, data, len);
+
+ break;
+ case true when _useIbm:
+ crc16_update(_nativeContext, data, len);
+
+ break;
+ default:
+ {
+ if(_inverse)
+ StepInverse(ref _hashInt, _table, data, len);
+ else
+ Step(ref _hashInt, _table, data, len);
+
+ break;
+ }
+ }
+ }
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ public void Update(byte[] data) => Update(data, (uint)data.Length);
+
+ ///
+ /// Returns a byte array of the hash value.
+ public byte[] Final()
+ {
+ ushort crc = 0;
+
+ switch(_useNative)
+ {
+ case true when _useCcitt:
+ crc16_ccitt_final(_nativeContext, ref crc);
+ crc16_ccitt_free(_nativeContext);
+
+ break;
+ case true when _useIbm:
+ crc16_final(_nativeContext, ref crc);
+ crc16_free(_nativeContext);
+
+ break;
+ default:
+ {
+ if(_inverse)
+ crc = (ushort)~(_hashInt ^ _finalSeed);
+ else
+ crc = (ushort)(_hashInt ^ _finalSeed);
+
+ break;
+ }
+ }
+
+ return BigEndianBitConverter.GetBytes(crc);
+ }
+
+ ///
+ /// Returns a hexadecimal representation of the hash value.
+ public string End()
+ {
+ var crc16Output = new StringBuilder();
+ ushort final = 0;
+
+ switch(_useNative)
+ {
+ case true when _useCcitt:
+ crc16_ccitt_final(_nativeContext, ref final);
+ crc16_ccitt_free(_nativeContext);
+
+ break;
+ case true when _useIbm:
+ crc16_final(_nativeContext, ref final);
+ crc16_free(_nativeContext);
+
+ break;
+ default:
+ {
+ if(_inverse)
+ final = (ushort)~(_hashInt ^ _finalSeed);
+ else
+ final = (ushort)(_hashInt ^ _finalSeed);
+
+ break;
+ }
+ }
+
+ byte[] finalBytes = BigEndianBitConverter.GetBytes(final);
+
+ foreach(byte t in finalBytes) crc16Output.Append(t.ToString("x2"));
+
+ return crc16Output.ToString();
+ }
+
+#endregion
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial IntPtr crc16_init();
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial int crc16_update(IntPtr ctx, byte[] data, uint len);
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial int crc16_final(IntPtr ctx, ref ushort crc);
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial void crc16_free(IntPtr ctx);
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial IntPtr crc16_ccitt_init();
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial int crc16_ccitt_update(IntPtr ctx, byte[] data, uint len);
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial int crc16_ccitt_final(IntPtr ctx, ref ushort crc);
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial void crc16_ccitt_free(IntPtr ctx);
+
+ static void Step(ref ushort previousCrc, ushort[][] table, byte[] data, uint len)
+ {
+ // Unroll according to Intel slicing by uint8_t
+ // http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
+ // http://sourceforge.net/projects/slicing-by-8/
+
+ var currentPos = 0;
+ const int unroll = 4;
+ const int bytesAtOnce = 8 * unroll;
+
+ ushort crc = previousCrc;
+
+ while(len >= bytesAtOnce)
+ {
+ int unrolling;
+
+ for(unrolling = 0; unrolling < unroll; unrolling++)
+ {
+ // TODO: What trick is Microsoft doing here that's faster than arithmetic conversion
+ uint one = BitConverter.ToUInt32(data, currentPos) ^ crc;
+ currentPos += 4;
+ var two = BitConverter.ToUInt32(data, currentPos);
+ currentPos += 4;
+
+ crc = (ushort)(table[0][two >> 24 & 0xFF] ^
+ table[1][two >> 16 & 0xFF] ^
+ table[2][two >> 8 & 0xFF] ^
+ table[3][two & 0xFF] ^
+ table[4][one >> 24 & 0xFF] ^
+ table[5][one >> 16 & 0xFF] ^
+ table[6][one >> 8 & 0xFF] ^
+ table[7][one & 0xFF]);
+ }
+
+ len -= bytesAtOnce;
+ }
+
+ while(len-- != 0) crc = (ushort)(crc >> 8 ^ table[0][crc & 0xFF ^ data[currentPos++]]);
+
+ previousCrc = crc;
+ }
+
+ static void StepInverse(ref ushort previousCrc, ushort[][] table, byte[] data, uint len)
+ {
+ // Unroll according to Intel slicing by uint8_t
+ // http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
+ // http://sourceforge.net/projects/slicing-by-8/
+
+ var currentPos = 0;
+ const int unroll = 4;
+ const int bytesAtOnce = 8 * unroll;
+
+ ushort crc = previousCrc;
+
+ while(len >= bytesAtOnce)
+ {
+ int unrolling;
+
+ for(unrolling = 0; unrolling < unroll; unrolling++)
+ {
+ crc = (ushort)(table[7][data[currentPos + 0] ^ crc >> 8] ^
+ table[6][data[currentPos + 1] ^ crc & 0xFF] ^
+ table[5][data[currentPos + 2]] ^
+ table[4][data[currentPos + 3]] ^
+ table[3][data[currentPos + 4]] ^
+ table[2][data[currentPos + 5]] ^
+ table[1][data[currentPos + 6]] ^
+ table[0][data[currentPos + 7]]);
+
+ currentPos += 8;
+ }
+
+ len -= bytesAtOnce;
+ }
+
+ while(len-- != 0) crc = (ushort)(crc << 8 ^ table[0][crc >> 8 ^ data[currentPos++]]);
+
+ previousCrc = crc;
+ }
+
+ static ushort[][] GenerateTable(ushort polynomial, bool inverseTable)
+ {
+ var table = new ushort[8][];
+
+ for(var i = 0; i < 8; i++) table[i] = new ushort[256];
+
+ if(!inverseTable)
+ {
+ for(uint i = 0; i < 256; i++)
+ {
+ uint entry = i;
+
+ for(var j = 0; j < 8; j++)
+ {
+ if((entry & 1) == 1)
+ entry = entry >> 1 ^ polynomial;
+ else
+ entry >>= 1;
+ }
+
+ table[0][i] = (ushort)entry;
+ }
+ }
+ else
+ {
+ for(uint i = 0; i < 256; i++)
+ {
+ uint entry = i << 8;
+
+ for(uint j = 0; j < 8; j++)
+ {
+ if((entry & 0x8000) > 0)
+ entry = entry << 1 ^ polynomial;
+ else
+ entry <<= 1;
+
+ table[0][i] = (ushort)entry;
+ }
+ }
+ }
+
+ for(var slice = 1; slice < 8; slice++)
+ {
+ for(var i = 0; i < 256; i++)
+ {
+ if(inverseTable)
+ table[slice][i] = (ushort)(table[slice - 1][i] << 8 ^ table[0][table[slice - 1][i] >> 8]);
+ else
+ table[slice][i] = (ushort)(table[slice - 1][i] >> 8 ^ table[0][table[slice - 1][i] & 0xFF]);
+ }
+ }
+
+ return table;
+ }
+
+ /// Gets the hash of a file in hexadecimal and as a byte array.
+ /// File path.
+ /// Byte array of the hash value.
+ /// CRC polynomial
+ /// CRC seed
+ /// CRC lookup table
+ /// Is CRC inverted?
+ public static string File(string filename, out byte[] hash, ushort polynomial, ushort seed, ushort[][] table,
+ bool inverse)
+ {
+ bool useNative = Native.IsSupported;
+
+ bool useCcitt = polynomial == CRC16CcittContext.CRC16CcittPoly &&
+ seed == CRC16CcittContext.CRC16CcittSeed &&
+ inverse;
+
+ bool useIbm = polynomial == CRC16IbmContext.CRC16IbmPoly && seed == CRC16IbmContext.CRC16IbmSeed && !inverse;
+
+ IntPtr nativeContext = IntPtr.Zero;
+
+ var fileStream = new FileStream(filename, FileMode.Open);
+
+ ushort localHashInt = seed;
+
+ switch(useNative)
+ {
+ case true when useCcitt:
+ nativeContext = crc16_ccitt_init();
+ useNative = nativeContext != IntPtr.Zero;
+
+ break;
+ case true when useIbm:
+ nativeContext = crc16_init();
+ useNative = nativeContext != IntPtr.Zero;
+
+ break;
+ }
+
+ ushort[][] localTable = table ?? GenerateTable(polynomial, inverse);
+
+ var buffer = new byte[65536];
+ int read = fileStream.EnsureRead(buffer, 0, 65536);
+
+ while(read > 0)
+ {
+ switch(useNative)
+ {
+ case true when useCcitt:
+ crc16_ccitt_update(nativeContext, buffer, (uint)read);
+
+ break;
+ case true when useIbm:
+ crc16_update(nativeContext, buffer, (uint)read);
+
+ break;
+ default:
+ {
+ if(inverse)
+ StepInverse(ref localHashInt, localTable, buffer, (uint)read);
+ else
+ Step(ref localHashInt, localTable, buffer, (uint)read);
+
+ break;
+ }
+ }
+
+ read = fileStream.EnsureRead(buffer, 0, 65536);
+ }
+
+ localHashInt ^= seed;
+
+ switch(useNative)
+ {
+ case true when useCcitt:
+ crc16_ccitt_final(nativeContext, ref localHashInt);
+ crc16_ccitt_free(nativeContext);
+
+ break;
+ case true when useIbm:
+ crc16_final(nativeContext, ref localHashInt);
+ crc16_free(nativeContext);
+
+ break;
+ default:
+ {
+ if(inverse) localHashInt = (ushort)~localHashInt;
+
+ break;
+ }
+ }
+
+ hash = BigEndianBitConverter.GetBytes(localHashInt);
+
+ var crc16Output = new StringBuilder();
+
+ foreach(byte h in hash) crc16Output.Append(h.ToString("x2"));
+
+ fileStream.Close();
+
+ return crc16Output.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Length of the data buffer to hash.
+ /// Byte array of the hash value.
+ /// CRC polynomial
+ /// CRC seed
+ /// CRC lookup table
+ /// Is CRC inverted?
+ public static string Data(byte[] data, uint len, out byte[] hash, ushort polynomial, ushort seed, ushort[][] table,
+ bool inverse)
+ {
+ bool useNative = Native.IsSupported;
+
+ bool useCcitt = polynomial == CRC16CcittContext.CRC16CcittPoly &&
+ seed == CRC16CcittContext.CRC16CcittSeed &&
+ inverse;
+
+ bool useIbm = polynomial == CRC16IbmContext.CRC16IbmPoly && seed == CRC16IbmContext.CRC16IbmSeed && !inverse;
+
+ IntPtr nativeContext = IntPtr.Zero;
+
+ ushort localHashInt = seed;
+
+ switch(useNative)
+ {
+ case true when useCcitt:
+ nativeContext = crc16_ccitt_init();
+ useNative = nativeContext != IntPtr.Zero;
+
+ break;
+ case true when useIbm:
+ nativeContext = crc16_init();
+ useNative = nativeContext != IntPtr.Zero;
+
+ break;
+ }
+
+ ushort[][] localTable = table ?? GenerateTable(polynomial, inverse);
+
+ switch(useNative)
+ {
+ case true when useCcitt:
+ crc16_ccitt_update(nativeContext, data, len);
+
+ break;
+ case true when useIbm:
+ crc16_update(nativeContext, data, len);
+
+ break;
+ default:
+ {
+ if(inverse)
+ StepInverse(ref localHashInt, localTable, data, len);
+ else
+ Step(ref localHashInt, localTable, data, len);
+
+ break;
+ }
+ }
+
+ localHashInt ^= seed;
+
+ switch(useNative)
+ {
+ case true when useCcitt:
+ crc16_ccitt_final(nativeContext, ref localHashInt);
+ crc16_ccitt_free(nativeContext);
+
+ break;
+ case true when useIbm:
+ crc16_final(nativeContext, ref localHashInt);
+ crc16_free(nativeContext);
+
+ break;
+ default:
+ {
+ if(inverse) localHashInt = (ushort)~localHashInt;
+
+ break;
+ }
+ }
+
+ hash = BigEndianBitConverter.GetBytes(localHashInt);
+
+ var crc16Output = new StringBuilder();
+
+ foreach(byte h in hash) crc16Output.Append(h.ToString("x2"));
+
+ return crc16Output.ToString();
+ }
+
+ /// Calculates the CRC16 of the specified buffer with the specified parameters
+ /// Buffer
+ /// Polynomial
+ /// Seed
+ /// Pre-generated lookup table
+ /// Inverse CRC
+ /// CRC16
+ public static ushort Calculate(byte[] buffer, ushort polynomial, ushort seed, ushort[][] table, bool inverse)
+ {
+ bool useNative = Native.IsSupported;
+
+ bool useCcitt = polynomial == CRC16CcittContext.CRC16CcittPoly &&
+ seed == CRC16CcittContext.CRC16CcittSeed &&
+ inverse;
+
+ bool useIbm = polynomial == CRC16IbmContext.CRC16IbmPoly && seed == CRC16IbmContext.CRC16IbmSeed && !inverse;
+
+ IntPtr nativeContext = IntPtr.Zero;
+
+ ushort localHashInt = seed;
+
+ switch(useNative)
+ {
+ case true when useCcitt:
+ nativeContext = crc16_ccitt_init();
+ useNative = nativeContext != IntPtr.Zero;
+
+ break;
+ case true when useIbm:
+ nativeContext = crc16_init();
+ useNative = nativeContext != IntPtr.Zero;
+
+ break;
+ }
+
+ ushort[][] localTable = table ?? GenerateTable(polynomial, inverse);
+
+ switch(useNative)
+ {
+ case true when useCcitt:
+ crc16_ccitt_update(nativeContext, buffer, (uint)buffer.Length);
+
+ break;
+ case true when useIbm:
+ crc16_update(nativeContext, buffer, (uint)buffer.Length);
+
+ break;
+ default:
+ {
+ if(inverse)
+ StepInverse(ref localHashInt, localTable, buffer, (uint)buffer.Length);
+ else
+ Step(ref localHashInt, localTable, buffer, (uint)buffer.Length);
+
+ break;
+ }
+ }
+
+ localHashInt ^= seed;
+
+ switch(useNative)
+ {
+ case true when useCcitt:
+ crc16_ccitt_final(nativeContext, ref localHashInt);
+ crc16_ccitt_free(nativeContext);
+
+ break;
+ case true when useIbm:
+ crc16_final(nativeContext, ref localHashInt);
+ crc16_free(nativeContext);
+
+ break;
+ default:
+ {
+ if(inverse) localHashInt = (ushort)~localHashInt;
+
+ break;
+ }
+ }
+
+ return localHashInt;
+ }
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/CRC16IBMContext.cs b/Aaru.Checksums/CRC16IBMContext.cs
new file mode 100644
index 000000000..1070befb0
--- /dev/null
+++ b/Aaru.Checksums/CRC16IBMContext.cs
@@ -0,0 +1,264 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : CRC16IBMContext.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Implements a CRC16 algorithm with the IBM polynomial.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Aaru.Checksums;
+
+///
+/// Implements the CRC16 algorithm with IBM polynomial and seed
+[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
+[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
+[SuppressMessage("ReSharper", "MemberCanBeInternal")]
+public sealed class CRC16IbmContext : Crc16Context
+{
+ internal const ushort CRC16IbmPoly = 0xA001;
+ internal const ushort CRC16IbmSeed = 0x0000;
+
+ static readonly ushort[][] _ibmCrc16Table =
+ [
+ [
+ 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500,
+ 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1,
+ 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81,
+ 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540,
+ 0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001,
+ 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0,
+ 0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80,
+ 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
+ 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700,
+ 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 0xA001, 0x60C0,
+ 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480,
+ 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41,
+ 0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01,
+ 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1,
+ 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181,
+ 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
+ 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901,
+ 0x59C0, 0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1,
+ 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680,
+ 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
+ ],
+ [
+ 0x0000, 0x9001, 0x6001, 0xF000, 0xC002, 0x5003, 0xA003, 0x3002, 0xC007, 0x5006, 0xA006, 0x3007, 0x0005,
+ 0x9004, 0x6004, 0xF005, 0xC00D, 0x500C, 0xA00C, 0x300D, 0x000F, 0x900E, 0x600E, 0xF00F, 0x000A, 0x900B,
+ 0x600B, 0xF00A, 0xC008, 0x5009, 0xA009, 0x3008, 0xC019, 0x5018, 0xA018, 0x3019, 0x001B, 0x901A, 0x601A,
+ 0xF01B, 0x001E, 0x901F, 0x601F, 0xF01E, 0xC01C, 0x501D, 0xA01D, 0x301C, 0x0014, 0x9015, 0x6015, 0xF014,
+ 0xC016, 0x5017, 0xA017, 0x3016, 0xC013, 0x5012, 0xA012, 0x3013, 0x0011, 0x9010, 0x6010, 0xF011, 0xC031,
+ 0x5030, 0xA030, 0x3031, 0x0033, 0x9032, 0x6032, 0xF033, 0x0036, 0x9037, 0x6037, 0xF036, 0xC034, 0x5035,
+ 0xA035, 0x3034, 0x003C, 0x903D, 0x603D, 0xF03C, 0xC03E, 0x503F, 0xA03F, 0x303E, 0xC03B, 0x503A, 0xA03A,
+ 0x303B, 0x0039, 0x9038, 0x6038, 0xF039, 0x0028, 0x9029, 0x6029, 0xF028, 0xC02A, 0x502B, 0xA02B, 0x302A,
+ 0xC02F, 0x502E, 0xA02E, 0x302F, 0x002D, 0x902C, 0x602C, 0xF02D, 0xC025, 0x5024, 0xA024, 0x3025, 0x0027,
+ 0x9026, 0x6026, 0xF027, 0x0022, 0x9023, 0x6023, 0xF022, 0xC020, 0x5021, 0xA021, 0x3020, 0xC061, 0x5060,
+ 0xA060, 0x3061, 0x0063, 0x9062, 0x6062, 0xF063, 0x0066, 0x9067, 0x6067, 0xF066, 0xC064, 0x5065, 0xA065,
+ 0x3064, 0x006C, 0x906D, 0x606D, 0xF06C, 0xC06E, 0x506F, 0xA06F, 0x306E, 0xC06B, 0x506A, 0xA06A, 0x306B,
+ 0x0069, 0x9068, 0x6068, 0xF069, 0x0078, 0x9079, 0x6079, 0xF078, 0xC07A, 0x507B, 0xA07B, 0x307A, 0xC07F,
+ 0x507E, 0xA07E, 0x307F, 0x007D, 0x907C, 0x607C, 0xF07D, 0xC075, 0x5074, 0xA074, 0x3075, 0x0077, 0x9076,
+ 0x6076, 0xF077, 0x0072, 0x9073, 0x6073, 0xF072, 0xC070, 0x5071, 0xA071, 0x3070, 0x0050, 0x9051, 0x6051,
+ 0xF050, 0xC052, 0x5053, 0xA053, 0x3052, 0xC057, 0x5056, 0xA056, 0x3057, 0x0055, 0x9054, 0x6054, 0xF055,
+ 0xC05D, 0x505C, 0xA05C, 0x305D, 0x005F, 0x905E, 0x605E, 0xF05F, 0x005A, 0x905B, 0x605B, 0xF05A, 0xC058,
+ 0x5059, 0xA059, 0x3058, 0xC049, 0x5048, 0xA048, 0x3049, 0x004B, 0x904A, 0x604A, 0xF04B, 0x004E, 0x904F,
+ 0x604F, 0xF04E, 0xC04C, 0x504D, 0xA04D, 0x304C, 0x0044, 0x9045, 0x6045, 0xF044, 0xC046, 0x5047, 0xA047,
+ 0x3046, 0xC043, 0x5042, 0xA042, 0x3043, 0x0041, 0x9040, 0x6040, 0xF041
+ ],
+ [
+ 0x0000, 0xC051, 0xC0A1, 0x00F0, 0xC141, 0x0110, 0x01E0, 0xC1B1, 0xC281, 0x02D0, 0x0220, 0xC271, 0x03C0,
+ 0xC391, 0xC361, 0x0330, 0xC501, 0x0550, 0x05A0, 0xC5F1, 0x0440, 0xC411, 0xC4E1, 0x04B0, 0x0780, 0xC7D1,
+ 0xC721, 0x0770, 0xC6C1, 0x0690, 0x0660, 0xC631, 0xCA01, 0x0A50, 0x0AA0, 0xCAF1, 0x0B40, 0xCB11, 0xCBE1,
+ 0x0BB0, 0x0880, 0xC8D1, 0xC821, 0x0870, 0xC9C1, 0x0990, 0x0960, 0xC931, 0x0F00, 0xCF51, 0xCFA1, 0x0FF0,
+ 0xCE41, 0x0E10, 0x0EE0, 0xCEB1, 0xCD81, 0x0DD0, 0x0D20, 0xCD71, 0x0CC0, 0xCC91, 0xCC61, 0x0C30, 0xD401,
+ 0x1450, 0x14A0, 0xD4F1, 0x1540, 0xD511, 0xD5E1, 0x15B0, 0x1680, 0xD6D1, 0xD621, 0x1670, 0xD7C1, 0x1790,
+ 0x1760, 0xD731, 0x1100, 0xD151, 0xD1A1, 0x11F0, 0xD041, 0x1010, 0x10E0, 0xD0B1, 0xD381, 0x13D0, 0x1320,
+ 0xD371, 0x12C0, 0xD291, 0xD261, 0x1230, 0x1E00, 0xDE51, 0xDEA1, 0x1EF0, 0xDF41, 0x1F10, 0x1FE0, 0xDFB1,
+ 0xDC81, 0x1CD0, 0x1C20, 0xDC71, 0x1DC0, 0xDD91, 0xDD61, 0x1D30, 0xDB01, 0x1B50, 0x1BA0, 0xDBF1, 0x1A40,
+ 0xDA11, 0xDAE1, 0x1AB0, 0x1980, 0xD9D1, 0xD921, 0x1970, 0xD8C1, 0x1890, 0x1860, 0xD831, 0xE801, 0x2850,
+ 0x28A0, 0xE8F1, 0x2940, 0xE911, 0xE9E1, 0x29B0, 0x2A80, 0xEAD1, 0xEA21, 0x2A70, 0xEBC1, 0x2B90, 0x2B60,
+ 0xEB31, 0x2D00, 0xED51, 0xEDA1, 0x2DF0, 0xEC41, 0x2C10, 0x2CE0, 0xECB1, 0xEF81, 0x2FD0, 0x2F20, 0xEF71,
+ 0x2EC0, 0xEE91, 0xEE61, 0x2E30, 0x2200, 0xE251, 0xE2A1, 0x22F0, 0xE341, 0x2310, 0x23E0, 0xE3B1, 0xE081,
+ 0x20D0, 0x2020, 0xE071, 0x21C0, 0xE191, 0xE161, 0x2130, 0xE701, 0x2750, 0x27A0, 0xE7F1, 0x2640, 0xE611,
+ 0xE6E1, 0x26B0, 0x2580, 0xE5D1, 0xE521, 0x2570, 0xE4C1, 0x2490, 0x2460, 0xE431, 0x3C00, 0xFC51, 0xFCA1,
+ 0x3CF0, 0xFD41, 0x3D10, 0x3DE0, 0xFDB1, 0xFE81, 0x3ED0, 0x3E20, 0xFE71, 0x3FC0, 0xFF91, 0xFF61, 0x3F30,
+ 0xF901, 0x3950, 0x39A0, 0xF9F1, 0x3840, 0xF811, 0xF8E1, 0x38B0, 0x3B80, 0xFBD1, 0xFB21, 0x3B70, 0xFAC1,
+ 0x3A90, 0x3A60, 0xFA31, 0xF601, 0x3650, 0x36A0, 0xF6F1, 0x3740, 0xF711, 0xF7E1, 0x37B0, 0x3480, 0xF4D1,
+ 0xF421, 0x3470, 0xF5C1, 0x3590, 0x3560, 0xF531, 0x3300, 0xF351, 0xF3A1, 0x33F0, 0xF241, 0x3210, 0x32E0,
+ 0xF2B1, 0xF181, 0x31D0, 0x3120, 0xF171, 0x30C0, 0xF091, 0xF061, 0x3030
+ ],
+ [
+ 0x0000, 0xFC01, 0xB801, 0x4400, 0x3001, 0xCC00, 0x8800, 0x7401, 0x6002, 0x9C03, 0xD803, 0x2402, 0x5003,
+ 0xAC02, 0xE802, 0x1403, 0xC004, 0x3C05, 0x7805, 0x8404, 0xF005, 0x0C04, 0x4804, 0xB405, 0xA006, 0x5C07,
+ 0x1807, 0xE406, 0x9007, 0x6C06, 0x2806, 0xD407, 0xC00B, 0x3C0A, 0x780A, 0x840B, 0xF00A, 0x0C0B, 0x480B,
+ 0xB40A, 0xA009, 0x5C08, 0x1808, 0xE409, 0x9008, 0x6C09, 0x2809, 0xD408, 0x000F, 0xFC0E, 0xB80E, 0x440F,
+ 0x300E, 0xCC0F, 0x880F, 0x740E, 0x600D, 0x9C0C, 0xD80C, 0x240D, 0x500C, 0xAC0D, 0xE80D, 0x140C, 0xC015,
+ 0x3C14, 0x7814, 0x8415, 0xF014, 0x0C15, 0x4815, 0xB414, 0xA017, 0x5C16, 0x1816, 0xE417, 0x9016, 0x6C17,
+ 0x2817, 0xD416, 0x0011, 0xFC10, 0xB810, 0x4411, 0x3010, 0xCC11, 0x8811, 0x7410, 0x6013, 0x9C12, 0xD812,
+ 0x2413, 0x5012, 0xAC13, 0xE813, 0x1412, 0x001E, 0xFC1F, 0xB81F, 0x441E, 0x301F, 0xCC1E, 0x881E, 0x741F,
+ 0x601C, 0x9C1D, 0xD81D, 0x241C, 0x501D, 0xAC1C, 0xE81C, 0x141D, 0xC01A, 0x3C1B, 0x781B, 0x841A, 0xF01B,
+ 0x0C1A, 0x481A, 0xB41B, 0xA018, 0x5C19, 0x1819, 0xE418, 0x9019, 0x6C18, 0x2818, 0xD419, 0xC029, 0x3C28,
+ 0x7828, 0x8429, 0xF028, 0x0C29, 0x4829, 0xB428, 0xA02B, 0x5C2A, 0x182A, 0xE42B, 0x902A, 0x6C2B, 0x282B,
+ 0xD42A, 0x002D, 0xFC2C, 0xB82C, 0x442D, 0x302C, 0xCC2D, 0x882D, 0x742C, 0x602F, 0x9C2E, 0xD82E, 0x242F,
+ 0x502E, 0xAC2F, 0xE82F, 0x142E, 0x0022, 0xFC23, 0xB823, 0x4422, 0x3023, 0xCC22, 0x8822, 0x7423, 0x6020,
+ 0x9C21, 0xD821, 0x2420, 0x5021, 0xAC20, 0xE820, 0x1421, 0xC026, 0x3C27, 0x7827, 0x8426, 0xF027, 0x0C26,
+ 0x4826, 0xB427, 0xA024, 0x5C25, 0x1825, 0xE424, 0x9025, 0x6C24, 0x2824, 0xD425, 0x003C, 0xFC3D, 0xB83D,
+ 0x443C, 0x303D, 0xCC3C, 0x883C, 0x743D, 0x603E, 0x9C3F, 0xD83F, 0x243E, 0x503F, 0xAC3E, 0xE83E, 0x143F,
+ 0xC038, 0x3C39, 0x7839, 0x8438, 0xF039, 0x0C38, 0x4838, 0xB439, 0xA03A, 0x5C3B, 0x183B, 0xE43A, 0x903B,
+ 0x6C3A, 0x283A, 0xD43B, 0xC037, 0x3C36, 0x7836, 0x8437, 0xF036, 0x0C37, 0x4837, 0xB436, 0xA035, 0x5C34,
+ 0x1834, 0xE435, 0x9034, 0x6C35, 0x2835, 0xD434, 0x0033, 0xFC32, 0xB832, 0x4433, 0x3032, 0xCC33, 0x8833,
+ 0x7432, 0x6031, 0x9C30, 0xD830, 0x2431, 0x5030, 0xAC31, 0xE831, 0x1430
+ ],
+ [
+ 0x0000, 0xC03D, 0xC079, 0x0044, 0xC0F1, 0x00CC, 0x0088, 0xC0B5, 0xC1E1, 0x01DC, 0x0198, 0xC1A5, 0x0110,
+ 0xC12D, 0xC169, 0x0154, 0xC3C1, 0x03FC, 0x03B8, 0xC385, 0x0330, 0xC30D, 0xC349, 0x0374, 0x0220, 0xC21D,
+ 0xC259, 0x0264, 0xC2D1, 0x02EC, 0x02A8, 0xC295, 0xC781, 0x07BC, 0x07F8, 0xC7C5, 0x0770, 0xC74D, 0xC709,
+ 0x0734, 0x0660, 0xC65D, 0xC619, 0x0624, 0xC691, 0x06AC, 0x06E8, 0xC6D5, 0x0440, 0xC47D, 0xC439, 0x0404,
+ 0xC4B1, 0x048C, 0x04C8, 0xC4F5, 0xC5A1, 0x059C, 0x05D8, 0xC5E5, 0x0550, 0xC56D, 0xC529, 0x0514, 0xCF01,
+ 0x0F3C, 0x0F78, 0xCF45, 0x0FF0, 0xCFCD, 0xCF89, 0x0FB4, 0x0EE0, 0xCEDD, 0xCE99, 0x0EA4, 0xCE11, 0x0E2C,
+ 0x0E68, 0xCE55, 0x0CC0, 0xCCFD, 0xCCB9, 0x0C84, 0xCC31, 0x0C0C, 0x0C48, 0xCC75, 0xCD21, 0x0D1C, 0x0D58,
+ 0xCD65, 0x0DD0, 0xCDED, 0xCDA9, 0x0D94, 0x0880, 0xC8BD, 0xC8F9, 0x08C4, 0xC871, 0x084C, 0x0808, 0xC835,
+ 0xC961, 0x095C, 0x0918, 0xC925, 0x0990, 0xC9AD, 0xC9E9, 0x09D4, 0xCB41, 0x0B7C, 0x0B38, 0xCB05, 0x0BB0,
+ 0xCB8D, 0xCBC9, 0x0BF4, 0x0AA0, 0xCA9D, 0xCAD9, 0x0AE4, 0xCA51, 0x0A6C, 0x0A28, 0xCA15, 0xDE01, 0x1E3C,
+ 0x1E78, 0xDE45, 0x1EF0, 0xDECD, 0xDE89, 0x1EB4, 0x1FE0, 0xDFDD, 0xDF99, 0x1FA4, 0xDF11, 0x1F2C, 0x1F68,
+ 0xDF55, 0x1DC0, 0xDDFD, 0xDDB9, 0x1D84, 0xDD31, 0x1D0C, 0x1D48, 0xDD75, 0xDC21, 0x1C1C, 0x1C58, 0xDC65,
+ 0x1CD0, 0xDCED, 0xDCA9, 0x1C94, 0x1980, 0xD9BD, 0xD9F9, 0x19C4, 0xD971, 0x194C, 0x1908, 0xD935, 0xD861,
+ 0x185C, 0x1818, 0xD825, 0x1890, 0xD8AD, 0xD8E9, 0x18D4, 0xDA41, 0x1A7C, 0x1A38, 0xDA05, 0x1AB0, 0xDA8D,
+ 0xDAC9, 0x1AF4, 0x1BA0, 0xDB9D, 0xDBD9, 0x1BE4, 0xDB51, 0x1B6C, 0x1B28, 0xDB15, 0x1100, 0xD13D, 0xD179,
+ 0x1144, 0xD1F1, 0x11CC, 0x1188, 0xD1B5, 0xD0E1, 0x10DC, 0x1098, 0xD0A5, 0x1010, 0xD02D, 0xD069, 0x1054,
+ 0xD2C1, 0x12FC, 0x12B8, 0xD285, 0x1230, 0xD20D, 0xD249, 0x1274, 0x1320, 0xD31D, 0xD359, 0x1364, 0xD3D1,
+ 0x13EC, 0x13A8, 0xD395, 0xD681, 0x16BC, 0x16F8, 0xD6C5, 0x1670, 0xD64D, 0xD609, 0x1634, 0x1760, 0xD75D,
+ 0xD719, 0x1724, 0xD791, 0x17AC, 0x17E8, 0xD7D5, 0x1540, 0xD57D, 0xD539, 0x1504, 0xD5B1, 0x158C, 0x15C8,
+ 0xD5F5, 0xD4A1, 0x149C, 0x14D8, 0xD4E5, 0x1450, 0xD46D, 0xD429, 0x1414
+ ],
+ [
+ 0x0000, 0xD101, 0xE201, 0x3300, 0x8401, 0x5500, 0x6600, 0xB701, 0x4801, 0x9900, 0xAA00, 0x7B01, 0xCC00,
+ 0x1D01, 0x2E01, 0xFF00, 0x9002, 0x4103, 0x7203, 0xA302, 0x1403, 0xC502, 0xF602, 0x2703, 0xD803, 0x0902,
+ 0x3A02, 0xEB03, 0x5C02, 0x8D03, 0xBE03, 0x6F02, 0x6007, 0xB106, 0x8206, 0x5307, 0xE406, 0x3507, 0x0607,
+ 0xD706, 0x2806, 0xF907, 0xCA07, 0x1B06, 0xAC07, 0x7D06, 0x4E06, 0x9F07, 0xF005, 0x2104, 0x1204, 0xC305,
+ 0x7404, 0xA505, 0x9605, 0x4704, 0xB804, 0x6905, 0x5A05, 0x8B04, 0x3C05, 0xED04, 0xDE04, 0x0F05, 0xC00E,
+ 0x110F, 0x220F, 0xF30E, 0x440F, 0x950E, 0xA60E, 0x770F, 0x880F, 0x590E, 0x6A0E, 0xBB0F, 0x0C0E, 0xDD0F,
+ 0xEE0F, 0x3F0E, 0x500C, 0x810D, 0xB20D, 0x630C, 0xD40D, 0x050C, 0x360C, 0xE70D, 0x180D, 0xC90C, 0xFA0C,
+ 0x2B0D, 0x9C0C, 0x4D0D, 0x7E0D, 0xAF0C, 0xA009, 0x7108, 0x4208, 0x9309, 0x2408, 0xF509, 0xC609, 0x1708,
+ 0xE808, 0x3909, 0x0A09, 0xDB08, 0x6C09, 0xBD08, 0x8E08, 0x5F09, 0x300B, 0xE10A, 0xD20A, 0x030B, 0xB40A,
+ 0x650B, 0x560B, 0x870A, 0x780A, 0xA90B, 0x9A0B, 0x4B0A, 0xFC0B, 0x2D0A, 0x1E0A, 0xCF0B, 0xC01F, 0x111E,
+ 0x221E, 0xF31F, 0x441E, 0x951F, 0xA61F, 0x771E, 0x881E, 0x591F, 0x6A1F, 0xBB1E, 0x0C1F, 0xDD1E, 0xEE1E,
+ 0x3F1F, 0x501D, 0x811C, 0xB21C, 0x631D, 0xD41C, 0x051D, 0x361D, 0xE71C, 0x181C, 0xC91D, 0xFA1D, 0x2B1C,
+ 0x9C1D, 0x4D1C, 0x7E1C, 0xAF1D, 0xA018, 0x7119, 0x4219, 0x9318, 0x2419, 0xF518, 0xC618, 0x1719, 0xE819,
+ 0x3918, 0x0A18, 0xDB19, 0x6C18, 0xBD19, 0x8E19, 0x5F18, 0x301A, 0xE11B, 0xD21B, 0x031A, 0xB41B, 0x651A,
+ 0x561A, 0x871B, 0x781B, 0xA91A, 0x9A1A, 0x4B1B, 0xFC1A, 0x2D1B, 0x1E1B, 0xCF1A, 0x0011, 0xD110, 0xE210,
+ 0x3311, 0x8410, 0x5511, 0x6611, 0xB710, 0x4810, 0x9911, 0xAA11, 0x7B10, 0xCC11, 0x1D10, 0x2E10, 0xFF11,
+ 0x9013, 0x4112, 0x7212, 0xA313, 0x1412, 0xC513, 0xF613, 0x2712, 0xD812, 0x0913, 0x3A13, 0xEB12, 0x5C13,
+ 0x8D12, 0xBE12, 0x6F13, 0x6016, 0xB117, 0x8217, 0x5316, 0xE417, 0x3516, 0x0616, 0xD717, 0x2817, 0xF916,
+ 0xCA16, 0x1B17, 0xAC16, 0x7D17, 0x4E17, 0x9F16, 0xF014, 0x2115, 0x1215, 0xC314, 0x7415, 0xA514, 0x9614,
+ 0x4715, 0xB815, 0x6914, 0x5A14, 0x8B15, 0x3C14, 0xED15, 0xDE15, 0x0F14
+ ],
+ [
+ 0x0000, 0xC010, 0xC023, 0x0033, 0xC045, 0x0055, 0x0066, 0xC076, 0xC089, 0x0099, 0x00AA, 0xC0BA, 0x00CC,
+ 0xC0DC, 0xC0EF, 0x00FF, 0xC111, 0x0101, 0x0132, 0xC122, 0x0154, 0xC144, 0xC177, 0x0167, 0x0198, 0xC188,
+ 0xC1BB, 0x01AB, 0xC1DD, 0x01CD, 0x01FE, 0xC1EE, 0xC221, 0x0231, 0x0202, 0xC212, 0x0264, 0xC274, 0xC247,
+ 0x0257, 0x02A8, 0xC2B8, 0xC28B, 0x029B, 0xC2ED, 0x02FD, 0x02CE, 0xC2DE, 0x0330, 0xC320, 0xC313, 0x0303,
+ 0xC375, 0x0365, 0x0356, 0xC346, 0xC3B9, 0x03A9, 0x039A, 0xC38A, 0x03FC, 0xC3EC, 0xC3DF, 0x03CF, 0xC441,
+ 0x0451, 0x0462, 0xC472, 0x0404, 0xC414, 0xC427, 0x0437, 0x04C8, 0xC4D8, 0xC4EB, 0x04FB, 0xC48D, 0x049D,
+ 0x04AE, 0xC4BE, 0x0550, 0xC540, 0xC573, 0x0563, 0xC515, 0x0505, 0x0536, 0xC526, 0xC5D9, 0x05C9, 0x05FA,
+ 0xC5EA, 0x059C, 0xC58C, 0xC5BF, 0x05AF, 0x0660, 0xC670, 0xC643, 0x0653, 0xC625, 0x0635, 0x0606, 0xC616,
+ 0xC6E9, 0x06F9, 0x06CA, 0xC6DA, 0x06AC, 0xC6BC, 0xC68F, 0x069F, 0xC771, 0x0761, 0x0752, 0xC742, 0x0734,
+ 0xC724, 0xC717, 0x0707, 0x07F8, 0xC7E8, 0xC7DB, 0x07CB, 0xC7BD, 0x07AD, 0x079E, 0xC78E, 0xC881, 0x0891,
+ 0x08A2, 0xC8B2, 0x08C4, 0xC8D4, 0xC8E7, 0x08F7, 0x0808, 0xC818, 0xC82B, 0x083B, 0xC84D, 0x085D, 0x086E,
+ 0xC87E, 0x0990, 0xC980, 0xC9B3, 0x09A3, 0xC9D5, 0x09C5, 0x09F6, 0xC9E6, 0xC919, 0x0909, 0x093A, 0xC92A,
+ 0x095C, 0xC94C, 0xC97F, 0x096F, 0x0AA0, 0xCAB0, 0xCA83, 0x0A93, 0xCAE5, 0x0AF5, 0x0AC6, 0xCAD6, 0xCA29,
+ 0x0A39, 0x0A0A, 0xCA1A, 0x0A6C, 0xCA7C, 0xCA4F, 0x0A5F, 0xCBB1, 0x0BA1, 0x0B92, 0xCB82, 0x0BF4, 0xCBE4,
+ 0xCBD7, 0x0BC7, 0x0B38, 0xCB28, 0xCB1B, 0x0B0B, 0xCB7D, 0x0B6D, 0x0B5E, 0xCB4E, 0x0CC0, 0xCCD0, 0xCCE3,
+ 0x0CF3, 0xCC85, 0x0C95, 0x0CA6, 0xCCB6, 0xCC49, 0x0C59, 0x0C6A, 0xCC7A, 0x0C0C, 0xCC1C, 0xCC2F, 0x0C3F,
+ 0xCDD1, 0x0DC1, 0x0DF2, 0xCDE2, 0x0D94, 0xCD84, 0xCDB7, 0x0DA7, 0x0D58, 0xCD48, 0xCD7B, 0x0D6B, 0xCD1D,
+ 0x0D0D, 0x0D3E, 0xCD2E, 0xCEE1, 0x0EF1, 0x0EC2, 0xCED2, 0x0EA4, 0xCEB4, 0xCE87, 0x0E97, 0x0E68, 0xCE78,
+ 0xCE4B, 0x0E5B, 0xCE2D, 0x0E3D, 0x0E0E, 0xCE1E, 0x0FF0, 0xCFE0, 0xCFD3, 0x0FC3, 0xCFB5, 0x0FA5, 0x0F96,
+ 0xCF86, 0xCF79, 0x0F69, 0x0F5A, 0xCF4A, 0x0F3C, 0xCF2C, 0xCF1F, 0x0F0F
+ ],
+ [
+ 0x0000, 0xCCC1, 0xD981, 0x1540, 0xF301, 0x3FC0, 0x2A80, 0xE641, 0xA601, 0x6AC0, 0x7F80, 0xB341, 0x5500,
+ 0x99C1, 0x8C81, 0x4040, 0x0C01, 0xC0C0, 0xD580, 0x1941, 0xFF00, 0x33C1, 0x2681, 0xEA40, 0xAA00, 0x66C1,
+ 0x7381, 0xBF40, 0x5901, 0x95C0, 0x8080, 0x4C41, 0x1802, 0xD4C3, 0xC183, 0x0D42, 0xEB03, 0x27C2, 0x3282,
+ 0xFE43, 0xBE03, 0x72C2, 0x6782, 0xAB43, 0x4D02, 0x81C3, 0x9483, 0x5842, 0x1403, 0xD8C2, 0xCD82, 0x0143,
+ 0xE702, 0x2BC3, 0x3E83, 0xF242, 0xB202, 0x7EC3, 0x6B83, 0xA742, 0x4103, 0x8DC2, 0x9882, 0x5443, 0x3004,
+ 0xFCC5, 0xE985, 0x2544, 0xC305, 0x0FC4, 0x1A84, 0xD645, 0x9605, 0x5AC4, 0x4F84, 0x8345, 0x6504, 0xA9C5,
+ 0xBC85, 0x7044, 0x3C05, 0xF0C4, 0xE584, 0x2945, 0xCF04, 0x03C5, 0x1685, 0xDA44, 0x9A04, 0x56C5, 0x4385,
+ 0x8F44, 0x6905, 0xA5C4, 0xB084, 0x7C45, 0x2806, 0xE4C7, 0xF187, 0x3D46, 0xDB07, 0x17C6, 0x0286, 0xCE47,
+ 0x8E07, 0x42C6, 0x5786, 0x9B47, 0x7D06, 0xB1C7, 0xA487, 0x6846, 0x2407, 0xE8C6, 0xFD86, 0x3147, 0xD706,
+ 0x1BC7, 0x0E87, 0xC246, 0x8206, 0x4EC7, 0x5B87, 0x9746, 0x7107, 0xBDC6, 0xA886, 0x6447, 0x6008, 0xACC9,
+ 0xB989, 0x7548, 0x9309, 0x5FC8, 0x4A88, 0x8649, 0xC609, 0x0AC8, 0x1F88, 0xD349, 0x3508, 0xF9C9, 0xEC89,
+ 0x2048, 0x6C09, 0xA0C8, 0xB588, 0x7949, 0x9F08, 0x53C9, 0x4689, 0x8A48, 0xCA08, 0x06C9, 0x1389, 0xDF48,
+ 0x3909, 0xF5C8, 0xE088, 0x2C49, 0x780A, 0xB4CB, 0xA18B, 0x6D4A, 0x8B0B, 0x47CA, 0x528A, 0x9E4B, 0xDE0B,
+ 0x12CA, 0x078A, 0xCB4B, 0x2D0A, 0xE1CB, 0xF48B, 0x384A, 0x740B, 0xB8CA, 0xAD8A, 0x614B, 0x870A, 0x4BCB,
+ 0x5E8B, 0x924A, 0xD20A, 0x1ECB, 0x0B8B, 0xC74A, 0x210B, 0xEDCA, 0xF88A, 0x344B, 0x500C, 0x9CCD, 0x898D,
+ 0x454C, 0xA30D, 0x6FCC, 0x7A8C, 0xB64D, 0xF60D, 0x3ACC, 0x2F8C, 0xE34D, 0x050C, 0xC9CD, 0xDC8D, 0x104C,
+ 0x5C0D, 0x90CC, 0x858C, 0x494D, 0xAF0C, 0x63CD, 0x768D, 0xBA4C, 0xFA0C, 0x36CD, 0x238D, 0xEF4C, 0x090D,
+ 0xC5CC, 0xD08C, 0x1C4D, 0x480E, 0x84CF, 0x918F, 0x5D4E, 0xBB0F, 0x77CE, 0x628E, 0xAE4F, 0xEE0F, 0x22CE,
+ 0x378E, 0xFB4F, 0x1D0E, 0xD1CF, 0xC48F, 0x084E, 0x440F, 0x88CE, 0x9D8E, 0x514F, 0xB70E, 0x7BCF, 0x6E8F,
+ 0xA24E, 0xE20E, 0x2ECF, 0x3B8F, 0xF74E, 0x110F, 0xDDCE, 0xC88E, 0x044F
+ ]
+ ];
+
+ /// Initializes an instance of the CRC16 with IBM polynomial and seed.
+ ///
+ public CRC16IbmContext() : base(CRC16IbmPoly, CRC16IbmSeed, _ibmCrc16Table, false) {}
+
+ public new string Name => Localization.CRC16_IBM_Name;
+ public new Guid Id => new("0470433E-0C78-4C37-8C9F-BD8E72340E78");
+ public new string Author => Authors.NataliaPortillo;
+
+ /// Gets the hash of a file
+ /// File path.
+
+ // ReSharper disable once ReturnTypeCanBeEnumerable.Global
+ public static byte[] File(string filename)
+ {
+ File(filename, out byte[] hash);
+
+ return hash;
+ }
+
+ /// Gets the hash of a file in hexadecimal and as a byte array.
+ /// File path.
+ /// Byte array of the hash value.
+ public static string File(string filename, out byte[] hash) =>
+ File(filename, out hash, CRC16IbmPoly, CRC16IbmSeed, _ibmCrc16Table, false);
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Length of the data buffer to hash.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, uint len, out byte[] hash) =>
+ Data(data, len, out hash, CRC16IbmPoly, CRC16IbmSeed, _ibmCrc16Table, false);
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/CRC32/arm_simd.cs b/Aaru.Checksums/CRC32/arm_simd.cs
new file mode 100644
index 000000000..4d4e6bac0
--- /dev/null
+++ b/Aaru.Checksums/CRC32/arm_simd.cs
@@ -0,0 +1,132 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : arm_simd.cs
+// Author(s) : Natalia Portillo
+// The Chromium Authors
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Compute CRC32 checksum using ARM special instructions..
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// ****************************************************************************/
+
+using System;
+using System.Runtime.Intrinsics.Arm;
+
+namespace Aaru.Checksums.CRC32;
+
+static class ArmSimd
+{
+ internal static uint Step64(byte[] buf, long len, uint crc)
+ {
+ uint c = crc;
+
+ var bufPos = 0;
+
+ while(len >= 64)
+ {
+ c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
+ bufPos += 8;
+ c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
+ bufPos += 8;
+ c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
+ bufPos += 8;
+ c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
+ bufPos += 8;
+ c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
+ bufPos += 8;
+ c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
+ bufPos += 8;
+ c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
+ bufPos += 8;
+ c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
+ bufPos += 8;
+ len -= 64;
+ }
+
+ while(len >= 8)
+ {
+ c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos));
+ bufPos += 8;
+ len -= 8;
+ }
+
+ while(len-- > 0) c = Crc32.ComputeCrc32(c, buf[bufPos++]);
+
+ return c;
+ }
+
+ internal static uint Step32(byte[] buf, long len, uint crc)
+ {
+ uint c = crc;
+
+ var bufPos = 0;
+
+ while(len >= 32)
+ {
+ c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
+ bufPos += 4;
+ c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
+ bufPos += 4;
+ c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
+ bufPos += 4;
+ c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
+ bufPos += 4;
+ c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
+ bufPos += 4;
+ c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
+ bufPos += 4;
+ c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
+ bufPos += 4;
+ c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
+ bufPos += 4;
+ len -= 32;
+ }
+
+ while(len >= 4)
+ {
+ c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos));
+ bufPos += 4;
+ len -= 4;
+ }
+
+ while(len-- > 0) c = Crc32.ComputeCrc32(c, buf[bufPos++]);
+
+ return c;
+ }
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/CRC32/clmul.cs b/Aaru.Checksums/CRC32/clmul.cs
new file mode 100644
index 000000000..03a1e5d87
--- /dev/null
+++ b/Aaru.Checksums/CRC32/clmul.cs
@@ -0,0 +1,229 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : clmul.cs
+// Author(s) : Natalia Portillo
+// Wajdi Feghali
+// Jim Guilford
+// Vinodh Gopal
+// Erdinc Ozturk
+// Jim Kukunas
+// Marian Beermann
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Compute the CRC32 using a parallelized folding approach with the PCLMULQDQ
+// instruction.
+//
+// A white paper describing this algorithm can be found at:
+// http://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from
+// the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// Copyright (c) 2016 Marian Beermann (add support for initial value, restructuring)
+// Copyright (C) 2013 Intel Corporation. All rights reserved.
+// ****************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace Aaru.Checksums.CRC32;
+
+static class Clmul
+{
+ static readonly uint[] _crcK =
+ [
+ 0xccaa009e, 0x00000000, /* rk1 */ 0x751997d0, 0x00000001, /* rk2 */ 0xccaa009e, 0x00000000, /* rk5 */
+ 0x63cd6124, 0x00000001, /* rk6 */ 0xf7011640, 0x00000001, /* rk7 */ 0xdb710640, 0x00000001 /* rk8 */
+ ];
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static void Fold4(ref Vector128 xmmCRC0, ref Vector128 xmmCRC1, ref Vector128 xmmCRC2,
+ ref Vector128 xmmCRC3)
+ {
+ var xmmFold4 = Vector128.Create(0xc6e41596, 0x00000001, 0x54442bd4, 0x00000001);
+
+ Vector128 xTmp0 = xmmCRC0;
+ Vector128 xTmp1 = xmmCRC1;
+ Vector128 xTmp2 = xmmCRC2;
+ Vector128 xTmp3 = xmmCRC3;
+
+ xmmCRC0 = Pclmulqdq.CarrylessMultiply(xmmCRC0.AsUInt64(), xmmFold4.AsUInt64(), 0x01).AsUInt32();
+ xTmp0 = Pclmulqdq.CarrylessMultiply(xTmp0.AsUInt64(), xmmFold4.AsUInt64(), 0x10).AsUInt32();
+ Vector128 psCRC0 = xmmCRC0.AsSingle();
+ Vector128 psT0 = xTmp0.AsSingle();
+ Vector128 psRes0 = Sse.Xor(psCRC0, psT0);
+
+ xmmCRC1 = Pclmulqdq.CarrylessMultiply(xmmCRC1.AsUInt64(), xmmFold4.AsUInt64(), 0x01).AsUInt32();
+ xTmp1 = Pclmulqdq.CarrylessMultiply(xTmp1.AsUInt64(), xmmFold4.AsUInt64(), 0x10).AsUInt32();
+ Vector128 psCRC1 = xmmCRC1.AsSingle();
+ Vector128 psT1 = xTmp1.AsSingle();
+ Vector128 psRes1 = Sse.Xor(psCRC1, psT1);
+
+ xmmCRC2 = Pclmulqdq.CarrylessMultiply(xmmCRC2.AsUInt64(), xmmFold4.AsUInt64(), 0x01).AsUInt32();
+ xTmp2 = Pclmulqdq.CarrylessMultiply(xTmp2.AsUInt64(), xmmFold4.AsUInt64(), 0x10).AsUInt32();
+ Vector128 psCRC2 = xmmCRC2.AsSingle();
+ Vector128 psT2 = xTmp2.AsSingle();
+ Vector128 psRes2 = Sse.Xor(psCRC2, psT2);
+
+ xmmCRC3 = Pclmulqdq.CarrylessMultiply(xmmCRC3.AsUInt64(), xmmFold4.AsUInt64(), 0x01).AsUInt32();
+ xTmp3 = Pclmulqdq.CarrylessMultiply(xTmp3.AsUInt64(), xmmFold4.AsUInt64(), 0x10).AsUInt32();
+ Vector128 psCRC3 = xmmCRC3.AsSingle();
+ Vector128 psT3 = xTmp3.AsSingle();
+ Vector128 psRes3 = Sse.Xor(psCRC3, psT3);
+
+ xmmCRC0 = psRes0.AsUInt32();
+ xmmCRC1 = psRes1.AsUInt32();
+ xmmCRC2 = psRes2.AsUInt32();
+ xmmCRC3 = psRes3.AsUInt32();
+ }
+
+ internal static uint Step(byte[] src, long len, uint initialCRC)
+ {
+ Vector128 xmmInitial = Sse2.ConvertScalarToVector128UInt32(initialCRC);
+ Vector128 xmmCRC0 = Sse2.ConvertScalarToVector128UInt32(0x9db42487);
+ Vector128 xmmCRC1 = Vector128.Zero;
+ Vector128 xmmCRC2 = Vector128.Zero;
+ Vector128 xmmCRC3 = Vector128.Zero;
+ var bufPos = 0;
+
+ var first = true;
+
+ /* fold 512 to 32 step variable declarations for ISO-C90 compat. */
+ var xmmMask = Vector128.Create(0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000);
+ var xmmMask2 = Vector128.Create(0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);
+
+ while((len -= 64) >= 0)
+ {
+ var xmmT0 = Vector128.Create(BitConverter.ToUInt32(src, bufPos),
+ BitConverter.ToUInt32(src, bufPos + 4),
+ BitConverter.ToUInt32(src, bufPos + 8),
+ BitConverter.ToUInt32(src, bufPos + 12));
+
+ bufPos += 16;
+
+ var xmmT1 = Vector128.Create(BitConverter.ToUInt32(src, bufPos),
+ BitConverter.ToUInt32(src, bufPos + 4),
+ BitConverter.ToUInt32(src, bufPos + 8),
+ BitConverter.ToUInt32(src, bufPos + 12));
+
+ bufPos += 16;
+
+ var xmmT2 = Vector128.Create(BitConverter.ToUInt32(src, bufPos),
+ BitConverter.ToUInt32(src, bufPos + 4),
+ BitConverter.ToUInt32(src, bufPos + 8),
+ BitConverter.ToUInt32(src, bufPos + 12));
+
+ bufPos += 16;
+
+ var xmmT3 = Vector128.Create(BitConverter.ToUInt32(src, bufPos),
+ BitConverter.ToUInt32(src, bufPos + 4),
+ BitConverter.ToUInt32(src, bufPos + 8),
+ BitConverter.ToUInt32(src, bufPos + 12));
+
+ bufPos += 16;
+
+ if(first)
+ {
+ first = false;
+ xmmT0 = Sse2.Xor(xmmT0, xmmInitial);
+ }
+
+ Fold4(ref xmmCRC0, ref xmmCRC1, ref xmmCRC2, ref xmmCRC3);
+
+ xmmCRC0 = Sse2.Xor(xmmCRC0, xmmT0);
+ xmmCRC1 = Sse2.Xor(xmmCRC1, xmmT1);
+ xmmCRC2 = Sse2.Xor(xmmCRC2, xmmT2);
+ xmmCRC3 = Sse2.Xor(xmmCRC3, xmmT3);
+ }
+
+ /* fold 512 to 32 */
+
+ /*
+ * k1
+ */
+ var crcFold = Vector128.Create(_crcK[0], _crcK[1], _crcK[2], _crcK[3]);
+
+ Vector128 xTmp0 = Pclmulqdq.CarrylessMultiply(xmmCRC0.AsUInt64(), crcFold.AsUInt64(), 0x10).AsUInt32();
+
+ xmmCRC0 = Pclmulqdq.CarrylessMultiply(xmmCRC0.AsUInt64(), crcFold.AsUInt64(), 0x01).AsUInt32();
+ xmmCRC1 = Sse2.Xor(xmmCRC1, xTmp0);
+ xmmCRC1 = Sse2.Xor(xmmCRC1, xmmCRC0);
+
+ Vector128 xTmp1 = Pclmulqdq.CarrylessMultiply(xmmCRC1.AsUInt64(), crcFold.AsUInt64(), 0x10).AsUInt32();
+
+ xmmCRC1 = Pclmulqdq.CarrylessMultiply(xmmCRC1.AsUInt64(), crcFold.AsUInt64(), 0x01).AsUInt32();
+ xmmCRC2 = Sse2.Xor(xmmCRC2, xTmp1);
+ xmmCRC2 = Sse2.Xor(xmmCRC2, xmmCRC1);
+
+ Vector128 xTmp2 = Pclmulqdq.CarrylessMultiply(xmmCRC2.AsUInt64(), crcFold.AsUInt64(), 0x10).AsUInt32();
+
+ xmmCRC2 = Pclmulqdq.CarrylessMultiply(xmmCRC2.AsUInt64(), crcFold.AsUInt64(), 0x01).AsUInt32();
+ xmmCRC3 = Sse2.Xor(xmmCRC3, xTmp2);
+ xmmCRC3 = Sse2.Xor(xmmCRC3, xmmCRC2);
+
+ /*
+ * k5
+ */
+ crcFold = Vector128.Create(_crcK[4], _crcK[5], _crcK[6], _crcK[7]);
+
+ xmmCRC0 = xmmCRC3;
+ xmmCRC3 = Pclmulqdq.CarrylessMultiply(xmmCRC3.AsUInt64(), crcFold.AsUInt64(), 0).AsUInt32();
+ xmmCRC0 = Sse2.ShiftRightLogical128BitLane(xmmCRC0, 8);
+ xmmCRC3 = Sse2.Xor(xmmCRC3, xmmCRC0);
+
+ xmmCRC0 = xmmCRC3;
+ xmmCRC3 = Sse2.ShiftLeftLogical128BitLane(xmmCRC3, 4);
+ xmmCRC3 = Pclmulqdq.CarrylessMultiply(xmmCRC3.AsUInt64(), crcFold.AsUInt64(), 0x10).AsUInt32();
+ xmmCRC3 = Sse2.Xor(xmmCRC3, xmmCRC0);
+ xmmCRC3 = Sse2.And(xmmCRC3, xmmMask2);
+
+ /*
+ * k7
+ */
+ xmmCRC1 = xmmCRC3;
+ xmmCRC2 = xmmCRC3;
+ crcFold = Vector128.Create(_crcK[8], _crcK[9], _crcK[10], _crcK[11]);
+
+ xmmCRC3 = Pclmulqdq.CarrylessMultiply(xmmCRC3.AsUInt64(), crcFold.AsUInt64(), 0).AsUInt32();
+ xmmCRC3 = Sse2.Xor(xmmCRC3, xmmCRC2);
+ xmmCRC3 = Sse2.And(xmmCRC3, xmmMask);
+
+ xmmCRC2 = xmmCRC3;
+ xmmCRC3 = Pclmulqdq.CarrylessMultiply(xmmCRC3.AsUInt64(), crcFold.AsUInt64(), 0x10).AsUInt32();
+ xmmCRC3 = Sse2.Xor(xmmCRC3, xmmCRC2);
+ xmmCRC3 = Sse2.Xor(xmmCRC3, xmmCRC1);
+
+ /*
+ * could just as well write xmm_crc3[2], doing a movaps and truncating, but
+ * no real advantage - it's a tiny bit slower per call, while no additional CPUs
+ * would be supported by only requiring SSSE3 and CLMUL instead of SSE4.1 + CLMUL
+ */
+ return ~Sse41.Extract(xmmCRC3, 2);
+ }
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/CRC32Context.cs b/Aaru.Checksums/CRC32Context.cs
new file mode 100644
index 000000000..409fbe25c
--- /dev/null
+++ b/Aaru.Checksums/CRC32Context.cs
@@ -0,0 +1,673 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : CRC32Context.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Implements a CRC32 algorithm.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.Arm;
+using System.Runtime.Intrinsics.X86;
+using System.Text;
+using Aaru.Checksums.CRC32;
+using Aaru.CommonTypes.Interfaces;
+using Aaru.Helpers;
+
+namespace Aaru.Checksums;
+
+///
+/// Implements a CRC32 algorithm
+[SuppressMessage("ReSharper", "UnusedMember.Global")]
+[SuppressMessage("ReSharper", "MemberCanBeInternal")]
+[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
+[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
+public sealed partial class Crc32Context : IChecksum
+{
+ const uint CRC32_ISO_POLY = 0xEDB88320;
+ const uint CRC32_ISO_SEED = 0xFFFFFFFF;
+
+ internal static readonly uint[][] ISOCrc32Table =
+ [
+ [
+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
+ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
+ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
+ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
+ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
+ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
+ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
+ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
+ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
+ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
+ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
+ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
+ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
+ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
+ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
+ ],
+ [
+ 0x00000000, 0x191B3141, 0x32366282, 0x2B2D53C3, 0x646CC504, 0x7D77F445, 0x565AA786, 0x4F4196C7,
+ 0xC8D98A08, 0xD1C2BB49, 0xFAEFE88A, 0xE3F4D9CB, 0xACB54F0C, 0xB5AE7E4D, 0x9E832D8E, 0x87981CCF,
+ 0x4AC21251, 0x53D92310, 0x78F470D3, 0x61EF4192, 0x2EAED755, 0x37B5E614, 0x1C98B5D7, 0x05838496,
+ 0x821B9859, 0x9B00A918, 0xB02DFADB, 0xA936CB9A, 0xE6775D5D, 0xFF6C6C1C, 0xD4413FDF, 0xCD5A0E9E,
+ 0x958424A2, 0x8C9F15E3, 0xA7B24620, 0xBEA97761, 0xF1E8E1A6, 0xE8F3D0E7, 0xC3DE8324, 0xDAC5B265,
+ 0x5D5DAEAA, 0x44469FEB, 0x6F6BCC28, 0x7670FD69, 0x39316BAE, 0x202A5AEF, 0x0B07092C, 0x121C386D,
+ 0xDF4636F3, 0xC65D07B2, 0xED705471, 0xF46B6530, 0xBB2AF3F7, 0xA231C2B6, 0x891C9175, 0x9007A034,
+ 0x179FBCFB, 0x0E848DBA, 0x25A9DE79, 0x3CB2EF38, 0x73F379FF, 0x6AE848BE, 0x41C51B7D, 0x58DE2A3C,
+ 0xF0794F05, 0xE9627E44, 0xC24F2D87, 0xDB541CC6, 0x94158A01, 0x8D0EBB40, 0xA623E883, 0xBF38D9C2,
+ 0x38A0C50D, 0x21BBF44C, 0x0A96A78F, 0x138D96CE, 0x5CCC0009, 0x45D73148, 0x6EFA628B, 0x77E153CA,
+ 0xBABB5D54, 0xA3A06C15, 0x888D3FD6, 0x91960E97, 0xDED79850, 0xC7CCA911, 0xECE1FAD2, 0xF5FACB93,
+ 0x7262D75C, 0x6B79E61D, 0x4054B5DE, 0x594F849F, 0x160E1258, 0x0F152319, 0x243870DA, 0x3D23419B,
+ 0x65FD6BA7, 0x7CE65AE6, 0x57CB0925, 0x4ED03864, 0x0191AEA3, 0x188A9FE2, 0x33A7CC21, 0x2ABCFD60,
+ 0xAD24E1AF, 0xB43FD0EE, 0x9F12832D, 0x8609B26C, 0xC94824AB, 0xD05315EA, 0xFB7E4629, 0xE2657768,
+ 0x2F3F79F6, 0x362448B7, 0x1D091B74, 0x04122A35, 0x4B53BCF2, 0x52488DB3, 0x7965DE70, 0x607EEF31,
+ 0xE7E6F3FE, 0xFEFDC2BF, 0xD5D0917C, 0xCCCBA03D, 0x838A36FA, 0x9A9107BB, 0xB1BC5478, 0xA8A76539,
+ 0x3B83984B, 0x2298A90A, 0x09B5FAC9, 0x10AECB88, 0x5FEF5D4F, 0x46F46C0E, 0x6DD93FCD, 0x74C20E8C,
+ 0xF35A1243, 0xEA412302, 0xC16C70C1, 0xD8774180, 0x9736D747, 0x8E2DE606, 0xA500B5C5, 0xBC1B8484,
+ 0x71418A1A, 0x685ABB5B, 0x4377E898, 0x5A6CD9D9, 0x152D4F1E, 0x0C367E5F, 0x271B2D9C, 0x3E001CDD,
+ 0xB9980012, 0xA0833153, 0x8BAE6290, 0x92B553D1, 0xDDF4C516, 0xC4EFF457, 0xEFC2A794, 0xF6D996D5,
+ 0xAE07BCE9, 0xB71C8DA8, 0x9C31DE6B, 0x852AEF2A, 0xCA6B79ED, 0xD37048AC, 0xF85D1B6F, 0xE1462A2E,
+ 0x66DE36E1, 0x7FC507A0, 0x54E85463, 0x4DF36522, 0x02B2F3E5, 0x1BA9C2A4, 0x30849167, 0x299FA026,
+ 0xE4C5AEB8, 0xFDDE9FF9, 0xD6F3CC3A, 0xCFE8FD7B, 0x80A96BBC, 0x99B25AFD, 0xB29F093E, 0xAB84387F,
+ 0x2C1C24B0, 0x350715F1, 0x1E2A4632, 0x07317773, 0x4870E1B4, 0x516BD0F5, 0x7A468336, 0x635DB277,
+ 0xCBFAD74E, 0xD2E1E60F, 0xF9CCB5CC, 0xE0D7848D, 0xAF96124A, 0xB68D230B, 0x9DA070C8, 0x84BB4189,
+ 0x03235D46, 0x1A386C07, 0x31153FC4, 0x280E0E85, 0x674F9842, 0x7E54A903, 0x5579FAC0, 0x4C62CB81,
+ 0x8138C51F, 0x9823F45E, 0xB30EA79D, 0xAA1596DC, 0xE554001B, 0xFC4F315A, 0xD7626299, 0xCE7953D8,
+ 0x49E14F17, 0x50FA7E56, 0x7BD72D95, 0x62CC1CD4, 0x2D8D8A13, 0x3496BB52, 0x1FBBE891, 0x06A0D9D0,
+ 0x5E7EF3EC, 0x4765C2AD, 0x6C48916E, 0x7553A02F, 0x3A1236E8, 0x230907A9, 0x0824546A, 0x113F652B,
+ 0x96A779E4, 0x8FBC48A5, 0xA4911B66, 0xBD8A2A27, 0xF2CBBCE0, 0xEBD08DA1, 0xC0FDDE62, 0xD9E6EF23,
+ 0x14BCE1BD, 0x0DA7D0FC, 0x268A833F, 0x3F91B27E, 0x70D024B9, 0x69CB15F8, 0x42E6463B, 0x5BFD777A,
+ 0xDC656BB5, 0xC57E5AF4, 0xEE530937, 0xF7483876, 0xB809AEB1, 0xA1129FF0, 0x8A3FCC33, 0x9324FD72
+ ],
+ [
+ 0x00000000, 0x01C26A37, 0x0384D46E, 0x0246BE59, 0x0709A8DC, 0x06CBC2EB, 0x048D7CB2, 0x054F1685,
+ 0x0E1351B8, 0x0FD13B8F, 0x0D9785D6, 0x0C55EFE1, 0x091AF964, 0x08D89353, 0x0A9E2D0A, 0x0B5C473D,
+ 0x1C26A370, 0x1DE4C947, 0x1FA2771E, 0x1E601D29, 0x1B2F0BAC, 0x1AED619B, 0x18ABDFC2, 0x1969B5F5,
+ 0x1235F2C8, 0x13F798FF, 0x11B126A6, 0x10734C91, 0x153C5A14, 0x14FE3023, 0x16B88E7A, 0x177AE44D,
+ 0x384D46E0, 0x398F2CD7, 0x3BC9928E, 0x3A0BF8B9, 0x3F44EE3C, 0x3E86840B, 0x3CC03A52, 0x3D025065,
+ 0x365E1758, 0x379C7D6F, 0x35DAC336, 0x3418A901, 0x3157BF84, 0x3095D5B3, 0x32D36BEA, 0x331101DD,
+ 0x246BE590, 0x25A98FA7, 0x27EF31FE, 0x262D5BC9, 0x23624D4C, 0x22A0277B, 0x20E69922, 0x2124F315,
+ 0x2A78B428, 0x2BBADE1F, 0x29FC6046, 0x283E0A71, 0x2D711CF4, 0x2CB376C3, 0x2EF5C89A, 0x2F37A2AD,
+ 0x709A8DC0, 0x7158E7F7, 0x731E59AE, 0x72DC3399, 0x7793251C, 0x76514F2B, 0x7417F172, 0x75D59B45,
+ 0x7E89DC78, 0x7F4BB64F, 0x7D0D0816, 0x7CCF6221, 0x798074A4, 0x78421E93, 0x7A04A0CA, 0x7BC6CAFD,
+ 0x6CBC2EB0, 0x6D7E4487, 0x6F38FADE, 0x6EFA90E9, 0x6BB5866C, 0x6A77EC5B, 0x68315202, 0x69F33835,
+ 0x62AF7F08, 0x636D153F, 0x612BAB66, 0x60E9C151, 0x65A6D7D4, 0x6464BDE3, 0x662203BA, 0x67E0698D,
+ 0x48D7CB20, 0x4915A117, 0x4B531F4E, 0x4A917579, 0x4FDE63FC, 0x4E1C09CB, 0x4C5AB792, 0x4D98DDA5,
+ 0x46C49A98, 0x4706F0AF, 0x45404EF6, 0x448224C1, 0x41CD3244, 0x400F5873, 0x4249E62A, 0x438B8C1D,
+ 0x54F16850, 0x55330267, 0x5775BC3E, 0x56B7D609, 0x53F8C08C, 0x523AAABB, 0x507C14E2, 0x51BE7ED5,
+ 0x5AE239E8, 0x5B2053DF, 0x5966ED86, 0x58A487B1, 0x5DEB9134, 0x5C29FB03, 0x5E6F455A, 0x5FAD2F6D,
+ 0xE1351B80, 0xE0F771B7, 0xE2B1CFEE, 0xE373A5D9, 0xE63CB35C, 0xE7FED96B, 0xE5B86732, 0xE47A0D05,
+ 0xEF264A38, 0xEEE4200F, 0xECA29E56, 0xED60F461, 0xE82FE2E4, 0xE9ED88D3, 0xEBAB368A, 0xEA695CBD,
+ 0xFD13B8F0, 0xFCD1D2C7, 0xFE976C9E, 0xFF5506A9, 0xFA1A102C, 0xFBD87A1B, 0xF99EC442, 0xF85CAE75,
+ 0xF300E948, 0xF2C2837F, 0xF0843D26, 0xF1465711, 0xF4094194, 0xF5CB2BA3, 0xF78D95FA, 0xF64FFFCD,
+ 0xD9785D60, 0xD8BA3757, 0xDAFC890E, 0xDB3EE339, 0xDE71F5BC, 0xDFB39F8B, 0xDDF521D2, 0xDC374BE5,
+ 0xD76B0CD8, 0xD6A966EF, 0xD4EFD8B6, 0xD52DB281, 0xD062A404, 0xD1A0CE33, 0xD3E6706A, 0xD2241A5D,
+ 0xC55EFE10, 0xC49C9427, 0xC6DA2A7E, 0xC7184049, 0xC25756CC, 0xC3953CFB, 0xC1D382A2, 0xC011E895,
+ 0xCB4DAFA8, 0xCA8FC59F, 0xC8C97BC6, 0xC90B11F1, 0xCC440774, 0xCD866D43, 0xCFC0D31A, 0xCE02B92D,
+ 0x91AF9640, 0x906DFC77, 0x922B422E, 0x93E92819, 0x96A63E9C, 0x976454AB, 0x9522EAF2, 0x94E080C5,
+ 0x9FBCC7F8, 0x9E7EADCF, 0x9C381396, 0x9DFA79A1, 0x98B56F24, 0x99770513, 0x9B31BB4A, 0x9AF3D17D,
+ 0x8D893530, 0x8C4B5F07, 0x8E0DE15E, 0x8FCF8B69, 0x8A809DEC, 0x8B42F7DB, 0x89044982, 0x88C623B5,
+ 0x839A6488, 0x82580EBF, 0x801EB0E6, 0x81DCDAD1, 0x8493CC54, 0x8551A663, 0x8717183A, 0x86D5720D,
+ 0xA9E2D0A0, 0xA820BA97, 0xAA6604CE, 0xABA46EF9, 0xAEEB787C, 0xAF29124B, 0xAD6FAC12, 0xACADC625,
+ 0xA7F18118, 0xA633EB2F, 0xA4755576, 0xA5B73F41, 0xA0F829C4, 0xA13A43F3, 0xA37CFDAA, 0xA2BE979D,
+ 0xB5C473D0, 0xB40619E7, 0xB640A7BE, 0xB782CD89, 0xB2CDDB0C, 0xB30FB13B, 0xB1490F62, 0xB08B6555,
+ 0xBBD72268, 0xBA15485F, 0xB853F606, 0xB9919C31, 0xBCDE8AB4, 0xBD1CE083, 0xBF5A5EDA, 0xBE9834ED
+ ],
+ [
+ 0x00000000, 0xB8BC6765, 0xAA09C88B, 0x12B5AFEE, 0x8F629757, 0x37DEF032, 0x256B5FDC, 0x9DD738B9,
+ 0xC5B428EF, 0x7D084F8A, 0x6FBDE064, 0xD7018701, 0x4AD6BFB8, 0xF26AD8DD, 0xE0DF7733, 0x58631056,
+ 0x5019579F, 0xE8A530FA, 0xFA109F14, 0x42ACF871, 0xDF7BC0C8, 0x67C7A7AD, 0x75720843, 0xCDCE6F26,
+ 0x95AD7F70, 0x2D111815, 0x3FA4B7FB, 0x8718D09E, 0x1ACFE827, 0xA2738F42, 0xB0C620AC, 0x087A47C9,
+ 0xA032AF3E, 0x188EC85B, 0x0A3B67B5, 0xB28700D0, 0x2F503869, 0x97EC5F0C, 0x8559F0E2, 0x3DE59787,
+ 0x658687D1, 0xDD3AE0B4, 0xCF8F4F5A, 0x7733283F, 0xEAE41086, 0x525877E3, 0x40EDD80D, 0xF851BF68,
+ 0xF02BF8A1, 0x48979FC4, 0x5A22302A, 0xE29E574F, 0x7F496FF6, 0xC7F50893, 0xD540A77D, 0x6DFCC018,
+ 0x359FD04E, 0x8D23B72B, 0x9F9618C5, 0x272A7FA0, 0xBAFD4719, 0x0241207C, 0x10F48F92, 0xA848E8F7,
+ 0x9B14583D, 0x23A83F58, 0x311D90B6, 0x89A1F7D3, 0x1476CF6A, 0xACCAA80F, 0xBE7F07E1, 0x06C36084,
+ 0x5EA070D2, 0xE61C17B7, 0xF4A9B859, 0x4C15DF3C, 0xD1C2E785, 0x697E80E0, 0x7BCB2F0E, 0xC377486B,
+ 0xCB0D0FA2, 0x73B168C7, 0x6104C729, 0xD9B8A04C, 0x446F98F5, 0xFCD3FF90, 0xEE66507E, 0x56DA371B,
+ 0x0EB9274D, 0xB6054028, 0xA4B0EFC6, 0x1C0C88A3, 0x81DBB01A, 0x3967D77F, 0x2BD27891, 0x936E1FF4,
+ 0x3B26F703, 0x839A9066, 0x912F3F88, 0x299358ED, 0xB4446054, 0x0CF80731, 0x1E4DA8DF, 0xA6F1CFBA,
+ 0xFE92DFEC, 0x462EB889, 0x549B1767, 0xEC277002, 0x71F048BB, 0xC94C2FDE, 0xDBF98030, 0x6345E755,
+ 0x6B3FA09C, 0xD383C7F9, 0xC1366817, 0x798A0F72, 0xE45D37CB, 0x5CE150AE, 0x4E54FF40, 0xF6E89825,
+ 0xAE8B8873, 0x1637EF16, 0x048240F8, 0xBC3E279D, 0x21E91F24, 0x99557841, 0x8BE0D7AF, 0x335CB0CA,
+ 0xED59B63B, 0x55E5D15E, 0x47507EB0, 0xFFEC19D5, 0x623B216C, 0xDA874609, 0xC832E9E7, 0x708E8E82,
+ 0x28ED9ED4, 0x9051F9B1, 0x82E4565F, 0x3A58313A, 0xA78F0983, 0x1F336EE6, 0x0D86C108, 0xB53AA66D,
+ 0xBD40E1A4, 0x05FC86C1, 0x1749292F, 0xAFF54E4A, 0x322276F3, 0x8A9E1196, 0x982BBE78, 0x2097D91D,
+ 0x78F4C94B, 0xC048AE2E, 0xD2FD01C0, 0x6A4166A5, 0xF7965E1C, 0x4F2A3979, 0x5D9F9697, 0xE523F1F2,
+ 0x4D6B1905, 0xF5D77E60, 0xE762D18E, 0x5FDEB6EB, 0xC2098E52, 0x7AB5E937, 0x680046D9, 0xD0BC21BC,
+ 0x88DF31EA, 0x3063568F, 0x22D6F961, 0x9A6A9E04, 0x07BDA6BD, 0xBF01C1D8, 0xADB46E36, 0x15080953,
+ 0x1D724E9A, 0xA5CE29FF, 0xB77B8611, 0x0FC7E174, 0x9210D9CD, 0x2AACBEA8, 0x38191146, 0x80A57623,
+ 0xD8C66675, 0x607A0110, 0x72CFAEFE, 0xCA73C99B, 0x57A4F122, 0xEF189647, 0xFDAD39A9, 0x45115ECC,
+ 0x764DEE06, 0xCEF18963, 0xDC44268D, 0x64F841E8, 0xF92F7951, 0x41931E34, 0x5326B1DA, 0xEB9AD6BF,
+ 0xB3F9C6E9, 0x0B45A18C, 0x19F00E62, 0xA14C6907, 0x3C9B51BE, 0x842736DB, 0x96929935, 0x2E2EFE50,
+ 0x2654B999, 0x9EE8DEFC, 0x8C5D7112, 0x34E11677, 0xA9362ECE, 0x118A49AB, 0x033FE645, 0xBB838120,
+ 0xE3E09176, 0x5B5CF613, 0x49E959FD, 0xF1553E98, 0x6C820621, 0xD43E6144, 0xC68BCEAA, 0x7E37A9CF,
+ 0xD67F4138, 0x6EC3265D, 0x7C7689B3, 0xC4CAEED6, 0x591DD66F, 0xE1A1B10A, 0xF3141EE4, 0x4BA87981,
+ 0x13CB69D7, 0xAB770EB2, 0xB9C2A15C, 0x017EC639, 0x9CA9FE80, 0x241599E5, 0x36A0360B, 0x8E1C516E,
+ 0x866616A7, 0x3EDA71C2, 0x2C6FDE2C, 0x94D3B949, 0x090481F0, 0xB1B8E695, 0xA30D497B, 0x1BB12E1E,
+ 0x43D23E48, 0xFB6E592D, 0xE9DBF6C3, 0x516791A6, 0xCCB0A91F, 0x740CCE7A, 0x66B96194, 0xDE0506F1
+ ],
+ [
+ 0x00000000, 0x3D6029B0, 0x7AC05360, 0x47A07AD0, 0xF580A6C0, 0xC8E08F70, 0x8F40F5A0, 0xB220DC10,
+ 0x30704BC1, 0x0D106271, 0x4AB018A1, 0x77D03111, 0xC5F0ED01, 0xF890C4B1, 0xBF30BE61, 0x825097D1,
+ 0x60E09782, 0x5D80BE32, 0x1A20C4E2, 0x2740ED52, 0x95603142, 0xA80018F2, 0xEFA06222, 0xD2C04B92,
+ 0x5090DC43, 0x6DF0F5F3, 0x2A508F23, 0x1730A693, 0xA5107A83, 0x98705333, 0xDFD029E3, 0xE2B00053,
+ 0xC1C12F04, 0xFCA106B4, 0xBB017C64, 0x866155D4, 0x344189C4, 0x0921A074, 0x4E81DAA4, 0x73E1F314,
+ 0xF1B164C5, 0xCCD14D75, 0x8B7137A5, 0xB6111E15, 0x0431C205, 0x3951EBB5, 0x7EF19165, 0x4391B8D5,
+ 0xA121B886, 0x9C419136, 0xDBE1EBE6, 0xE681C256, 0x54A11E46, 0x69C137F6, 0x2E614D26, 0x13016496,
+ 0x9151F347, 0xAC31DAF7, 0xEB91A027, 0xD6F18997, 0x64D15587, 0x59B17C37, 0x1E1106E7, 0x23712F57,
+ 0x58F35849, 0x659371F9, 0x22330B29, 0x1F532299, 0xAD73FE89, 0x9013D739, 0xD7B3ADE9, 0xEAD38459,
+ 0x68831388, 0x55E33A38, 0x124340E8, 0x2F236958, 0x9D03B548, 0xA0639CF8, 0xE7C3E628, 0xDAA3CF98,
+ 0x3813CFCB, 0x0573E67B, 0x42D39CAB, 0x7FB3B51B, 0xCD93690B, 0xF0F340BB, 0xB7533A6B, 0x8A3313DB,
+ 0x0863840A, 0x3503ADBA, 0x72A3D76A, 0x4FC3FEDA, 0xFDE322CA, 0xC0830B7A, 0x872371AA, 0xBA43581A,
+ 0x9932774D, 0xA4525EFD, 0xE3F2242D, 0xDE920D9D, 0x6CB2D18D, 0x51D2F83D, 0x167282ED, 0x2B12AB5D,
+ 0xA9423C8C, 0x9422153C, 0xD3826FEC, 0xEEE2465C, 0x5CC29A4C, 0x61A2B3FC, 0x2602C92C, 0x1B62E09C,
+ 0xF9D2E0CF, 0xC4B2C97F, 0x8312B3AF, 0xBE729A1F, 0x0C52460F, 0x31326FBF, 0x7692156F, 0x4BF23CDF,
+ 0xC9A2AB0E, 0xF4C282BE, 0xB362F86E, 0x8E02D1DE, 0x3C220DCE, 0x0142247E, 0x46E25EAE, 0x7B82771E,
+ 0xB1E6B092, 0x8C869922, 0xCB26E3F2, 0xF646CA42, 0x44661652, 0x79063FE2, 0x3EA64532, 0x03C66C82,
+ 0x8196FB53, 0xBCF6D2E3, 0xFB56A833, 0xC6368183, 0x74165D93, 0x49767423, 0x0ED60EF3, 0x33B62743,
+ 0xD1062710, 0xEC660EA0, 0xABC67470, 0x96A65DC0, 0x248681D0, 0x19E6A860, 0x5E46D2B0, 0x6326FB00,
+ 0xE1766CD1, 0xDC164561, 0x9BB63FB1, 0xA6D61601, 0x14F6CA11, 0x2996E3A1, 0x6E369971, 0x5356B0C1,
+ 0x70279F96, 0x4D47B626, 0x0AE7CCF6, 0x3787E546, 0x85A73956, 0xB8C710E6, 0xFF676A36, 0xC2074386,
+ 0x4057D457, 0x7D37FDE7, 0x3A978737, 0x07F7AE87, 0xB5D77297, 0x88B75B27, 0xCF1721F7, 0xF2770847,
+ 0x10C70814, 0x2DA721A4, 0x6A075B74, 0x576772C4, 0xE547AED4, 0xD8278764, 0x9F87FDB4, 0xA2E7D404,
+ 0x20B743D5, 0x1DD76A65, 0x5A7710B5, 0x67173905, 0xD537E515, 0xE857CCA5, 0xAFF7B675, 0x92979FC5,
+ 0xE915E8DB, 0xD475C16B, 0x93D5BBBB, 0xAEB5920B, 0x1C954E1B, 0x21F567AB, 0x66551D7B, 0x5B3534CB,
+ 0xD965A31A, 0xE4058AAA, 0xA3A5F07A, 0x9EC5D9CA, 0x2CE505DA, 0x11852C6A, 0x562556BA, 0x6B457F0A,
+ 0x89F57F59, 0xB49556E9, 0xF3352C39, 0xCE550589, 0x7C75D999, 0x4115F029, 0x06B58AF9, 0x3BD5A349,
+ 0xB9853498, 0x84E51D28, 0xC34567F8, 0xFE254E48, 0x4C059258, 0x7165BBE8, 0x36C5C138, 0x0BA5E888,
+ 0x28D4C7DF, 0x15B4EE6F, 0x521494BF, 0x6F74BD0F, 0xDD54611F, 0xE03448AF, 0xA794327F, 0x9AF41BCF,
+ 0x18A48C1E, 0x25C4A5AE, 0x6264DF7E, 0x5F04F6CE, 0xED242ADE, 0xD044036E, 0x97E479BE, 0xAA84500E,
+ 0x4834505D, 0x755479ED, 0x32F4033D, 0x0F942A8D, 0xBDB4F69D, 0x80D4DF2D, 0xC774A5FD, 0xFA148C4D,
+ 0x78441B9C, 0x4524322C, 0x028448FC, 0x3FE4614C, 0x8DC4BD5C, 0xB0A494EC, 0xF704EE3C, 0xCA64C78C
+ ],
+ [
+ 0x00000000, 0xCB5CD3A5, 0x4DC8A10B, 0x869472AE, 0x9B914216, 0x50CD91B3, 0xD659E31D, 0x1D0530B8,
+ 0xEC53826D, 0x270F51C8, 0xA19B2366, 0x6AC7F0C3, 0x77C2C07B, 0xBC9E13DE, 0x3A0A6170, 0xF156B2D5,
+ 0x03D6029B, 0xC88AD13E, 0x4E1EA390, 0x85427035, 0x9847408D, 0x531B9328, 0xD58FE186, 0x1ED33223,
+ 0xEF8580F6, 0x24D95353, 0xA24D21FD, 0x6911F258, 0x7414C2E0, 0xBF481145, 0x39DC63EB, 0xF280B04E,
+ 0x07AC0536, 0xCCF0D693, 0x4A64A43D, 0x81387798, 0x9C3D4720, 0x57619485, 0xD1F5E62B, 0x1AA9358E,
+ 0xEBFF875B, 0x20A354FE, 0xA6372650, 0x6D6BF5F5, 0x706EC54D, 0xBB3216E8, 0x3DA66446, 0xF6FAB7E3,
+ 0x047A07AD, 0xCF26D408, 0x49B2A6A6, 0x82EE7503, 0x9FEB45BB, 0x54B7961E, 0xD223E4B0, 0x197F3715,
+ 0xE82985C0, 0x23755665, 0xA5E124CB, 0x6EBDF76E, 0x73B8C7D6, 0xB8E41473, 0x3E7066DD, 0xF52CB578,
+ 0x0F580A6C, 0xC404D9C9, 0x4290AB67, 0x89CC78C2, 0x94C9487A, 0x5F959BDF, 0xD901E971, 0x125D3AD4,
+ 0xE30B8801, 0x28575BA4, 0xAEC3290A, 0x659FFAAF, 0x789ACA17, 0xB3C619B2, 0x35526B1C, 0xFE0EB8B9,
+ 0x0C8E08F7, 0xC7D2DB52, 0x4146A9FC, 0x8A1A7A59, 0x971F4AE1, 0x5C439944, 0xDAD7EBEA, 0x118B384F,
+ 0xE0DD8A9A, 0x2B81593F, 0xAD152B91, 0x6649F834, 0x7B4CC88C, 0xB0101B29, 0x36846987, 0xFDD8BA22,
+ 0x08F40F5A, 0xC3A8DCFF, 0x453CAE51, 0x8E607DF4, 0x93654D4C, 0x58399EE9, 0xDEADEC47, 0x15F13FE2,
+ 0xE4A78D37, 0x2FFB5E92, 0xA96F2C3C, 0x6233FF99, 0x7F36CF21, 0xB46A1C84, 0x32FE6E2A, 0xF9A2BD8F,
+ 0x0B220DC1, 0xC07EDE64, 0x46EAACCA, 0x8DB67F6F, 0x90B34FD7, 0x5BEF9C72, 0xDD7BEEDC, 0x16273D79,
+ 0xE7718FAC, 0x2C2D5C09, 0xAAB92EA7, 0x61E5FD02, 0x7CE0CDBA, 0xB7BC1E1F, 0x31286CB1, 0xFA74BF14,
+ 0x1EB014D8, 0xD5ECC77D, 0x5378B5D3, 0x98246676, 0x852156CE, 0x4E7D856B, 0xC8E9F7C5, 0x03B52460,
+ 0xF2E396B5, 0x39BF4510, 0xBF2B37BE, 0x7477E41B, 0x6972D4A3, 0xA22E0706, 0x24BA75A8, 0xEFE6A60D,
+ 0x1D661643, 0xD63AC5E6, 0x50AEB748, 0x9BF264ED, 0x86F75455, 0x4DAB87F0, 0xCB3FF55E, 0x006326FB,
+ 0xF135942E, 0x3A69478B, 0xBCFD3525, 0x77A1E680, 0x6AA4D638, 0xA1F8059D, 0x276C7733, 0xEC30A496,
+ 0x191C11EE, 0xD240C24B, 0x54D4B0E5, 0x9F886340, 0x828D53F8, 0x49D1805D, 0xCF45F2F3, 0x04192156,
+ 0xF54F9383, 0x3E134026, 0xB8873288, 0x73DBE12D, 0x6EDED195, 0xA5820230, 0x2316709E, 0xE84AA33B,
+ 0x1ACA1375, 0xD196C0D0, 0x5702B27E, 0x9C5E61DB, 0x815B5163, 0x4A0782C6, 0xCC93F068, 0x07CF23CD,
+ 0xF6999118, 0x3DC542BD, 0xBB513013, 0x700DE3B6, 0x6D08D30E, 0xA65400AB, 0x20C07205, 0xEB9CA1A0,
+ 0x11E81EB4, 0xDAB4CD11, 0x5C20BFBF, 0x977C6C1A, 0x8A795CA2, 0x41258F07, 0xC7B1FDA9, 0x0CED2E0C,
+ 0xFDBB9CD9, 0x36E74F7C, 0xB0733DD2, 0x7B2FEE77, 0x662ADECF, 0xAD760D6A, 0x2BE27FC4, 0xE0BEAC61,
+ 0x123E1C2F, 0xD962CF8A, 0x5FF6BD24, 0x94AA6E81, 0x89AF5E39, 0x42F38D9C, 0xC467FF32, 0x0F3B2C97,
+ 0xFE6D9E42, 0x35314DE7, 0xB3A53F49, 0x78F9ECEC, 0x65FCDC54, 0xAEA00FF1, 0x28347D5F, 0xE368AEFA,
+ 0x16441B82, 0xDD18C827, 0x5B8CBA89, 0x90D0692C, 0x8DD55994, 0x46898A31, 0xC01DF89F, 0x0B412B3A,
+ 0xFA1799EF, 0x314B4A4A, 0xB7DF38E4, 0x7C83EB41, 0x6186DBF9, 0xAADA085C, 0x2C4E7AF2, 0xE712A957,
+ 0x15921919, 0xDECECABC, 0x585AB812, 0x93066BB7, 0x8E035B0F, 0x455F88AA, 0xC3CBFA04, 0x089729A1,
+ 0xF9C19B74, 0x329D48D1, 0xB4093A7F, 0x7F55E9DA, 0x6250D962, 0xA90C0AC7, 0x2F987869, 0xE4C4ABCC
+ ],
+ [
+ 0x00000000, 0xA6770BB4, 0x979F1129, 0x31E81A9D, 0xF44F2413, 0x52382FA7, 0x63D0353A, 0xC5A73E8E,
+ 0x33EF4E67, 0x959845D3, 0xA4705F4E, 0x020754FA, 0xC7A06A74, 0x61D761C0, 0x503F7B5D, 0xF64870E9,
+ 0x67DE9CCE, 0xC1A9977A, 0xF0418DE7, 0x56368653, 0x9391B8DD, 0x35E6B369, 0x040EA9F4, 0xA279A240,
+ 0x5431D2A9, 0xF246D91D, 0xC3AEC380, 0x65D9C834, 0xA07EF6BA, 0x0609FD0E, 0x37E1E793, 0x9196EC27,
+ 0xCFBD399C, 0x69CA3228, 0x582228B5, 0xFE552301, 0x3BF21D8F, 0x9D85163B, 0xAC6D0CA6, 0x0A1A0712,
+ 0xFC5277FB, 0x5A257C4F, 0x6BCD66D2, 0xCDBA6D66, 0x081D53E8, 0xAE6A585C, 0x9F8242C1, 0x39F54975,
+ 0xA863A552, 0x0E14AEE6, 0x3FFCB47B, 0x998BBFCF, 0x5C2C8141, 0xFA5B8AF5, 0xCBB39068, 0x6DC49BDC,
+ 0x9B8CEB35, 0x3DFBE081, 0x0C13FA1C, 0xAA64F1A8, 0x6FC3CF26, 0xC9B4C492, 0xF85CDE0F, 0x5E2BD5BB,
+ 0x440B7579, 0xE27C7ECD, 0xD3946450, 0x75E36FE4, 0xB044516A, 0x16335ADE, 0x27DB4043, 0x81AC4BF7,
+ 0x77E43B1E, 0xD19330AA, 0xE07B2A37, 0x460C2183, 0x83AB1F0D, 0x25DC14B9, 0x14340E24, 0xB2430590,
+ 0x23D5E9B7, 0x85A2E203, 0xB44AF89E, 0x123DF32A, 0xD79ACDA4, 0x71EDC610, 0x4005DC8D, 0xE672D739,
+ 0x103AA7D0, 0xB64DAC64, 0x87A5B6F9, 0x21D2BD4D, 0xE47583C3, 0x42028877, 0x73EA92EA, 0xD59D995E,
+ 0x8BB64CE5, 0x2DC14751, 0x1C295DCC, 0xBA5E5678, 0x7FF968F6, 0xD98E6342, 0xE86679DF, 0x4E11726B,
+ 0xB8590282, 0x1E2E0936, 0x2FC613AB, 0x89B1181F, 0x4C162691, 0xEA612D25, 0xDB8937B8, 0x7DFE3C0C,
+ 0xEC68D02B, 0x4A1FDB9F, 0x7BF7C102, 0xDD80CAB6, 0x1827F438, 0xBE50FF8C, 0x8FB8E511, 0x29CFEEA5,
+ 0xDF879E4C, 0x79F095F8, 0x48188F65, 0xEE6F84D1, 0x2BC8BA5F, 0x8DBFB1EB, 0xBC57AB76, 0x1A20A0C2,
+ 0x8816EAF2, 0x2E61E146, 0x1F89FBDB, 0xB9FEF06F, 0x7C59CEE1, 0xDA2EC555, 0xEBC6DFC8, 0x4DB1D47C,
+ 0xBBF9A495, 0x1D8EAF21, 0x2C66B5BC, 0x8A11BE08, 0x4FB68086, 0xE9C18B32, 0xD82991AF, 0x7E5E9A1B,
+ 0xEFC8763C, 0x49BF7D88, 0x78576715, 0xDE206CA1, 0x1B87522F, 0xBDF0599B, 0x8C184306, 0x2A6F48B2,
+ 0xDC27385B, 0x7A5033EF, 0x4BB82972, 0xEDCF22C6, 0x28681C48, 0x8E1F17FC, 0xBFF70D61, 0x198006D5,
+ 0x47ABD36E, 0xE1DCD8DA, 0xD034C247, 0x7643C9F3, 0xB3E4F77D, 0x1593FCC9, 0x247BE654, 0x820CEDE0,
+ 0x74449D09, 0xD23396BD, 0xE3DB8C20, 0x45AC8794, 0x800BB91A, 0x267CB2AE, 0x1794A833, 0xB1E3A387,
+ 0x20754FA0, 0x86024414, 0xB7EA5E89, 0x119D553D, 0xD43A6BB3, 0x724D6007, 0x43A57A9A, 0xE5D2712E,
+ 0x139A01C7, 0xB5ED0A73, 0x840510EE, 0x22721B5A, 0xE7D525D4, 0x41A22E60, 0x704A34FD, 0xD63D3F49,
+ 0xCC1D9F8B, 0x6A6A943F, 0x5B828EA2, 0xFDF58516, 0x3852BB98, 0x9E25B02C, 0xAFCDAAB1, 0x09BAA105,
+ 0xFFF2D1EC, 0x5985DA58, 0x686DC0C5, 0xCE1ACB71, 0x0BBDF5FF, 0xADCAFE4B, 0x9C22E4D6, 0x3A55EF62,
+ 0xABC30345, 0x0DB408F1, 0x3C5C126C, 0x9A2B19D8, 0x5F8C2756, 0xF9FB2CE2, 0xC813367F, 0x6E643DCB,
+ 0x982C4D22, 0x3E5B4696, 0x0FB35C0B, 0xA9C457BF, 0x6C636931, 0xCA146285, 0xFBFC7818, 0x5D8B73AC,
+ 0x03A0A617, 0xA5D7ADA3, 0x943FB73E, 0x3248BC8A, 0xF7EF8204, 0x519889B0, 0x6070932D, 0xC6079899,
+ 0x304FE870, 0x9638E3C4, 0xA7D0F959, 0x01A7F2ED, 0xC400CC63, 0x6277C7D7, 0x539FDD4A, 0xF5E8D6FE,
+ 0x647E3AD9, 0xC209316D, 0xF3E12BF0, 0x55962044, 0x90311ECA, 0x3646157E, 0x07AE0FE3, 0xA1D90457,
+ 0x579174BE, 0xF1E67F0A, 0xC00E6597, 0x66796E23, 0xA3DE50AD, 0x05A95B19, 0x34414184, 0x92364A30
+ ],
+ [
+ 0x00000000, 0xCCAA009E, 0x4225077D, 0x8E8F07E3, 0x844A0EFA, 0x48E00E64, 0xC66F0987, 0x0AC50919,
+ 0xD3E51BB5, 0x1F4F1B2B, 0x91C01CC8, 0x5D6A1C56, 0x57AF154F, 0x9B0515D1, 0x158A1232, 0xD92012AC,
+ 0x7CBB312B, 0xB01131B5, 0x3E9E3656, 0xF23436C8, 0xF8F13FD1, 0x345B3F4F, 0xBAD438AC, 0x767E3832,
+ 0xAF5E2A9E, 0x63F42A00, 0xED7B2DE3, 0x21D12D7D, 0x2B142464, 0xE7BE24FA, 0x69312319, 0xA59B2387,
+ 0xF9766256, 0x35DC62C8, 0xBB53652B, 0x77F965B5, 0x7D3C6CAC, 0xB1966C32, 0x3F196BD1, 0xF3B36B4F,
+ 0x2A9379E3, 0xE639797D, 0x68B67E9E, 0xA41C7E00, 0xAED97719, 0x62737787, 0xECFC7064, 0x205670FA,
+ 0x85CD537D, 0x496753E3, 0xC7E85400, 0x0B42549E, 0x01875D87, 0xCD2D5D19, 0x43A25AFA, 0x8F085A64,
+ 0x562848C8, 0x9A824856, 0x140D4FB5, 0xD8A74F2B, 0xD2624632, 0x1EC846AC, 0x9047414F, 0x5CED41D1,
+ 0x299DC2ED, 0xE537C273, 0x6BB8C590, 0xA712C50E, 0xADD7CC17, 0x617DCC89, 0xEFF2CB6A, 0x2358CBF4,
+ 0xFA78D958, 0x36D2D9C6, 0xB85DDE25, 0x74F7DEBB, 0x7E32D7A2, 0xB298D73C, 0x3C17D0DF, 0xF0BDD041,
+ 0x5526F3C6, 0x998CF358, 0x1703F4BB, 0xDBA9F425, 0xD16CFD3C, 0x1DC6FDA2, 0x9349FA41, 0x5FE3FADF,
+ 0x86C3E873, 0x4A69E8ED, 0xC4E6EF0E, 0x084CEF90, 0x0289E689, 0xCE23E617, 0x40ACE1F4, 0x8C06E16A,
+ 0xD0EBA0BB, 0x1C41A025, 0x92CEA7C6, 0x5E64A758, 0x54A1AE41, 0x980BAEDF, 0x1684A93C, 0xDA2EA9A2,
+ 0x030EBB0E, 0xCFA4BB90, 0x412BBC73, 0x8D81BCED, 0x8744B5F4, 0x4BEEB56A, 0xC561B289, 0x09CBB217,
+ 0xAC509190, 0x60FA910E, 0xEE7596ED, 0x22DF9673, 0x281A9F6A, 0xE4B09FF4, 0x6A3F9817, 0xA6959889,
+ 0x7FB58A25, 0xB31F8ABB, 0x3D908D58, 0xF13A8DC6, 0xFBFF84DF, 0x37558441, 0xB9DA83A2, 0x7570833C,
+ 0x533B85DA, 0x9F918544, 0x111E82A7, 0xDDB48239, 0xD7718B20, 0x1BDB8BBE, 0x95548C5D, 0x59FE8CC3,
+ 0x80DE9E6F, 0x4C749EF1, 0xC2FB9912, 0x0E51998C, 0x04949095, 0xC83E900B, 0x46B197E8, 0x8A1B9776,
+ 0x2F80B4F1, 0xE32AB46F, 0x6DA5B38C, 0xA10FB312, 0xABCABA0B, 0x6760BA95, 0xE9EFBD76, 0x2545BDE8,
+ 0xFC65AF44, 0x30CFAFDA, 0xBE40A839, 0x72EAA8A7, 0x782FA1BE, 0xB485A120, 0x3A0AA6C3, 0xF6A0A65D,
+ 0xAA4DE78C, 0x66E7E712, 0xE868E0F1, 0x24C2E06F, 0x2E07E976, 0xE2ADE9E8, 0x6C22EE0B, 0xA088EE95,
+ 0x79A8FC39, 0xB502FCA7, 0x3B8DFB44, 0xF727FBDA, 0xFDE2F2C3, 0x3148F25D, 0xBFC7F5BE, 0x736DF520,
+ 0xD6F6D6A7, 0x1A5CD639, 0x94D3D1DA, 0x5879D144, 0x52BCD85D, 0x9E16D8C3, 0x1099DF20, 0xDC33DFBE,
+ 0x0513CD12, 0xC9B9CD8C, 0x4736CA6F, 0x8B9CCAF1, 0x8159C3E8, 0x4DF3C376, 0xC37CC495, 0x0FD6C40B,
+ 0x7AA64737, 0xB60C47A9, 0x3883404A, 0xF42940D4, 0xFEEC49CD, 0x32464953, 0xBCC94EB0, 0x70634E2E,
+ 0xA9435C82, 0x65E95C1C, 0xEB665BFF, 0x27CC5B61, 0x2D095278, 0xE1A352E6, 0x6F2C5505, 0xA386559B,
+ 0x061D761C, 0xCAB77682, 0x44387161, 0x889271FF, 0x825778E6, 0x4EFD7878, 0xC0727F9B, 0x0CD87F05,
+ 0xD5F86DA9, 0x19526D37, 0x97DD6AD4, 0x5B776A4A, 0x51B26353, 0x9D1863CD, 0x1397642E, 0xDF3D64B0,
+ 0x83D02561, 0x4F7A25FF, 0xC1F5221C, 0x0D5F2282, 0x079A2B9B, 0xCB302B05, 0x45BF2CE6, 0x89152C78,
+ 0x50353ED4, 0x9C9F3E4A, 0x121039A9, 0xDEBA3937, 0xD47F302E, 0x18D530B0, 0x965A3753, 0x5AF037CD,
+ 0xFF6B144A, 0x33C114D4, 0xBD4E1337, 0x71E413A9, 0x7B211AB0, 0xB78B1A2E, 0x39041DCD, 0xF5AE1D53,
+ 0x2C8E0FFF, 0xE0240F61, 0x6EAB0882, 0xA201081C, 0xA8C40105, 0x646E019B, 0xEAE10678, 0x264B06E6
+ ]
+ ];
+
+ readonly uint _finalSeed;
+ readonly IntPtr _nativeContext;
+ readonly uint[][] _table;
+ readonly bool _useIso;
+ readonly bool _useNative;
+ uint _hashInt;
+
+ /// Initializes the CRC32 table and seed as CRC32-ISO
+ public Crc32Context()
+ {
+ _hashInt = CRC32_ISO_SEED;
+ _finalSeed = CRC32_ISO_SEED;
+ _table = ISOCrc32Table;
+ _useIso = true;
+
+ if(!Native.IsSupported) return;
+
+ _nativeContext = crc32_init();
+ _useNative = _nativeContext != IntPtr.Zero;
+ }
+
+ /// Initializes the CRC32 table with a custom polynomial and seed
+ public Crc32Context(uint polynomial, uint seed)
+ {
+ _hashInt = seed;
+ _finalSeed = seed;
+ _useIso = polynomial == CRC32_ISO_POLY && seed == CRC32_ISO_SEED;
+
+ if(Native.IsSupported && _useIso)
+ {
+ _nativeContext = crc32_init();
+ _useNative = _nativeContext != IntPtr.Zero;
+ }
+ else
+ _table = GenerateTable(polynomial);
+ }
+
+#region IChecksum Members
+
+ ///
+ public string Name => Localization.CRC32_Name;
+
+ ///
+ public Guid Id => new("BCC4E18A-79CD-4B52-8A57-2B599E5176B3");
+
+ ///
+ public string Author => Authors.NataliaPortillo;
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ /// Length of buffer to hash.
+ public void Update(byte[] data, uint len) =>
+ Step(ref _hashInt, _table, data, len, _useIso, _useNative, _nativeContext);
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ public void Update(byte[] data) => Update(data, (uint)data.Length);
+
+ ///
+ /// Returns a byte array of the hash value.
+ public byte[] Final()
+ {
+ uint crc = _hashInt ^ _finalSeed;
+
+ if(!_useNative || !_useIso) return BigEndianBitConverter.GetBytes(crc);
+
+ crc32_final(_nativeContext, ref crc);
+ crc32_free(_nativeContext);
+
+ return BigEndianBitConverter.GetBytes(crc);
+ }
+
+ ///
+ /// Returns a hexadecimal representation of the hash value.
+ public string End()
+ {
+ uint crc = _hashInt ^ _finalSeed;
+
+ var crc32Output = new StringBuilder();
+
+ if(_useNative && _useIso)
+ {
+ crc32_final(_nativeContext, ref crc);
+ crc32_free(_nativeContext);
+ }
+
+ for(var i = 0; i < BigEndianBitConverter.GetBytes(crc).Length; i++)
+ crc32Output.Append(BigEndianBitConverter.GetBytes(crc)[i].ToString("x2"));
+
+ return crc32Output.ToString();
+ }
+
+#endregion
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial IntPtr crc32_init();
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial int crc32_update(IntPtr ctx, byte[] data, uint len);
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial int crc32_final(IntPtr ctx, ref uint crc);
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial void crc32_free(IntPtr ctx);
+
+ static uint[][] GenerateTable(uint polynomial)
+ {
+ var table = new uint[8][];
+
+ for(var i = 0; i < 8; i++) table[i] = new uint[256];
+
+ for(var i = 0; i < 256; i++)
+ {
+ var entry = (uint)i;
+
+ for(var j = 0; j < 8; j++)
+ {
+ if((entry & 1) == 1)
+ entry = entry >> 1 ^ polynomial;
+ else
+ entry >>= 1;
+ }
+
+ table[0][i] = entry;
+ }
+
+ for(var slice = 1; slice < 8; slice++)
+ {
+ for(var i = 0; i < 256; i++)
+ table[slice][i] = table[slice - 1][i] >> 8 ^ table[0][table[slice - 1][i] & 0xFF];
+ }
+
+ return table;
+ }
+
+ static void Step(ref uint previousCrc, uint[][] table, byte[] data, uint len, bool useIso, bool useNative,
+ IntPtr nativeContext)
+ {
+ if(useNative && useIso)
+ {
+ crc32_update(nativeContext, data, len);
+
+ return;
+ }
+
+ var currentPos = 0;
+
+ if(useIso)
+ {
+ if(Pclmulqdq.IsSupported && Sse41.IsSupported && Ssse3.IsSupported && Sse2.IsSupported)
+ {
+ // Only works in blocks of 16 bytes
+ uint blocks = len / 64;
+
+ if(blocks > 0)
+ {
+ previousCrc = ~Clmul.Step(data, blocks * 64, ~previousCrc);
+
+ currentPos = (int)(blocks * 64);
+ len -= blocks * 64;
+ }
+
+ if(len == 0) return;
+ }
+
+ if(Crc32.Arm64.IsSupported)
+ {
+ previousCrc = ArmSimd.Step64(data, len, previousCrc);
+
+ return;
+ }
+
+ if(Crc32.IsSupported)
+ {
+ previousCrc = ArmSimd.Step32(data, len, previousCrc);
+
+ return;
+ }
+ }
+
+ // Unroll according to Intel slicing by uint8_t
+ // http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
+ // http://sourceforge.net/projects/slicing-by-8/
+ const int unroll = 4;
+ const int bytesAtOnce = 8 * unroll;
+ uint crc = previousCrc;
+
+ while(len >= bytesAtOnce)
+ {
+ int unrolling;
+
+ for(unrolling = 0; unrolling < unroll; unrolling++)
+ {
+ uint one = BitConverter.ToUInt32(data, currentPos) ^ crc;
+ currentPos += 4;
+ var two = BitConverter.ToUInt32(data, currentPos);
+ currentPos += 4;
+
+ crc = table[0][two >> 24 & 0xFF] ^
+ table[1][two >> 16 & 0xFF] ^
+ table[2][two >> 8 & 0xFF] ^
+ table[3][two & 0xFF] ^
+ table[4][one >> 24 & 0xFF] ^
+ table[5][one >> 16 & 0xFF] ^
+ table[6][one >> 8 & 0xFF] ^
+ table[7][one & 0xFF];
+ }
+
+ len -= bytesAtOnce;
+ }
+
+ while(len-- != 0) crc = crc >> 8 ^ table[0][crc & 0xFF ^ data[currentPos++]];
+
+ previousCrc = crc;
+ }
+
+ /// Gets the hash of a file
+ /// File path.
+
+ // ReSharper disable once ReturnTypeCanBeEnumerable.Global
+ public static byte[] File(string filename)
+ {
+ File(filename, out byte[] hash);
+
+ return hash;
+ }
+
+ /// Gets the hash of a file in hexadecimal and as a byte array.
+ /// File path.
+ /// Byte array of the hash value.
+ public static string File(string filename, out byte[] hash) =>
+ File(filename, out hash, CRC32_ISO_POLY, CRC32_ISO_SEED);
+
+ /// Gets the hash of a file in hexadecimal and as a byte array.
+ /// File path.
+ /// Byte array of the hash value.
+ /// CRC polynomial
+ /// CRC seed
+ public static string File(string filename, out byte[] hash, uint polynomial, uint seed)
+ {
+ bool useIso = polynomial == CRC32_ISO_POLY && seed == CRC32_ISO_SEED;
+ bool useNative = Native.IsSupported;
+ IntPtr nativeContext = IntPtr.Zero;
+
+ if(useNative && useIso)
+ {
+ nativeContext = crc32_init();
+ useNative = nativeContext != IntPtr.Zero;
+ }
+
+ var fileStream = new FileStream(filename, FileMode.Open);
+
+ uint localHashInt = seed;
+
+ uint[][] localTable = GenerateTable(polynomial);
+
+ var buffer = new byte[65536];
+ int read = fileStream.EnsureRead(buffer, 0, 65536);
+
+ while(read > 0)
+ {
+ Step(ref localHashInt, localTable, buffer, (uint)read, useIso, useNative, nativeContext);
+
+ read = fileStream.EnsureRead(buffer, 0, 65536);
+ }
+
+ localHashInt ^= seed;
+
+ if(useNative && useIso)
+ {
+ crc32_final(nativeContext, ref localHashInt);
+ crc32_free(nativeContext);
+ }
+
+ hash = BigEndianBitConverter.GetBytes(localHashInt);
+
+ var crc32Output = new StringBuilder();
+
+ foreach(byte h in hash) crc32Output.Append(h.ToString("x2"));
+
+ fileStream.Close();
+
+ return crc32Output.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Length of the data buffer to hash.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, uint len, out byte[] hash) =>
+ Data(data, len, out hash, CRC32_ISO_POLY, CRC32_ISO_SEED);
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Length of the data buffer to hash.
+ /// Byte array of the hash value.
+ /// CRC polynomial
+ /// CRC seed
+ public static string Data(byte[] data, uint len, out byte[] hash, uint polynomial, uint seed)
+ {
+ bool useIso = polynomial == CRC32_ISO_POLY && seed == CRC32_ISO_SEED;
+ bool useNative = Native.IsSupported;
+ IntPtr nativeContext = IntPtr.Zero;
+
+ if(useNative && useIso)
+ {
+ nativeContext = crc32_init();
+ useNative = nativeContext != IntPtr.Zero;
+ }
+
+ uint localHashInt = seed;
+
+ uint[][] localTable = GenerateTable(polynomial);
+
+ Step(ref localHashInt, localTable, data, len, useIso, useNative, nativeContext);
+
+ localHashInt ^= seed;
+
+ if(useNative && useIso)
+ {
+ crc32_final(nativeContext, ref localHashInt);
+ crc32_free(nativeContext);
+ }
+
+ hash = BigEndianBitConverter.GetBytes(localHashInt);
+
+ var crc32Output = new StringBuilder();
+
+ foreach(byte h in hash) crc32Output.Append(h.ToString("x2"));
+
+ return crc32Output.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/CRC64/clmul.cs b/Aaru.Checksums/CRC64/clmul.cs
new file mode 100644
index 000000000..018861e48
--- /dev/null
+++ b/Aaru.Checksums/CRC64/clmul.cs
@@ -0,0 +1,122 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : clmul.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Compute the CRC64 using a parallelized folding approach with the PCLMULQDQ
+// instruction.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This file is under the public domain:
+// https://github.com/rawrunprotected/crc
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace Aaru.Checksums.CRC64;
+
+static class Clmul
+{
+ static readonly byte[] _shuffleMasks =
+ [
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x8f, 0x8e,
+ 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80
+ ];
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static void ShiftRight128(Vector128 initial, uint n, out Vector128 outLeft,
+ out Vector128 outRight)
+ {
+ uint maskPos = 16 - n;
+
+ var maskA = Vector128.Create(_shuffleMasks[maskPos],
+ _shuffleMasks[maskPos + 1],
+ _shuffleMasks[maskPos + 2],
+ _shuffleMasks[maskPos + 3],
+ _shuffleMasks[maskPos + 4],
+ _shuffleMasks[maskPos + 5],
+ _shuffleMasks[maskPos + 6],
+ _shuffleMasks[maskPos + 7],
+ _shuffleMasks[maskPos + 8],
+ _shuffleMasks[maskPos + 9],
+ _shuffleMasks[maskPos + 10],
+ _shuffleMasks[maskPos + 11],
+ _shuffleMasks[maskPos + 12],
+ _shuffleMasks[maskPos + 13],
+ _shuffleMasks[maskPos + 14],
+ _shuffleMasks[maskPos + 15]);
+
+ Vector128 maskB = Sse2.Xor(maskA, Sse2.CompareEqual(Vector128.Zero, Vector128.Zero));
+
+ outLeft = Ssse3.Shuffle(initial.AsByte(), maskB).AsUInt64();
+ outRight = Ssse3.Shuffle(initial.AsByte(), maskA).AsUInt64();
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static Vector128 Fold(Vector128 input, Vector128 foldConstants) =>
+ Sse2.Xor(Pclmulqdq.CarrylessMultiply(input, foldConstants, 0x00),
+ Pclmulqdq.CarrylessMultiply(input, foldConstants, 0x11));
+
+ internal static ulong Step(ulong crc, byte[] data, uint length)
+ {
+ var bufPos = 16;
+ const ulong k1 = 0xe05dd497ca393ae4;
+ const ulong k2 = 0xdabe95afc7875f40;
+ const ulong mu = 0x9c3e466c172963d5;
+ const ulong pol = 0x92d8af2baf0e1e85;
+ var foldConstants1 = Vector128.Create(k1, k2);
+ var foldConstants2 = Vector128.Create(mu, pol);
+ var initialCrc = Vector128.Create(~crc, 0);
+ length -= 16;
+
+ // Initial CRC can simply be added to data
+ ShiftRight128(initialCrc, 0, out Vector128 crc0, out Vector128 crc1);
+
+ Vector128 accumulator =
+ Sse2.Xor(Fold(Sse2.Xor(crc0,
+ Vector128.Create(BitConverter.ToUInt64(data, 0), BitConverter.ToUInt64(data, 8))),
+ foldConstants1),
+ crc1);
+
+ while(length >= 32)
+ {
+ accumulator =
+ Fold(Sse2.Xor(Vector128.Create(BitConverter.ToUInt64(data, bufPos),
+ BitConverter.ToUInt64(data, bufPos + 8)),
+ accumulator),
+ foldConstants1);
+
+ length -= 16;
+ bufPos += 16;
+ }
+
+ Vector128 p = Sse2.Xor(accumulator,
+ Vector128.Create(BitConverter.ToUInt64(data, bufPos),
+ BitConverter.ToUInt64(data, bufPos + 8)));
+
+ Vector128 r = Sse2.Xor(Pclmulqdq.CarrylessMultiply(p, foldConstants1, 0x10),
+ Sse2.ShiftRightLogical128BitLane(p, 8));
+
+ // Final Barrett reduction
+ Vector128 t1 = Pclmulqdq.CarrylessMultiply(r, foldConstants2, 0x00);
+
+ Vector128 t2 = Sse2.Xor(Sse2.Xor(Pclmulqdq.CarrylessMultiply(t1, foldConstants2, 0x10),
+ Sse2.ShiftLeftLogical128BitLane(t1, 8)),
+ r);
+
+ return ~((ulong)Sse41.Extract(t2.AsUInt32(), 3) << 32 | Sse41.Extract(t2.AsUInt32(), 2));
+ }
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/CRC64Context.cs b/Aaru.Checksums/CRC64Context.cs
new file mode 100644
index 000000000..e0572eaa5
--- /dev/null
+++ b/Aaru.Checksums/CRC64Context.cs
@@ -0,0 +1,594 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : CRC64Context.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Implements a CRC64 algorithm.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.X86;
+using System.Text;
+using Aaru.Checksums.CRC64;
+using Aaru.CommonTypes.Interfaces;
+using Aaru.Helpers;
+
+namespace Aaru.Checksums;
+
+///
+/// Implements a CRC64 algorithm
+[SuppressMessage("ReSharper", "UnusedMember.Global")]
+[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
+[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
+[SuppressMessage("ReSharper", "MemberCanBeInternal")]
+public sealed partial class Crc64Context : IChecksum
+{
+ /// ECMA CRC64 polynomial
+ const ulong CRC64_ECMA_POLY = 0xC96C5795D7870F42;
+ /// ECMA CRC64 seed
+ const ulong CRC64_ECMA_SEED = 0xFFFFFFFFFFFFFFFF;
+
+ static readonly ulong[][] _ecmaCrc64Table =
+ [
+ [
+ 0x0000000000000000, 0xB32E4CBE03A75F6F, 0xF4843657A840A05B, 0x47AA7AE9ABE7FF34, 0x7BD0C384FF8F5E33,
+ 0xC8FE8F3AFC28015C, 0x8F54F5D357CFFE68, 0x3C7AB96D5468A107, 0xF7A18709FF1EBC66, 0x448FCBB7FCB9E309,
+ 0x0325B15E575E1C3D, 0xB00BFDE054F94352, 0x8C71448D0091E255, 0x3F5F08330336BD3A, 0x78F572DAA8D1420E,
+ 0xCBDB3E64AB761D61, 0x7D9BA13851336649, 0xCEB5ED8652943926, 0x891F976FF973C612, 0x3A31DBD1FAD4997D,
+ 0x064B62BCAEBC387A, 0xB5652E02AD1B6715, 0xF2CF54EB06FC9821, 0x41E11855055BC74E, 0x8A3A2631AE2DDA2F,
+ 0x39146A8FAD8A8540, 0x7EBE1066066D7A74, 0xCD905CD805CA251B, 0xF1EAE5B551A2841C, 0x42C4A90B5205DB73,
+ 0x056ED3E2F9E22447, 0xB6409F5CFA457B28, 0xFB374270A266CC92, 0x48190ECEA1C193FD, 0x0FB374270A266CC9,
+ 0xBC9D3899098133A6, 0x80E781F45DE992A1, 0x33C9CD4A5E4ECDCE, 0x7463B7A3F5A932FA, 0xC74DFB1DF60E6D95,
+ 0x0C96C5795D7870F4, 0xBFB889C75EDF2F9B, 0xF812F32EF538D0AF, 0x4B3CBF90F69F8FC0, 0x774606FDA2F72EC7,
+ 0xC4684A43A15071A8, 0x83C230AA0AB78E9C, 0x30EC7C140910D1F3, 0x86ACE348F355AADB, 0x3582AFF6F0F2F5B4,
+ 0x7228D51F5B150A80, 0xC10699A158B255EF, 0xFD7C20CC0CDAF4E8, 0x4E526C720F7DAB87, 0x09F8169BA49A54B3,
+ 0xBAD65A25A73D0BDC, 0x710D64410C4B16BD, 0xC22328FF0FEC49D2, 0x85895216A40BB6E6, 0x36A71EA8A7ACE989,
+ 0x0ADDA7C5F3C4488E, 0xB9F3EB7BF06317E1, 0xFE5991925B84E8D5, 0x4D77DD2C5823B7BA, 0x64B62BCAEBC387A1,
+ 0xD7986774E864D8CE, 0x90321D9D438327FA, 0x231C512340247895, 0x1F66E84E144CD992, 0xAC48A4F017EB86FD,
+ 0xEBE2DE19BC0C79C9, 0x58CC92A7BFAB26A6, 0x9317ACC314DD3BC7, 0x2039E07D177A64A8, 0x67939A94BC9D9B9C,
+ 0xD4BDD62ABF3AC4F3, 0xE8C76F47EB5265F4, 0x5BE923F9E8F53A9B, 0x1C4359104312C5AF, 0xAF6D15AE40B59AC0,
+ 0x192D8AF2BAF0E1E8, 0xAA03C64CB957BE87, 0xEDA9BCA512B041B3, 0x5E87F01B11171EDC, 0x62FD4976457FBFDB,
+ 0xD1D305C846D8E0B4, 0x96797F21ED3F1F80, 0x2557339FEE9840EF, 0xEE8C0DFB45EE5D8E, 0x5DA24145464902E1,
+ 0x1A083BACEDAEFDD5, 0xA9267712EE09A2BA, 0x955CCE7FBA6103BD, 0x267282C1B9C65CD2, 0x61D8F8281221A3E6,
+ 0xD2F6B4961186FC89, 0x9F8169BA49A54B33, 0x2CAF25044A02145C, 0x6B055FEDE1E5EB68, 0xD82B1353E242B407,
+ 0xE451AA3EB62A1500, 0x577FE680B58D4A6F, 0x10D59C691E6AB55B, 0xA3FBD0D71DCDEA34, 0x6820EEB3B6BBF755,
+ 0xDB0EA20DB51CA83A, 0x9CA4D8E41EFB570E, 0x2F8A945A1D5C0861, 0x13F02D374934A966, 0xA0DE61894A93F609,
+ 0xE7741B60E174093D, 0x545A57DEE2D35652, 0xE21AC88218962D7A, 0x5134843C1B317215, 0x169EFED5B0D68D21,
+ 0xA5B0B26BB371D24E, 0x99CA0B06E7197349, 0x2AE447B8E4BE2C26, 0x6D4E3D514F59D312, 0xDE6071EF4CFE8C7D,
+ 0x15BB4F8BE788911C, 0xA6950335E42FCE73, 0xE13F79DC4FC83147, 0x521135624C6F6E28, 0x6E6B8C0F1807CF2F,
+ 0xDD45C0B11BA09040, 0x9AEFBA58B0476F74, 0x29C1F6E6B3E0301B, 0xC96C5795D7870F42, 0x7A421B2BD420502D,
+ 0x3DE861C27FC7AF19, 0x8EC62D7C7C60F076, 0xB2BC941128085171, 0x0192D8AF2BAF0E1E, 0x4638A2468048F12A,
+ 0xF516EEF883EFAE45, 0x3ECDD09C2899B324, 0x8DE39C222B3EEC4B, 0xCA49E6CB80D9137F, 0x7967AA75837E4C10,
+ 0x451D1318D716ED17, 0xF6335FA6D4B1B278, 0xB199254F7F564D4C, 0x02B769F17CF11223, 0xB4F7F6AD86B4690B,
+ 0x07D9BA1385133664, 0x4073C0FA2EF4C950, 0xF35D8C442D53963F, 0xCF273529793B3738, 0x7C0979977A9C6857,
+ 0x3BA3037ED17B9763, 0x888D4FC0D2DCC80C, 0x435671A479AAD56D, 0xF0783D1A7A0D8A02, 0xB7D247F3D1EA7536,
+ 0x04FC0B4DD24D2A59, 0x3886B22086258B5E, 0x8BA8FE9E8582D431, 0xCC0284772E652B05, 0x7F2CC8C92DC2746A,
+ 0x325B15E575E1C3D0, 0x8175595B76469CBF, 0xC6DF23B2DDA1638B, 0x75F16F0CDE063CE4, 0x498BD6618A6E9DE3,
+ 0xFAA59ADF89C9C28C, 0xBD0FE036222E3DB8, 0x0E21AC88218962D7, 0xC5FA92EC8AFF7FB6, 0x76D4DE52895820D9,
+ 0x317EA4BB22BFDFED, 0x8250E80521188082, 0xBE2A516875702185, 0x0D041DD676D77EEA, 0x4AAE673FDD3081DE,
+ 0xF9802B81DE97DEB1, 0x4FC0B4DD24D2A599, 0xFCEEF8632775FAF6, 0xBB44828A8C9205C2, 0x086ACE348F355AAD,
+ 0x34107759DB5DFBAA, 0x873E3BE7D8FAA4C5, 0xC094410E731D5BF1, 0x73BA0DB070BA049E, 0xB86133D4DBCC19FF,
+ 0x0B4F7F6AD86B4690, 0x4CE50583738CB9A4, 0xFFCB493D702BE6CB, 0xC3B1F050244347CC, 0x709FBCEE27E418A3,
+ 0x3735C6078C03E797, 0x841B8AB98FA4B8F8, 0xADDA7C5F3C4488E3, 0x1EF430E13FE3D78C, 0x595E4A08940428B8,
+ 0xEA7006B697A377D7, 0xD60ABFDBC3CBD6D0, 0x6524F365C06C89BF, 0x228E898C6B8B768B, 0x91A0C532682C29E4,
+ 0x5A7BFB56C35A3485, 0xE955B7E8C0FD6BEA, 0xAEFFCD016B1A94DE, 0x1DD181BF68BDCBB1, 0x21AB38D23CD56AB6,
+ 0x9285746C3F7235D9, 0xD52F0E859495CAED, 0x6601423B97329582, 0xD041DD676D77EEAA, 0x636F91D96ED0B1C5,
+ 0x24C5EB30C5374EF1, 0x97EBA78EC690119E, 0xAB911EE392F8B099, 0x18BF525D915FEFF6, 0x5F1528B43AB810C2,
+ 0xEC3B640A391F4FAD, 0x27E05A6E926952CC, 0x94CE16D091CE0DA3, 0xD3646C393A29F297, 0x604A2087398EADF8,
+ 0x5C3099EA6DE60CFF, 0xEF1ED5546E415390, 0xA8B4AFBDC5A6ACA4, 0x1B9AE303C601F3CB, 0x56ED3E2F9E224471,
+ 0xE5C372919D851B1E, 0xA26908783662E42A, 0x114744C635C5BB45, 0x2D3DFDAB61AD1A42, 0x9E13B115620A452D,
+ 0xD9B9CBFCC9EDBA19, 0x6A978742CA4AE576, 0xA14CB926613CF817, 0x1262F598629BA778, 0x55C88F71C97C584C,
+ 0xE6E6C3CFCADB0723, 0xDA9C7AA29EB3A624, 0x69B2361C9D14F94B, 0x2E184CF536F3067F, 0x9D36004B35545910,
+ 0x2B769F17CF112238, 0x9858D3A9CCB67D57, 0xDFF2A94067518263, 0x6CDCE5FE64F6DD0C, 0x50A65C93309E7C0B,
+ 0xE388102D33392364, 0xA4226AC498DEDC50, 0x170C267A9B79833F, 0xDCD7181E300F9E5E, 0x6FF954A033A8C131,
+ 0x28532E49984F3E05, 0x9B7D62F79BE8616A, 0xA707DB9ACF80C06D, 0x14299724CC279F02, 0x5383EDCD67C06036,
+ 0xE0ADA17364673F59
+ ],
+ [
+ 0x0000000000000000, 0x54E979925CD0F10D, 0xA9D2F324B9A1E21A, 0xFD3B8AB6E5711317, 0xC17D4962DC4DDAB1,
+ 0x959430F0809D2BBC, 0x68AFBA4665EC38AB, 0x3C46C3D4393CC9A6, 0x10223DEE1795ABE7, 0x44CB447C4B455AEA,
+ 0xB9F0CECAAE3449FD, 0xED19B758F2E4B8F0, 0xD15F748CCBD87156, 0x85B60D1E9708805B, 0x788D87A87279934C,
+ 0x2C64FE3A2EA96241, 0x20447BDC2F2B57CE, 0x74AD024E73FBA6C3, 0x899688F8968AB5D4, 0xDD7FF16ACA5A44D9,
+ 0xE13932BEF3668D7F, 0xB5D04B2CAFB67C72, 0x48EBC19A4AC76F65, 0x1C02B80816179E68, 0x3066463238BEFC29,
+ 0x648F3FA0646E0D24, 0x99B4B516811F1E33, 0xCD5DCC84DDCFEF3E, 0xF11B0F50E4F32698, 0xA5F276C2B823D795,
+ 0x58C9FC745D52C482, 0x0C2085E60182358F, 0x4088F7B85E56AF9C, 0x14618E2A02865E91, 0xE95A049CE7F74D86,
+ 0xBDB37D0EBB27BC8B, 0x81F5BEDA821B752D, 0xD51CC748DECB8420, 0x28274DFE3BBA9737, 0x7CCE346C676A663A,
+ 0x50AACA5649C3047B, 0x0443B3C41513F576, 0xF9783972F062E661, 0xAD9140E0ACB2176C, 0x91D78334958EDECA,
+ 0xC53EFAA6C95E2FC7, 0x380570102C2F3CD0, 0x6CEC098270FFCDDD, 0x60CC8C64717DF852, 0x3425F5F62DAD095F,
+ 0xC91E7F40C8DC1A48, 0x9DF706D2940CEB45, 0xA1B1C506AD3022E3, 0xF558BC94F1E0D3EE, 0x086336221491C0F9,
+ 0x5C8A4FB0484131F4, 0x70EEB18A66E853B5, 0x2407C8183A38A2B8, 0xD93C42AEDF49B1AF, 0x8DD53B3C839940A2,
+ 0xB193F8E8BAA58904, 0xE57A817AE6757809, 0x18410BCC03046B1E, 0x4CA8725E5FD49A13, 0x8111EF70BCAD5F38,
+ 0xD5F896E2E07DAE35, 0x28C31C54050CBD22, 0x7C2A65C659DC4C2F, 0x406CA61260E08589, 0x1485DF803C307484,
+ 0xE9BE5536D9416793, 0xBD572CA48591969E, 0x9133D29EAB38F4DF, 0xC5DAAB0CF7E805D2, 0x38E121BA129916C5,
+ 0x6C0858284E49E7C8, 0x504E9BFC77752E6E, 0x04A7E26E2BA5DF63, 0xF99C68D8CED4CC74, 0xAD75114A92043D79,
+ 0xA15594AC938608F6, 0xF5BCED3ECF56F9FB, 0x088767882A27EAEC, 0x5C6E1E1A76F71BE1, 0x6028DDCE4FCBD247,
+ 0x34C1A45C131B234A, 0xC9FA2EEAF66A305D, 0x9D135778AABAC150, 0xB177A9428413A311, 0xE59ED0D0D8C3521C,
+ 0x18A55A663DB2410B, 0x4C4C23F46162B006, 0x700AE020585E79A0, 0x24E399B2048E88AD, 0xD9D81304E1FF9BBA,
+ 0x8D316A96BD2F6AB7, 0xC19918C8E2FBF0A4, 0x9570615ABE2B01A9, 0x684BEBEC5B5A12BE, 0x3CA2927E078AE3B3,
+ 0x00E451AA3EB62A15, 0x540D28386266DB18, 0xA936A28E8717C80F, 0xFDDFDB1CDBC73902, 0xD1BB2526F56E5B43,
+ 0x85525CB4A9BEAA4E, 0x7869D6024CCFB959, 0x2C80AF90101F4854, 0x10C66C44292381F2, 0x442F15D675F370FF,
+ 0xB9149F60908263E8, 0xEDFDE6F2CC5292E5, 0xE1DD6314CDD0A76A, 0xB5341A8691005667, 0x480F903074714570,
+ 0x1CE6E9A228A1B47D, 0x20A02A76119D7DDB, 0x744953E44D4D8CD6, 0x8972D952A83C9FC1, 0xDD9BA0C0F4EC6ECC,
+ 0xF1FF5EFADA450C8D, 0xA51627688695FD80, 0x582DADDE63E4EE97, 0x0CC4D44C3F341F9A, 0x308217980608D63C,
+ 0x646B6E0A5AD82731, 0x9950E4BCBFA93426, 0xCDB99D2EE379C52B, 0x90FB71CAD654A0F5, 0xC41208588A8451F8,
+ 0x392982EE6FF542EF, 0x6DC0FB7C3325B3E2, 0x518638A80A197A44, 0x056F413A56C98B49, 0xF854CB8CB3B8985E,
+ 0xACBDB21EEF686953, 0x80D94C24C1C10B12, 0xD43035B69D11FA1F, 0x290BBF007860E908, 0x7DE2C69224B01805,
+ 0x41A405461D8CD1A3, 0x154D7CD4415C20AE, 0xE876F662A42D33B9, 0xBC9F8FF0F8FDC2B4, 0xB0BF0A16F97FF73B,
+ 0xE4567384A5AF0636, 0x196DF93240DE1521, 0x4D8480A01C0EE42C, 0x71C2437425322D8A, 0x252B3AE679E2DC87,
+ 0xD810B0509C93CF90, 0x8CF9C9C2C0433E9D, 0xA09D37F8EEEA5CDC, 0xF4744E6AB23AADD1, 0x094FC4DC574BBEC6,
+ 0x5DA6BD4E0B9B4FCB, 0x61E07E9A32A7866D, 0x350907086E777760, 0xC8328DBE8B066477, 0x9CDBF42CD7D6957A,
+ 0xD073867288020F69, 0x849AFFE0D4D2FE64, 0x79A1755631A3ED73, 0x2D480CC46D731C7E, 0x110ECF10544FD5D8,
+ 0x45E7B682089F24D5, 0xB8DC3C34EDEE37C2, 0xEC3545A6B13EC6CF, 0xC051BB9C9F97A48E, 0x94B8C20EC3475583,
+ 0x698348B826364694, 0x3D6A312A7AE6B799, 0x012CF2FE43DA7E3F, 0x55C58B6C1F0A8F32, 0xA8FE01DAFA7B9C25,
+ 0xFC177848A6AB6D28, 0xF037FDAEA72958A7, 0xA4DE843CFBF9A9AA, 0x59E50E8A1E88BABD, 0x0D0C771842584BB0,
+ 0x314AB4CC7B648216, 0x65A3CD5E27B4731B, 0x989847E8C2C5600C, 0xCC713E7A9E159101, 0xE015C040B0BCF340,
+ 0xB4FCB9D2EC6C024D, 0x49C73364091D115A, 0x1D2E4AF655CDE057, 0x216889226CF129F1, 0x7581F0B03021D8FC,
+ 0x88BA7A06D550CBEB, 0xDC53039489803AE6, 0x11EA9EBA6AF9FFCD, 0x4503E72836290EC0, 0xB8386D9ED3581DD7,
+ 0xECD1140C8F88ECDA, 0xD097D7D8B6B4257C, 0x847EAE4AEA64D471, 0x794524FC0F15C766, 0x2DAC5D6E53C5366B,
+ 0x01C8A3547D6C542A, 0x5521DAC621BCA527, 0xA81A5070C4CDB630, 0xFCF329E2981D473D, 0xC0B5EA36A1218E9B,
+ 0x945C93A4FDF17F96, 0x6967191218806C81, 0x3D8E608044509D8C, 0x31AEE56645D2A803, 0x65479CF41902590E,
+ 0x987C1642FC734A19, 0xCC956FD0A0A3BB14, 0xF0D3AC04999F72B2, 0xA43AD596C54F83BF, 0x59015F20203E90A8,
+ 0x0DE826B27CEE61A5, 0x218CD888524703E4, 0x7565A11A0E97F2E9, 0x885E2BACEBE6E1FE, 0xDCB7523EB73610F3,
+ 0xE0F191EA8E0AD955, 0xB418E878D2DA2858, 0x492362CE37AB3B4F, 0x1DCA1B5C6B7BCA42, 0x5162690234AF5051,
+ 0x058B1090687FA15C, 0xF8B09A268D0EB24B, 0xAC59E3B4D1DE4346, 0x901F2060E8E28AE0, 0xC4F659F2B4327BED,
+ 0x39CDD344514368FA, 0x6D24AAD60D9399F7, 0x414054EC233AFBB6, 0x15A92D7E7FEA0ABB, 0xE892A7C89A9B19AC,
+ 0xBC7BDE5AC64BE8A1, 0x803D1D8EFF772107, 0xD4D4641CA3A7D00A, 0x29EFEEAA46D6C31D, 0x7D0697381A063210,
+ 0x712612DE1B84079F, 0x25CF6B4C4754F692, 0xD8F4E1FAA225E585, 0x8C1D9868FEF51488, 0xB05B5BBCC7C9DD2E,
+ 0xE4B2222E9B192C23, 0x1989A8987E683F34, 0x4D60D10A22B8CE39, 0x61042F300C11AC78, 0x35ED56A250C15D75,
+ 0xC8D6DC14B5B04E62, 0x9C3FA586E960BF6F, 0xA0796652D05C76C9, 0xF4901FC08C8C87C4, 0x09AB957669FD94D3,
+ 0x5D42ECE4352D65DE
+ ],
+ [
+ 0x0000000000000000, 0x3F0BE14A916A6DCB, 0x7E17C29522D4DB96, 0x411C23DFB3BEB65D, 0xFC2F852A45A9B72C,
+ 0xC3246460D4C3DAE7, 0x823847BF677D6CBA, 0xBD33A6F5F6170171, 0x6A87A57F245D70DD, 0x558C4435B5371D16,
+ 0x149067EA0689AB4B, 0x2B9B86A097E3C680, 0x96A8205561F4C7F1, 0xA9A3C11FF09EAA3A, 0xE8BFE2C043201C67,
+ 0xD7B4038AD24A71AC, 0xD50F4AFE48BAE1BA, 0xEA04ABB4D9D08C71, 0xAB18886B6A6E3A2C, 0x94136921FB0457E7,
+ 0x2920CFD40D135696, 0x162B2E9E9C793B5D, 0x57370D412FC78D00, 0x683CEC0BBEADE0CB, 0xBF88EF816CE79167,
+ 0x80830ECBFD8DFCAC, 0xC19F2D144E334AF1, 0xFE94CC5EDF59273A, 0x43A76AAB294E264B, 0x7CAC8BE1B8244B80,
+ 0x3DB0A83E0B9AFDDD, 0x02BB49749AF09016, 0x38C63AD73E7BDDF1, 0x07CDDB9DAF11B03A, 0x46D1F8421CAF0667,
+ 0x79DA19088DC56BAC, 0xC4E9BFFD7BD26ADD, 0xFBE25EB7EAB80716, 0xBAFE7D685906B14B, 0x85F59C22C86CDC80,
+ 0x52419FA81A26AD2C, 0x6D4A7EE28B4CC0E7, 0x2C565D3D38F276BA, 0x135DBC77A9981B71, 0xAE6E1A825F8F1A00,
+ 0x9165FBC8CEE577CB, 0xD079D8177D5BC196, 0xEF72395DEC31AC5D, 0xEDC9702976C13C4B, 0xD2C29163E7AB5180,
+ 0x93DEB2BC5415E7DD, 0xACD553F6C57F8A16, 0x11E6F50333688B67, 0x2EED1449A202E6AC, 0x6FF1379611BC50F1,
+ 0x50FAD6DC80D63D3A, 0x874ED556529C4C96, 0xB845341CC3F6215D, 0xF95917C370489700, 0xC652F689E122FACB,
+ 0x7B61507C1735FBBA, 0x446AB136865F9671, 0x057692E935E1202C, 0x3A7D73A3A48B4DE7, 0x718C75AE7CF7BBE2,
+ 0x4E8794E4ED9DD629, 0x0F9BB73B5E236074, 0x30905671CF490DBF, 0x8DA3F084395E0CCE, 0xB2A811CEA8346105,
+ 0xF3B432111B8AD758, 0xCCBFD35B8AE0BA93, 0x1B0BD0D158AACB3F, 0x2400319BC9C0A6F4, 0x651C12447A7E10A9,
+ 0x5A17F30EEB147D62, 0xE72455FB1D037C13, 0xD82FB4B18C6911D8, 0x9933976E3FD7A785, 0xA6387624AEBDCA4E,
+ 0xA4833F50344D5A58, 0x9B88DE1AA5273793, 0xDA94FDC5169981CE, 0xE59F1C8F87F3EC05, 0x58ACBA7A71E4ED74,
+ 0x67A75B30E08E80BF, 0x26BB78EF533036E2, 0x19B099A5C25A5B29, 0xCE049A2F10102A85, 0xF10F7B65817A474E,
+ 0xB01358BA32C4F113, 0x8F18B9F0A3AE9CD8, 0x322B1F0555B99DA9, 0x0D20FE4FC4D3F062, 0x4C3CDD90776D463F,
+ 0x73373CDAE6072BF4, 0x494A4F79428C6613, 0x7641AE33D3E60BD8, 0x375D8DEC6058BD85, 0x08566CA6F132D04E,
+ 0xB565CA530725D13F, 0x8A6E2B19964FBCF4, 0xCB7208C625F10AA9, 0xF479E98CB49B6762, 0x23CDEA0666D116CE,
+ 0x1CC60B4CF7BB7B05, 0x5DDA28934405CD58, 0x62D1C9D9D56FA093, 0xDFE26F2C2378A1E2, 0xE0E98E66B212CC29,
+ 0xA1F5ADB901AC7A74, 0x9EFE4CF390C617BF, 0x9C4505870A3687A9, 0xA34EE4CD9B5CEA62, 0xE252C71228E25C3F,
+ 0xDD592658B98831F4, 0x606A80AD4F9F3085, 0x5F6161E7DEF55D4E, 0x1E7D42386D4BEB13, 0x2176A372FC2186D8,
+ 0xF6C2A0F82E6BF774, 0xC9C941B2BF019ABF, 0x88D5626D0CBF2CE2, 0xB7DE83279DD54129, 0x0AED25D26BC24058,
+ 0x35E6C498FAA82D93, 0x74FAE74749169BCE, 0x4BF1060DD87CF605, 0xE318EB5CF9EF77C4, 0xDC130A1668851A0F,
+ 0x9D0F29C9DB3BAC52, 0xA204C8834A51C199, 0x1F376E76BC46C0E8, 0x203C8F3C2D2CAD23, 0x6120ACE39E921B7E,
+ 0x5E2B4DA90FF876B5, 0x899F4E23DDB20719, 0xB694AF694CD86AD2, 0xF7888CB6FF66DC8F, 0xC8836DFC6E0CB144,
+ 0x75B0CB09981BB035, 0x4ABB2A430971DDFE, 0x0BA7099CBACF6BA3, 0x34ACE8D62BA50668, 0x3617A1A2B155967E,
+ 0x091C40E8203FFBB5, 0x4800633793814DE8, 0x770B827D02EB2023, 0xCA382488F4FC2152, 0xF533C5C265964C99,
+ 0xB42FE61DD628FAC4, 0x8B2407574742970F, 0x5C9004DD9508E6A3, 0x639BE59704628B68, 0x2287C648B7DC3D35,
+ 0x1D8C270226B650FE, 0xA0BF81F7D0A1518F, 0x9FB460BD41CB3C44, 0xDEA84362F2758A19, 0xE1A3A228631FE7D2,
+ 0xDBDED18BC794AA35, 0xE4D530C156FEC7FE, 0xA5C9131EE54071A3, 0x9AC2F254742A1C68, 0x27F154A1823D1D19,
+ 0x18FAB5EB135770D2, 0x59E69634A0E9C68F, 0x66ED777E3183AB44, 0xB15974F4E3C9DAE8, 0x8E5295BE72A3B723,
+ 0xCF4EB661C11D017E, 0xF045572B50776CB5, 0x4D76F1DEA6606DC4, 0x727D1094370A000F, 0x3361334B84B4B652,
+ 0x0C6AD20115DEDB99, 0x0ED19B758F2E4B8F, 0x31DA7A3F1E442644, 0x70C659E0ADFA9019, 0x4FCDB8AA3C90FDD2,
+ 0xF2FE1E5FCA87FCA3, 0xCDF5FF155BED9168, 0x8CE9DCCAE8532735, 0xB3E23D8079394AFE, 0x64563E0AAB733B52,
+ 0x5B5DDF403A195699, 0x1A41FC9F89A7E0C4, 0x254A1DD518CD8D0F, 0x9879BB20EEDA8C7E, 0xA7725A6A7FB0E1B5,
+ 0xE66E79B5CC0E57E8, 0xD96598FF5D643A23, 0x92949EF28518CC26, 0xAD9F7FB81472A1ED, 0xEC835C67A7CC17B0,
+ 0xD388BD2D36A67A7B, 0x6EBB1BD8C0B17B0A, 0x51B0FA9251DB16C1, 0x10ACD94DE265A09C, 0x2FA73807730FCD57,
+ 0xF8133B8DA145BCFB, 0xC718DAC7302FD130, 0x8604F9188391676D, 0xB90F185212FB0AA6, 0x043CBEA7E4EC0BD7,
+ 0x3B375FED7586661C, 0x7A2B7C32C638D041, 0x45209D785752BD8A, 0x479BD40CCDA22D9C, 0x789035465CC84057,
+ 0x398C1699EF76F60A, 0x0687F7D37E1C9BC1, 0xBBB45126880B9AB0, 0x84BFB06C1961F77B, 0xC5A393B3AADF4126,
+ 0xFAA872F93BB52CED, 0x2D1C7173E9FF5D41, 0x121790397895308A, 0x530BB3E6CB2B86D7, 0x6C0052AC5A41EB1C,
+ 0xD133F459AC56EA6D, 0xEE3815133D3C87A6, 0xAF2436CC8E8231FB, 0x902FD7861FE85C30, 0xAA52A425BB6311D7,
+ 0x9559456F2A097C1C, 0xD44566B099B7CA41, 0xEB4E87FA08DDA78A, 0x567D210FFECAA6FB, 0x6976C0456FA0CB30,
+ 0x286AE39ADC1E7D6D, 0x176102D04D7410A6, 0xC0D5015A9F3E610A, 0xFFDEE0100E540CC1, 0xBEC2C3CFBDEABA9C,
+ 0x81C922852C80D757, 0x3CFA8470DA97D626, 0x03F1653A4BFDBBED, 0x42ED46E5F8430DB0, 0x7DE6A7AF6929607B,
+ 0x7F5DEEDBF3D9F06D, 0x40560F9162B39DA6, 0x014A2C4ED10D2BFB, 0x3E41CD0440674630, 0x83726BF1B6704741,
+ 0xBC798ABB271A2A8A, 0xFD65A96494A49CD7, 0xC26E482E05CEF11C, 0x15DA4BA4D78480B0, 0x2AD1AAEE46EEED7B,
+ 0x6BCD8931F5505B26, 0x54C6687B643A36ED, 0xE9F5CE8E922D379C, 0xD6FE2FC403475A57, 0x97E20C1BB0F9EC0A,
+ 0xA8E9ED51219381C1
+ ],
+ [
+ 0x0000000000000000, 0x1DEE8A5E222CA1DC, 0x3BDD14BC445943B8, 0x26339EE26675E264, 0x77BA297888B28770,
+ 0x6A54A326AA9E26AC, 0x4C673DC4CCEBC4C8, 0x5189B79AEEC76514, 0xEF7452F111650EE0, 0xF29AD8AF3349AF3C,
+ 0xD4A9464D553C4D58, 0xC947CC137710EC84, 0x98CE7B8999D78990, 0x8520F1D7BBFB284C, 0xA3136F35DD8ECA28,
+ 0xBEFDE56BFFA26BF4, 0x4C300AC98DC40345, 0x51DE8097AFE8A299, 0x77ED1E75C99D40FD, 0x6A03942BEBB1E121,
+ 0x3B8A23B105768435, 0x2664A9EF275A25E9, 0x0057370D412FC78D, 0x1DB9BD5363036651, 0xA34458389CA10DA5,
+ 0xBEAAD266BE8DAC79, 0x98994C84D8F84E1D, 0x8577C6DAFAD4EFC1, 0xD4FE714014138AD5, 0xC910FB1E363F2B09,
+ 0xEF2365FC504AC96D, 0xF2CDEFA2726668B1, 0x986015931B88068A, 0x858E9FCD39A4A756, 0xA3BD012F5FD14532,
+ 0xBE538B717DFDE4EE, 0xEFDA3CEB933A81FA, 0xF234B6B5B1162026, 0xD4072857D763C242, 0xC9E9A209F54F639E,
+ 0x771447620AED086A, 0x6AFACD3C28C1A9B6, 0x4CC953DE4EB44BD2, 0x5127D9806C98EA0E, 0x00AE6E1A825F8F1A,
+ 0x1D40E444A0732EC6, 0x3B737AA6C606CCA2, 0x269DF0F8E42A6D7E, 0xD4501F5A964C05CF, 0xC9BE9504B460A413,
+ 0xEF8D0BE6D2154677, 0xF26381B8F039E7AB, 0xA3EA36221EFE82BF, 0xBE04BC7C3CD22363, 0x9837229E5AA7C107,
+ 0x85D9A8C0788B60DB, 0x3B244DAB87290B2F, 0x26CAC7F5A505AAF3, 0x00F95917C3704897, 0x1D17D349E15CE94B,
+ 0x4C9E64D30F9B8C5F, 0x5170EE8D2DB72D83, 0x7743706F4BC2CFE7, 0x6AADFA3169EE6E3B, 0xA218840D981E1391,
+ 0xBFF60E53BA32B24D, 0x99C590B1DC475029, 0x842B1AEFFE6BF1F5, 0xD5A2AD7510AC94E1, 0xC84C272B3280353D,
+ 0xEE7FB9C954F5D759, 0xF391339776D97685, 0x4D6CD6FC897B1D71, 0x50825CA2AB57BCAD, 0x76B1C240CD225EC9,
+ 0x6B5F481EEF0EFF15, 0x3AD6FF8401C99A01, 0x273875DA23E53BDD, 0x010BEB384590D9B9, 0x1CE5616667BC7865,
+ 0xEE288EC415DA10D4, 0xF3C6049A37F6B108, 0xD5F59A785183536C, 0xC81B102673AFF2B0, 0x9992A7BC9D6897A4,
+ 0x847C2DE2BF443678, 0xA24FB300D931D41C, 0xBFA1395EFB1D75C0, 0x015CDC3504BF1E34, 0x1CB2566B2693BFE8,
+ 0x3A81C88940E65D8C, 0x276F42D762CAFC50, 0x76E6F54D8C0D9944, 0x6B087F13AE213898, 0x4D3BE1F1C854DAFC,
+ 0x50D56BAFEA787B20, 0x3A78919E8396151B, 0x27961BC0A1BAB4C7, 0x01A58522C7CF56A3, 0x1C4B0F7CE5E3F77F,
+ 0x4DC2B8E60B24926B, 0x502C32B8290833B7, 0x761FAC5A4F7DD1D3, 0x6BF126046D51700F, 0xD50CC36F92F31BFB,
+ 0xC8E24931B0DFBA27, 0xEED1D7D3D6AA5843, 0xF33F5D8DF486F99F, 0xA2B6EA171A419C8B, 0xBF586049386D3D57,
+ 0x996BFEAB5E18DF33, 0x848574F57C347EEF, 0x76489B570E52165E, 0x6BA611092C7EB782, 0x4D958FEB4A0B55E6,
+ 0x507B05B56827F43A, 0x01F2B22F86E0912E, 0x1C1C3871A4CC30F2, 0x3A2FA693C2B9D296, 0x27C12CCDE095734A,
+ 0x993CC9A61F3718BE, 0x84D243F83D1BB962, 0xA2E1DD1A5B6E5B06, 0xBF0F57447942FADA, 0xEE86E0DE97859FCE,
+ 0xF3686A80B5A93E12, 0xD55BF462D3DCDC76, 0xC8B57E3CF1F07DAA, 0xD6E9A7309F3239A7, 0xCB072D6EBD1E987B,
+ 0xED34B38CDB6B7A1F, 0xF0DA39D2F947DBC3, 0xA1538E481780BED7, 0xBCBD041635AC1F0B, 0x9A8E9AF453D9FD6F,
+ 0x876010AA71F55CB3, 0x399DF5C18E573747, 0x24737F9FAC7B969B, 0x0240E17DCA0E74FF, 0x1FAE6B23E822D523,
+ 0x4E27DCB906E5B037, 0x53C956E724C911EB, 0x75FAC80542BCF38F, 0x6814425B60905253, 0x9AD9ADF912F63AE2,
+ 0x873727A730DA9B3E, 0xA104B94556AF795A, 0xBCEA331B7483D886, 0xED6384819A44BD92, 0xF08D0EDFB8681C4E,
+ 0xD6BE903DDE1DFE2A, 0xCB501A63FC315FF6, 0x75ADFF0803933402, 0x6843755621BF95DE, 0x4E70EBB447CA77BA,
+ 0x539E61EA65E6D666, 0x0217D6708B21B372, 0x1FF95C2EA90D12AE, 0x39CAC2CCCF78F0CA, 0x24244892ED545116,
+ 0x4E89B2A384BA3F2D, 0x536738FDA6969EF1, 0x7554A61FC0E37C95, 0x68BA2C41E2CFDD49, 0x39339BDB0C08B85D,
+ 0x24DD11852E241981, 0x02EE8F674851FBE5, 0x1F0005396A7D5A39, 0xA1FDE05295DF31CD, 0xBC136A0CB7F39011,
+ 0x9A20F4EED1867275, 0x87CE7EB0F3AAD3A9, 0xD647C92A1D6DB6BD, 0xCBA943743F411761, 0xED9ADD965934F505,
+ 0xF07457C87B1854D9, 0x02B9B86A097E3C68, 0x1F5732342B529DB4, 0x3964ACD64D277FD0, 0x248A26886F0BDE0C,
+ 0x7503911281CCBB18, 0x68ED1B4CA3E01AC4, 0x4EDE85AEC595F8A0, 0x53300FF0E7B9597C, 0xEDCDEA9B181B3288,
+ 0xF02360C53A379354, 0xD610FE275C427130, 0xCBFE74797E6ED0EC, 0x9A77C3E390A9B5F8, 0x879949BDB2851424,
+ 0xA1AAD75FD4F0F640, 0xBC445D01F6DC579C, 0x74F1233D072C2A36, 0x691FA96325008BEA, 0x4F2C37814375698E,
+ 0x52C2BDDF6159C852, 0x034B0A458F9EAD46, 0x1EA5801BADB20C9A, 0x38961EF9CBC7EEFE, 0x257894A7E9EB4F22,
+ 0x9B8571CC164924D6, 0x866BFB923465850A, 0xA05865705210676E, 0xBDB6EF2E703CC6B2, 0xEC3F58B49EFBA3A6,
+ 0xF1D1D2EABCD7027A, 0xD7E24C08DAA2E01E, 0xCA0CC656F88E41C2, 0x38C129F48AE82973, 0x252FA3AAA8C488AF,
+ 0x031C3D48CEB16ACB, 0x1EF2B716EC9DCB17, 0x4F7B008C025AAE03, 0x52958AD220760FDF, 0x74A614304603EDBB,
+ 0x69489E6E642F4C67, 0xD7B57B059B8D2793, 0xCA5BF15BB9A1864F, 0xEC686FB9DFD4642B, 0xF186E5E7FDF8C5F7,
+ 0xA00F527D133FA0E3, 0xBDE1D8233113013F, 0x9BD246C15766E35B, 0x863CCC9F754A4287, 0xEC9136AE1CA42CBC,
+ 0xF17FBCF03E888D60, 0xD74C221258FD6F04, 0xCAA2A84C7AD1CED8, 0x9B2B1FD69416ABCC, 0x86C59588B63A0A10,
+ 0xA0F60B6AD04FE874, 0xBD188134F26349A8, 0x03E5645F0DC1225C, 0x1E0BEE012FED8380, 0x383870E3499861E4,
+ 0x25D6FABD6BB4C038, 0x745F4D278573A52C, 0x69B1C779A75F04F0, 0x4F82599BC12AE694, 0x526CD3C5E3064748,
+ 0xA0A13C6791602FF9, 0xBD4FB639B34C8E25, 0x9B7C28DBD5396C41, 0x8692A285F715CD9D, 0xD71B151F19D2A889,
+ 0xCAF59F413BFE0955, 0xECC601A35D8BEB31, 0xF1288BFD7FA74AED, 0x4FD56E9680052119, 0x523BE4C8A22980C5,
+ 0x74087A2AC45C62A1, 0x69E6F074E670C37D, 0x386F47EE08B7A669, 0x2581CDB02A9B07B5, 0x03B253524CEEE5D1,
+ 0x1E5CD90C6EC2440D
+ ]
+ ];
+
+ readonly ulong _finalSeed;
+ readonly IntPtr _nativeContext;
+ readonly ulong[][] _table;
+ readonly bool _useEcma;
+ readonly bool _useNative;
+ ulong _hashInt;
+
+ /// Initializes the CRC64 table and seed as CRC64-ECMA
+ public Crc64Context()
+ {
+ _hashInt = CRC64_ECMA_SEED;
+ _table = _ecmaCrc64Table;
+ _finalSeed = CRC64_ECMA_SEED;
+ _useEcma = true;
+
+ if(!Native.IsSupported) return;
+
+ _nativeContext = crc64_init();
+ _useNative = _nativeContext != IntPtr.Zero;
+ }
+
+ /// Initializes the CRC16 table with a custom polynomial and seed
+ public Crc64Context(ulong polynomial, ulong seed)
+ {
+ _hashInt = seed;
+ _finalSeed = seed;
+ _useEcma = polynomial == CRC64_ECMA_POLY && seed == CRC64_ECMA_SEED;
+
+ if(Native.IsSupported && _useEcma)
+ {
+ _nativeContext = crc64_init();
+ _useNative = _nativeContext != IntPtr.Zero;
+ }
+ else
+ _table = GenerateTable(polynomial);
+ }
+
+#region IChecksum Members
+
+ ///
+ public string Name => Localization.CRC64_ECMA_Name;
+
+ ///
+ public Guid Id => new("D0C0D902-420A-45DA-A235-9D48BEE4B1CE");
+
+ ///
+ public string Author => Authors.NataliaPortillo;
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ /// Length of buffer to hash.
+ public void Update(byte[] data, uint len) =>
+ Step(ref _hashInt, _table, data, len, _useEcma, _useNative, _nativeContext);
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ public void Update(byte[] data) => Update(data, (uint)data.Length);
+
+ ///
+ /// Returns a byte array of the hash value.
+ public byte[] Final()
+ {
+ ulong crc = _hashInt ^ _finalSeed;
+
+ if(!_useNative || !_useEcma) return BigEndianBitConverter.GetBytes(crc);
+
+ crc64_final(_nativeContext, ref crc);
+ crc64_free(_nativeContext);
+
+ return BigEndianBitConverter.GetBytes(crc);
+ }
+
+ ///
+ /// Returns a hexadecimal representation of the hash value.
+ public string End()
+ {
+ ulong crc = _hashInt ^ _finalSeed;
+
+ var crc64Output = new StringBuilder();
+
+ if(_useNative && _useEcma)
+ {
+ crc64_final(_nativeContext, ref crc);
+ crc64_free(_nativeContext);
+ }
+
+ for(var i = 0; i < BigEndianBitConverter.GetBytes(crc).Length; i++)
+ crc64Output.Append(BigEndianBitConverter.GetBytes(crc)[i].ToString("x2"));
+
+ return crc64Output.ToString();
+ }
+
+#endregion
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial IntPtr crc64_init();
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial int crc64_update(IntPtr ctx, byte[] data, uint len);
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial int crc64_final(IntPtr ctx, ref ulong crc);
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial void crc64_free(IntPtr ctx);
+
+ static ulong[][] GenerateTable(ulong polynomial)
+ {
+ var table = new ulong[8][];
+
+ for(var i = 0; i < 8; i++) table[i] = new ulong[256];
+
+ for(var i = 0; i < 256; i++)
+ {
+ var entry = (ulong)i;
+
+ for(var j = 0; j < 8; j++)
+ {
+ if((entry & 1) == 1)
+ entry = entry >> 1 ^ polynomial;
+ else
+ entry >>= 1;
+ }
+
+ table[0][i] = entry;
+ }
+
+ for(var slice = 1; slice < 4; slice++)
+ {
+ for(var i = 0; i < 256; i++)
+ table[slice][i] = table[slice - 1][i] >> 8 ^ table[0][table[slice - 1][i] & 0xFF];
+ }
+
+ return table;
+ }
+
+ static void Step(ref ulong previousCrc, ulong[][] table, byte[] data, uint len, bool useEcma, bool useNative,
+ IntPtr nativeContext)
+ {
+ if(useNative && useEcma)
+ {
+ crc64_update(nativeContext, data, len);
+
+ return;
+ }
+
+ var dataOff = 0;
+
+ if(useEcma && Pclmulqdq.IsSupported && Sse41.IsSupported && Ssse3.IsSupported && Sse2.IsSupported)
+ {
+ // Only works in blocks of 32 bytes
+ uint blocks = len / 32;
+
+ if(blocks > 0)
+ {
+ previousCrc = ~Clmul.Step(~previousCrc, data, blocks * 32);
+
+ dataOff = (int)(blocks * 32);
+ len -= blocks * 32;
+ }
+
+ if(len == 0) return;
+ }
+
+ // Unroll according to Intel slicing by uint8_t
+ // http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
+ // http://sourceforge.net/projects/slicing-by-8/
+
+ ulong crc = previousCrc;
+
+ if(len > 4)
+ {
+ long limit = dataOff + (len & ~(uint)3);
+ len &= 3;
+
+ while(dataOff < limit)
+ {
+ var tmp = (uint)(crc ^ BitConverter.ToUInt32(data, dataOff));
+ dataOff += 4;
+
+ crc = table[3][tmp & 0xFF] ^
+ table[2][tmp >> 8 & 0xFF] ^
+ crc >> 32 ^
+ table[1][tmp >> 16 & 0xFF] ^
+ table[0][tmp >> 24];
+ }
+ }
+
+ while(len-- != 0) crc = table[0][data[dataOff++] ^ crc & 0xFF] ^ crc >> 8;
+
+ previousCrc = crc;
+ }
+
+ /// Gets the hash of a file
+ /// File path.
+
+ // ReSharper disable once ReturnTypeCanBeEnumerable.Global
+ public static byte[] File(string filename)
+ {
+ File(filename, out byte[] localHash);
+
+ return localHash;
+ }
+
+ /// Gets the hash of a file in hexadecimal and as a byte array.
+ /// File path.
+ /// Byte array of the hash value.
+ public static string File(string filename, out byte[] hash) =>
+ File(filename, out hash, CRC64_ECMA_POLY, CRC64_ECMA_SEED);
+
+ /// Gets the hash of a file in hexadecimal and as a byte array.
+ /// File path.
+ /// Byte array of the hash value.
+ /// CRC polynomial
+ /// CRC seed
+ public static string File(string filename, out byte[] hash, ulong polynomial, ulong seed)
+ {
+ bool useEcma = polynomial == CRC64_ECMA_POLY && seed == CRC64_ECMA_SEED;
+ bool useNative = Native.IsSupported;
+ IntPtr nativeContext = IntPtr.Zero;
+
+ if(useNative && useEcma)
+ {
+ nativeContext = crc64_init();
+ useNative = nativeContext != IntPtr.Zero;
+ }
+
+ var fileStream = new FileStream(filename, FileMode.Open);
+
+ ulong localHashInt = seed;
+
+ ulong[][] localTable = GenerateTable(polynomial);
+
+ var buffer = new byte[65536];
+ int read = fileStream.EnsureRead(buffer, 0, 65536);
+
+ while(read > 0)
+ {
+ Step(ref localHashInt, localTable, buffer, (uint)read, useEcma, useNative, nativeContext);
+
+ read = fileStream.EnsureRead(buffer, 0, 65536);
+ }
+
+ localHashInt ^= seed;
+
+ if(useNative && useEcma)
+ {
+ crc64_final(nativeContext, ref localHashInt);
+ crc64_free(nativeContext);
+ }
+
+ hash = BigEndianBitConverter.GetBytes(localHashInt);
+
+ var crc64Output = new StringBuilder();
+
+ foreach(byte h in hash) crc64Output.Append(h.ToString("x2"));
+
+ fileStream.Close();
+
+ return crc64Output.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Length of the data buffer to hash.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, uint len, out byte[] hash) =>
+ Data(data, len, out hash, CRC64_ECMA_POLY, CRC64_ECMA_SEED);
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Length of the data buffer to hash.
+ /// Byte array of the hash value.
+ /// CRC polynomial
+ /// CRC seed
+ public static string Data(byte[] data, uint len, out byte[] hash, ulong polynomial, ulong seed)
+ {
+ bool useEcma = polynomial == CRC64_ECMA_POLY && seed == CRC64_ECMA_SEED;
+ bool useNative = Native.IsSupported;
+ IntPtr nativeContext = IntPtr.Zero;
+
+ if(useNative && useEcma)
+ {
+ nativeContext = crc64_init();
+ useNative = nativeContext != IntPtr.Zero;
+ }
+
+ ulong localHashInt = seed;
+
+ ulong[][] localTable = GenerateTable(polynomial);
+
+ Step(ref localHashInt, localTable, data, len, useEcma, useNative, nativeContext);
+
+ localHashInt ^= seed;
+
+ if(useNative && useEcma)
+ {
+ crc64_final(nativeContext, ref localHashInt);
+ crc64_free(nativeContext);
+ }
+
+ hash = BigEndianBitConverter.GetBytes(localHashInt);
+
+ var crc64Output = new StringBuilder();
+
+ foreach(byte h in hash) crc64Output.Append(h.ToString("x2"));
+
+ return crc64Output.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/Fletcher32/neon.cs b/Aaru.Checksums/Fletcher32/neon.cs
new file mode 100644
index 000000000..21e175818
--- /dev/null
+++ b/Aaru.Checksums/Fletcher32/neon.cs
@@ -0,0 +1,246 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : neon.cs
+// Author(s) : Natalia Portillo
+// The Chromium Authors
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Compute Fletcher32 checksum using NEON vectorization.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// ****************************************************************************/
+
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.Arm;
+
+namespace Aaru.Checksums.Fletcher32;
+
+static class Neon
+{
+ internal static void Step(ref ushort preSum1, ref ushort preSum2, byte[] buf, uint len)
+ {
+ /*
+ * Split Fletcher-32 into component sums.
+ */
+ uint s1 = preSum1;
+ uint s2 = preSum2;
+
+ var bufPos = 0;
+
+ /*
+ * Process the data in blocks.
+ */
+ const uint block_Size = 1 << 5;
+ uint blocks = len / block_Size;
+ len -= blocks * block_Size;
+
+ while(blocks != 0)
+ {
+ uint n = Fletcher32Context.Nmax / block_Size; /* The NMAX constraint. */
+
+ if(n > blocks) n = blocks;
+
+ blocks -= n;
+ /*
+ * Process n blocks of data. At most NMAX data bytes can be
+ * processed before s2 must be reduced modulo FLETCHER_MODULE.
+ */
+ var v_S2 = Vector128.Create(s1 * n, 0, 0, 0);
+ var v_S1 = Vector128.Create(0u, 0, 0, 0);
+ Vector128 v_Column_Sum_1 = AdvSimd.DuplicateToVector128((ushort)0);
+ Vector128 v_Column_Sum_2 = AdvSimd.DuplicateToVector128((ushort)0);
+ Vector128 v_Column_Sum_3 = AdvSimd.DuplicateToVector128((ushort)0);
+ Vector128 v_Column_Sum_4 = AdvSimd.DuplicateToVector128((ushort)0);
+
+ do
+ {
+ /*
+ * Load 32 input bytes.
+ */
+ var bytes1 = Vector128.Create(buf[bufPos],
+ buf[bufPos + 1],
+ buf[bufPos + 2],
+ buf[bufPos + 3],
+ buf[bufPos + 4],
+ buf[bufPos + 5],
+ buf[bufPos + 6],
+ buf[bufPos + 7],
+ buf[bufPos + 8],
+ buf[bufPos + 9],
+ buf[bufPos + 10],
+ buf[bufPos + 11],
+ buf[bufPos + 12],
+ buf[bufPos + 13],
+ buf[bufPos + 14],
+ buf[bufPos + 15]);
+
+ bufPos += 16;
+
+ var bytes2 = Vector128.Create(buf[bufPos],
+ buf[bufPos + 1],
+ buf[bufPos + 2],
+ buf[bufPos + 3],
+ buf[bufPos + 4],
+ buf[bufPos + 5],
+ buf[bufPos + 6],
+ buf[bufPos + 7],
+ buf[bufPos + 8],
+ buf[bufPos + 9],
+ buf[bufPos + 10],
+ buf[bufPos + 11],
+ buf[bufPos + 12],
+ buf[bufPos + 13],
+ buf[bufPos + 14],
+ buf[bufPos + 15]);
+
+ bufPos += 16;
+ /*
+ * Add previous block byte sum to v_s2.
+ */
+ v_S2 = AdvSimd.Add(v_S2, v_S1);
+
+ /*
+ * Horizontally add the bytes for s1.
+ */
+ v_S1 = AdvSimd.AddPairwiseWideningAndAdd(v_S1,
+ AdvSimd
+ .AddPairwiseWideningAndAdd(AdvSimd
+ .AddPairwiseWidening(bytes1),
+ bytes2));
+
+ /*
+ * Vertically add the bytes for s2.
+ */
+ v_Column_Sum_1 = AdvSimd.AddWideningLower(v_Column_Sum_1, bytes1.GetLower());
+ v_Column_Sum_2 = AdvSimd.AddWideningLower(v_Column_Sum_2, bytes1.GetUpper());
+ v_Column_Sum_3 = AdvSimd.AddWideningLower(v_Column_Sum_3, bytes2.GetLower());
+ v_Column_Sum_4 = AdvSimd.AddWideningLower(v_Column_Sum_4, bytes2.GetUpper());
+ } while(--n != 0);
+
+ v_S2 = AdvSimd.ShiftLeftLogical(v_S2, 5);
+
+ /*
+ * Multiply-add bytes by [ 32, 31, 30, ... ] for s2.
+ */
+ v_S2 = AdvSimd.MultiplyWideningLowerAndAdd(v_S2,
+ v_Column_Sum_1.GetLower(),
+ Vector64.Create((ushort)32, 31, 30, 29));
+
+ v_S2 = AdvSimd.MultiplyWideningLowerAndAdd(v_S2,
+ v_Column_Sum_1.GetUpper(),
+ Vector64.Create((ushort)28, 27, 26, 25));
+
+ v_S2 = AdvSimd.MultiplyWideningLowerAndAdd(v_S2,
+ v_Column_Sum_2.GetLower(),
+ Vector64.Create((ushort)24, 23, 22, 21));
+
+ v_S2 = AdvSimd.MultiplyWideningLowerAndAdd(v_S2,
+ v_Column_Sum_2.GetUpper(),
+ Vector64.Create((ushort)20, 19, 18, 17));
+
+ v_S2 = AdvSimd.MultiplyWideningLowerAndAdd(v_S2,
+ v_Column_Sum_3.GetLower(),
+ Vector64.Create((ushort)16, 15, 14, 13));
+
+ v_S2 = AdvSimd.MultiplyWideningLowerAndAdd(v_S2,
+ v_Column_Sum_3.GetUpper(),
+ Vector64.Create((ushort)12, 11, 10, 9));
+
+ v_S2 = AdvSimd.MultiplyWideningLowerAndAdd(v_S2,
+ v_Column_Sum_4.GetLower(),
+ Vector64.Create((ushort)8, 7, 6, 5));
+
+ v_S2 = AdvSimd.MultiplyWideningLowerAndAdd(v_S2,
+ v_Column_Sum_4.GetUpper(),
+ Vector64.Create((ushort)4, 3, 2, 1));
+
+ /*
+ * Sum epi32 ints v_s1(s2) and accumulate in s1(s2).
+ */
+ Vector64 sum1 = AdvSimd.AddPairwise(v_S1.GetLower(), v_S1.GetUpper());
+ Vector64 sum2 = AdvSimd.AddPairwise(v_S2.GetLower(), v_S2.GetUpper());
+ Vector64 s1S2 = AdvSimd.AddPairwise(sum1, sum2);
+ s1 += AdvSimd.Extract(s1S2, 0);
+ s2 += AdvSimd.Extract(s1S2, 1);
+ /*
+ * Reduce.
+ */
+ s1 %= Fletcher32Context.FletcherModule;
+ s2 %= Fletcher32Context.FletcherModule;
+ }
+
+ /*
+ * Handle leftover data.
+ */
+ if(len != 0)
+ {
+ if(len >= 16)
+ {
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ len -= 16;
+ }
+
+ while(len-- != 0) s2 += s1 += buf[bufPos++];
+
+ if(s1 >= Fletcher32Context.FletcherModule) s1 -= Fletcher32Context.FletcherModule;
+
+ s2 %= Fletcher32Context.FletcherModule;
+ }
+
+ /*
+ * Return the recombined sums.
+ */
+ preSum1 = (ushort)(s1 & 0xFFFF);
+ preSum2 = (ushort)(s2 & 0xFFFF);
+ }
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/Fletcher32/ssse3.cs b/Aaru.Checksums/Fletcher32/ssse3.cs
new file mode 100644
index 000000000..8787b08a4
--- /dev/null
+++ b/Aaru.Checksums/Fletcher32/ssse3.cs
@@ -0,0 +1,188 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : ssse3.cs
+// Author(s) : Natalia Portillo
+// The Chromium Authors
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Compute Fletcher32 checksum using SSSE3 vectorization.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// ****************************************************************************/
+
+using System;
+using System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+
+namespace Aaru.Checksums.Fletcher32;
+
+static class Ssse3
+{
+ internal static void Step(ref ushort sum1, ref ushort sum2, byte[] buf, uint len)
+ {
+ uint s1 = sum1;
+ uint s2 = sum2;
+ var bufPos = 0;
+
+ /*
+ * Process the data in blocks.
+ */
+ const uint block_Size = 1 << 5;
+ uint blocks = len / block_Size;
+ len -= blocks * block_Size;
+
+ while(blocks != 0)
+ {
+ uint n = Fletcher32Context.Nmax / block_Size; /* The NMAX constraint. */
+
+ if(n > blocks) n = blocks;
+
+ blocks -= n;
+
+ Vector128 tap1 = Vector128.Create(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17)
+ .AsByte();
+
+ Vector128 tap2 = Vector128.Create(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1).AsByte();
+ Vector128 zero = Vector128.Create(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).AsByte();
+ var ones = Vector128.Create(1, 1, 1, 1, 1, 1, 1, 1);
+ /*
+ * Process n blocks of data. At most NMAX data bytes can be
+ * processed before s2 must be reduced modulo BASE.
+ */
+ var v_Ps = Vector128.Create(s1 * n, 0, 0, 0);
+ var v_S2 = Vector128.Create(s2, 0, 0, 0);
+ var v_S1 = Vector128.Create(0u, 0, 0, 0);
+
+ do
+ {
+ /*
+ * Load 32 input bytes.
+ */
+ var bytes1 = Vector128.Create(BitConverter.ToUInt32(buf, bufPos),
+ BitConverter.ToUInt32(buf, bufPos + 4),
+ BitConverter.ToUInt32(buf, bufPos + 8),
+ BitConverter.ToUInt32(buf, bufPos + 12));
+
+ bufPos += 16;
+
+ var bytes2 = Vector128.Create(BitConverter.ToUInt32(buf, bufPos),
+ BitConverter.ToUInt32(buf, bufPos + 4),
+ BitConverter.ToUInt32(buf, bufPos + 8),
+ BitConverter.ToUInt32(buf, bufPos + 12));
+
+ bufPos += 16;
+
+ /*
+ * Add previous block byte sum to v_ps.
+ */
+ v_Ps = Sse2.Add(v_Ps, v_S1);
+ /*
+ * Horizontally add the bytes for s1, multiply-adds the
+ * bytes by [ 32, 31, 30, ... ] for s2.
+ */
+ v_S1 = Sse2.Add(v_S1, Sse2.SumAbsoluteDifferences(bytes1.AsByte(), zero).AsUInt32());
+
+ Vector128 mad1 =
+ System.Runtime.Intrinsics.X86.Ssse3.MultiplyAddAdjacent(bytes1.AsByte(), tap1.AsSByte());
+
+ v_S2 = Sse2.Add(v_S2, Sse2.MultiplyAddAdjacent(mad1.AsInt16(), ones.AsInt16()).AsUInt32());
+ v_S1 = Sse2.Add(v_S1, Sse2.SumAbsoluteDifferences(bytes2.AsByte(), zero).AsUInt32());
+
+ Vector128 mad2 =
+ System.Runtime.Intrinsics.X86.Ssse3.MultiplyAddAdjacent(bytes2.AsByte(), tap2.AsSByte());
+
+ v_S2 = Sse2.Add(v_S2, Sse2.MultiplyAddAdjacent(mad2.AsInt16(), ones.AsInt16()).AsUInt32());
+ } while(--n != 0);
+
+ v_S2 = Sse2.Add(v_S2, Sse2.ShiftLeftLogical(v_Ps, 5));
+ /*
+ * Sum epi32 ints v_s1(s2) and accumulate in s1(s2).
+ */
+ v_S1 = Sse2.Add(v_S1, Sse2.Shuffle(v_S1, 177));
+ v_S1 = Sse2.Add(v_S1, Sse2.Shuffle(v_S1, 78));
+ s1 += (uint)Sse2.ConvertToInt32(v_S1.AsInt32());
+ v_S2 = Sse2.Add(v_S2, Sse2.Shuffle(v_S2, 177));
+ v_S2 = Sse2.Add(v_S2, Sse2.Shuffle(v_S2, 78));
+ s2 = (uint)Sse2.ConvertToInt32(v_S2.AsInt32());
+ /*
+ * Reduce.
+ */
+ s1 %= Fletcher32Context.FletcherModule;
+ s2 %= Fletcher32Context.FletcherModule;
+ }
+
+ /*
+ * Handle leftover data.
+ */
+ if(len != 0)
+ {
+ if(len >= 16)
+ {
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ s2 += s1 += buf[bufPos++];
+ len -= 16;
+ }
+
+ while(len-- != 0) s2 += s1 += buf[bufPos++];
+
+ if(s1 >= Fletcher32Context.FletcherModule) s1 -= Fletcher32Context.FletcherModule;
+
+ s2 %= Fletcher32Context.FletcherModule;
+ }
+
+ /*
+ * Return the recombined sums.
+ */
+ sum1 = (ushort)(s1 & 0xFFFF);
+ sum2 = (ushort)(s2 & 0xFFFF);
+ }
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/FletcherContext.cs b/Aaru.Checksums/FletcherContext.cs
new file mode 100644
index 000000000..46c9696ab
--- /dev/null
+++ b/Aaru.Checksums/FletcherContext.cs
@@ -0,0 +1,749 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : FletcherContext.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Implements Fletcher-32 and Fletcher-16 algorithms.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+// Disabled because the speed is abnormally slow
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics.Arm;
+using System.Text;
+using Aaru.Checksums.Fletcher32;
+using Aaru.CommonTypes.Interfaces;
+using Aaru.Helpers;
+using Ssse3 = System.Runtime.Intrinsics.X86.Ssse3;
+
+namespace Aaru.Checksums;
+
+///
+/// Implements the Fletcher-32 algorithm
+[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
+[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
+[SuppressMessage("ReSharper", "UnusedMember.Global")]
+public sealed partial class Fletcher32Context : IChecksum
+{
+ internal const ushort FletcherModule = 0xFFFF;
+ internal const uint Nmax = 5552;
+ readonly IntPtr _nativeContext;
+ readonly bool _useNative;
+ ushort _sum1, _sum2;
+
+ /// Initializes the Fletcher-32 sums
+ public Fletcher32Context()
+ {
+ _sum1 = 0xFFFF;
+ _sum2 = 0xFFFF;
+
+ if(!Native.IsSupported) return;
+
+ _nativeContext = fletcher32_init();
+ _useNative = _nativeContext != IntPtr.Zero;
+ }
+
+#region IChecksum Members
+
+ ///
+ public string Name => Localization.Fletcher32_Name;
+
+ ///
+ public Guid Id => new("0E51B39F-C5E6-4CED-9E59-BA5A42B3B2F4");
+
+ ///
+ public string Author => Authors.NataliaPortillo;
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ /// Length of buffer to hash.
+ public void Update(byte[] data, uint len) => Step(ref _sum1, ref _sum2, data, len, _useNative, _nativeContext);
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ public void Update(byte[] data) => Update(data, (uint)data.Length);
+
+ ///
+ /// Returns a byte array of the hash value.
+ public byte[] Final()
+ {
+ var finalSum = (uint)(_sum2 << 16 | _sum1);
+
+ if(!_useNative) return BigEndianBitConverter.GetBytes(finalSum);
+
+ fletcher32_final(_nativeContext, ref finalSum);
+ fletcher32_free(_nativeContext);
+
+ return BigEndianBitConverter.GetBytes(finalSum);
+ }
+
+ ///
+ /// Returns a hexadecimal representation of the hash value.
+ public string End()
+ {
+ var finalSum = (uint)(_sum2 << 16 | _sum1);
+
+ if(_useNative)
+ {
+ fletcher32_final(_nativeContext, ref finalSum);
+ fletcher32_free(_nativeContext);
+ }
+
+ var fletcherOutput = new StringBuilder();
+
+ for(var i = 0; i < BigEndianBitConverter.GetBytes(finalSum).Length; i++)
+ fletcherOutput.Append(BigEndianBitConverter.GetBytes(finalSum)[i].ToString("x2"));
+
+ return fletcherOutput.ToString();
+ }
+
+#endregion
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial IntPtr fletcher32_init();
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial int fletcher32_update(IntPtr ctx, byte[] data, uint len);
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial int fletcher32_final(IntPtr ctx, ref uint crc);
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial void fletcher32_free(IntPtr ctx);
+
+ static void Step(ref ushort previousSum1, ref ushort previousSum2, byte[] data, uint len, bool useNative,
+ IntPtr nativeContext)
+ {
+ if(useNative)
+ {
+ fletcher32_update(nativeContext, data, len);
+
+ return;
+ }
+
+ if(Ssse3.IsSupported)
+ {
+ Fletcher32.Ssse3.Step(ref previousSum1, ref previousSum2, data, len);
+
+ return;
+ }
+
+ if(AdvSimd.IsSupported)
+ {
+ Neon.Step(ref previousSum1, ref previousSum2, data, len);
+
+ return;
+ }
+
+ uint sum1 = previousSum1;
+ uint sum2 = previousSum2;
+ var dataOff = 0;
+
+ switch(len)
+ {
+ /* in case user likes doing a byte at a time, keep it fast */
+ case 1:
+ {
+ sum1 += data[dataOff];
+
+ if(sum1 >= FletcherModule) sum1 -= FletcherModule;
+
+ sum2 += sum1;
+
+ if(sum2 >= FletcherModule) sum2 -= FletcherModule;
+
+ previousSum1 = (ushort)(sum1 & 0xFFFF);
+ previousSum2 = (ushort)(sum2 & 0xFFFF);
+
+ return;
+ }
+ /* in case short lengths are provided, keep it somewhat fast */
+ case < 16:
+ {
+ while(len-- > 0)
+ {
+ sum1 += data[dataOff++];
+ sum2 += sum1;
+ }
+
+ if(sum1 >= FletcherModule) sum1 -= FletcherModule;
+
+ sum2 %= FletcherModule; /* only added so many FLETCHER_MODULE's */
+ previousSum1 = (ushort)(sum1 & 0xFFFF);
+ previousSum2 = (ushort)(sum2 & 0xFFFF);
+
+ return;
+ }
+ }
+
+ /* do length NMAX blocks -- requires just one modulo operation */
+ while(len >= Nmax)
+ {
+ len -= Nmax;
+ uint n = Nmax / 16;
+
+ do
+ {
+ sum1 += data[dataOff];
+ sum2 += sum1;
+ sum1 += data[dataOff + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 2 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4 + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4 + 2 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 2 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 4];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 4 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 4 + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 4 + 2 + 1];
+ sum2 += sum1;
+
+ /* 16 sums unrolled */
+ dataOff += 16;
+ } while(--n != 0);
+
+ sum1 %= FletcherModule;
+ sum2 %= FletcherModule;
+ }
+
+ /* do remaining bytes (less than NMAX, still just one modulo) */
+ if(len != 0)
+ {
+ /* avoid modulos if none remaining */
+ while(len >= 16)
+ {
+ len -= 16;
+ sum1 += data[dataOff];
+ sum2 += sum1;
+ sum1 += data[dataOff + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 2 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4 + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4 + 2 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 2 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 4];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 4 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 4 + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 4 + 2 + 1];
+ sum2 += sum1;
+
+ dataOff += 16;
+ }
+
+ while(len-- != 0)
+ {
+ sum1 += data[dataOff++];
+ sum2 += sum1;
+ }
+
+ sum1 %= FletcherModule;
+ sum2 %= FletcherModule;
+ }
+
+ previousSum1 = (ushort)(sum1 & 0xFFFF);
+ previousSum2 = (ushort)(sum2 & 0xFFFF);
+ }
+
+ /// Gets the hash of a file
+ /// File path.
+ public static byte[] File(string filename)
+ {
+ File(filename, out byte[] hash);
+
+ return hash;
+ }
+
+ /// Gets the hash of a file in hexadecimal and as a byte array.
+ /// File path.
+ /// Byte array of the hash value.
+ public static string File(string filename, out byte[] hash)
+ {
+ bool useNative = Native.IsSupported;
+ IntPtr nativeContext = IntPtr.Zero;
+
+ if(useNative)
+ {
+ nativeContext = fletcher32_init();
+
+ if(nativeContext == IntPtr.Zero) useNative = false;
+ }
+
+ var fileStream = new FileStream(filename, FileMode.Open);
+
+ ushort localSum1 = 0xFFFF;
+ ushort localSum2 = 0xFFFF;
+
+ var buffer = new byte[65536];
+ int read = fileStream.EnsureRead(buffer, 0, 65536);
+
+ while(read > 0)
+ {
+ Step(ref localSum1, ref localSum2, buffer, (uint)read, useNative, nativeContext);
+
+ read = fileStream.EnsureRead(buffer, 0, 65536);
+ }
+
+ var finalSum = (uint)(localSum2 << 16 | localSum1);
+
+ if(useNative)
+ {
+ fletcher32_final(nativeContext, ref finalSum);
+ fletcher32_free(nativeContext);
+ }
+
+ hash = BigEndianBitConverter.GetBytes(finalSum);
+
+ var fletcherOutput = new StringBuilder();
+
+ foreach(byte h in hash) fletcherOutput.Append(h.ToString("x2"));
+
+ fileStream.Close();
+
+ return fletcherOutput.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Length of the data buffer to hash.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, uint len, out byte[] hash)
+ {
+ bool useNative = Native.IsSupported;
+ IntPtr nativeContext = IntPtr.Zero;
+
+ if(useNative)
+ {
+ nativeContext = fletcher32_init();
+
+ if(nativeContext == IntPtr.Zero) useNative = false;
+ }
+
+ ushort localSum1 = 0xFFFF;
+ ushort localSum2 = 0xFFFF;
+
+ Step(ref localSum1, ref localSum2, data, len, useNative, nativeContext);
+
+ var finalSum = (uint)(localSum2 << 16 | localSum1);
+
+ if(useNative)
+ {
+ fletcher32_final(nativeContext, ref finalSum);
+ fletcher32_free(nativeContext);
+ }
+
+ hash = BigEndianBitConverter.GetBytes(finalSum);
+
+ var adlerOutput = new StringBuilder();
+
+ foreach(byte h in hash) adlerOutput.Append(h.ToString("x2"));
+
+ return adlerOutput.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
+}
+
+///
+/// Implements the Fletcher-16 algorithm
+[SuppressMessage("ReSharper", "UnusedMember.Global")]
+[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
+[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
+public sealed partial class Fletcher16Context : IChecksum
+{
+ const byte FLETCHER_MODULE = 0xFF;
+ const byte NMAX = 22;
+
+ readonly IntPtr _nativeContext;
+ readonly bool _useNative;
+ byte _sum1, _sum2;
+
+ /// Initializes the Fletcher-16 sums
+ public Fletcher16Context()
+ {
+ _sum1 = 0xFF;
+ _sum2 = 0xFF;
+
+ if(!Native.IsSupported) return;
+
+ _nativeContext = fletcher16_init();
+ _useNative = _nativeContext != IntPtr.Zero;
+ }
+
+#region IChecksum Members
+
+ ///
+ public string Name => Localization.Fletcher16_Name;
+
+ ///
+ public Guid Id => new("80C51F1D-71F8-4741-A0CF-18FA8102EE4B");
+
+ ///
+ public string Author => Authors.NataliaPortillo;
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ /// Length of buffer to hash.
+ public void Update(byte[] data, uint len) => Step(ref _sum1, ref _sum2, data, len, _useNative, _nativeContext);
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ public void Update(byte[] data) => Update(data, (uint)data.Length);
+
+ ///
+ /// Returns a byte array of the hash value.
+ public byte[] Final()
+ {
+ var finalSum = (ushort)(_sum2 << 8 | _sum1);
+
+ if(!_useNative) return BigEndianBitConverter.GetBytes(finalSum);
+
+ fletcher16_final(_nativeContext, ref finalSum);
+ fletcher16_free(_nativeContext);
+
+ return BigEndianBitConverter.GetBytes(finalSum);
+ }
+
+ ///
+ /// Returns a hexadecimal representation of the hash value.
+ public string End()
+ {
+ var finalSum = (ushort)(_sum2 << 8 | _sum1);
+
+ if(_useNative)
+ {
+ fletcher16_final(_nativeContext, ref finalSum);
+ fletcher16_free(_nativeContext);
+ }
+
+ var fletcherOutput = new StringBuilder();
+
+ for(var i = 0; i < BigEndianBitConverter.GetBytes(finalSum).Length; i++)
+ fletcherOutput.Append(BigEndianBitConverter.GetBytes(finalSum)[i].ToString("x2"));
+
+ return fletcherOutput.ToString();
+ }
+
+#endregion
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial IntPtr fletcher16_init();
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial int fletcher16_update(IntPtr ctx, byte[] data, uint len);
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial int fletcher16_final(IntPtr ctx, ref ushort checksum);
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial void fletcher16_free(IntPtr ctx);
+
+ static void Step(ref byte previousSum1, ref byte previousSum2, byte[] data, uint len, bool useNative,
+ IntPtr nativeContext)
+ {
+ if(useNative)
+ {
+ fletcher16_update(nativeContext, data, len);
+
+ return;
+ }
+
+ uint sum1 = previousSum1;
+ uint sum2 = previousSum2;
+ var dataOff = 0;
+
+ switch(len)
+ {
+ /* in case user likes doing a byte at a time, keep it fast */
+ case 1:
+ {
+ sum1 += data[dataOff];
+
+ if(sum1 >= FLETCHER_MODULE) sum1 -= FLETCHER_MODULE;
+
+ sum2 += sum1;
+
+ if(sum2 >= FLETCHER_MODULE) sum2 -= FLETCHER_MODULE;
+
+ previousSum1 = (byte)(sum1 & 0xFF);
+ previousSum2 = (byte)(sum2 & 0xFF);
+
+ return;
+ }
+ /* in case short lengths are provided, keep it somewhat fast */
+ case < 11:
+ {
+ while(len-- > 0)
+ {
+ sum1 += data[dataOff++];
+ sum2 += sum1;
+ }
+
+ if(sum1 >= FLETCHER_MODULE) sum1 -= FLETCHER_MODULE;
+
+ sum2 %= FLETCHER_MODULE; /* only added so many FLETCHER_MODULE's */
+ previousSum1 = (byte)(sum1 & 0xFF);
+ previousSum2 = (byte)(sum2 & 0xFF);
+
+ return;
+ }
+ }
+
+ /* do length NMAX blocks -- requires just one modulo operation */
+ while(len >= NMAX)
+ {
+ len -= NMAX;
+ uint n = NMAX / 11;
+
+ do
+ {
+ sum1 += data[dataOff];
+ sum2 += sum1;
+ sum1 += data[dataOff + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 2 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4 + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4 + 2 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 2];
+ sum2 += sum1;
+
+ /* 11 sums unrolled */
+ dataOff += 11;
+ } while(--n != 0);
+
+ sum1 %= FLETCHER_MODULE;
+ sum2 %= FLETCHER_MODULE;
+ }
+
+ /* do remaining bytes (less than NMAX, still just one modulo) */
+ if(len != 0)
+ {
+ /* avoid modulos if none remaining */
+ while(len >= 11)
+ {
+ len -= 11;
+ sum1 += data[dataOff];
+ sum2 += sum1;
+ sum1 += data[dataOff + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 2 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4 + 2];
+ sum2 += sum1;
+ sum1 += data[dataOff + 4 + 2 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 1];
+ sum2 += sum1;
+ sum1 += data[dataOff + 8 + 2];
+ sum2 += sum1;
+
+ dataOff += 11;
+ }
+
+ while(len-- != 0)
+ {
+ sum1 += data[dataOff++];
+ sum2 += sum1;
+ }
+
+ sum1 %= FLETCHER_MODULE;
+ sum2 %= FLETCHER_MODULE;
+ }
+
+ previousSum1 = (byte)(sum1 & 0xFF);
+ previousSum2 = (byte)(sum2 & 0xFF);
+ }
+
+ /// Gets the hash of a file
+ /// File path.
+ public static byte[] File(string filename)
+ {
+ File(filename, out byte[] hash);
+
+ return hash;
+ }
+
+ /// Gets the hash of a file in hexadecimal and as a byte array.
+ /// File path.
+ /// Byte array of the hash value.
+ public static string File(string filename, out byte[] hash)
+ {
+ bool useNative = Native.IsSupported;
+ IntPtr nativeContext = IntPtr.Zero;
+
+ if(useNative)
+ {
+ nativeContext = fletcher16_init();
+
+ if(nativeContext == IntPtr.Zero) useNative = false;
+ }
+
+ var fileStream = new FileStream(filename, FileMode.Open);
+
+ byte localSum1 = 0xFF;
+ byte localSum2 = 0xFF;
+
+ var buffer = new byte[65536];
+ int read = fileStream.EnsureRead(buffer, 0, 65536);
+
+ while(read > 0)
+ {
+ Step(ref localSum1, ref localSum2, buffer, (uint)read, useNative, nativeContext);
+
+ read = fileStream.EnsureRead(buffer, 0, 65536);
+ }
+
+ var finalSum = (ushort)(localSum2 << 8 | localSum1);
+
+ if(useNative)
+ {
+ fletcher16_final(nativeContext, ref finalSum);
+ fletcher16_free(nativeContext);
+ }
+
+ hash = BigEndianBitConverter.GetBytes(finalSum);
+
+ var fletcherOutput = new StringBuilder();
+
+ foreach(byte h in hash) fletcherOutput.Append(h.ToString("x2"));
+
+ fileStream.Close();
+
+ return fletcherOutput.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Length of the data buffer to hash.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, uint len, out byte[] hash)
+ {
+ bool useNative = Native.IsSupported;
+ IntPtr nativeContext = IntPtr.Zero;
+
+ if(useNative)
+ {
+ nativeContext = fletcher16_init();
+
+ if(nativeContext == IntPtr.Zero) useNative = false;
+ }
+
+ byte localSum1 = 0xFF;
+ byte localSum2 = 0xFF;
+
+ Step(ref localSum1, ref localSum2, data, len, useNative, nativeContext);
+
+ var finalSum = (ushort)(localSum2 << 8 | localSum1);
+
+ if(useNative)
+ {
+ fletcher16_final(nativeContext, ref finalSum);
+ fletcher16_free(nativeContext);
+ }
+
+ hash = BigEndianBitConverter.GetBytes(finalSum);
+
+ var adlerOutput = new StringBuilder();
+
+ foreach(byte h in hash) adlerOutput.Append(h.ToString("x2"));
+
+ return adlerOutput.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/Localization/Localization.Designer.cs b/Aaru.Checksums/Localization/Localization.Designer.cs
new file mode 100644
index 000000000..2a0b2bcce
--- /dev/null
+++ b/Aaru.Checksums/Localization/Localization.Designer.cs
@@ -0,0 +1,420 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace Aaru.Checksums {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Localization {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Localization() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Aaru.Checksums.Localization.Localization", typeof(Localization).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Adler-32.
+ ///
+ internal static string Adler32_Name {
+ get {
+ return ResourceManager.GetString("Adler32_Name", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Assertion failed.
+ ///
+ internal static string Assertion_failed {
+ get {
+ return ResourceManager.GetString("Assertion_failed", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to CD-Text Pack 4 CRC 0x{0:X4}, expected 0x{1:X4}.
+ ///
+ internal static string CD_Text_Pack_four_CRC_0_expected_1 {
+ get {
+ return ResourceManager.GetString("CD_Text_Pack_four_CRC_0_expected_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to CD-Text Pack 1 CRC 0x{0:X4}, expected 0x{1:X4}.
+ ///
+ internal static string CD_Text_Pack_one_CRC_0_expected_1 {
+ get {
+ return ResourceManager.GetString("CD_Text_Pack_one_CRC_0_expected_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to CD-Text Pack 3 CRC 0x{0:X4}, expected 0x{1:X4}.
+ ///
+ internal static string CD_Text_Pack_three_CRC_0_expected_1 {
+ get {
+ return ResourceManager.GetString("CD_Text_Pack_three_CRC_0_expected_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to CD-Text Pack 2 CRC 0x{0:X4}, expected 0x{1:X4}.
+ ///
+ internal static string CD_Text_Pack_two_CRC_0_expected_1 {
+ get {
+ return ResourceManager.GetString("CD_Text_Pack_two_CRC_0_expected_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to CRC-16 (CCITT).
+ ///
+ internal static string CRC16_CCITT_Name {
+ get {
+ return ResourceManager.GetString("CRC16_CCITT_Name", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to CRC-16 (IBM).
+ ///
+ internal static string CRC16_IBM_Name {
+ get {
+ return ResourceManager.GetString("CRC16_IBM_Name", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to CRC-32.
+ ///
+ internal static string CRC32_Name {
+ get {
+ return ResourceManager.GetString("CRC32_Name", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to CRC-64 (ECMA).
+ ///
+ internal static string CRC64_ECMA_Name {
+ get {
+ return ResourceManager.GetString("CRC64_ECMA_Name", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cyclic CDTP2 0x{0:X4}, Calc CDTP2 0x{1:X4}.
+ ///
+ internal static string Cyclic_CDTP2_0_Calc_CDTP2_1 {
+ get {
+ return ResourceManager.GetString("Cyclic_CDTP2_0_Calc_CDTP2_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cyclic CDTP3 0x{0:X4}, Calc CDTP3 0x{1:X4}.
+ ///
+ internal static string Cyclic_CDTP3_0_Calc_CDTP3_1 {
+ get {
+ return ResourceManager.GetString("Cyclic_CDTP3_0_Calc_CDTP3_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cyclic CDTP4 0x{0:X4}, Calc CDTP4 0x{1:X4}.
+ ///
+ internal static string Cyclic_CDTP4_0_Calc_CDTP4_1 {
+ get {
+ return ResourceManager.GetString("Cyclic_CDTP4_0_Calc_CDTP4_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Detected CD+EG Pack in subchannel.
+ ///
+ internal static string Detected_CD_EG_Pack_in_subchannel {
+ get {
+ return ResourceManager.GetString("Detected_CD_EG_Pack_in_subchannel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Detected CD+G Pack in subchannel.
+ ///
+ internal static string Detected_CD_G_Pack_in_subchannel {
+ get {
+ return ResourceManager.GetString("Detected_CD_G_Pack_in_subchannel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Detected CD+MIDI Pack in subchannel.
+ ///
+ internal static string Detected_CD_MIDI_Pack_in_subchannel {
+ get {
+ return ResourceManager.GetString("Detected_CD_MIDI_Pack_in_subchannel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Detected CD-TEXT Pack in subchannel.
+ ///
+ internal static string Detected_CD_TEXT_Pack_in_subchannel {
+ get {
+ return ResourceManager.GetString("Detected_CD_TEXT_Pack_in_subchannel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Detected Line Graphics Pack in subchannel.
+ ///
+ internal static string Detected_Line_Graphics_Pack_in_subchannel {
+ get {
+ return ResourceManager.GetString("Detected_Line_Graphics_Pack_in_subchannel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Detected unknown Pack type in subchannel: mode {0}, item {1}.
+ ///
+ internal static string Detected_unknown_Pack_type_in_subchannel_mode_0_item_1 {
+ get {
+ return ResourceManager.GetString("Detected_unknown_Pack_type_in_subchannel_mode_0_item_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Detected User Pack in subchannel.
+ ///
+ internal static string Detected_User_Pack_in_subchannel {
+ get {
+ return ResourceManager.GetString("Detected_User_Pack_in_subchannel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Detected Zero Pack in subchannel.
+ ///
+ internal static string Detected_Zero_Pack_in_subchannel {
+ get {
+ return ResourceManager.GetString("Detected_Zero_Pack_in_subchannel", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to
+ /// Erasure positions as determined by roots of Eras Loc Poly:
+ ///.
+ ///
+ internal static string Erasure_positions_as_determined_by_roots_of_Eras_Loc_Poly {
+ get {
+ return ResourceManager.GetString("Erasure_positions_as_determined_by_roots_of_Eras_Loc_Poly", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to
+ /// ERROR: denominator = 0
+ ///.
+ ///
+ internal static string ERROR_denominator_equals_zero {
+ get {
+ return ResourceManager.GetString("ERROR_denominator_equals_zero", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to
+ /// Final error positions: .
+ ///
+ internal static string Final_error_positions {
+ get {
+ return ResourceManager.GetString("Final_error_positions", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Fletcher-16.
+ ///
+ internal static string Fletcher16_Name {
+ get {
+ return ResourceManager.GetString("Fletcher16_Name", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Fletcher-32.
+ ///
+ internal static string Fletcher32_Name {
+ get {
+ return ResourceManager.GetString("Fletcher32_Name", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to
+ /// lambda(x) is WRONG
+ ///.
+ ///
+ internal static string lambda_is_wrong {
+ get {
+ return ResourceManager.GetString("lambda_is_wrong", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to m must be between 2 and 16 inclusive.
+ ///
+ internal static string m_must_be_between_2_and_16_inclusive {
+ get {
+ return ResourceManager.GetString("m_must_be_between_2_and_16_inclusive", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to MD5.
+ ///
+ internal static string MD5_Name {
+ get {
+ return ResourceManager.GetString("MD5_Name", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Not yet implemented..
+ ///
+ internal static string Not_yet_implemented {
+ get {
+ return ResourceManager.GetString("Not_yet_implemented", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Q subchannel CRC 0x{0:X4}, expected 0x{1:X4}.
+ ///
+ internal static string Q_subchannel_CRC_0_expected_1 {
+ get {
+ return ResourceManager.GetString("Q_subchannel_CRC_0_expected_1", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to SHA1.
+ ///
+ internal static string SHA1_Name {
+ get {
+ return ResourceManager.GetString("SHA1_Name", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to SHA256.
+ ///
+ internal static string SHA256_Name {
+ get {
+ return ResourceManager.GetString("SHA256_Name", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to SHA384.
+ ///
+ internal static string SHA384_Name {
+ get {
+ return ResourceManager.GetString("SHA384_Name", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to SHA512.
+ ///
+ internal static string SHA512_Name {
+ get {
+ return ResourceManager.GetString("SHA512_Name", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to SpamSum does not have a binary representation..
+ ///
+ internal static string SpamSum_does_not_have_a_binary_representation {
+ get {
+ return ResourceManager.GetString("SpamSum_does_not_have_a_binary_representation", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to SpamSum.
+ ///
+ internal static string SpamSum_Name {
+ get {
+ return ResourceManager.GetString("SpamSum_Name", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The input exceeds data types..
+ ///
+ internal static string The_input_exceeds_data_types {
+ get {
+ return ResourceManager.GetString("The_input_exceeds_data_types", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Trying to calculate RS without initializing!.
+ ///
+ internal static string Trying_to_calculate_RS_without_initializing {
+ get {
+ return ResourceManager.GetString("Trying_to_calculate_RS_without_initializing", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/Aaru.Checksums/Localization/Localization.es.resx b/Aaru.Checksums/Localization/Localization.es.resx
new file mode 100644
index 000000000..9f9a0e949
--- /dev/null
+++ b/Aaru.Checksums/Localization/Localization.es.resx
@@ -0,0 +1,136 @@
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
+ PublicKeyToken=b77a5c561934e089
+
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
+ PublicKeyToken=b77a5c561934e089
+
+
+
+ Error de aserción
+
+
+ CRC del paquete 4 de CD-Text es 0x{0:X4} se esperaba 0x{1:X4}
+
+
+ CRC del paquete 1 de CD-Text es 0x{0:X4} se esperaba 0x{1:X4}
+
+
+ CRC del paquete 3 de CD-Text es 0x{0:X4} se esperaba 0x{1:X4}
+
+
+ CRC del paquete 4 de CD-Text es 0x{0:X4} se esperaba 0x{1:X4}
+
+
+ CDTP2 cíclico 0x{0:X4}, CDTP2 calculado 0x{1:X4}
+
+
+ CDTP3 cíclico 0x{0:X4}, CDTP3 calculado 0x{1:X4}
+
+
+ CDTP4 cíclico 0x{0:X4}, CDTP4 calculado 0x{1:X4}
+
+
+ Detectado paquete CD+EG en el subcanal
+
+
+ Detectado paquete CD+G en el subcanal
+
+
+ Detectado paquete CD+MIDI en el subcanal
+
+
+ Detectado paquete CD-TEXT en el subcanal
+
+
+ Detectado paquete de gráficos lineales en el subcanal
+
+
+ Detectado paquete de tipo desconocido en el subcanal: modo {0}, elemento {1}
+
+
+ Detectado paquete de usuario en el subcanal
+
+
+ Detectado paquete cero en el subcanal
+
+
+ Posiciones de borrado determinadas por el polinomio:
+
+
+ ERROR: denominador = 0
+
+
+ Posiciones finales de error:
+
+
+ lambda(x) es INCORRECTO
+
+
+ m debe estar entre 2 y 16 inclusivos
+
+
+ Aún no implementado.
+
+
+ CRC del subcanal Q es 0x{0:X4}, se esperaba 0x{1:X4}
+
+
+ SpamSum no posee una representación binaria.
+
+
+ La entrada excede los tipos de datos
+
+
+ ¡Intentando calcular RS sin inicializar!
+
+
+ Adler-32
+
+
+ CRC-16 (CCITT)
+
+
+ CRC-16 (IBM)
+
+
+ CRC-32
+
+
+ CRC-64 (ECMA)
+
+
+ Fletcher-32
+
+
+ Fletcher-16
+
+
+ MD5
+
+
+ SHA1
+
+
+ SHA256
+
+
+ SHA384
+
+
+ SHA512
+
+
+ SpamSum
+
+
\ No newline at end of file
diff --git a/Aaru.Checksums/Localization/Localization.resx b/Aaru.Checksums/Localization/Localization.resx
new file mode 100644
index 000000000..4d624dda0
--- /dev/null
+++ b/Aaru.Checksums/Localization/Localization.resx
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 1.3
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
+ PublicKeyToken=b77a5c561934e089
+
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral,
+ PublicKeyToken=b77a5c561934e089
+
+
+
+ Detected Zero Pack in subchannel
+
+
+ Detected Line Graphics Pack in subchannel
+
+
+ Detected CD+G Pack in subchannel
+
+
+ Detected CD+EG Pack in subchannel
+
+
+ Detected CD-TEXT Pack in subchannel
+
+
+ Detected CD+MIDI Pack in subchannel
+
+
+ Detected User Pack in subchannel
+
+
+ Detected unknown Pack type in subchannel: mode {0}, item {1}
+
+
+ Q subchannel CRC 0x{0:X4}, expected 0x{1:X4}
+
+
+ CD-Text Pack 1 CRC 0x{0:X4}, expected 0x{1:X4}
+
+
+ Cyclic CDTP2 0x{0:X4}, Calc CDTP2 0x{1:X4}
+
+
+ CD-Text Pack 2 CRC 0x{0:X4}, expected 0x{1:X4}
+
+
+ Cyclic CDTP3 0x{0:X4}, Calc CDTP3 0x{1:X4}
+
+
+ CD-Text Pack 3 CRC 0x{0:X4}, expected 0x{1:X4}
+
+
+ Cyclic CDTP4 0x{0:X4}, Calc CDTP4 0x{1:X4}
+
+
+ CD-Text Pack 4 CRC 0x{0:X4}, expected 0x{1:X4}
+
+
+ m must be between 2 and 16 inclusive
+
+
+ Trying to calculate RS without initializing!
+
+
+
+ lambda(x) is WRONG
+
+
+
+
+ Erasure positions as determined by roots of Eras Loc Poly:
+
+
+
+
+ Final error positions:
+
+
+
+ ERROR: denominator = 0
+
+
+
+ SpamSum does not have a binary representation.
+
+
+ Assertion failed
+
+
+ The input exceeds data types.
+
+
+ Not yet implemented.
+
+
+ Adler-32
+
+
+ CRC-16 (CCITT)
+
+
+ CRC-16 (IBM)
+
+
+ CRC-32
+
+
+ CRC-64 (ECMA)
+
+
+ Fletcher-32
+
+
+ Fletcher-16
+
+
+ MD5
+
+
+ SHA1
+
+
+ SHA256
+
+
+ SHA384
+
+
+ SHA512
+
+
+ SpamSum
+
+
\ No newline at end of file
diff --git a/Aaru.Checksums/MD5Context.cs b/Aaru.Checksums/MD5Context.cs
new file mode 100644
index 000000000..3061b6dd0
--- /dev/null
+++ b/Aaru.Checksums/MD5Context.cs
@@ -0,0 +1,145 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : MD5Context.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Wraps up .NET MD5 implementation to a Init(), Update(), Final() context.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
+using Aaru.CommonTypes.Interfaces;
+
+namespace Aaru.Checksums;
+
+///
+/// Wraps up .NET MD5 implementation to a Init(), Update(), Final() context.
+public sealed class Md5Context : IChecksum
+{
+ readonly MD5 _provider;
+
+ /// Initializes the MD5 hash provider
+ public Md5Context() => _provider = MD5.Create();
+
+#region IChecksum Members
+
+ ///
+ public string Name => Localization.MD5_Name;
+
+ ///
+ public Guid Id => new("C78674C4-F699-4FAB-A618-1661AF659A7C");
+
+ ///
+ public string Author => Authors.NataliaPortillo;
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ /// Length of buffer to hash.
+ public void Update(byte[] data, uint len) => _provider.TransformBlock(data, 0, (int)len, data, 0);
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ public void Update(byte[] data) => Update(data, (uint)data.Length);
+
+ ///
+ /// Returns a byte array of the hash value.
+ public byte[] Final()
+ {
+ _provider.TransformFinalBlock([], 0, 0);
+
+ return _provider.Hash;
+ }
+
+ ///
+ /// Returns a hexadecimal representation of the hash value.
+ public string End()
+ {
+ _provider.TransformFinalBlock([], 0, 0);
+ var md5Output = new StringBuilder();
+
+ if(_provider.Hash is null) return null;
+
+ foreach(byte h in _provider.Hash) md5Output.Append(h.ToString("x2"));
+
+ return md5Output.ToString();
+ }
+
+#endregion
+
+ /// Gets the hash of a file
+ /// File path.
+ public static byte[] File(string filename)
+ {
+ var localMd5Provider = MD5.Create();
+ var fileStream = new FileStream(filename, FileMode.Open);
+ byte[] result = localMd5Provider.ComputeHash(fileStream);
+ fileStream.Close();
+
+ return result;
+ }
+
+ /// Gets the hash of a file in hexadecimal and as a byte array.
+ /// File path.
+ /// Byte array of the hash value.
+ public static string File(string filename, out byte[] hash)
+ {
+ var localMd5Provider = MD5.Create();
+ var fileStream = new FileStream(filename, FileMode.Open);
+ hash = localMd5Provider.ComputeHash(fileStream);
+ var md5Output = new StringBuilder();
+
+ foreach(byte h in hash) md5Output.Append(h.ToString("x2"));
+
+ fileStream.Close();
+
+ return md5Output.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Length of the data buffer to hash.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, uint len, out byte[] hash)
+ {
+ var localMd5Provider = MD5.Create();
+ hash = localMd5Provider.ComputeHash(data, 0, (int)len);
+ var md5Output = new StringBuilder();
+
+ foreach(byte h in hash) md5Output.Append(h.ToString("x2"));
+
+ return md5Output.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/Native.cs b/Aaru.Checksums/Native.cs
new file mode 100644
index 000000000..e2e48e033
--- /dev/null
+++ b/Aaru.Checksums/Native.cs
@@ -0,0 +1,81 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Native.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Checks that Aaru.Checksums.Native library is available and usable.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System.Runtime.InteropServices;
+
+namespace Aaru.Checksums;
+
+/// Handles native implementations of compression algorithms
+public static partial class Native
+{
+ static bool _checked;
+ static bool _supported;
+
+ /// Set to return native as never supported
+ public static bool ForceManaged { get; set; }
+
+ ///
+ /// If set to true the native library was found and loaded correctly and its reported version is
+ /// compatible.
+ ///
+ public static bool IsSupported
+ {
+ get
+ {
+ if(ForceManaged) return false;
+
+ if(_checked) return _supported;
+
+ ulong version;
+ _checked = true;
+
+ try
+ {
+ version = get_acn_version();
+ }
+ catch
+ {
+ _supported = false;
+
+ return false;
+ }
+
+ // TODO: Check version compatibility
+ _supported = version >= 0x06000000;
+
+ return _supported;
+ }
+ }
+
+ [LibraryImport("libAaru.Checksums.Native", SetLastError = true)]
+ private static partial ulong get_acn_version();
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/ReedSolomon.cs b/Aaru.Checksums/ReedSolomon.cs
new file mode 100644
index 000000000..8b4d811bf
--- /dev/null
+++ b/Aaru.Checksums/ReedSolomon.cs
@@ -0,0 +1,632 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : ReedSolomon.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Calculates a Reed-Solomon.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// Copyright (C) 1996 Phil Karn
+// Copyright (C) 1995 Robert Morelos-Zaragoza
+// Copyright (C) 1995 Hari Thirumoorthy
+// ****************************************************************************/
+
+/*
+ * Reed-Solomon coding and decoding
+ * Phil Karn (karn at ka9q.ampr.org) September 1996
+ *
+ * This file is derived from the program "new_rs_erasures.c" by Robert
+ * Morelos-Zaragoza (robert at spectra.eng.hawaii.edu) and Hari Thirumoorthy
+ * (harit at spectra.eng.hawaii.edu), Aug 1995
+ *
+ * I've made changes to improve performance, clean up the code and make it
+ * easier to follow. Data is now passed to the encoding and decoding functions
+ * through arguments rather than in global arrays. The decode function returns
+ * the number of corrected symbols, or -1 if the word is uncorrectable.
+ *
+ * This code supports a symbol size from 2 bits up to 16 bits,
+ * implying a block size of 3 2-bit symbols (6 bits) up to 65535
+ * 16-bit symbols (1,048,560 bits). The code parameters are set in rs.h.
+ *
+ * Note that if symbols larger than 8 bits are used, the type of each
+ * data array element switches from unsigned char to unsigned int. The
+ * caller must ensure that elements larger than the symbol range are
+ * not passed to the encoder or decoder.
+ *
+ */
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+using Aaru.Console;
+
+namespace Aaru.Checksums;
+
+/// Implements the Reed-Solomon algorithm
+[SuppressMessage("ReSharper", "UnusedMember.Global")]
+[SuppressMessage("ReSharper", "UnusedType.Global")]
+public class ReedSolomon
+{
+ /// Alpha exponent for the first root of the generator polynomial
+ const int B0 = 1;
+ const string MODULE_NAME = "Reed Solomon";
+ /// No legal value in index form represents zero, so we need a special value for this purpose
+ int _a0;
+ /// index->polynomial form conversion table
+ int[] _alphaTo;
+ /// Generator polynomial g(x) Degree of g(x) = 2*TT has roots @**B0, @**(B0+1), ... ,@^(B0+2*TT-1)
+ int[] _gg;
+ /// Polynomial->index form conversion table
+ int[] _indexOf;
+ bool _initialized;
+ int _mm, _kk, _nn;
+ ///
+ /// Primitive polynomials - see Lin & Costello, Error Control Coding Appendix A, and Lee & Messerschmitt, Digital
+ /// Communication p. 453.
+ ///
+ int[] _pp;
+
+ /// Initializes the Reed-Solomon with RS(n,k) with GF(2^m)
+ public void InitRs(int n, int k, int m)
+ {
+ _pp = m switch
+ {
+ 2 => [1, 1, 1],
+ 3 => [1, 1, 0, 1],
+ 4 => [1, 1, 0, 0, 1],
+ 5 => [1, 0, 1, 0, 0, 1],
+ 6 => [1, 1, 0, 0, 0, 0, 1],
+ 7 => [1, 0, 0, 1, 0, 0, 0, 1],
+ 8 => [1, 0, 1, 1, 1, 0, 0, 0, 1],
+ 9 => [1, 0, 0, 0, 1, 0, 0, 0, 0, 1],
+ 10 => [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1],
+ 11 => [1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+ 12 => [1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1],
+ 13 => [1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+ 14 => [1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1],
+ 15 => [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+ 16 => [1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1],
+ _ => throw new ArgumentOutOfRangeException(nameof(m),
+ Localization.m_must_be_between_2_and_16_inclusive)
+ };
+
+ _mm = m;
+ _kk = k;
+ _nn = n;
+ _a0 = n;
+ _alphaTo = new int[n + 1];
+ _indexOf = new int[n + 1];
+
+ _gg = new int[_nn - _kk + 1];
+
+ generate_gf();
+ gen_poly();
+
+ _initialized = true;
+ }
+
+ int Modnn(int x)
+ {
+ while(x >= _nn)
+ {
+ x -= _nn;
+ x = (x >> _mm) + (x & _nn);
+ }
+
+ return x;
+ }
+
+ static int Min(int a, int b) => a < b ? a : b;
+
+ static void Clear(ref int[] a, int n)
+ {
+ int ci;
+
+ for(ci = n - 1; ci >= 0; ci--) a[ci] = 0;
+ }
+
+ static void Copy(ref int[] a, ref int[] b, int n)
+ {
+ int ci;
+
+ for(ci = n - 1; ci >= 0; ci--) a[ci] = b[ci];
+ }
+
+ static void Copydown(ref int[] a, ref int[] b, int n)
+ {
+ int ci;
+
+ for(ci = n - 1; ci >= 0; ci--) a[ci] = b[ci];
+ }
+
+ /* generate GF(2**m) from the irreducible polynomial p(X) in p[0]..p[m]
+ lookup tables: index->polynomial form alpha_to[] contains j=alpha**i;
+ polynomial form -> index form index_of[j=alpha**i] = i
+ alpha=2 is the primitive element of GF(2**m)
+ HARI's COMMENT: (4/13/94) alpha_to[] can be used as follows:
+ Let @ represent the primitive element commonly called "alpha" that
+ is the root of the primitive polynomial p(x). Then in GF(2^m), for any
+ 0 <= i <= 2^m-2,
+ @^i = a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1)
+ where the binary vector (a(0),a(1),a(2),...,a(m-1)) is the representation
+ of the integer "alpha_to[i]" with a(0) being the LSB and a(m-1) the MSB. Thus for
+ example the polynomial representation of @^5 would be given by the binary
+ representation of the integer "alpha_to[5]".
+ Similarily, index_of[] can be used as follows:
+ As above, let @ represent the primitive element of GF(2^m) that is
+ the root of the primitive polynomial p(x). In order to find the power
+ of @ (alpha) that has the polynomial representation
+ a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1)
+ we consider the integer "i" whose binary representation with a(0) being LSB
+ and a(m-1) MSB is (a(0),a(1),...,a(m-1)) and locate the entry
+ "index_of[i]". Now, @^index_of[i] is that element whose polynomial
+ representation is (a(0),a(1),a(2),...,a(m-1)).
+ NOTE:
+ The element alpha_to[2^m-1] = 0 always signifying that the
+ representation of "@^infinity" = 0 is (0,0,0,...,0).
+ Similarily, the element index_of[0] = A0 always signifying
+ that the power of alpha which has the polynomial representation
+ (0,0,...,0) is "infinity".
+
+ */
+ void generate_gf()
+ {
+ int i;
+
+ var mask = 1;
+ _alphaTo[_mm] = 0;
+
+ for(i = 0; i < _mm; i++)
+ {
+ _alphaTo[i] = mask;
+ _indexOf[_alphaTo[i]] = i;
+
+ /* If Pp[i] == 1 then, term @^i occurs in poly-repr of @^MM */
+ if(_pp[i] != 0) _alphaTo[_mm] ^= mask; /* Bit-wise EXOR operation */
+
+ mask <<= 1; /* single left-shift */
+ }
+
+ _indexOf[_alphaTo[_mm]] = _mm;
+ /*
+ * Have obtained poly-repr of @^MM. Poly-repr of @^(i+1) is given by
+ * poly-repr of @^i shifted left one-bit and accounting for any @^MM
+ * term that may occur when poly-repr of @^i is shifted.
+ */
+ mask >>= 1;
+
+ for(i = _mm + 1; i < _nn; i++)
+ {
+ if(_alphaTo[i - 1] >= mask)
+ _alphaTo[i] = _alphaTo[_mm] ^ (_alphaTo[i - 1] ^ mask) << 1;
+ else
+ _alphaTo[i] = _alphaTo[i - 1] << 1;
+
+ _indexOf[_alphaTo[i]] = i;
+ }
+
+ _indexOf[0] = _a0;
+ _alphaTo[_nn] = 0;
+ }
+
+ /*
+ * Obtain the generator polynomial of the TT-error correcting, length
+ * NN=(2**MM -1) Reed Solomon code from the product of (X+@**(B0+i)), i = 0,
+ * ... ,(2*TT-1)
+ *
+ * Examples:
+ *
+ * If B0 = 1, TT = 1. deg(g(x)) = 2*TT = 2.
+ * g(x) = (x+@) (x+@**2)
+ *
+ * If B0 = 0, TT = 2. deg(g(x)) = 2*TT = 4.
+ * g(x) = (x+1) (x+@) (x+@**2) (x+@**3)
+ */
+ void gen_poly()
+ {
+ int i;
+
+ _gg[0] = _alphaTo[B0];
+ _gg[1] = 1; /* g(x) = (X+@**B0) initially */
+
+ for(i = 2; i <= _nn - _kk; i++)
+ {
+ _gg[i] = 1;
+
+ /*
+ * Below multiply (Gg[0]+Gg[1]*x + ... +Gg[i]x^i) by
+ * (@**(B0+i-1) + x)
+ */
+ for(int j = i - 1; j > 0; j--)
+ {
+ if(_gg[j] != 0)
+ _gg[j] = _gg[j - 1] ^ _alphaTo[Modnn(_indexOf[_gg[j]] + B0 + i - 1)];
+ else
+ _gg[j] = _gg[j - 1];
+ }
+
+ /* Gg[0] can never be zero */
+ _gg[0] = _alphaTo[Modnn(_indexOf[_gg[0]] + B0 + i - 1)];
+ }
+
+ /* convert Gg[] to index form for quicker encoding */
+ for(i = 0; i <= _nn - _kk; i++) _gg[i] = _indexOf[_gg[i]];
+ }
+
+ /*
+ * take the string of symbols in data[i], i=0..(k-1) and encode
+ * systematically to produce NN-KK parity symbols in bb[0]..bb[NN-KK-1] data[]
+ * is input and bb[] is output in polynomial form. Encoding is done by using
+ * a feedback shift register with appropriate connections specified by the
+ * elements of Gg[], which was generated above. Codeword is c(X) =
+ * data(X)*X**(NN-KK)+ b(X)
+ */
+ /// Takes the symbols in data to output parity in bb.
+ /// Returns -1 if an illegal symbol is found.
+ /// Data symbols.
+ /// Outs parity symbols.
+ public int encode_rs(int[] data, out int[] bb)
+ {
+ if(!_initialized)
+ throw new UnauthorizedAccessException(Localization.Trying_to_calculate_RS_without_initializing);
+
+ int i;
+ bb = new int[_nn - _kk];
+
+ Clear(ref bb, _nn - _kk);
+
+ for(i = _kk - 1; i >= 0; i--)
+ {
+ if(_mm != 8)
+ if(data[i] > _nn)
+ return -1; /* Illegal symbol */
+
+ int feedback = _indexOf[data[i] ^ bb[_nn - _kk - 1]];
+
+ if(feedback != _a0)
+ {
+ /* feedback term is non-zero */
+ for(int j = _nn - _kk - 1; j > 0; j--)
+ {
+ if(_gg[j] != _a0)
+ bb[j] = bb[j - 1] ^ _alphaTo[Modnn(_gg[j] + feedback)];
+ else
+ bb[j] = bb[j - 1];
+ }
+
+ bb[0] = _alphaTo[Modnn(_gg[0] + feedback)];
+ }
+ else
+ {
+ /* feedback term is zero. encoder becomes a
+ * single-byte shifter */
+ for(int j = _nn - _kk - 1; j > 0; j--) bb[j] = bb[j - 1];
+
+ bb[0] = 0;
+ }
+ }
+
+ return 0;
+ }
+
+ /*
+ * Performs ERRORS+ERASURES decoding of RS codes. If decoding is successful,
+ * writes the codeword into data[] itself. Otherwise data[] is unaltered.
+ *
+ * Return number of symbols corrected, or -1 if codeword is illegal
+ * or uncorrectable.
+ *
+ * First "no_eras" erasures are declared by the calling program. Then, the
+ * maximum # of errors correctable is t_after_eras = floor((NN-KK-no_eras)/2).
+ * If the number of channel errors is not greater than "t_after_eras" the
+ * transmitted codeword will be recovered. Details of algorithm can be found
+ * in R. Blahut's "Theory ... of Error-Correcting Codes".
+ */
+ /// Decodes the RS. If decoding is successful outputs corrected data symbols.
+ /// Returns corrected symbols, -1 if illegal or uncorrectable
+ /// Data symbols.
+ /// Position of erasures.
+ /// Number of erasures.
+ public int eras_dec_rs(ref int[] data, out int[] erasPos, int noEras)
+ {
+ if(!_initialized)
+ throw new UnauthorizedAccessException(Localization.Trying_to_calculate_RS_without_initializing);
+
+ erasPos = new int[_nn - _kk];
+ int i, j;
+ int q, tmp;
+ var recd = new int[_nn];
+ var lambda = new int[_nn - _kk + 1]; /* Err+Eras Locator poly */
+ var s = new int[_nn - _kk + 1]; /* syndrome poly */
+ var b = new int[_nn - _kk + 1];
+ var t = new int[_nn - _kk + 1];
+ var omega = new int[_nn - _kk + 1];
+ var root = new int[_nn - _kk];
+ var reg = new int[_nn - _kk + 1];
+ var loc = new int[_nn - _kk];
+ int count;
+
+ /* data[] is in polynomial form, copy and convert to index form */
+ for(i = _nn - 1; i >= 0; i--)
+ {
+ if(_mm != 8)
+ if(data[i] > _nn)
+ return -1; /* Illegal symbol */
+
+ recd[i] = _indexOf[data[i]];
+ }
+
+ /* first form the syndromes; i.e., evaluate recd(x) at roots of g(x)
+ * namely @**(B0+i), i = 0, ... ,(NN-KK-1)
+ */
+ var synError = 0;
+
+ for(i = 1; i <= _nn - _kk; i++)
+ {
+ tmp = 0;
+
+ for(j = 0; j < _nn; j++)
+ if(recd[j] != _a0) /* recd[j] in index form */
+ tmp ^= _alphaTo[Modnn(recd[j] + (B0 + i - 1) * j)];
+
+ synError |= tmp; /* set flag if non-zero syndrome =>
+ * error */
+
+ /* store syndrome in index form */
+ s[i] = _indexOf[tmp];
+ }
+
+ if(synError == 0) return 0;
+
+ Clear(ref lambda, _nn - _kk);
+ lambda[0] = 1;
+
+ if(noEras > 0)
+ {
+ /* Init lambda to be the erasure locator polynomial */
+ lambda[1] = _alphaTo[erasPos[0]];
+
+ for(i = 1; i < noEras; i++)
+ {
+ int u = erasPos[i];
+
+ for(j = i + 1; j > 0; j--)
+ {
+ tmp = _indexOf[lambda[j - 1]];
+
+ if(tmp != _a0) lambda[j] ^= _alphaTo[Modnn(u + tmp)];
+ }
+ }
+
+#if DEBUG
+ /* find roots of the erasure location polynomial */
+ for(i = 1; i <= noEras; i++) reg[i] = _indexOf[lambda[i]];
+
+ count = 0;
+
+ for(i = 1; i <= _nn; i++)
+ {
+ q = 1;
+
+ for(j = 1; j <= noEras; j++)
+ {
+ if(reg[j] == _a0) continue;
+
+ reg[j] = Modnn(reg[j] + j);
+ q ^= _alphaTo[reg[j]];
+ }
+
+ if(q != 0) continue;
+
+ /* store root and error location
+ * number indices
+ */
+ root[count] = i;
+ loc[count] = _nn - i;
+ count++;
+ }
+
+ if(count != noEras)
+ {
+ AaruConsole.DebugWriteLine(MODULE_NAME, Localization.lambda_is_wrong);
+
+ return -1;
+ }
+
+ AaruConsole.DebugWriteLine(MODULE_NAME,
+ Localization.Erasure_positions_as_determined_by_roots_of_Eras_Loc_Poly);
+
+ for(i = 0; i < count; i++) AaruConsole.DebugWriteLine(MODULE_NAME, "{0} ", loc[i]);
+
+ AaruConsole.DebugWriteLine(MODULE_NAME, "\n");
+#endif
+ }
+
+ for(i = 0; i < _nn - _kk + 1; i++) b[i] = _indexOf[lambda[i]];
+
+ /*
+ * Begin Berlekamp-Massey algorithm to determine error+erasure
+ * locator polynomial
+ */
+ int r = noEras;
+ int el = noEras;
+
+ while(++r <= _nn - _kk)
+ {
+ /* r is the step number */
+ /* Compute discrepancy at the r-th step in poly-form */
+ var discrR = 0;
+
+ for(i = 0; i < r; i++)
+ if(lambda[i] != 0 && s[r - i] != _a0)
+ discrR ^= _alphaTo[Modnn(_indexOf[lambda[i]] + s[r - i])];
+
+ discrR = _indexOf[discrR]; /* Index form */
+
+ if(discrR == _a0)
+ {
+ /* 2 lines below: B(x) <-- x*B(x) */
+ Copydown(ref b, ref b, _nn - _kk);
+ b[0] = _a0;
+ }
+ else
+ {
+ /* 7 lines below: T(x) <-- lambda(x) - discr_r*x*b(x) */
+ t[0] = lambda[0];
+
+ for(i = 0; i < _nn - _kk; i++)
+ {
+ if(b[i] != _a0)
+ t[i + 1] = lambda[i + 1] ^ _alphaTo[Modnn(discrR + b[i])];
+ else
+ t[i + 1] = lambda[i + 1];
+ }
+
+ if(2 * el <= r + noEras - 1)
+ {
+ el = r + noEras - el;
+
+ /*
+ * 2 lines below: B(x) <-- inv(discr_r) *
+ * lambda(x)
+ */
+ for(i = 0; i <= _nn - _kk; i++)
+ b[i] = lambda[i] == 0 ? _a0 : Modnn(_indexOf[lambda[i]] - discrR + _nn);
+ }
+ else
+ {
+ /* 2 lines below: B(x) <-- x*B(x) */
+ Copydown(ref b, ref b, _nn - _kk);
+ b[0] = _a0;
+ }
+
+ Copy(ref lambda, ref t, _nn - _kk + 1);
+ }
+ }
+
+ /* Convert lambda to index form and compute deg(lambda(x)) */
+ var degLambda = 0;
+
+ for(i = 0; i < _nn - _kk + 1; i++)
+ {
+ lambda[i] = _indexOf[lambda[i]];
+
+ if(lambda[i] != _a0) degLambda = i;
+ }
+
+ /*
+ * Find roots of the error+erasure locator polynomial. By Chien
+ * Search
+ */
+ int temp = reg[0];
+ Copy(ref reg, ref lambda, _nn - _kk);
+ reg[0] = temp;
+ count = 0; /* Number of roots of lambda(x) */
+
+ for(i = 1; i <= _nn; i++)
+ {
+ q = 1;
+
+ for(j = degLambda; j > 0; j--)
+ {
+ if(reg[j] == _a0) continue;
+
+ reg[j] = Modnn(reg[j] + j);
+ q ^= _alphaTo[reg[j]];
+ }
+
+ if(q != 0) continue;
+
+ /* store root (index-form) and error location number */
+ root[count] = i;
+ loc[count] = _nn - i;
+ count++;
+ }
+
+#if DEBUG
+ AaruConsole.DebugWriteLine(MODULE_NAME, Localization.Final_error_positions);
+
+ for(i = 0; i < count; i++) AaruConsole.DebugWriteLine(MODULE_NAME, "{0} ", loc[i]);
+
+ AaruConsole.DebugWriteLine(MODULE_NAME, "\n");
+#endif
+
+ if(degLambda != count) return -1;
+
+ /*
+ * Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo
+ * x**(NN-KK)). in index form. Also find deg(omega).
+ */
+ var degOmega = 0;
+
+ for(i = 0; i < _nn - _kk; i++)
+ {
+ tmp = 0;
+ j = degLambda < i ? degLambda : i;
+
+ for(; j >= 0; j--)
+ if(s[i + 1 - j] != _a0 && lambda[j] != _a0)
+ tmp ^= _alphaTo[Modnn(s[i + 1 - j] + lambda[j])];
+
+ if(tmp != 0) degOmega = i;
+
+ omega[i] = _indexOf[tmp];
+ }
+
+ omega[_nn - _kk] = _a0;
+
+ /*
+ * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
+ * inv(X(l))**(B0-1) and den = lambda_pr(inv(X(l))) all in poly-form
+ */
+ for(j = count - 1; j >= 0; j--)
+ {
+ var num1 = 0;
+
+ for(i = degOmega; i >= 0; i--)
+ if(omega[i] != _a0)
+ num1 ^= _alphaTo[Modnn(omega[i] + i * root[j])];
+
+ int num2 = _alphaTo[Modnn(root[j] * (B0 - 1) + _nn)];
+ var den = 0;
+
+ /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
+ for(i = Min(degLambda, _nn - _kk - 1) & ~1; i >= 0; i -= 2)
+ if(lambda[i + 1] != _a0)
+ den ^= _alphaTo[Modnn(lambda[i + 1] + i * root[j])];
+
+ if(den == 0)
+ {
+ AaruConsole.DebugWriteLine(MODULE_NAME, Localization.ERROR_denominator_equals_zero);
+
+ return -1;
+ }
+
+ /* Apply error to data */
+ if(num1 != 0) data[loc[j]] ^= _alphaTo[Modnn(_indexOf[num1] + _indexOf[num2] + _nn - _indexOf[den])];
+ }
+
+ return count;
+ }
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/Register.cs b/Aaru.Checksums/Register.cs
new file mode 100644
index 000000000..3c909dddb
--- /dev/null
+++ b/Aaru.Checksums/Register.cs
@@ -0,0 +1,46 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Register.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Core algorithms.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Registers all plugins in this assembly.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using Aaru.CommonTypes.Interfaces;
+
+namespace Aaru.Checksums;
+
+// Needs to have the interface here so the source generator knows THIS IS the class
+// ReSharper disable once RedundantExtendsListEntry
+///
+public sealed partial class Register : IPluginRegister;
\ No newline at end of file
diff --git a/Aaru.Checksums/SHA1Context.cs b/Aaru.Checksums/SHA1Context.cs
new file mode 100644
index 000000000..e58096b61
--- /dev/null
+++ b/Aaru.Checksums/SHA1Context.cs
@@ -0,0 +1,151 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : SHA1Context.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Wraps up .NET SHA1 implementation to a Init(), Update(), Final() context.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
+using Aaru.CommonTypes.Interfaces;
+
+namespace Aaru.Checksums;
+
+///
+/// Wraps up .NET SHA1 implementation to a Init(), Update(), Final() context.
+[SuppressMessage("ReSharper", "MemberCanBeInternal")]
+[SuppressMessage("ReSharper", "UnusedMember.Global")]
+[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
+public sealed class Sha1Context : IChecksum
+{
+ readonly SHA1 _provider;
+
+ /// Initializes the SHA1 hash provider
+ public Sha1Context() => _provider = SHA1.Create();
+
+#region IChecksum Members
+
+ ///
+ public string Name => Localization.SHA1_Name;
+
+ ///
+ public Guid Id => new("5C28939D-DCBB-4C6E-8498-C509ABD99FC2");
+
+ ///
+ public string Author => Authors.NataliaPortillo;
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ /// Length of buffer to hash.
+ public void Update(byte[] data, uint len) => _provider.TransformBlock(data, 0, (int)len, data, 0);
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ public void Update(byte[] data) => Update(data, (uint)data.Length);
+
+ ///
+ /// Returns a byte array of the hash value.
+ public byte[] Final()
+ {
+ _provider.TransformFinalBlock([], 0, 0);
+
+ return _provider.Hash;
+ }
+
+ ///
+ /// Returns a hexadecimal representation of the hash value.
+ public string End()
+ {
+ _provider.TransformFinalBlock([], 0, 0);
+ var sha1Output = new StringBuilder();
+
+ if(_provider.Hash is null) return null;
+
+ foreach(byte h in _provider.Hash) sha1Output.Append(h.ToString("x2"));
+
+ return sha1Output.ToString();
+ }
+
+#endregion
+
+ /// Gets the hash of a file
+ /// File path.
+
+ // ReSharper disable once ReturnTypeCanBeEnumerable.Global
+ public static byte[] File(string filename)
+ {
+ var localSha1Provider = SHA1.Create();
+ var fileStream = new FileStream(filename, FileMode.Open);
+ byte[] result = localSha1Provider.ComputeHash(fileStream);
+ fileStream.Close();
+
+ return result;
+ }
+
+ /// Gets the hash of a file in hexadecimal and as a byte array.
+ /// File path.
+ /// Byte array of the hash value.
+ public static string File(string filename, out byte[] hash)
+ {
+ var localSha1Provider = SHA1.Create();
+ var fileStream = new FileStream(filename, FileMode.Open);
+ hash = localSha1Provider.ComputeHash(fileStream);
+ var sha1Output = new StringBuilder();
+
+ foreach(byte h in hash) sha1Output.Append(h.ToString("x2"));
+
+ fileStream.Close();
+
+ return sha1Output.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Length of the data buffer to hash.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, uint len, out byte[] hash)
+ {
+ var localSha1Provider = SHA1.Create();
+ hash = localSha1Provider.ComputeHash(data, 0, (int)len);
+ var sha1Output = new StringBuilder();
+
+ foreach(byte h in hash) sha1Output.Append(h.ToString("x2"));
+
+ return sha1Output.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/SHA256Context.cs b/Aaru.Checksums/SHA256Context.cs
new file mode 100644
index 000000000..ca66320d5
--- /dev/null
+++ b/Aaru.Checksums/SHA256Context.cs
@@ -0,0 +1,151 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : SHA256Context.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Wraps up .NET SHA256 implementation to a Init(), Update(), Final() context.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
+using Aaru.CommonTypes.Interfaces;
+
+namespace Aaru.Checksums;
+
+///
+/// Wraps up .NET SHA256 implementation to a Init(), Update(), Final() context.
+[SuppressMessage("ReSharper", "UnusedMember.Global")]
+[SuppressMessage("ReSharper", "MemberCanBeInternal")]
+[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
+public sealed class Sha256Context : IChecksum
+{
+ readonly SHA256 _provider;
+
+ /// Initializes the SHA256 hash provider
+ public Sha256Context() => _provider = SHA256.Create();
+
+#region IChecksum Members
+
+ ///
+ public string Name => Localization.SHA256_Name;
+
+ ///
+ public Guid Id => new("A6F0EF52-064D-41D1-8619-240481749B70");
+
+ ///
+ public string Author => Authors.NataliaPortillo;
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ /// Length of buffer to hash.
+ public void Update(byte[] data, uint len) => _provider.TransformBlock(data, 0, (int)len, data, 0);
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ public void Update(byte[] data) => Update(data, (uint)data.Length);
+
+ ///
+ /// Returns a byte array of the hash value.
+ public byte[] Final()
+ {
+ _provider.TransformFinalBlock([], 0, 0);
+
+ return _provider.Hash;
+ }
+
+ ///
+ /// Returns a hexadecimal representation of the hash value.
+ public string End()
+ {
+ _provider.TransformFinalBlock([], 0, 0);
+ var sha256Output = new StringBuilder();
+
+ if(_provider.Hash is null) return null;
+
+ foreach(byte h in _provider.Hash) sha256Output.Append(h.ToString("x2"));
+
+ return sha256Output.ToString();
+ }
+
+#endregion
+
+ /// Gets the hash of a file
+ /// File path.
+
+ // ReSharper disable once ReturnTypeCanBeEnumerable.Global
+ public static byte[] File(string filename)
+ {
+ var localSha256Provider = SHA256.Create();
+ var fileStream = new FileStream(filename, FileMode.Open);
+ byte[] result = localSha256Provider.ComputeHash(fileStream);
+ fileStream.Close();
+
+ return result;
+ }
+
+ /// Gets the hash of a file in hexadecimal and as a byte array.
+ /// File path.
+ /// Byte array of the hash value.
+ public static string File(string filename, out byte[] hash)
+ {
+ var localSha256Provider = SHA256.Create();
+ var fileStream = new FileStream(filename, FileMode.Open);
+ hash = localSha256Provider.ComputeHash(fileStream);
+ var sha256Output = new StringBuilder();
+
+ foreach(byte h in hash) sha256Output.Append(h.ToString("x2"));
+
+ fileStream.Close();
+
+ return sha256Output.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Length of the data buffer to hash.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, uint len, out byte[] hash)
+ {
+ var localSha256Provider = SHA256.Create();
+ hash = localSha256Provider.ComputeHash(data, 0, (int)len);
+ var sha256Output = new StringBuilder();
+
+ foreach(byte h in hash) sha256Output.Append(h.ToString("x2"));
+
+ return sha256Output.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/SHA384Context.cs b/Aaru.Checksums/SHA384Context.cs
new file mode 100644
index 000000000..9d52ae6a2
--- /dev/null
+++ b/Aaru.Checksums/SHA384Context.cs
@@ -0,0 +1,152 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : SHA384Context.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Wraps up .NET SHA384 implementation to a Init(), Update(), Final() context.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
+using Aaru.CommonTypes.Interfaces;
+
+namespace Aaru.Checksums;
+
+///
+/// Wraps up .NET SHA384 implementation to a Init(), Update(), Final() context.
+[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
+[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
+[SuppressMessage("ReSharper", "MemberCanBeInternal")]
+[SuppressMessage("ReSharper", "UnusedMember.Global")]
+public sealed class Sha384Context : IChecksum
+{
+ readonly SHA384 _provider;
+
+ /// Initializes the SHA384 hash provider
+ public Sha384Context() => _provider = SHA384.Create();
+
+#region IChecksum Members
+
+ ///
+ public string Name => Localization.SHA384_Name;
+
+ ///
+ public Guid Id => new("4A2A1820-E157-4842-B1E2-0E629FA60DDD");
+
+ ///
+ public string Author => Authors.NataliaPortillo;
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ /// Length of buffer to hash.
+ public void Update(byte[] data, uint len) => _provider.TransformBlock(data, 0, (int)len, data, 0);
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ public void Update(byte[] data) => Update(data, (uint)data.Length);
+
+ ///
+ /// Returns a byte array of the hash value.
+ public byte[] Final()
+ {
+ _provider.TransformFinalBlock([], 0, 0);
+
+ return _provider.Hash;
+ }
+
+ ///
+ /// Returns a hexadecimal representation of the hash value.
+ public string End()
+ {
+ _provider.TransformFinalBlock([], 0, 0);
+ var sha384Output = new StringBuilder();
+
+ if(_provider.Hash is null) return null;
+
+ foreach(byte h in _provider.Hash) sha384Output.Append(h.ToString("x2"));
+
+ return sha384Output.ToString();
+ }
+
+#endregion
+
+ /// Gets the hash of a file
+ /// File path.
+
+ // ReSharper disable once ReturnTypeCanBeEnumerable.Global
+ public static byte[] File(string filename)
+ {
+ var localSha384Provider = SHA384.Create();
+ var fileStream = new FileStream(filename, FileMode.Open);
+ byte[] result = localSha384Provider.ComputeHash(fileStream);
+ fileStream.Close();
+
+ return result;
+ }
+
+ /// Gets the hash of a file in hexadecimal and as a byte array.
+ /// File path.
+ /// Byte array of the hash value.
+ public static string File(string filename, out byte[] hash)
+ {
+ var localSha384Provider = SHA384.Create();
+ var fileStream = new FileStream(filename, FileMode.Open);
+ hash = localSha384Provider.ComputeHash(fileStream);
+ var sha384Output = new StringBuilder();
+
+ foreach(byte h in hash) sha384Output.Append(h.ToString("x2"));
+
+ fileStream.Close();
+
+ return sha384Output.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Length of the data buffer to hash.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, uint len, out byte[] hash)
+ {
+ var localSha384Provider = SHA384.Create();
+ hash = localSha384Provider.ComputeHash(data, 0, (int)len);
+ var sha384Output = new StringBuilder();
+
+ foreach(byte h in hash) sha384Output.Append(h.ToString("x2"));
+
+ return sha384Output.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/SHA512Context.cs b/Aaru.Checksums/SHA512Context.cs
new file mode 100644
index 000000000..e0e7ab337
--- /dev/null
+++ b/Aaru.Checksums/SHA512Context.cs
@@ -0,0 +1,150 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : SHA512Context.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Wraps up .NET SHA512 implementation to a Init(), Update(), Final() context.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
+using Aaru.CommonTypes.Interfaces;
+
+namespace Aaru.Checksums;
+
+///
+/// Wraps up .NET SHA512 implementation to a Init(), Update(), Final() context.
+[SuppressMessage("ReSharper", "UnusedMethodReturnValue.Global")]
+[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
+[SuppressMessage("ReSharper", "MemberCanBeInternal")]
+[SuppressMessage("ReSharper", "UnusedMember.Global")]
+public sealed class Sha512Context : IChecksum
+{
+ readonly SHA512 _provider;
+
+ /// Initializes the SHA512 hash provider
+ public Sha512Context() => _provider = SHA512.Create();
+
+#region IChecksum Members
+
+ ///
+ public string Name => Localization.SHA512_Name;
+
+ ///
+ public Guid Id => new("1E167BCB-2362-44DA-B5B0-B7ED3A22D5A6");
+
+ ///
+ public string Author => Authors.NataliaPortillo;
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ /// Length of buffer to hash.
+ public void Update(byte[] data, uint len) => _provider.TransformBlock(data, 0, (int)len, data, 0);
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ public void Update(byte[] data) => Update(data, (uint)data.Length);
+
+ ///
+ /// Returns a byte array of the hash value.
+ public byte[] Final()
+ {
+ _provider.TransformFinalBlock([], 0, 0);
+
+ return _provider.Hash;
+ }
+
+ ///
+ /// Returns a hexadecimal representation of the hash value.
+ public string End()
+ {
+ _provider.TransformFinalBlock([], 0, 0);
+ var sha512Output = new StringBuilder();
+
+ if(_provider.Hash is null) return null;
+
+ foreach(byte h in _provider.Hash) sha512Output.Append(h.ToString("x2"));
+
+ return sha512Output.ToString();
+ }
+
+#endregion
+
+ /// Gets the hash of a file
+ /// File path.
+ public static byte[] File(string filename)
+ {
+ var localSha512Provider = SHA512.Create();
+ var fileStream = new FileStream(filename, FileMode.Open);
+ byte[] result = localSha512Provider.ComputeHash(fileStream);
+ fileStream.Close();
+
+ return result;
+ }
+
+ /// Gets the hash of a file in hexadecimal and as a byte array.
+ /// File path.
+ /// Byte array of the hash value.
+ public static string File(string filename, out byte[] hash)
+ {
+ var localSha512Provider = SHA512.Create();
+ var fileStream = new FileStream(filename, FileMode.Open);
+ hash = localSha512Provider.ComputeHash(fileStream);
+ var sha512Output = new StringBuilder();
+
+ foreach(byte h in hash) sha512Output.Append(h.ToString("x2"));
+
+ fileStream.Close();
+
+ return sha512Output.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Length of the data buffer to hash.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, uint len, out byte[] hash)
+ {
+ var localSha512Provider = SHA512.Create();
+ hash = localSha512Provider.ComputeHash(data, 0, (int)len);
+ var sha512Output = new StringBuilder();
+
+ foreach(byte h in hash) sha512Output.Append(h.ToString("x2"));
+
+ return sha512Output.ToString();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Byte array of the hash value.
+ public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
+}
\ No newline at end of file
diff --git a/Aaru.Checksums/SpamSumContext.cs b/Aaru.Checksums/SpamSumContext.cs
new file mode 100644
index 000000000..e93b28c9f
--- /dev/null
+++ b/Aaru.Checksums/SpamSumContext.cs
@@ -0,0 +1,531 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : SpamSumContext.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Checksums.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Implements the SpamSum fuzzy hashing algorithm.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+// Based on ssdeep
+// Copyright (C) 2002 Andrew Tridgell
+// Copyright (C) 2006 ManTech International Corporation
+// Copyright (C) 2013 Helmut Grohne
+//
+// Earlier versions of this code were named fuzzy.c and can be found at:
+// http://www.samba.org/ftp/unpacked/junkcode/spamsum/
+// http://ssdeep.sf.net/
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
+using System.Text;
+using Aaru.CommonTypes.Interfaces;
+
+namespace Aaru.Checksums;
+
+///
+/// Implements the SpamSum fuzzy hashing algorithm.
+[SuppressMessage("ReSharper", "UnusedMember.Global")]
+[SuppressMessage("ReSharper", "UnusedParameter.Global")]
+[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
+[SuppressMessage("ReSharper", "MemberCanBeInternal")]
+[SuppressMessage("ReSharper", "OutParameterValueIsAlwaysDiscarded.Global")]
+public sealed class SpamSumContext : IChecksum
+{
+ const uint ROLLING_WINDOW = 7;
+ const uint MIN_BLOCKSIZE = 3;
+ const uint HASH_PRIME = 0x01000193;
+ const uint HASH_INIT = 0x28021967;
+ const uint NUM_BLOCKHASHES = 31;
+ const uint SPAMSUM_LENGTH = 64;
+ const uint FUZZY_MAX_RESULT = 2 * SPAMSUM_LENGTH + 20;
+
+ //"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ readonly byte[] _b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"u8.ToArray();
+ FuzzyState _self;
+
+ /// Initializes the SpamSum structures
+ public SpamSumContext()
+ {
+ _self = new FuzzyState
+ {
+ Bh = new BlockhashContext[NUM_BLOCKHASHES]
+ };
+
+ for(var i = 0; i < NUM_BLOCKHASHES; i++) _self.Bh[i].Digest = new byte[SPAMSUM_LENGTH];
+
+ _self.Bhstart = 0;
+ _self.Bhend = 1;
+ _self.Bh[0].H = HASH_INIT;
+ _self.Bh[0].Halfh = HASH_INIT;
+ _self.Bh[0].Digest[0] = 0;
+ _self.Bh[0].Halfdigest = 0;
+ _self.Bh[0].Dlen = 0;
+ _self.TotalSize = 0;
+ roll_init();
+ }
+
+#region IChecksum Members
+
+ ///
+ public string Name => Localization.SpamSum_Name;
+
+ ///
+ public Guid Id => new("DA692981-3291-47D8-B8B9-A87F0605F6E9");
+
+ ///
+ public string Author => Authors.NataliaPortillo;
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ /// Length of buffer to hash.
+ public void Update(byte[] data, uint len)
+ {
+ _self.TotalSize += len;
+
+ for(var i = 0; i < len; i++) fuzzy_engine_step(data[i]);
+ }
+
+ ///
+ /// Updates the hash with data.
+ /// Data buffer.
+ public void Update(byte[] data) => Update(data, (uint)data.Length);
+
+ ///
+ /// Returns a byte array of the hash value.
+ public byte[] Final() =>
+ throw new NotImplementedException(Localization.SpamSum_does_not_have_a_binary_representation);
+
+ ///
+ /// Returns a base64 representation of the hash value.
+ public string End()
+ {
+ FuzzyDigest(out byte[] result);
+
+ return CToString(result);
+ }
+
+#endregion
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ void roll_init() => _self.Roll = new RollState
+ {
+ Window = new byte[ROLLING_WINDOW]
+ };
+
+ /*
+ * a rolling hash, based on the Adler checksum. By using a rolling hash
+ * we can perform auto resynchronisation after inserts/deletes
+
+ * internally, h1 is the sum of the bytes in the window and h2
+ * is the sum of the bytes times the index
+
+ * h3 is a shift/xor based rolling hash, and is mostly needed to ensure that
+ * we can cope with large blocksize values
+ */
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ void roll_hash(byte c)
+ {
+ _self.Roll.H2 -= _self.Roll.H1;
+ _self.Roll.H2 += ROLLING_WINDOW * c;
+
+ _self.Roll.H1 += c;
+ _self.Roll.H1 -= _self.Roll.Window[_self.Roll.N % ROLLING_WINDOW];
+
+ _self.Roll.Window[_self.Roll.N % ROLLING_WINDOW] = c;
+ _self.Roll.N++;
+
+ /* The original spamsum AND'ed this value with 0xFFFFFFFF which
+ * in theory should have no effect. This AND has been removed
+ * for performance (jk) */
+ _self.Roll.H3 <<= 5;
+ _self.Roll.H3 ^= c;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ uint roll_sum() => _self.Roll.H1 + _self.Roll.H2 + _self.Roll.H3;
+
+ /* A simple non-rolling hash, based on the FNV hash. */
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static uint sum_hash(byte c, uint h) => h * HASH_PRIME ^ c;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static uint SSDEEP_BS(uint index) => MIN_BLOCKSIZE << (int)index;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ void fuzzy_try_fork_blockhash()
+ {
+ switch(_self.Bhend)
+ {
+ case >= NUM_BLOCKHASHES:
+ return;
+
+ // assert
+ case 0:
+ throw new Exception(Localization.Assertion_failed);
+ }
+
+ uint obh = _self.Bhend - 1;
+ uint nbh = _self.Bhend;
+ _self.Bh[nbh].H = _self.Bh[obh].H;
+ _self.Bh[nbh].Halfh = _self.Bh[obh].Halfh;
+ _self.Bh[nbh].Digest[0] = 0;
+ _self.Bh[nbh].Halfdigest = 0;
+ _self.Bh[nbh].Dlen = 0;
+ ++_self.Bhend;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ void fuzzy_try_reduce_blockhash()
+ {
+ if(_self.Bhstart >= _self.Bhend) throw new Exception(Localization.Assertion_failed);
+
+ if(_self.Bhend - _self.Bhstart < 2)
+ /* Need at least two working hashes. */
+ return;
+
+ if((ulong)SSDEEP_BS(_self.Bhstart) * SPAMSUM_LENGTH >= _self.TotalSize)
+ /* Initial blocksize estimate would select this or a smaller
+ * blocksize. */
+ return;
+
+ if(_self.Bh[_self.Bhstart + 1].Dlen < SPAMSUM_LENGTH / 2)
+ /* Estimate adjustment would select this blocksize. */
+ return;
+
+ /* At this point we are clearly no longer interested in the
+ * start_blocksize. Get rid of it. */
+ ++_self.Bhstart;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ void fuzzy_engine_step(byte c)
+ {
+ uint i;
+ /* At each character we update the rolling hash and the normal hashes.
+ * When the rolling hash hits a reset value then we emit a normal hash
+ * as a element of the signature and reset the normal hash. */
+ roll_hash(c);
+ ulong h = roll_sum();
+
+ for(i = _self.Bhstart; i < _self.Bhend; ++i)
+ {
+ _self.Bh[i].H = sum_hash(c, _self.Bh[i].H);
+ _self.Bh[i].Halfh = sum_hash(c, _self.Bh[i].Halfh);
+ }
+
+ for(i = _self.Bhstart; i < _self.Bhend; ++i)
+ {
+ /* With growing blocksize almost no runs fail the next test. */
+ if(h % SSDEEP_BS(i) != SSDEEP_BS(i) - 1)
+ /* Once this condition is false for one bs, it is
+ * automatically false for all further bs. I.e. if
+ * h === -1 (mod 2*bs) then h === -1 (mod bs). */
+ break;
+
+ /* We have hit a reset point. We now emit hashes which are
+ * based on all characters in the piece of the message between
+ * the last reset point and this one */
+ if(0 == _self.Bh[i].Dlen) fuzzy_try_fork_blockhash();
+
+ _self.Bh[i].Digest[_self.Bh[i].Dlen] = _b64[_self.Bh[i].H % 64];
+ _self.Bh[i].Halfdigest = _b64[_self.Bh[i].Halfh % 64];
+
+ if(_self.Bh[i].Dlen < SPAMSUM_LENGTH - 1)
+ {
+ /* We can have a problem with the tail overflowing. The
+ * easiest way to cope with this is to only reset the
+ * normal hash if we have room for more characters in
+ * our signature. This has the effect of combining the
+ * last few pieces of the message into a single piece
+ * */
+ _self.Bh[i].Digest[++_self.Bh[i].Dlen] = 0;
+ _self.Bh[i].H = HASH_INIT;
+
+ if(_self.Bh[i].Dlen >= SPAMSUM_LENGTH / 2) continue;
+
+ _self.Bh[i].Halfh = HASH_INIT;
+ _self.Bh[i].Halfdigest = 0;
+ }
+ else
+ fuzzy_try_reduce_blockhash();
+ }
+ }
+
+ // CLAUNIA: Flags seems to never be used in ssdeep, so I just removed it for code simplicity
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ void FuzzyDigest(out byte[] result)
+ {
+ var sb = new StringBuilder();
+ uint bi = _self.Bhstart;
+ uint h = roll_sum();
+ var remain = (int)(FUZZY_MAX_RESULT - 1); /* Exclude terminating '\0'. */
+ result = new byte[FUZZY_MAX_RESULT];
+
+ /* Verify that our elimination was not overeager. */
+ if(!(bi == 0 || (ulong)SSDEEP_BS(bi) / 2 * SPAMSUM_LENGTH < _self.TotalSize))
+ throw new Exception(Localization.Assertion_failed);
+
+ /* Initial blocksize guess. */
+ while((ulong)SSDEEP_BS(bi) * SPAMSUM_LENGTH < _self.TotalSize)
+ {
+ ++bi;
+
+ if(bi >= NUM_BLOCKHASHES) throw new OverflowException(Localization.The_input_exceeds_data_types);
+ }
+
+ /* Adapt blocksize guess to actual digest length. */
+ while(bi >= _self.Bhend) --bi;
+
+ while(bi > _self.Bhstart && _self.Bh[bi].Dlen < SPAMSUM_LENGTH / 2) --bi;
+
+ if(bi > 0 && _self.Bh[bi].Dlen < SPAMSUM_LENGTH / 2) throw new Exception(Localization.Assertion_failed);
+
+ sb.Append($"{SSDEEP_BS(bi)}:");
+ int i = Encoding.ASCII.GetBytes(sb.ToString()).Length;
+
+ if(i <= 0)
+ /* Maybe snprintf has set errno here? */
+ throw new OverflowException(Localization.The_input_exceeds_data_types);
+
+ if(i >= remain) throw new Exception(Localization.Assertion_failed);
+
+ remain -= i;
+
+ Array.Copy(Encoding.ASCII.GetBytes(sb.ToString()), 0, result, 0, i);
+
+ int resultOff = i;
+
+ i = (int)_self.Bh[bi].Dlen;
+
+ if(i > remain) throw new Exception(Localization.Assertion_failed);
+
+ Array.Copy(_self.Bh[bi].Digest, 0, result, resultOff, i);
+ resultOff += i;
+ remain -= i;
+
+ if(h != 0)
+ {
+ if(remain <= 0) throw new Exception(Localization.Assertion_failed);
+
+ result[resultOff] = _b64[_self.Bh[bi].H % 64];
+
+ if(i < 3 ||
+ result[resultOff] != result[resultOff - 1] ||
+ result[resultOff] != result[resultOff - 2] ||
+ result[resultOff] != result[resultOff - 3])
+ {
+ ++resultOff;
+ --remain;
+ }
+ }
+ else if(_self.Bh[bi].Digest[i] != 0)
+ {
+ if(remain <= 0) throw new Exception(Localization.Assertion_failed);
+
+ result[resultOff] = _self.Bh[bi].Digest[i];
+
+ if(i < 3 ||
+ result[resultOff] != result[resultOff - 1] ||
+ result[resultOff] != result[resultOff - 2] ||
+ result[resultOff] != result[resultOff - 3])
+ {
+ ++resultOff;
+ --remain;
+ }
+ }
+
+ if(remain <= 0) throw new Exception(Localization.Assertion_failed);
+
+ result[resultOff++] = 0x3A; // ':'
+ --remain;
+
+ if(bi < _self.Bhend - 1)
+ {
+ ++bi;
+ i = (int)_self.Bh[bi].Dlen;
+
+ if(i > remain) throw new Exception(Localization.Assertion_failed);
+
+ Array.Copy(_self.Bh[bi].Digest, 0, result, resultOff, i);
+ resultOff += i;
+ remain -= i;
+
+ if(h != 0)
+ {
+ if(remain <= 0) throw new Exception(Localization.Assertion_failed);
+
+ h = _self.Bh[bi].Halfh;
+ result[resultOff] = _b64[h % 64];
+
+ if(i < 3 ||
+ result[resultOff] != result[resultOff - 1] ||
+ result[resultOff] != result[resultOff - 2] ||
+ result[resultOff] != result[resultOff - 3])
+ {
+ ++resultOff;
+ --remain;
+ }
+ }
+ else
+ {
+ i = _self.Bh[bi].Halfdigest;
+
+ if(i != 0)
+ {
+ if(remain <= 0) throw new Exception(Localization.Assertion_failed);
+
+ result[resultOff] = (byte)i;
+
+ if(i < 3 ||
+ result[resultOff] != result[resultOff - 1] ||
+ result[resultOff] != result[resultOff - 2] ||
+ result[resultOff] != result[resultOff - 3])
+ {
+ ++resultOff;
+ --remain;
+ }
+ }
+ }
+ }
+ else if(h != 0)
+ {
+ if(_self.Bh[bi].Dlen != 0) throw new Exception(Localization.Assertion_failed);
+
+ if(remain <= 0) throw new Exception(Localization.Assertion_failed);
+
+ result[resultOff++] = _b64[_self.Bh[bi].H % 64];
+ /* No need to bother with FUZZY_FLAG_ELIMSEQ, because this
+ * digest has length 1. */
+ --remain;
+ }
+
+ result[resultOff] = 0;
+ }
+
+ /// Gets the hash of a file
+ /// File path.
+ public static byte[] File(string filename) =>
+ throw new NotImplementedException(Localization.SpamSum_does_not_have_a_binary_representation);
+
+ /// Gets the hash of a file in hexadecimal and as a byte array.
+ /// File path.
+ /// Byte array of the hash value.
+ public static string File(string filename, out byte[] hash) =>
+ throw new NotImplementedException(Localization.Not_yet_implemented);
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// Length of the data buffer to hash.
+ /// null
+ /// Base64 representation of SpamSum $blocksize:$hash:$hash
+ public static string Data(byte[] data, uint len, out byte[] hash)
+ {
+ var fuzzyContext = new SpamSumContext();
+
+ fuzzyContext.Update(data, len);
+
+ hash = null;
+
+ return fuzzyContext.End();
+ }
+
+ /// Gets the hash of the specified data buffer.
+ /// Data buffer.
+ /// null
+ /// Base64 representation of SpamSum $blocksize:$hash:$hash
+ public static string Data(byte[] data, out byte[] hash) => Data(data, (uint)data.Length, out hash);
+
+ // Converts an ASCII null-terminated string to .NET string
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ static string CToString(byte[] cString)
+ {
+ var count = 0;
+
+ // ReSharper disable once LoopCanBeConvertedToQuery
+ // LINQ is six times slower
+ foreach(byte c in cString)
+ {
+ if(c == 0) break;
+
+ count++;
+ }
+
+ return Encoding.ASCII.GetString(cString, 0, count);
+ }
+
+#region Nested type: BlockhashContext
+
+ /* A blockhash contains a signature state for a specific (implicit) blocksize.
+ * The blocksize is given by SSDEEP_BS(index). The h and halfh members are the
+ * FNV hashes, where halfh stops to be reset after digest is SPAMSUM_LENGTH/2
+ * long. The halfh hash is needed be able to truncate digest for the second
+ * output hash to stay compatible with ssdeep output. */
+ struct BlockhashContext
+ {
+ public uint H;
+ public uint Halfh;
+ public byte[] Digest;
+
+ // SPAMSUM_LENGTH
+ public byte Halfdigest;
+ public uint Dlen;
+ }
+
+#endregion
+
+#region Nested type: FuzzyState
+
+ struct FuzzyState
+ {
+ public uint Bhstart;
+ public uint Bhend;
+ public BlockhashContext[] Bh;
+
+ //NUM_BLOCKHASHES
+ public ulong TotalSize;
+ public RollState Roll;
+ }
+
+#endregion
+
+#region Nested type: RollState
+
+ struct RollState
+ {
+ public byte[] Window;
+
+ // ROLLING_WINDOW
+ public uint H1;
+ public uint H2;
+ public uint H3;
+ public uint N;
+ }
+
+#endregion
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes b/Aaru.CommonTypes
deleted file mode 160000
index 2aa15f080..000000000
--- a/Aaru.CommonTypes
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 2aa15f080b7fe2e0b2a00e5575b336202ddfe5fd
diff --git a/Aaru.CommonTypes/.gitignore b/Aaru.CommonTypes/.gitignore
new file mode 100644
index 000000000..05c540d38
--- /dev/null
+++ b/Aaru.CommonTypes/.gitignore
@@ -0,0 +1,595 @@
+### VisualStudio template
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015/2017 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# Visual Studio 2017 auto generated files
+Generated\ Files/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# Benchmark Results
+BenchmarkDotNet.Artifacts/
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+# StyleCop
+StyleCopReport.xml
+
+# Files built by Visual Studio
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.iobj
+*.pch
+*.pdb
+*.ipdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# Visual Studio Trace Files
+*.e2e
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# AxoCover is a Code Coverage Tool
+.axoCover/*
+!.axoCover/settings.json
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# Note: Comment the next line if you want to checkin your web deploy settings,
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/[Pp]ackages/*
+# except build/, which is used as an MSBuild target.
+!**/[Pp]ackages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/[Pp]ackages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+*.appx
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Including strong name files can present a security risk
+# (https://github.com/github/gitignore/pull/2483#issue-259490424)
+#*.snk
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+ServiceFabricBackup/
+*.rptproj.bak
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+*.rptproj.rsuser
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# CodeRush
+.cr/
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Tabs Studio
+*.tss
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
+
+# Azure Stream Analytics local run output
+ASALocalRun/
+
+# MSBuild Binary and Structured Log
+*.binlog
+
+# NVidia Nsight GPU debugger configuration file
+*.nvuser
+
+# MFractors (Xamarin productivity tool) working folder
+.mfractor/
+### Linux template
+
+# temporary files which can be created if a process still has a handle open of a deleted file
+.fuse_hidden*
+
+# KDE directory preferences
+.directory
+
+# Linux trash folder which might appear on any partition or disk
+.Trash-*
+
+# .nfs files are created when an open file is removed but is still being accessed
+.nfs*
+### Xcode template
+# Xcode
+#
+# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
+
+## User settings
+xcuserdata/
+
+## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
+*.xcscmblueprint
+*.xccheckout
+
+## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
+build/
+DerivedData/
+*.moved-aside
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+### VisualStudioCode template
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+### C++ template
+# Prerequisites
+*.d
+
+# Compiled Object files
+*.slo
+*.lo
+*.o
+
+# Precompiled Headers
+*.gch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Fortran module files
+*.mod
+*.smod
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
+### MonoDevelop template
+#User Specific
+*.usertasks
+
+#Mono Project Files
+*.resources
+test-results/
+### GPG template
+secring.*
+
+### JetBrains template
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+### CMake template
+CMakeCache.txt
+CMakeFiles
+CMakeScripts
+Testing
+Makefile
+cmake_install.cmake
+install_manifest.txt
+compile_commands.json
+CTestTestfile.cmake
+### C template
+# Object files
+*.ko
+*.elf
+
+# Linker output
+*.map
+*.exp
+
+*.so.*
+
+# Executables
+*.i*86
+*.x86_64
+*.hex
+
+# Debug files
+*.dSYM/
+*.su
+*.idb
+
+# Kernel Module Compile Results
+*.mod*
+*.cmd
+.tmp_versions/
+modules.order
+Module.symvers
+Mkfile.old
+dkms.conf
+### Windows template
+# Windows thumbnail cache files
+Thumbs.db
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msix
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
+
+# NuGet Packages Directory
+packages/
+## TODO: If the tool you use requires repositories.config uncomment the next line
+#!packages/repositories.config
+
+# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
+# This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented)
+!packages/build/
+
+
+# Others
+sql/
+*.Cache
+
+# Visual Studio 2017
+.vs
+
+workspace.xml
+cmake-build-debug
+### macOS template
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+pkg/**/pkg
+pkg/**/src
+pkg/**/*.asc
+pkg/**/*.sig
+pkg/**/*.tar.xz
+pkg/**/*.zip
+pkg/**/aaru
+
+.sonarqube
\ No newline at end of file
diff --git a/Aaru.CommonTypes/Aaru.CommonTypes.csproj b/Aaru.CommonTypes/Aaru.CommonTypes.csproj
new file mode 100644
index 000000000..b3a682596
--- /dev/null
+++ b/Aaru.CommonTypes/Aaru.CommonTypes.csproj
@@ -0,0 +1,108 @@
+
+
+
+ 2.0
+ {F2B84194-26EB-4227-B1C5-6602517E85AE}
+ Library
+ Aaru.CommonTypes
+ Aaru.CommonTypes
+ $(Version)
+ true
+ 6.0.0-alpha9
+ Claunia.com
+ Copyright © 2011-2024 Natalia Portillo
+ Aaru Data Preservation Suite
+ Aaru.CommonTypes
+ $(Version)
+ net8.0
+ 12
+ Contains common types defined by the Aaru Data Preservation Suite.
+ https://github.com/aaru-dps/
+ MIT
+ https://github.com/aaru-dps/Aaru.CommonTypes
+ true
+ en-US
+ true
+ true
+ snupkg
+ Natalia Portillo <claunia@claunia.com>
+ true
+ true
+ true
+
+
+ CS1591;CS1574
+
+
+
+
+
+
+ $(Version)+{chash:8}
+ true
+ true
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+ LICENSE.MIT
+
+
+
+
+
+
+
+
+
+ ResXFileCodeGenerator
+ Localization.Designer.cs
+
+
+
diff --git a/Aaru.CommonTypes/Aaru.CommonTypes.csproj.DotSettings b/Aaru.CommonTypes/Aaru.CommonTypes.csproj.DotSettings
new file mode 100644
index 000000000..c2586551b
--- /dev/null
+++ b/Aaru.CommonTypes/Aaru.CommonTypes.csproj.DotSettings
@@ -0,0 +1,7 @@
+
+ True
+ True
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/ATA.cs b/Aaru.CommonTypes/AaruMetadata/ATA.cs
new file mode 100644
index 000000000..bb8309592
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/ATA.cs
@@ -0,0 +1,58 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : ATA.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+using System;
+using Schemas;
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+public class ATA
+{
+ public Dump Identify { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator ATA(ATAType cicm) => cicm is null
+ ? null
+ : new ATA
+ {
+ Identify = cicm.Identify
+ };
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/AaruMetadata.cs b/Aaru.CommonTypes/AaruMetadata/AaruMetadata.cs
new file mode 100644
index 000000000..01fb8cb2c
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/AaruMetadata.cs
@@ -0,0 +1,207 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : AaruMetadata.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Text.Json.Serialization;
+using Schemas;
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
+[JsonSerializable(typeof(MetadataJson))]
+
+// ReSharper disable once PartialTypeWithSinglePart
+public partial class MetadataJsonContext : JsonSerializerContext;
+
+public class MetadataJson
+{
+ public Metadata AaruMetadata { get; set; }
+}
+
+public class Metadata
+{
+ public List Developers { get; set; }
+ public List Publishers { get; set; }
+ public List Authors { get; set; }
+ public List Performers { get; set; }
+ public string Name { get; set; }
+ public string Version { get; set; }
+ public ReleaseType? Release { get; set; }
+ public DateTime? ReleaseDate { get; set; }
+ public List Barcodes { get; set; }
+ public string PartNumber { get; set; }
+ public string SerialNumber { get; set; }
+ public List Keywords { get; set; }
+ public List Magazines { get; set; }
+ public List Books { get; set; }
+ public List Categories { get; set; }
+ public List Subcategories { get; set; }
+ public List Languages { get; set; }
+ public List Systems { get; set; }
+ public List Architectures { get; set; }
+ public List RequiredOperatingSystems { get; set; }
+ public List UserManuals { get; set; }
+ public List OpticalDiscs { get; set; }
+ public List Advertisements { get; set; }
+ public List LinearMedias { get; set; }
+ public List PciCards { get; set; }
+ public List BlockMedias { get; set; }
+ public List AudioMedias { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator Metadata(CICMMetadataType cicm)
+ {
+ if(cicm is null) return null;
+
+ var metadata = new Metadata
+ {
+ Developers = cicm.Developer is null ? null : [..cicm.Developer],
+ Publishers = cicm.Publisher is null ? null : [..cicm.Publisher],
+ Authors = cicm.Author is null ? null : [..cicm.Author],
+ Performers = cicm.Performer is null ? null : [..cicm.Performer],
+ Name = cicm.Name,
+ Version = cicm.Version,
+ Release = cicm.ReleaseTypeSpecified ? (ReleaseType)cicm.ReleaseType : null,
+ ReleaseDate = cicm.ReleaseDateSpecified ? cicm.ReleaseDate : null,
+ PartNumber = cicm.PartNumber,
+ SerialNumber = cicm.SerialNumber,
+ Keywords = cicm.Keywords is null ? null : [..cicm.Keywords],
+ Categories = cicm.Categories is null ? null : [..cicm.Categories],
+ Subcategories = cicm.Subcategories is null ? null : [..cicm.Subcategories],
+ Systems = cicm.Systems is null ? null : [..cicm.Systems]
+ };
+
+ if(cicm.Barcodes is not null)
+ {
+ metadata.Barcodes = [];
+
+ foreach(Schemas.BarcodeType code in cicm.Barcodes) metadata.Barcodes.Add(code);
+ }
+
+ if(cicm.Magazine is not null)
+ {
+ metadata.Magazines = [];
+
+ foreach(MagazineType magazine in cicm.Magazine) metadata.Magazines.Add(magazine);
+ }
+
+ if(cicm.Book is not null)
+ {
+ metadata.Books = [];
+
+ foreach(BookType book in cicm.Book) metadata.Books.Add(book);
+ }
+
+ if(cicm.Languages is not null)
+ {
+ metadata.Languages = [];
+
+ foreach(LanguagesTypeLanguage lng in cicm.Languages) metadata.Languages.Add((Language)lng);
+ }
+
+ if(cicm.Architectures is not null)
+ {
+ metadata.Architectures = [];
+
+ foreach(ArchitecturesTypeArchitecture arch in cicm.Architectures)
+ metadata.Architectures.Add((Architecture)arch);
+ }
+
+ if(cicm.RequiredOperatingSystems is not null)
+ {
+ metadata.RequiredOperatingSystems = [];
+
+ foreach(RequiredOperatingSystemType os in cicm.RequiredOperatingSystems)
+ metadata.RequiredOperatingSystems.Add(os);
+ }
+
+ if(cicm.UserManual is not null)
+ {
+ metadata.UserManuals = [];
+
+ foreach(UserManualType manual in cicm.UserManual) metadata.UserManuals.Add(manual);
+ }
+
+ if(cicm.OpticalDisc is not null)
+ {
+ metadata.OpticalDiscs = [];
+
+ foreach(OpticalDiscType disc in cicm.OpticalDisc) metadata.OpticalDiscs.Add(disc);
+ }
+
+ if(cicm.Advertisement is not null)
+ {
+ metadata.Advertisements = [];
+
+ foreach(AdvertisementType adv in cicm.Advertisement) metadata.Advertisements.Add(adv);
+ }
+
+ if(cicm.LinearMedia is not null)
+ {
+ metadata.LinearMedias = [];
+
+ foreach(LinearMediaType media in cicm.LinearMedia) metadata.LinearMedias.Add(media);
+ }
+
+ if(cicm.PCICard is not null)
+ {
+ metadata.PciCards = [];
+
+ foreach(PCIType pci in cicm.PCICard) metadata.PciCards.Add(pci);
+ }
+
+ if(cicm.BlockMedia is not null)
+ {
+ metadata.BlockMedias = [];
+
+ foreach(BlockMediaType media in cicm.BlockMedia) metadata.BlockMedias.Add(media);
+ }
+
+ if(cicm.AudioMedia is null) return metadata;
+
+ metadata.AudioMedias = [];
+
+ foreach(AudioMediaType media in cicm.AudioMedia) metadata.AudioMedias.Add(media);
+
+ return metadata;
+ }
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/Advertisement.cs b/Aaru.CommonTypes/AaruMetadata/Advertisement.cs
new file mode 100644
index 000000000..1bc5a41f1
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/Advertisement.cs
@@ -0,0 +1,111 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Advertisement.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using Schemas;
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+public class Advertisement
+{
+ public string Manufacturer { get; set; }
+ public string Product { get; set; }
+ public File File { get; set; }
+ public ulong FileSize { get; set; }
+ public ulong? Frames { get; set; }
+ public double Duration { get; set; }
+ public float? MeanFrameRate { get; set; }
+ public List Checksums { get; set; }
+ public List AudioTracks { get; set; }
+ public List VideoTracks { get; set; }
+ public List SubtitleTracks { get; set; }
+ public Recording Recording { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator Advertisement(AdvertisementType cicm)
+ {
+ if(cicm is null) return null;
+
+ var adv = new Advertisement
+ {
+ Manufacturer = cicm.Manufacturer,
+ Product = cicm.Product,
+ File = cicm.File,
+ FileSize = cicm.FileSize,
+ Frames = cicm.FramesSpecified ? cicm.Frames : null,
+ Duration = cicm.Duration,
+ MeanFrameRate = cicm.MeanFrameRateSpecified ? cicm.MeanFrameRate : null,
+ Recording = cicm.Recording
+ };
+
+ if(cicm.Checksums is not null)
+ {
+ adv.Checksums = [];
+
+ foreach(Schemas.ChecksumType chk in cicm.Checksums) adv.Checksums.Add(chk);
+ }
+
+ if(cicm.AudioTrack is not null)
+ {
+ adv.AudioTracks = [];
+
+ foreach(AudioTracksType trk in cicm.AudioTrack) adv.AudioTracks.Add(trk);
+ }
+
+ if(cicm.VideoTrack is not null)
+ {
+ adv.VideoTracks = [];
+
+ foreach(VideoTracksType trk in cicm.VideoTrack) adv.VideoTracks.Add(trk);
+ }
+
+ if(cicm.SubtitleTrack is null) return adv;
+
+ {
+ adv.SubtitleTracks = [];
+
+ foreach(SubtitleTracksType trk in cicm.SubtitleTrack) adv.SubtitleTracks.Add(trk);
+ }
+
+ return adv;
+ }
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/Architecture.cs b/Aaru.CommonTypes/AaruMetadata/Architecture.cs
new file mode 100644
index 000000000..56aa22987
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/Architecture.cs
@@ -0,0 +1,129 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Architecture.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System.Text.Json.Serialization;
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+[JsonConverter(typeof(JsonStringEnumMemberConverter))]
+public enum Architecture
+{
+ [JsonPropertyName("4004")]
+ _4004,
+ [JsonPropertyName("4040")]
+ _4040,
+ [JsonPropertyName("6502")]
+ _6502,
+ [JsonPropertyName("65816")]
+ _65816,
+ [JsonPropertyName("8008")]
+ _8008,
+ [JsonPropertyName("8051")]
+ _8051,
+ [JsonPropertyName("8080")]
+ _8080,
+ [JsonPropertyName("8085")]
+ _8085,
+ Aarch64,
+ Am29000,
+ Amd64,
+ Apx432,
+ Arm,
+ Avr,
+ Avr32,
+ Axp,
+ Clipper,
+ Cray,
+ Esa390,
+ Hobbit,
+ I86,
+ I860,
+ I960,
+ Ia32,
+ Ia64,
+ M56K,
+ M6800,
+ M6801,
+ M6805,
+ M6809,
+ M68K,
+ M88K,
+ Mcs41,
+ Mcs48,
+ Mips32,
+ Mips64,
+ Msp430,
+ Nios2,
+ Openrisc,
+ Parisc,
+ PDP1,
+ PDP10,
+ PDP11,
+ PDP7,
+ PDP8,
+ Pic,
+ Power,
+ Ppc,
+ Ppc64,
+ Prism,
+ Renesasrx,
+ Riscv,
+ S360,
+ S370,
+ Sh,
+ Sh1,
+ Sh2,
+ Sh3,
+ Sh4,
+ Sh5,
+ Sh64,
+ Sparc,
+ Sparc64,
+ Transputer,
+ Vax,
+ We32000,
+ X32,
+ Z80,
+ Z800,
+ Z8000,
+ Z80000,
+ Zarch
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/AudioMedia.cs b/Aaru.CommonTypes/AaruMetadata/AudioMedia.cs
new file mode 100644
index 000000000..aaa8cc711
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/AudioMedia.cs
@@ -0,0 +1,138 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : AudioMedia.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using Schemas;
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+public class AudioMedia
+{
+ public Image Image { get; set; }
+ public ulong Size { get; set; }
+ public List Checksums { get; set; }
+ public Sequence Sequence { get; set; }
+ public string PartNumber { get; set; }
+ public string SerialNumber { get; set; }
+ public string Manufacturer { get; set; }
+ public string Model { get; set; }
+ public string AccoustID { get; set; }
+ public List Blocks { get; set; }
+ public string CopyProtection { get; set; }
+ public Dimensions Dimensions { get; set; }
+ public Scans Scans { get; set; }
+ public List DumpHardware { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator AudioMedia(AudioMediaType cicm)
+ {
+ if(cicm is null) return null;
+
+ var media = new AudioMedia
+ {
+ Image = cicm.Image,
+ Size = cicm.Size,
+ Sequence = cicm.Sequence,
+ PartNumber = cicm.PartNumber,
+ SerialNumber = cicm.SerialNumber,
+ Manufacturer = cicm.Manufacturer,
+ Model = cicm.Model,
+ AccoustID = cicm.AccoustID,
+ CopyProtection = cicm.CopyProtection,
+ Dimensions = cicm.Dimensions,
+ Scans = cicm.Scans
+ };
+
+ if(cicm.Checksums is not null)
+ {
+ media.Checksums = [];
+
+ foreach(Schemas.ChecksumType chk in cicm.Checksums) media.Checksums.Add(chk);
+ }
+
+ if(cicm.Block is not null)
+ {
+ media.Blocks = [];
+
+ foreach(AudioBlockType blk in cicm.Block) media.Blocks.Add(blk);
+ }
+
+ if(cicm.DumpHardwareArray is null) return media;
+
+ media.DumpHardware = [];
+
+ foreach(DumpHardwareType hw in cicm.DumpHardwareArray) media.DumpHardware.Add(hw);
+
+ return media;
+ }
+}
+
+public class AudioBlock
+{
+ public Image Image { get; set; }
+ public ulong Size { get; set; }
+ public string AccoustID { get; set; }
+ public List Checksums { get; set; }
+ public string Format { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator AudioBlock(AudioBlockType cicm)
+ {
+ if(cicm is null) return null;
+
+ var blk = new AudioBlock
+ {
+ Image = cicm.Image,
+ Size = cicm.Size,
+ AccoustID = cicm.AccoustID,
+ Format = cicm.Format
+ };
+
+ if(cicm.Checksums is null) return blk;
+
+ blk.Checksums = [];
+
+ foreach(Schemas.ChecksumType chk in cicm.Checksums) blk.Checksums.Add(chk);
+
+ return blk;
+ }
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/AudioVideo.cs b/Aaru.CommonTypes/AaruMetadata/AudioVideo.cs
new file mode 100644
index 000000000..fb1576b6f
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/AudioVideo.cs
@@ -0,0 +1,321 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : AudioVideo.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Text.Json.Serialization;
+using Schemas;
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+public class AudioTrack
+{
+ public List Languages { get; set; }
+ public uint Number { get; set; }
+ public string AccoustID { get; set; }
+ public string Codec { get; set; }
+ public uint Channels { get; set; }
+ public double SampleRate { get; set; }
+ public long MeanBitrate { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator AudioTrack(AudioTracksType cicm)
+ {
+ if(cicm is null) return null;
+
+ var trk = new AudioTrack
+ {
+ Number = cicm.TrackNumber,
+ AccoustID = cicm.AccoustID,
+ Codec = cicm.Codec,
+ Channels = cicm.Channels,
+ SampleRate = cicm.SampleRate,
+ MeanBitrate = cicm.MeanBitrate
+ };
+
+ if(cicm.Languages is null) return trk;
+
+ trk.Languages = [];
+
+ foreach(LanguagesTypeLanguage lng in cicm.Languages) trk.Languages.Add((Language)lng);
+
+ return trk;
+ }
+}
+
+public class VideoTrack
+{
+ public List Languages { get; set; }
+ public uint Number { get; set; }
+ public string Codec { get; set; }
+ public uint Horizontal { get; set; }
+ public uint Vertical { get; set; }
+ public long MeanBitrate { get; set; }
+
+ [JsonPropertyName("3D")]
+ public bool ThreeD { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator VideoTrack(VideoTracksType cicm)
+ {
+ if(cicm is null) return null;
+
+ var trk = new VideoTrack
+ {
+ Number = cicm.TrackNumber,
+ Codec = cicm.Codec,
+ Horizontal = cicm.Horizontal,
+ Vertical = cicm.Vertical,
+ MeanBitrate = cicm.MeanBitrate,
+ ThreeD = cicm.ThreeD
+ };
+
+ if(cicm.Languages is null) return trk;
+
+ trk.Languages = [];
+
+ foreach(LanguagesTypeLanguage lng in cicm.Languages) trk.Languages.Add((Language)lng);
+
+ return trk;
+ }
+}
+
+public class SubtitleTrack
+{
+ public List Languages { get; set; }
+ public uint Number { get; set; }
+ public string Codec { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator SubtitleTrack(SubtitleTracksType cicm)
+ {
+ if(cicm is null) return null;
+
+ var sub = new SubtitleTrack
+ {
+ Number = cicm.TrackNumber,
+ Codec = cicm.Codec
+ };
+
+ if(cicm.Languages is null) return sub;
+
+ sub.Languages = [];
+
+ foreach(LanguagesTypeLanguage lng in cicm.Languages) sub.Languages.Add((Language)lng);
+
+ return sub;
+ }
+}
+
+public class Recording
+{
+ public string Broadcaster { get; set; }
+ public string BroadcastPlatform { get; set; }
+ public SourceFormat SourceFormat { get; set; }
+ public DateTime Timestamp { get; set; }
+ public List Software { get; set; }
+ public Coordinates Coordinates { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator Recording(RecordingType cicm)
+ {
+ if(cicm is null) return null;
+
+ var recording = new Recording
+ {
+ Broadcaster = cicm.Broadcaster,
+ BroadcastPlatform = cicm.BroadcastPlatform,
+ SourceFormat = (SourceFormat)cicm.SourceFormat,
+ Timestamp = cicm.Timestamp,
+ Coordinates = cicm.Coordinates
+ };
+
+ if(cicm.Software is null) return recording;
+
+ recording.Software = [];
+
+ foreach(SoftwareType sw in cicm.Software) recording.Software.Add(sw);
+
+ return recording;
+ }
+}
+
+public class Coordinates
+{
+ public double Latitude { get; set; }
+ public double Longitude { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator Coordinates(CoordinatesType cicm) => cicm is null
+ ? null
+ : new Coordinates
+ {
+ Latitude = cicm.Latitude,
+ Longitude = cicm.Longitude
+ };
+}
+
+[JsonConverter(typeof(JsonStringEnumMemberConverter))]
+[SuppressMessage("ReSharper", "InconsistentNaming")]
+public enum SourceFormat
+{
+ [JsonPropertyName("ITU-A")]
+ ITUA,
+ [JsonPropertyName("ITU-B")]
+ ITUB,
+ [JsonPropertyName("ITU-C")]
+ ITUC,
+ [JsonPropertyName("ITU-D")]
+ ITUD,
+ [JsonPropertyName("ITU-E")]
+ ITUE,
+ [JsonPropertyName("ITU-F")]
+ ITUF,
+ [JsonPropertyName("ITU-G")]
+ ITUG,
+ [JsonPropertyName("ITU-H")]
+ ITUH,
+ [JsonPropertyName("ITU-I")]
+ ITUI,
+ [JsonPropertyName("ITU-J")]
+ ITUJ,
+ [JsonPropertyName("ITU-K")]
+ ITUK,
+ [JsonPropertyName("ITU-L")]
+ ITUL,
+ [JsonPropertyName("ITU-M")]
+ ITUM,
+ [JsonPropertyName("ITU-N")]
+ ITUN,
+ [JsonPropertyName("PAL-B")]
+ PALB,
+ [JsonPropertyName("SECAM-B")]
+ SECAMB,
+ [JsonPropertyName("PAL-D")]
+ PALD,
+ [JsonPropertyName("SECAM-D")]
+ SECAMD,
+ [JsonPropertyName("PAL-G")]
+ PALG,
+ [JsonPropertyName("SECAM-G")]
+ SECAMG,
+ [JsonPropertyName("PAL-H")]
+ PALH,
+ [JsonPropertyName("PAL-I")]
+ PALI,
+ [JsonPropertyName("PAL-K")]
+ PALK,
+ [JsonPropertyName("SECAM-K")]
+ SECAMK,
+ [JsonPropertyName("NTSC-M")]
+ NTSCM,
+ [JsonPropertyName("PAL-N")]
+ PALN,
+ [JsonPropertyName("PAL-M")]
+ PALM,
+ [JsonPropertyName("SECAM-M")]
+ SECAMM,
+ MUSE,
+ PALplus,
+ FM,
+ AM,
+ COFDM,
+ [JsonPropertyName("CAM-D")]
+ CAMD,
+ DAB,
+ [JsonPropertyName("DAB+")]
+ DAB1,
+ DRM,
+ [JsonPropertyName("DRM+")]
+ DRM1,
+ FMeXtra,
+ ATSC,
+ ATSC2,
+ ATSC3,
+ [JsonPropertyName("ATSC-M/H")]
+ ATSCMH,
+ [JsonPropertyName("DVB-T")]
+ DVBT,
+ [JsonPropertyName("DVB-T2")]
+ DVBT2,
+ [JsonPropertyName("DVB-S")]
+ DVBS,
+ [JsonPropertyName("DVB-S2")]
+ DVBS2,
+ [JsonPropertyName("DVB-S2X")]
+ DVBS2X,
+ [JsonPropertyName("DVB-C")]
+ DVBC,
+ [JsonPropertyName("DVB-C2")]
+ DVBC2,
+ [JsonPropertyName("DVB-H")]
+ DVBH,
+ [JsonPropertyName("DVB-NGH")]
+ DVBNGH,
+ [JsonPropertyName("DVB-SH")]
+ DVBSH,
+ [JsonPropertyName("ISDB-T")]
+ ISDBT,
+ [JsonPropertyName("ISDB-Tb")]
+ ISDBTb,
+ [JsonPropertyName("ISDB-S")]
+ ISDBS,
+ [JsonPropertyName("ISDB-C")]
+ ISDBC,
+ [JsonPropertyName("1seg")]
+ Item1seg,
+ DTMB,
+ CCMB,
+ [JsonPropertyName("T-DMB")]
+ TDMB,
+ [JsonPropertyName("S-DMB")]
+ SDMB,
+ IPTV,
+ [JsonPropertyName("DVB-MT")]
+ DVBMT,
+ [JsonPropertyName("DVB-MC")]
+ DVBMC,
+ [JsonPropertyName("DVB-MS")]
+ DVBMS,
+ ADR,
+ SDR
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/Barcode.cs b/Aaru.CommonTypes/AaruMetadata/Barcode.cs
new file mode 100644
index 000000000..29a473632
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/Barcode.cs
@@ -0,0 +1,95 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Barcode.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+using System.Text.Json.Serialization;
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+[JsonConverter(typeof(JsonStringEnumMemberConverter))]
+[SuppressMessage("ReSharper", "InconsistentNaming")]
+public enum BarcodeType
+{
+ Aztec,
+ Codabar,
+ Code11,
+ Code128,
+ Code39,
+ Code93,
+ CPC_Binary,
+ EZcode,
+ FIM,
+ ITF,
+ ITF14,
+ EAN13,
+ EAN8,
+ MaxiCode,
+ ISBN,
+ ISRC,
+ MSI,
+ ShotCode,
+ RM4SCC,
+ QR,
+ EAN5,
+ EAN2,
+ POSTNET,
+ PostBar,
+ Plessey,
+ Pharmacode,
+ PDF417,
+ PatchCode
+}
+
+public class Barcode
+{
+ public BarcodeType Type { get; set; }
+ public string Value { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator Barcode(Schemas.BarcodeType cicm) => cicm is null
+ ? null
+ : new Barcode
+ {
+ Type = (BarcodeType)cicm.type,
+ Value = cicm.Value
+ };
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/BlockMedia.cs b/Aaru.CommonTypes/AaruMetadata/BlockMedia.cs
new file mode 100644
index 000000000..e6ec10a76
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/BlockMedia.cs
@@ -0,0 +1,210 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : BlockMedia.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using Schemas;
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+public class BlockMedia
+{
+ public Image Image { get; set; }
+ public ulong Size { get; set; }
+ public List Checksums { get; set; }
+ public List ContentChecksums { get; set; }
+ public Sequence Sequence { get; set; }
+ public string Manufacturer { get; set; }
+ public string Model { get; set; }
+ public string Serial { get; set; }
+ public string Firmware { get; set; }
+ public string PartNumber { get; set; }
+ public string SerialNumber { get; set; }
+ public uint PhysicalBlockSize { get; set; }
+ public uint LogicalBlockSize { get; set; }
+ public ulong LogicalBlocks { get; set; }
+ public List VariableBlockSize { get; set; }
+ public List TapeInformation { get; set; }
+ public Scans Scans { get; set; }
+ public ATA ATA { get; set; }
+ public Pci Pci { get; set; }
+ public Pcmcia Pcmcia { get; set; }
+ public SecureDigital SecureDigital { get; set; }
+ public MultiMediaCard MultiMediaCard { get; set; }
+ public SCSI SCSI { get; set; }
+ public Usb Usb { get; set; }
+ public Dump Mam { get; set; }
+ public ushort? Heads { get; set; }
+ public uint? Cylinders { get; set; }
+ public ulong? SectorsPerTrack { get; set; }
+ public List Track { get; set; }
+ public string CopyProtection { get; set; }
+ public Dimensions Dimensions { get; set; }
+ public List FileSystemInformation { get; set; }
+ public List DumpHardware { get; set; }
+ public string MediaType { get; set; }
+ public string MediaSubType { get; set; }
+ public string Interface { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator BlockMedia(BlockMediaType cicm)
+ {
+ if(cicm is null) return null;
+
+ var media = new BlockMedia
+ {
+ Image = cicm.Image,
+ Size = cicm.Size,
+ Sequence = cicm.Sequence,
+ Manufacturer = cicm.Manufacturer,
+ Model = cicm.Model,
+ Serial = cicm.Serial,
+ Firmware = cicm.Firmware,
+ PartNumber = cicm.PartNumber,
+ SerialNumber = cicm.SerialNumber,
+ PhysicalBlockSize = cicm.PhysicalBlockSize,
+ LogicalBlockSize = cicm.LogicalBlockSize,
+ LogicalBlocks = cicm.LogicalBlocks,
+ Scans = cicm.Scans,
+ ATA = cicm.ATA,
+ Pci = cicm.PCI,
+ Pcmcia = cicm.PCMCIA,
+ SecureDigital = cicm.SecureDigital,
+ MultiMediaCard = cicm.MultiMediaCard,
+ SCSI = cicm.SCSI,
+ Usb = cicm.USB,
+ Mam = cicm.MAM,
+ Heads = cicm.HeadsSpecified ? cicm.Heads : null,
+ Cylinders = cicm.CylindersSpecified ? cicm.Cylinders : null,
+ SectorsPerTrack = cicm.SectorsPerTrackSpecified ? cicm.SectorsPerTrack : null,
+ CopyProtection = cicm.CopyProtection,
+ Dimensions = cicm.Dimensions,
+ MediaType = cicm.DiskType,
+ MediaSubType = cicm.DiskSubType,
+ Interface = cicm.Interface
+ };
+
+ if(cicm.Checksums is not null)
+ {
+ media.Checksums = [];
+
+ foreach(Schemas.ChecksumType chk in cicm.Checksums) media.Checksums.Add(chk);
+ }
+
+ if(cicm.ContentChecksums is not null)
+ {
+ media.ContentChecksums = [];
+
+ foreach(Schemas.ChecksumType chk in cicm.ContentChecksums) media.ContentChecksums.Add(chk);
+ }
+
+ if(cicm.VariableBlockSize is not null)
+ {
+ media.VariableBlockSize = [];
+
+ foreach(BlockSizeType blkSize in cicm.VariableBlockSize) media.VariableBlockSize.Add(blkSize);
+ }
+
+ if(cicm.TapeInformation is not null)
+ {
+ media.TapeInformation = [];
+
+ foreach(TapePartitionType tapeInformation in cicm.TapeInformation)
+ media.TapeInformation.Add(tapeInformation);
+ }
+
+ if(cicm.FileSystemInformation is not null)
+ {
+ media.FileSystemInformation = [];
+
+ foreach(PartitionType fsInfo in cicm.FileSystemInformation) media.FileSystemInformation.Add(fsInfo);
+ }
+
+ if(cicm.DumpHardwareArray is null) return media;
+
+ media.DumpHardware = [];
+
+ foreach(DumpHardwareType hw in cicm.DumpHardwareArray) media.DumpHardware.Add(hw);
+
+ return media;
+ }
+}
+
+public class BlockTrack
+{
+ public Image Image { get; set; }
+ public ulong Size { get; set; }
+ public ushort Head { get; set; }
+ public uint Cylinder { get; set; }
+ public ulong StartSector { get; set; }
+ public ulong EndSector { get; set; }
+ public ulong Sectors { get; set; }
+ public uint BytesPerSector { get; set; }
+ public List Checksums { get; set; }
+ public string Format { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator BlockTrack(BlockTrackType cicm)
+ {
+ if(cicm is null) return null;
+
+ var trk = new BlockTrack
+ {
+ Image = cicm.Image,
+ Size = cicm.Size,
+ Head = cicm.Head,
+ Cylinder = cicm.Cylinder,
+ StartSector = cicm.StartSector,
+ EndSector = cicm.EndSector,
+ Sectors = cicm.Sectors,
+ BytesPerSector = cicm.BytesPerSector,
+ Format = cicm.Format
+ };
+
+ if(cicm.Checksums is null) return trk;
+
+ trk.Checksums = [];
+
+ foreach(Schemas.ChecksumType chk in cicm.Checksums) trk.Checksums.Add(chk);
+
+ return trk;
+ }
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/Book.cs b/Aaru.CommonTypes/AaruMetadata/Book.cs
new file mode 100644
index 000000000..61bdd452a
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/Book.cs
@@ -0,0 +1,93 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Book.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using Schemas;
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+public class Book
+{
+ public List Barcodes { get; set; }
+ public Cover Cover { get; set; }
+ public string Name { get; set; }
+ public string Editorial { get; set; }
+ public string Author { get; set; }
+ public DateTime? PublicationDate { get; set; }
+ public List Languages { get; set; }
+ public uint? Pages { get; set; }
+ public string PageSize { get; set; }
+ public Scan Scan { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator Book(BookType cicm)
+ {
+ if(cicm is null) return null;
+
+ var book = new Book
+ {
+ Cover = cicm.Cover,
+ Name = cicm.Name,
+ Editorial = cicm.Editorial,
+ Author = cicm.Author,
+ PublicationDate = cicm.PublicationDateSpecified ? cicm.PublicationDate : null,
+ Pages = cicm.PagesSpecified ? cicm.Pages : null,
+ PageSize = cicm.PageSize,
+ Scan = cicm.Scan
+ };
+
+ if(cicm.Barcodes is not null)
+ {
+ book.Barcodes = [];
+
+ foreach(Schemas.BarcodeType code in cicm.Barcodes) book.Barcodes.Add(code);
+ }
+
+ if(cicm.Language is null) return book;
+
+ book.Languages = [];
+
+ foreach(LanguagesTypeLanguage lng in cicm.Language) book.Languages.Add((Language)lng);
+
+ return book;
+ }
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/Checksum.cs b/Aaru.CommonTypes/AaruMetadata/Checksum.cs
new file mode 100644
index 000000000..b2b48eda5
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/Checksum.cs
@@ -0,0 +1,91 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Checksum.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+using System;
+using System.Text.Json.Serialization;
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+public class Checksum
+{
+ public ChecksumType Type { get; set; }
+ public string Value { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator Checksum(Schemas.ChecksumType cicm) => cicm is null
+ ? null
+ : new Checksum
+ {
+ Value = cicm.Value,
+ Type = (ChecksumType)cicm.type
+ };
+}
+
+[JsonConverter(typeof(JsonStringEnumMemberConverter))]
+public enum ChecksumType
+{
+ Fletcher16,
+ Fletcher32,
+ Adler32,
+ CRC16,
+ CRC16Ccitt,
+ CRC32,
+ CRC64,
+ Md4,
+ Md5,
+ Dm6,
+ Ripemd128,
+ Ripemd160,
+ Ripemed320,
+ Sha1,
+ Sha224,
+ Sha256,
+ Sha384,
+ Sha512,
+ Sha3,
+ Skein,
+ Snefru,
+ Blake256,
+ Blake512,
+ Tiger,
+ Whirlpool,
+ SpamSum
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/Contents.cs b/Aaru.CommonTypes/AaruMetadata/Contents.cs
new file mode 100644
index 000000000..ec36f530d
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/Contents.cs
@@ -0,0 +1,222 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Contents.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using Schemas;
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+public class FilesystemContents
+{
+ public List Files { get; set; }
+ public List Directories { get; set; }
+ public string Namespace { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator FilesystemContents(FilesystemContentsType cicm)
+ {
+ if(cicm is null) return null;
+
+ var fs = new FilesystemContents
+ {
+ Namespace = cicm.@namespace
+ };
+
+ if(cicm.File is not null)
+ {
+ fs.Files = [];
+
+ foreach(ContentsFileType file in cicm.File) fs.Files.Add(file);
+ }
+
+ if(cicm.Directory is null) return fs;
+
+ fs.Directories = [];
+
+ foreach(DirectoryType dir in cicm.Directory) fs.Directories.Add(dir);
+
+ return fs;
+ }
+}
+
+public class ContentsFile
+{
+ public List Checksums { get; set; }
+ public List ExtendedAttributes { get; set; }
+ public string Name { get; set; }
+ public DateTime? CreationTime { get; set; }
+ public DateTime? AccessTime { get; set; }
+ public DateTime? StatusChangeTime { get; set; }
+ public DateTime? BackupTime { get; set; }
+ public DateTime? LastWriteTime { get; set; }
+ public ulong Attributes { get; set; }
+ public uint? PosixMode { get; set; }
+ public ulong? DeviceNumber { get; set; }
+ public ulong? PosixGroupId { get; set; }
+ public ulong Inode { get; set; }
+ public ulong Links { get; set; }
+ public ulong? PosixUserId { get; set; }
+ public ulong Length { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator ContentsFile(ContentsFileType cicm)
+ {
+ if(cicm is null) return null;
+
+ var file = new ContentsFile
+ {
+ Name = cicm.name,
+ CreationTime = cicm.creationTimeSpecified ? cicm.creationTime : null,
+ AccessTime = cicm.accessTimeSpecified ? cicm.accessTime : null,
+ StatusChangeTime = cicm.statusChangeTimeSpecified ? cicm.statusChangeTime : null,
+ BackupTime = cicm.backupTimeSpecified ? cicm.backupTime : null,
+ LastWriteTime = cicm.lastWriteTimeSpecified ? cicm.lastWriteTime : null,
+ Attributes = cicm.attributes,
+ PosixMode = cicm.posixModeSpecified ? cicm.posixMode : null,
+ DeviceNumber = cicm.deviceNumberSpecified ? cicm.deviceNumber : null,
+ PosixGroupId = cicm.posixGroupIdSpecified ? cicm.posixGroupId : null,
+ Inode = cicm.inode,
+ Links = cicm.links,
+ PosixUserId = cicm.posixUserIdSpecified ? cicm.posixUserId : null,
+ Length = cicm.length
+ };
+
+ if(cicm.Checksums is not null)
+ {
+ file.Checksums = [];
+
+ foreach(Schemas.ChecksumType chk in cicm.Checksums) file.Checksums.Add(chk);
+ }
+
+ if(cicm.ExtendedAttributes is null) return file;
+
+ file.ExtendedAttributes = [];
+
+ foreach(ExtendedAttributeType xa in cicm.ExtendedAttributes) file.ExtendedAttributes.Add(xa);
+
+ return file;
+ }
+}
+
+public class ExtendedAttribute
+{
+ public List Checksums { get; set; }
+ public string Name { get; set; }
+ public ulong Length { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator ExtendedAttribute(ExtendedAttributeType cicm)
+ {
+ if(cicm is null) return null;
+
+ var xa = new ExtendedAttribute
+ {
+ Name = cicm.name,
+ Length = cicm.length
+ };
+
+ if(cicm.Checksums is null) return xa;
+
+ xa.Checksums = [];
+
+ foreach(Schemas.ChecksumType chk in cicm.Checksums) xa.Checksums.Add(chk);
+
+ return xa;
+ }
+}
+
+public class Directory
+{
+ public List Files { get; set; }
+ public List Directories { get; set; }
+ public string Name { get; set; }
+ public DateTime? CreationTime { get; set; }
+ public DateTime? AccessTime { get; set; }
+ public DateTime? StatusChangeTime { get; set; }
+ public DateTime? BackupTime { get; set; }
+ public DateTime? LastWriteTime { get; set; }
+ public ulong Attributes { get; set; }
+ public uint? PosixMode { get; set; }
+ public ulong? DeviceNumber { get; set; }
+ public ulong? PosixGroupId { get; set; }
+ public ulong? Inode { get; set; }
+ public ulong? Links { get; set; }
+ public ulong? PosixUserId { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator Directory(DirectoryType cicm)
+ {
+ if(cicm is null) return null;
+
+ var dir = new Directory
+ {
+ Name = cicm.name,
+ CreationTime = cicm.creationTimeSpecified ? cicm.creationTime : null,
+ AccessTime = cicm.accessTimeSpecified ? cicm.accessTime : null,
+ StatusChangeTime = cicm.statusChangeTimeSpecified ? cicm.statusChangeTime : null,
+ BackupTime = cicm.backupTimeSpecified ? cicm.backupTime : null,
+ LastWriteTime = cicm.lastWriteTimeSpecified ? cicm.lastWriteTime : null,
+ Attributes = cicm.attributes,
+ PosixMode = cicm.posixModeSpecified ? cicm.posixMode : null,
+ DeviceNumber = cicm.deviceNumberSpecified ? cicm.deviceNumber : null,
+ PosixGroupId = cicm.posixGroupIdSpecified ? cicm.posixGroupId : null,
+ Inode = cicm.inodeSpecified ? cicm.inode : null,
+ Links = cicm.linksSpecified ? cicm.links : null,
+ PosixUserId = cicm.posixUserIdSpecified ? cicm.posixUserId : null
+ };
+
+ if(cicm.Directory is not null)
+ {
+ dir.Directories = [];
+
+ foreach(DirectoryType d in cicm.Directory) dir.Directories.Add(d);
+ }
+
+ if(cicm.File is null) return dir;
+
+ dir.Files = [];
+
+ foreach(ContentsFileType file in cicm.File) dir.Files.Add(file);
+
+ return dir;
+ }
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/Dimensions.cs b/Aaru.CommonTypes/AaruMetadata/Dimensions.cs
new file mode 100644
index 000000000..450b361bd
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/Dimensions.cs
@@ -0,0 +1,1160 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Dimensions.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+using System;
+using Schemas;
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+public class Dimensions
+{
+ public double? Diameter { get; set; }
+ public double? Height { get; set; }
+ public double? Width { get; set; }
+ public double Thickness { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator Dimensions(DimensionsType cicm) => cicm is null
+ ? null
+ : new Dimensions
+ {
+ Diameter =
+ cicm.DiameterSpecified
+ ? cicm.Diameter
+ : null,
+ Height = cicm.HeightSpecified
+ ? cicm.Height
+ : null,
+ Width = cicm.WidthSpecified
+ ? cicm.Width
+ : null,
+ Thickness = cicm.Thickness
+ };
+
+ /// Gets the physical dimensions, in metadata expected format, for a given media type
+ /// Media type
+ /// Dimensions metadata
+ public static Dimensions FromMediaType(MediaType mediaType)
+ {
+ var dmns = new Dimensions();
+
+ switch(mediaType)
+ {
+#region 5.25" floppy disk
+
+ case MediaType.Apple32SS:
+ case MediaType.Apple32DS:
+ case MediaType.Apple33SS:
+ case MediaType.Apple33DS:
+ case MediaType.AppleFileWare:
+ case MediaType.DOS_525_SS_DD_8:
+ case MediaType.DOS_525_SS_DD_9:
+ case MediaType.DOS_525_DS_DD_8:
+ case MediaType.DOS_525_DS_DD_9:
+ case MediaType.DOS_525_HD:
+ case MediaType.XDF_525:
+ case MediaType.ACORN_525_SS_SD_40:
+ case MediaType.ACORN_525_SS_SD_80:
+ case MediaType.ACORN_525_SS_DD_40:
+ case MediaType.ACORN_525_SS_DD_80:
+ case MediaType.ACORN_525_DS_DD:
+ case MediaType.ATARI_525_SD:
+ case MediaType.ATARI_525_ED:
+ case MediaType.ATARI_525_DD:
+ case MediaType.CBM_1540:
+ case MediaType.CBM_1540_Ext:
+ case MediaType.CBM_1571:
+ case MediaType.ECMA_66:
+ case MediaType.ECMA_70:
+ case MediaType.NEC_525_HD:
+ case MediaType.ECMA_78:
+ case MediaType.ECMA_78_2:
+ case MediaType.ECMA_99_8:
+ case MediaType.ECMA_99_15:
+ case MediaType.ECMA_99_26:
+ case MediaType.FDFORMAT_525_DD:
+ case MediaType.FDFORMAT_525_HD:
+ case MediaType.MetaFloppy_Mod_I:
+ case MediaType.MetaFloppy_Mod_II:
+ // According to ECMA-99 et al
+ dmns.Height = 133.3;
+
+ dmns.Width = 133.3;
+
+ dmns.Thickness = 1.65;
+
+ return dmns;
+
+#endregion 5.25" floppy disk
+
+#region 3.5" floppy disk
+
+ case MediaType.AppleSonySS:
+ case MediaType.AppleSonyDS:
+ case MediaType.DOS_35_SS_DD_8:
+ case MediaType.DOS_35_SS_DD_9:
+ case MediaType.DOS_35_DS_DD_8:
+ case MediaType.DOS_35_DS_DD_9:
+ case MediaType.DOS_35_HD:
+ case MediaType.DOS_35_ED:
+ case MediaType.DMF:
+ case MediaType.DMF_82:
+ case MediaType.XDF_35:
+ case MediaType.ACORN_35_DS_DD:
+ case MediaType.CBM_35_DD:
+ case MediaType.CBM_AMIGA_35_DD:
+ case MediaType.CBM_AMIGA_35_HD:
+ case MediaType.FDFORMAT_35_DD:
+ case MediaType.FDFORMAT_35_HD:
+ case MediaType.NEC_35_HD_8:
+ case MediaType.NEC_35_HD_15:
+ case MediaType.Floptical:
+ case MediaType.HiFD:
+ case MediaType.UHD144:
+ case MediaType.Apricot_35:
+ case MediaType.FD32MB:
+ // According to ECMA-100 et al
+ dmns.Height = 94;
+
+ dmns.Width = 90;
+
+ dmns.Thickness = 3.3;
+
+ return dmns;
+
+#endregion 3.5" floppy disk
+
+#region 8" floppy disk
+
+ case MediaType.IBM23FD:
+ case MediaType.IBM33FD_128:
+ case MediaType.IBM33FD_256:
+ case MediaType.IBM33FD_512:
+ case MediaType.IBM43FD_128:
+ case MediaType.IBM43FD_256:
+ case MediaType.IBM53FD_256:
+ case MediaType.IBM53FD_512:
+ case MediaType.IBM53FD_1024:
+ case MediaType.RX01:
+ case MediaType.RX02:
+ case MediaType.NEC_8_SD:
+ case MediaType.NEC_8_DD:
+ case MediaType.ECMA_54:
+ case MediaType.ECMA_59:
+ case MediaType.ECMA_69_8:
+ case MediaType.ECMA_69_15:
+ case MediaType.ECMA_69_26:
+ // According to ECMA-59 et al
+ dmns.Height = 203.2;
+
+ dmns.Width = 203.2;
+
+ dmns.Thickness = 1.65;
+
+ return dmns;
+
+#endregion 8" floppy disk
+
+#region 356mm magneto optical
+
+ case MediaType.ECMA_260:
+ case MediaType.ECMA_260_Double:
+ // According to ECMA-260 et al
+ dmns.Height = 421.84;
+
+ dmns.Width = 443.76;
+
+ dmns.Thickness = 25.4;
+
+ return dmns;
+
+#endregion 356mm magneto optical
+
+#region 300mm magneto optical
+
+ case MediaType.ECMA_189:
+ case MediaType.ECMA_190:
+ case MediaType.ECMA_317:
+ // According to ECMA-317 et al
+ dmns.Height = 340;
+
+ dmns.Width = 320;
+
+ dmns.Thickness = 17;
+
+ return dmns;
+
+#endregion 300mm magneto optical
+
+#region 5.25" magneto optical
+
+ case MediaType.ECMA_153:
+ case MediaType.ECMA_153_512:
+ case MediaType.ECMA_183_512:
+ case MediaType.ECMA_183:
+ case MediaType.ECMA_184_512:
+ case MediaType.ECMA_184:
+ case MediaType.ECMA_195:
+ case MediaType.ECMA_195_512:
+ case MediaType.ECMA_238:
+ case MediaType.ECMA_280:
+ case MediaType.ECMA_322:
+ case MediaType.ECMA_322_2k:
+ case MediaType.UDO:
+ case MediaType.UDO2:
+ case MediaType.UDO2_WORM:
+ case MediaType.ISO_15286:
+ case MediaType.ISO_15286_1024:
+ case MediaType.ISO_15286_512:
+ case MediaType.ISO_10089:
+ case MediaType.ISO_10089_512:
+ case MediaType.ECMA_322_1k:
+ case MediaType.ECMA_322_512:
+ case MediaType.ISO_14517:
+ case MediaType.ISO_14517_512:
+ // According to ECMA-183 et al
+ dmns.Height = 153;
+
+ dmns.Width = 135;
+
+ dmns.Thickness = 11;
+
+ return dmns;
+
+#endregion 5.25" magneto optical
+
+#region 3.5" magneto optical
+
+ case MediaType.ECMA_154:
+ case MediaType.ECMA_201:
+ case MediaType.ECMA_201_ROM:
+ case MediaType.ECMA_223:
+ case MediaType.ECMA_223_512:
+ case MediaType.GigaMo:
+ case MediaType.GigaMo2:
+ case MediaType.ISO_15041_512:
+ // According to ECMA-154 et al
+ dmns.Height = 94;
+
+ dmns.Width = 90;
+
+ dmns.Thickness = 6;
+
+ return dmns;
+
+#endregion 3.5" magneto optical
+
+ case MediaType.PD650:
+ case MediaType.PD650_WORM:
+ dmns.Height = 135;
+
+ dmns.Width = 124;
+
+ dmns.Thickness = 7.8;
+
+ return dmns;
+ case MediaType.ECMA_239:
+ dmns.Height = 97;
+
+ dmns.Width = 92;
+
+ dmns.Thickness = 5;
+
+ return dmns;
+ case MediaType.MMCmicro:
+ dmns.Height = 14;
+
+ dmns.Width = 12;
+
+ dmns.Thickness = 1.1;
+
+ return dmns;
+ case MediaType.MemoryStickMicro:
+ dmns.Height = 15;
+
+ dmns.Width = 12.5;
+
+ dmns.Thickness = 1.2;
+
+ return dmns;
+ case MediaType.microSD:
+ dmns.Height = 11;
+
+ dmns.Width = 15;
+
+ dmns.Thickness = 1;
+
+ return dmns;
+ case MediaType.miniSD:
+ dmns.Height = 21.5;
+
+ dmns.Width = 20;
+
+ dmns.Thickness = 1.4;
+
+ return dmns;
+ case MediaType.QIC3010:
+ case MediaType.QIC3020:
+ case MediaType.QIC3080:
+ case MediaType.QIC3095:
+ case MediaType.QIC320:
+ case MediaType.QIC40:
+ case MediaType.QIC80:
+ dmns.Height = 20;
+
+ dmns.Width = 21.5;
+
+ dmns.Thickness = 1.6;
+
+ return dmns;
+ case MediaType.RSMMC:
+ dmns.Height = 18;
+
+ dmns.Width = 24;
+
+ dmns.Thickness = 1.4;
+
+ return dmns;
+ case MediaType.MMC:
+ dmns.Height = 32;
+
+ dmns.Width = 24;
+
+ dmns.Thickness = 1.4;
+
+ return dmns;
+ case MediaType.SecureDigital:
+ dmns.Height = 32;
+
+ dmns.Width = 24;
+
+ dmns.Thickness = 2.1;
+
+ return dmns;
+ case MediaType.xD:
+ dmns.Height = 20;
+
+ dmns.Width = 25;
+
+ dmns.Thickness = 1.78;
+
+ return dmns;
+ case MediaType.XQD:
+ dmns.Height = 38.5;
+
+ dmns.Width = 29.8;
+
+ dmns.Thickness = 3.8;
+
+ return dmns;
+ case MediaType.MemoryStickDuo:
+ case MediaType.MemoryStickProDuo:
+ dmns.Height = 20;
+
+ dmns.Width = 31;
+
+ dmns.Thickness = 1.6;
+
+ return dmns;
+ case MediaType.Nintendo3DSGameCard:
+ case MediaType.NintendoDSGameCard:
+ case MediaType.NintendoDSiGameCard:
+ dmns.Height = 35;
+
+ dmns.Width = 33;
+
+ dmns.Thickness = 3.8;
+
+ return dmns;
+ case MediaType.DataPlay:
+ dmns.Height = 42;
+
+ dmns.Width = 33.5;
+
+ dmns.Thickness = 3;
+
+ return dmns;
+ case MediaType.Microdrive:
+ dmns.Height = 44;
+
+ dmns.Width = 34;
+
+ dmns.Thickness = 8;
+
+ return dmns;
+ case MediaType.ExpressCard34:
+ dmns.Height = 75;
+
+ dmns.Width = 34;
+
+ dmns.Thickness = 5;
+
+ return dmns;
+ case MediaType.SmartMedia:
+ dmns.Height = 45;
+
+ dmns.Width = 37;
+
+ dmns.Thickness = 0.76;
+
+ return dmns;
+ case MediaType.MiniCard:
+ dmns.Height = 45;
+
+ dmns.Width = 37;
+
+ dmns.Thickness = 3.5;
+
+ return dmns;
+ case MediaType.PlayStationMemoryCard:
+ case MediaType.PlayStationMemoryCard2:
+ dmns.Height = 55.7;
+
+ dmns.Width = 41.5;
+
+ dmns.Thickness = 7;
+
+ return dmns;
+ case MediaType.CFast:
+ case MediaType.CompactFlash:
+ dmns.Height = 36;
+
+ dmns.Width = 43;
+
+ dmns.Thickness = 3.3;
+
+ return dmns;
+ case MediaType.CompactFlashType2:
+ dmns.Height = 36;
+
+ dmns.Width = 43;
+
+ dmns.Thickness = 5;
+
+ return dmns;
+ case MediaType.ZXMicrodrive:
+ dmns.Height = 36;
+
+ dmns.Width = 43;
+
+ dmns.Thickness = 5;
+
+ return dmns;
+ case MediaType.MemoryStick:
+ case MediaType.MemoryStickPro:
+ dmns.Height = 21;
+
+ dmns.Width = 50;
+
+ dmns.Thickness = 2.6;
+
+ return dmns;
+ case MediaType.PocketZip:
+ dmns.Height = 54.5;
+
+ dmns.Width = 50;
+
+ dmns.Thickness = 2;
+
+ return dmns;
+ case MediaType.ExpressCard54:
+ dmns.Height = 75;
+
+ dmns.Width = 54;
+
+ dmns.Thickness = 5;
+
+ return dmns;
+ case MediaType.PCCardTypeI:
+ dmns.Height = 85.6;
+
+ dmns.Width = 54;
+
+ dmns.Thickness = 3.3;
+
+ return dmns;
+ case MediaType.PCCardTypeII:
+ dmns.Height = 85.6;
+
+ dmns.Width = 54;
+
+ dmns.Thickness = 5;
+
+ return dmns;
+ case MediaType.PCCardTypeIII:
+ dmns.Height = 85.6;
+
+ dmns.Width = 54;
+
+ dmns.Thickness = 10.5;
+
+ return dmns;
+ case MediaType.PCCardTypeIV:
+ dmns.Height = 85.6;
+
+ dmns.Width = 54;
+
+ dmns.Thickness = 16;
+
+ return dmns;
+ case MediaType.DataStore:
+ dmns.Height = 86.5;
+
+ dmns.Width = 54;
+
+ dmns.Thickness = 2.5;
+
+ return dmns;
+ case MediaType.VideoFloppy:
+ dmns.Height = 54;
+
+ dmns.Width = 60;
+
+ dmns.Thickness = 3.5;
+
+ return dmns;
+ case MediaType.VXA1:
+ case MediaType.VXA2:
+ case MediaType.VXA3:
+ dmns.Height = 95;
+
+ dmns.Width = 62.5;
+
+ dmns.Thickness = 15;
+
+ return dmns;
+ case MediaType.MiniDV:
+ dmns.Height = 47.5;
+
+ dmns.Width = 66;
+
+ dmns.Thickness = 12;
+
+ return dmns;
+ case MediaType.Wafer:
+ dmns.Height = 46.8;
+
+ dmns.Width = 67.1;
+
+ dmns.Thickness = 7.9;
+
+ return dmns;
+ case MediaType.NintendoDiskCard:
+ dmns.Height = 76.2;
+
+ dmns.Width = 71.12;
+
+ dmns.Thickness = 0;
+
+ return dmns;
+ case MediaType.HiMD:
+ case MediaType.MD:
+ case MediaType.MDData:
+ case MediaType.MDData2:
+ case MediaType.MD60:
+ case MediaType.MD74:
+ case MediaType.MD80:
+ dmns.Height = 68;
+
+ dmns.Width = 71.5;
+
+ dmns.Thickness = 4.8;
+
+ return dmns;
+ case MediaType.DAT160:
+ case MediaType.DAT320:
+ case MediaType.DAT72:
+ case MediaType.DDS1:
+ case MediaType.DDS2:
+ case MediaType.DDS3:
+ case MediaType.DDS4:
+ case MediaType.DigitalAudioTape:
+ dmns.Height = 54;
+
+ dmns.Width = 73;
+
+ dmns.Thickness = 10.5;
+
+ return dmns;
+ case MediaType.CompactFloppy:
+ dmns.Height = 100;
+
+ dmns.Width = 80;
+
+ dmns.Thickness = 5;
+
+ return dmns;
+ case MediaType.DECtapeII:
+ dmns.Height = 60;
+
+ dmns.Width = 81;
+
+ dmns.Thickness = 13;
+
+ return dmns;
+ case MediaType.Ditto:
+ dmns.Height = 60;
+
+ dmns.Width = 81;
+
+ dmns.Thickness = 14;
+
+ return dmns;
+ case MediaType.DittoMax:
+ dmns.Height = 126;
+
+ dmns.Width = 81;
+
+ dmns.Thickness = 14;
+
+ return dmns;
+ case MediaType.RDX:
+ case MediaType.RDX320:
+ dmns.Height = 119;
+
+ dmns.Width = 87;
+
+ dmns.Thickness = 23;
+
+ return dmns;
+ case MediaType.LS120:
+ case MediaType.LS240:
+ dmns.Height = 94;
+
+ dmns.Width = 90;
+
+ dmns.Thickness = 3.5;
+
+ return dmns;
+ case MediaType.Travan:
+ case MediaType.Travan3:
+ case MediaType.Travan4:
+ case MediaType.Travan5:
+ case MediaType.Travan7:
+ dmns.Height = 72;
+
+ dmns.Width = 92;
+
+ dmns.Thickness = 15;
+
+ return dmns;
+ case MediaType.Travan1Ex:
+ dmns.Height = 0;
+
+ dmns.Width = 92;
+
+ dmns.Thickness = 15;
+
+ return dmns;
+ case MediaType.Travan3Ex:
+ dmns.Height = 0;
+
+ dmns.Width = 92;
+
+ dmns.Thickness = 15;
+
+ return dmns;
+ case MediaType.ADR2120:
+ case MediaType.ADR260:
+ case MediaType.ADR30:
+ case MediaType.ADR50:
+ dmns.Height = 129;
+
+ dmns.Width = 93;
+
+ dmns.Thickness = 14.5;
+
+ return dmns;
+ case MediaType.Data8:
+ case MediaType.AIT1:
+ case MediaType.AIT1Turbo:
+ case MediaType.AIT2:
+ case MediaType.AIT2Turbo:
+ case MediaType.AIT3:
+ case MediaType.AIT3Ex:
+ case MediaType.AIT3Turbo:
+ case MediaType.AIT4:
+ case MediaType.AIT5:
+ case MediaType.AITETurbo:
+ case MediaType.Exatape106m:
+ case MediaType.Exatape160mXL:
+ case MediaType.Exatape112m:
+ case MediaType.Exatape125m:
+ case MediaType.Exatape150m:
+ case MediaType.Exatape15m:
+ case MediaType.Exatape170m:
+ case MediaType.Exatape225m:
+ case MediaType.Exatape22m:
+ case MediaType.Exatape22mAME:
+ case MediaType.Exatape28m:
+ case MediaType.Exatape40m:
+ case MediaType.Exatape45m:
+ case MediaType.Exatape54m:
+ case MediaType.Exatape75m:
+ case MediaType.Exatape76m:
+ case MediaType.Exatape80m:
+ dmns.Height = 62.5;
+
+ dmns.Width = 95;
+
+ dmns.Thickness = 15;
+
+ return dmns;
+ case MediaType.EZ135:
+ case MediaType.EZ230:
+ case MediaType.SQ327:
+ dmns.Height = 97;
+
+ dmns.Width = 98;
+
+ dmns.Thickness = 9.5;
+
+ return dmns;
+ case MediaType.SQ400:
+ case MediaType.SQ800:
+ case MediaType.SQ2000:
+ dmns.Height = 137;
+
+ dmns.Width = 137;
+
+ dmns.Thickness = 12;
+
+ return dmns;
+ case MediaType.ZIP100:
+ case MediaType.ZIP250:
+ case MediaType.ZIP750:
+ dmns.Height = 98.5;
+
+ dmns.Width = 98;
+
+ dmns.Thickness = 6.5;
+
+ return dmns;
+ case MediaType.Jaz:
+ case MediaType.Jaz2:
+ dmns.Height = 102;
+
+ dmns.Width = 98;
+
+ dmns.Thickness = 12;
+
+ return dmns;
+ case MediaType.Orb:
+ case MediaType.Orb5:
+ dmns.Height = 104;
+
+ dmns.Width = 98;
+
+ dmns.Thickness = 8;
+
+ return dmns;
+ case MediaType.SparQ:
+ dmns.Height = 98;
+
+ dmns.Width = 100;
+
+ dmns.Thickness = 9.7;
+
+ return dmns;
+ case MediaType.ProfessionalDisc:
+ case MediaType.ProfessionalDiscDual:
+ case MediaType.ProfessionalDiscTriple:
+ case MediaType.ProfessionalDiscQuad:
+ case MediaType.PDD:
+ case MediaType.PDD_WORM:
+ dmns.Height = 130;
+
+ dmns.Width = 128.5;
+
+ dmns.Thickness = 9;
+
+ return dmns;
+ case MediaType.SLR1:
+ case MediaType.SLR2:
+ case MediaType.SLR3:
+ case MediaType.SLR32:
+ case MediaType.SLR32SL:
+ case MediaType.SLR4:
+ case MediaType.SLR5:
+ case MediaType.SLR5SL:
+ case MediaType.SLR6:
+ case MediaType.SLRtape100:
+ case MediaType.SLRtape140:
+ case MediaType.SLRtape24:
+ case MediaType.SLRtape24SL:
+ case MediaType.SLRtape40:
+ case MediaType.SLRtape50:
+ case MediaType.SLRtape60:
+ case MediaType.SLRtape7:
+ case MediaType.SLRtape75:
+ case MediaType.SLRtape7SL:
+ dmns.Height = 150;
+
+ dmns.Width = 100;
+
+ dmns.Thickness = 18;
+
+ return dmns;
+ case MediaType.N64DD:
+ dmns.Height = 103.124;
+
+ dmns.Width = 101.092;
+
+ dmns.Thickness = 10.16;
+
+ return dmns;
+ case MediaType.CompactTapeI:
+ case MediaType.CompactTapeII:
+ case MediaType.DLTtapeIII:
+ case MediaType.DLTtapeIIIxt:
+ case MediaType.DLTtapeIV:
+ case MediaType.DLTtapeS4:
+ case MediaType.SDLT1:
+ case MediaType.SDLT2:
+ case MediaType.VStapeI:
+ dmns.Height = 105;
+
+ dmns.Width = 105;
+
+ dmns.Thickness = 25;
+
+ return dmns;
+ case MediaType.LTO:
+ case MediaType.LTO2:
+ case MediaType.LTO3:
+ case MediaType.LTO3WORM:
+ case MediaType.LTO4:
+ case MediaType.LTO4WORM:
+ case MediaType.LTO5:
+ case MediaType.LTO5WORM:
+ case MediaType.LTO6:
+ case MediaType.LTO6WORM:
+ case MediaType.LTO7:
+ case MediaType.LTO7WORM:
+ dmns.Height = 101.6;
+
+ dmns.Width = 105.41;
+
+ dmns.Thickness = 21.59;
+
+ return dmns;
+ case MediaType.IBM3480:
+ case MediaType.IBM3490:
+ case MediaType.IBM3490E:
+ case MediaType.IBM3592:
+ dmns.Height = 125.73;
+
+ dmns.Width = 107.95;
+
+ dmns.Thickness = 25.4;
+
+ return dmns;
+ case MediaType.T9840A:
+ case MediaType.T9840B:
+ case MediaType.T9840C:
+ case MediaType.T9840D:
+ case MediaType.T9940A:
+ case MediaType.T9940B:
+ dmns.Height = 124.46;
+
+ dmns.Width = 109.22;
+
+ dmns.Thickness = 25.4;
+
+ return dmns;
+ case MediaType.CompactCassette:
+ case MediaType.Dcas25:
+ case MediaType.Dcas85:
+ case MediaType.Dcas103:
+ dmns.Height = 63.5;
+
+ dmns.Width = 128;
+
+ dmns.Thickness = 12;
+
+ return dmns;
+ case MediaType.IBM3470:
+ dmns.Height = 58.42;
+
+ dmns.Width = 137.16;
+
+ dmns.Thickness = 16.51;
+
+ return dmns;
+ case MediaType.MLR1:
+ case MediaType.MLR3:
+ case MediaType.MLR1SL:
+ dmns.Height = 101.6;
+
+ dmns.Width = 152.4;
+
+ dmns.Thickness = 15.24;
+
+ return dmns;
+ case MediaType.QIC11:
+ case MediaType.QIC120:
+ case MediaType.QIC1350:
+ case MediaType.QIC150:
+ case MediaType.QIC24:
+ case MediaType.QIC525:
+ dmns.Height = 101.6;
+
+ dmns.Width = 154.2;
+
+ dmns.Thickness = 16.6;
+
+ return dmns;
+#pragma warning disable CS0612 // Type or member is obsolete
+ case MediaType.Bernoulli:
+#pragma warning restore CS0612 // Type or member is obsolete
+ case MediaType.Bernoulli10:
+ case MediaType.Bernoulli20:
+ dmns.Height = 280;
+
+ dmns.Width = 209;
+
+ dmns.Thickness = 18;
+
+ return dmns;
+#pragma warning disable CS0612 // Type or member is obsolete
+ case MediaType.Bernoulli2:
+#pragma warning restore CS0612 // Type or member is obsolete
+ case MediaType.BernoulliBox2_20:
+ case MediaType.Bernoulli35:
+ case MediaType.Bernoulli44:
+ case MediaType.Bernoulli65:
+ case MediaType.Bernoulli90:
+ case MediaType.Bernoulli105:
+ case MediaType.Bernoulli150:
+ case MediaType.Bernoulli230:
+ dmns.Height = 138;
+
+ dmns.Width = 136;
+
+ dmns.Thickness = 9;
+
+ return dmns;
+ case MediaType.DTF:
+ case MediaType.DTF2:
+ dmns.Height = 144.78;
+
+ dmns.Width = 254;
+
+ dmns.Thickness = 25.4;
+
+ return dmns;
+ case MediaType.LD:
+ case MediaType.LDROM:
+ case MediaType.LDROM2:
+ case MediaType.MegaLD:
+ case MediaType.LVROM:
+ dmns.Diameter = 300;
+
+ dmns.Thickness = 2.5;
+
+ return dmns;
+ case MediaType.CRVdisc:
+ dmns.Height = 344;
+
+ dmns.Width = 325;
+
+ dmns.Thickness = 15.6;
+
+ return dmns;
+ case MediaType.REV35:
+ case MediaType.REV70:
+ case MediaType.REV120:
+ dmns.Height = 74.8;
+
+ dmns.Width = 76.8;
+
+ dmns.Thickness = 10;
+
+ return dmns;
+
+#region CD/DVD/BD
+
+ case MediaType.CDDA:
+ case MediaType.CDG:
+ case MediaType.CDEG:
+ case MediaType.CDI:
+ case MediaType.CDROM:
+ case MediaType.CDROMXA:
+ case MediaType.CDPLUS:
+ case MediaType.CDMO:
+ case MediaType.CDR:
+ case MediaType.CDRW:
+ case MediaType.CDMRW:
+ case MediaType.VCD:
+ case MediaType.SVCD:
+ case MediaType.PCD:
+ case MediaType.SACD:
+ case MediaType.DDCD:
+ case MediaType.DDCDR:
+ case MediaType.DDCDRW:
+ case MediaType.DTSCD:
+ case MediaType.CDMIDI:
+ case MediaType.CDV:
+ case MediaType.CD:
+ case MediaType.DVDROM:
+ case MediaType.DVDR:
+ case MediaType.DVDRW:
+ case MediaType.DVDPR:
+ case MediaType.DVDPRW:
+ case MediaType.DVDPRWDL:
+ case MediaType.DVDRDL:
+ case MediaType.DVDPRDL:
+ case MediaType.DVDRAM:
+ case MediaType.DVDRWDL:
+ case MediaType.DVDDownload:
+ case MediaType.HDDVDROM:
+ case MediaType.HDDVDRAM:
+ case MediaType.HDDVDR:
+ case MediaType.HDDVDRW:
+ case MediaType.HDDVDRDL:
+ case MediaType.HDDVDRWDL:
+ case MediaType.BDROM:
+ case MediaType.BDR:
+ case MediaType.BDRE:
+ case MediaType.BDRXL:
+ case MediaType.BDREXL:
+ case MediaType.PS1CD:
+ case MediaType.PS2CD:
+ case MediaType.PS2DVD:
+ case MediaType.PS3DVD:
+ case MediaType.PS3BD:
+ case MediaType.PS4BD:
+ case MediaType.PS5BD:
+ case MediaType.XGD:
+ case MediaType.XGD2:
+ case MediaType.XGD3:
+ case MediaType.XGD4:
+ case MediaType.MEGACD:
+ case MediaType.SATURNCD:
+ case MediaType.GDROM:
+ case MediaType.GDR:
+ case MediaType.SuperCDROM2:
+ case MediaType.JaguarCD:
+ case MediaType.ThreeDO:
+ case MediaType.WOD:
+ case MediaType.WUOD:
+ case MediaType.PCFX:
+ case MediaType.CDIREADY:
+ case MediaType.FMTOWNS:
+ case MediaType.CDTV:
+ case MediaType.CD32:
+ case MediaType.Nuon:
+ case MediaType.Playdia:
+ case MediaType.Pippin:
+ case MediaType.MilCD:
+ case MediaType.CVD:
+ case MediaType.UHDBD:
+ dmns.Diameter = 120;
+
+ dmns.Thickness = 1.2;
+
+ return dmns;
+ case MediaType.GOD:
+ dmns.Diameter = 80;
+
+ dmns.Thickness = 1.2;
+
+ return dmns;
+ case MediaType.VideoNow:
+ dmns.Diameter = 85;
+
+ dmns.Thickness = 1.2;
+
+ return dmns;
+ case MediaType.VideoNowColor:
+ case MediaType.VideoNowXp:
+ dmns.Diameter = 108;
+
+ dmns.Thickness = 1.2;
+
+ return dmns;
+
+#endregion CD/DVD/BD
+
+#region Apple Hard Disks
+
+ // TODO: Find Apple Widget size
+ case MediaType.AppleProfile:
+ dmns.Height = 223.8;
+
+ dmns.Width = 438.9;
+
+ dmns.Thickness = 111.5;
+
+ return dmns;
+ case MediaType.AppleHD20:
+ dmns.Height = 246.4;
+
+ dmns.Width = 266.7;
+
+ dmns.Thickness = 78.7;
+
+ return dmns;
+
+#endregion Apple Hard Disks
+
+ case MediaType.UMD:
+ dmns.Height = 64;
+
+ dmns.Width = 63;
+
+ dmns.Thickness = 4;
+
+ return dmns;
+ case MediaType.HF12:
+ case MediaType.HF24:
+ dmns.Height = 137.5;
+
+ dmns.Width = 135.9;
+
+ dmns.Thickness = 5.64;
+
+ return dmns;
+ default:
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/Dump.cs b/Aaru.CommonTypes/AaruMetadata/Dump.cs
new file mode 100644
index 000000000..449050fe7
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/Dump.cs
@@ -0,0 +1,149 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Dump.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using Schemas;
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+public class Image
+{
+ public string Format { get; set; }
+ public ulong? Offset { get; set; }
+ public string Value { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator Image(ImageType cicm) => cicm is null
+ ? null
+ : new Image
+ {
+ Format = cicm.format,
+ Offset = cicm.offsetSpecified ? cicm.offset : null,
+ Value = cicm.Value
+ };
+}
+
+public class Dump
+{
+ public string Image { get; set; }
+ public ulong Size { get; set; }
+ public List Checksums { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator Dump(DumpType cicm)
+ {
+ if(cicm is null) return null;
+
+ Dump dump = new()
+ {
+ Image = cicm.Image,
+ Size = cicm.Size
+ };
+
+ if(cicm.Checksums is null) return dump;
+
+ dump.Checksums = [];
+
+ foreach(Schemas.ChecksumType chk in cicm.Checksums) dump.Checksums.Add(chk);
+
+ return dump;
+ }
+}
+
+public class Border
+{
+ public string Image { get; set; }
+ public ulong Size { get; set; }
+ public List Checksums { get; set; }
+ public uint? Session { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator Border(BorderType cicm)
+ {
+ if(cicm is null) return null;
+
+ var border = new Border
+ {
+ Image = cicm.Image,
+ Size = cicm.Size,
+ Session = cicm.sessionSpecified ? cicm.session : null
+ };
+
+ if(cicm.Checksums is null) return border;
+
+ border.Checksums = [];
+
+ foreach(Schemas.ChecksumType chk in cicm.Checksums) border.Checksums.Add(chk);
+
+ return border;
+ }
+}
+
+public class File
+{
+ public string Format { get; set; }
+ public string Value { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator File(FileType cicm) => cicm is null
+ ? null
+ : new File
+ {
+ Format = cicm.format,
+ Value = cicm.Value
+ };
+}
+
+public class BlockSize
+{
+ public uint StartingBlock { get; set; }
+ public uint Value { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator BlockSize(BlockSizeType cicm) => cicm is null
+ ? null
+ : new BlockSize
+ {
+ StartingBlock = cicm.startingBlock,
+ Value = cicm.Value
+ };
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/DumpHardware.cs b/Aaru.CommonTypes/AaruMetadata/DumpHardware.cs
new file mode 100644
index 000000000..628956220
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/DumpHardware.cs
@@ -0,0 +1,113 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : DumpHardware.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using Schemas;
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+public class DumpHardware
+{
+ public string Manufacturer { get; set; }
+ public string Model { get; set; }
+ public string Revision { get; set; }
+ public string Firmware { get; set; }
+ public string Serial { get; set; }
+ public List Extents { get; set; }
+ public Software Software { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator DumpHardware(DumpHardwareType cicm)
+ {
+ if(cicm is null) return null;
+
+ var hw = new DumpHardware
+ {
+ Manufacturer = cicm.Manufacturer,
+ Model = cicm.Model,
+ Revision = cicm.Revision,
+ Firmware = cicm.Firmware,
+ Serial = cicm.Serial,
+ Software = cicm.Software
+ };
+
+ if(cicm.Extents is null) return hw;
+
+ hw.Extents = [];
+
+ foreach(ExtentType ext in cicm.Extents) hw.Extents.Add(ext);
+
+ return hw;
+ }
+}
+
+public class Extent
+{
+ public ulong Start { get; set; }
+ public ulong End { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator Extent(ExtentType cicm) => cicm is null
+ ? null
+ : new Extent
+ {
+ Start = cicm.Start,
+ End = cicm.End
+ };
+}
+
+public class Software
+{
+ public string Name { get; set; }
+ public string Version { get; set; }
+ public string OperatingSystem { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator Software(SoftwareType cicm) => cicm is null
+ ? null
+ : new Software
+ {
+ Name = cicm.Name,
+ Version = cicm.Version,
+ OperatingSystem = cicm.OperatingSystem
+ };
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/FileSystem.cs b/Aaru.CommonTypes/AaruMetadata/FileSystem.cs
new file mode 100644
index 000000000..4bc5195ae
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/FileSystem.cs
@@ -0,0 +1,121 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : FileSystem.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using Schemas;
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+public class FileSystem
+{
+ public string Type { get; set; }
+ public DateTime? CreationDate { get; set; }
+ public DateTime? ModificationDate { get; set; }
+ public DateTime? BackupDate { get; set; }
+ public uint ClusterSize { get; set; }
+ public ulong Clusters { get; set; }
+ public ulong? Files { get; set; }
+ public bool Bootable { get; set; }
+ public string VolumeSerial { get; set; }
+ public string VolumeName { get; set; }
+ public ulong? FreeClusters { get; set; }
+ public bool Dirty { get; set; }
+ public DateTime? ExpirationDate { get; set; }
+ public DateTime? EffectiveDate { get; set; }
+ public string SystemIdentifier { get; set; }
+ public string VolumeSetIdentifier { get; set; }
+ public string PublisherIdentifier { get; set; }
+ public string DataPreparerIdentifier { get; set; }
+ public string ApplicationIdentifier { get; set; }
+ public FilesystemContents Contents { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator FileSystem(FileSystemType cicm) => cicm is null
+ ? null
+ : new FileSystem
+ {
+ Type = cicm.Type,
+ CreationDate =
+ cicm.CreationDateSpecified
+ ? cicm.CreationDate
+ : null,
+ ModificationDate =
+ cicm.ModificationDateSpecified
+ ? cicm.ModificationDate
+ : null,
+ BackupDate =
+ cicm.BackupDateSpecified
+ ? cicm.BackupDate
+ : null,
+ ClusterSize = cicm.ClusterSize,
+ Clusters = cicm.Clusters,
+ Files =
+ cicm.FilesSpecified
+ ? cicm.Files
+ : null,
+ Bootable = cicm.Bootable,
+ VolumeSerial = cicm.VolumeSerial,
+ VolumeName = cicm.VolumeName,
+ FreeClusters =
+ cicm.FreeClustersSpecified
+ ? cicm.FreeClusters
+ : null,
+ Dirty = cicm.Dirty,
+ ExpirationDate =
+ cicm.ExpirationDateSpecified
+ ? cicm.ExpirationDate
+ : null,
+ EffectiveDate =
+ cicm.EffectiveDateSpecified
+ ? cicm.EffectiveDate
+ : null,
+ SystemIdentifier = cicm.SystemIdentifier,
+ VolumeSetIdentifier =
+ cicm.VolumeSetIdentifier,
+ PublisherIdentifier =
+ cicm.PublisherIdentifier,
+ DataPreparerIdentifier =
+ cicm.DataPreparerIdentifier,
+ ApplicationIdentifier =
+ cicm.ApplicationIdentifier,
+ Contents = cicm.Contents
+ };
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/Language.cs b/Aaru.CommonTypes/AaruMetadata/Language.cs
new file mode 100644
index 000000000..de72d894a
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/Language.cs
@@ -0,0 +1,538 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Language.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System.Diagnostics.CodeAnalysis;
+using System.Text.Json.Serialization;
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+[JsonConverter(typeof(JsonStringEnumMemberConverter))]
+[SuppressMessage("ReSharper", "InconsistentNaming")]
+public enum Language
+{
+ aar,
+ abk,
+ ace,
+ ach,
+ ada,
+ ady,
+ afa,
+ afh,
+ afr,
+ ain,
+ aka,
+ akk,
+ alb,
+ ale,
+ alg,
+ alt,
+ amh,
+ ang,
+ anp,
+ apa,
+ ara,
+ arc,
+ arg,
+ arm,
+ arn,
+ arp,
+ art,
+ arw,
+ asm,
+ ast,
+ ath,
+ aus,
+ ava,
+ ave,
+ awa,
+ aym,
+ aze,
+ bad,
+ bai,
+ bak,
+ bal,
+ bam,
+ ban,
+ baq,
+ bas,
+ bat,
+ bej,
+ bel,
+ bem,
+ ben,
+ ber,
+ bho,
+ bih,
+ bik,
+ bin,
+ bis,
+ bla,
+ bnt,
+ bos,
+ bra,
+ bre,
+ btk,
+ bua,
+ bug,
+ bul,
+ bur,
+ byn,
+ cad,
+ cai,
+ car,
+ cat,
+ cau,
+ ceb,
+ cel,
+ cha,
+ chb,
+ che,
+ chg,
+ chi,
+ chk,
+ chm,
+ chn,
+ cho,
+ chp,
+ chr,
+ chu,
+ chv,
+ chy,
+ cmc,
+ cop,
+ cor,
+ cos,
+ cpe,
+ cpf,
+ cpp,
+ cre,
+ crh,
+ crp,
+ csb,
+ cus,
+ cze,
+ dak,
+ dan,
+ dar,
+ day,
+ del,
+ den,
+ dgr,
+ din,
+ div,
+ doi,
+ dra,
+ dsb,
+ dua,
+ dum,
+ dut,
+ dyu,
+ dzo,
+ efi,
+ egy,
+ eka,
+ elx,
+ eng,
+ enm,
+ epo,
+ est,
+ ewe,
+ ewo,
+ fan,
+ fao,
+ fat,
+ fij,
+ fil,
+ fin,
+ fiu,
+ fon,
+ fre,
+ frm,
+ fro,
+ frr,
+ frs,
+ fry,
+ ful,
+ fur,
+ gaa,
+ gay,
+ gba,
+ gem,
+ geo,
+ ger,
+ gez,
+ gil,
+ gla,
+ gle,
+ glg,
+ glv,
+ gmh,
+ goh,
+ gon,
+ gor,
+ got,
+ grb,
+ grc,
+ gre,
+ grn,
+ gsw,
+ guj,
+ gwi,
+ hai,
+ hat,
+ hau,
+ haw,
+ heb,
+ her,
+ hil,
+ him,
+ hin,
+ hit,
+ hmn,
+ hmo,
+ hrv,
+ hsb,
+ hun,
+ hup,
+ iba,
+ ibo,
+ ice,
+ ido,
+ iii,
+ ijo,
+ iku,
+ ile,
+ ilo,
+ ina,
+ inc,
+ ind,
+ ine,
+ inh,
+ ipk,
+ ira,
+ iro,
+ ita,
+ jav,
+ jbo,
+ jpn,
+ jpr,
+ jrb,
+ kaa,
+ kab,
+ kac,
+ kal,
+ kam,
+ kan,
+ kar,
+ kas,
+ kau,
+ kaw,
+ kaz,
+ kbd,
+ kha,
+ khi,
+ khm,
+ kho,
+ kik,
+ kin,
+ kir,
+ kmb,
+ kok,
+ kom,
+ kon,
+ kor,
+ kos,
+ kpe,
+ krc,
+ krl,
+ kro,
+ kru,
+ kua,
+ kum,
+ kur,
+ kut,
+ lad,
+ lah,
+ lam,
+ lao,
+ lat,
+ lav,
+ lez,
+ lim,
+ lin,
+ lit,
+ lol,
+ loz,
+ ltz,
+ lua,
+ lub,
+ lug,
+ lui,
+ lun,
+ luo,
+ lus,
+ mac,
+ mad,
+ mag,
+ mah,
+ mai,
+ mak,
+ mal,
+ man,
+ mao,
+ map,
+ mar,
+ mas,
+ may,
+ mdf,
+ mdr,
+ men,
+ mga,
+ mic,
+ min,
+ mis,
+ mkh,
+ mlg,
+ mlt,
+ mnc,
+ mni,
+ mno,
+ moh,
+ mon,
+ mos,
+ mul,
+ mun,
+ mus,
+ mwl,
+ mwr,
+ myn,
+ myv,
+ nah,
+ nai,
+ nap,
+ nau,
+ nav,
+ nbl,
+ nde,
+ ndo,
+ nds,
+ nep,
+ @new,
+ nia,
+ nic,
+ niu,
+ nno,
+ nob,
+ nog,
+ non,
+ nor,
+ nqo,
+ nso,
+ nub,
+ nwc,
+ nya,
+ nym,
+ nyn,
+ nyo,
+ nzi,
+ oci,
+ oji,
+ ori,
+ orm,
+ osa,
+ oss,
+ ota,
+ oto,
+ paa,
+ pag,
+ pal,
+ pam,
+ pan,
+ pap,
+ pau,
+ peo,
+ per,
+ phi,
+ phn,
+ pli,
+ pol,
+ pon,
+ por,
+ pra,
+ pro,
+ pus,
+ [JsonPropertyName("qaa-qtz")]
+ qaaqtz,
+ que,
+ raj,
+ rap,
+ rar,
+ roa,
+ roh,
+ rom,
+ rum,
+ run,
+ rup,
+ rus,
+ sad,
+ sag,
+ sah,
+ sai,
+ sal,
+ sam,
+ san,
+ sas,
+ sat,
+ scn,
+ sco,
+ sel,
+ sem,
+ sga,
+ sgn,
+ shn,
+ sid,
+ sin,
+ sio,
+ sit,
+ sla,
+ slo,
+ slv,
+ sma,
+ sme,
+ smi,
+ smj,
+ smn,
+ smo,
+ sms,
+ sna,
+ snd,
+ snk,
+ sog,
+ som,
+ son,
+ sot,
+ spa,
+ srd,
+ srn,
+ srp,
+ srr,
+ ssa,
+ ssw,
+ suk,
+ sun,
+ sus,
+ sux,
+ swa,
+ swe,
+ syc,
+ syr,
+ tah,
+ tai,
+ tam,
+ tat,
+ tel,
+ tem,
+ ter,
+ tet,
+ tgk,
+ tgl,
+ tha,
+ tib,
+ tig,
+ tir,
+ tiv,
+ tkl,
+ tlh,
+ tli,
+ tmh,
+ tog,
+ ton,
+ tpi,
+ tsi,
+ tsn,
+ tso,
+ tuk,
+ tum,
+ tup,
+ tur,
+ tut,
+ tvl,
+ twi,
+ tyv,
+ udm,
+ uga,
+ uig,
+ ukr,
+ umb,
+ und,
+ urd,
+ uzb,
+ vai,
+ ven,
+ vie,
+ vol,
+ vot,
+ wak,
+ wal,
+ war,
+ was,
+ wel,
+ wen,
+ wln,
+ wol,
+ xal,
+ xho,
+ yao,
+ yap,
+ yid,
+ yor,
+ ypk,
+ zap,
+ zbl,
+ zen,
+ zgh,
+ zha,
+ znd,
+ zul,
+ zun,
+ zxx,
+ zza
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/Layers.cs b/Aaru.CommonTypes/AaruMetadata/Layers.cs
new file mode 100644
index 000000000..ef0e4fe76
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/Layers.cs
@@ -0,0 +1,114 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Layers.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Text.Json.Serialization;
+using Schemas;
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+public class Layers
+{
+ public List Sectors { get; set; }
+ public LayerType? Type { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator Layers(LayersType cicm)
+ {
+ if(cicm is null) return null;
+
+ var layers = new Layers
+ {
+ Type = cicm.typeSpecified ? (LayerType)cicm.type : null
+ };
+
+ if(cicm.Sectors is null) return layers;
+
+ layers.Sectors = [];
+
+ foreach(SectorsType sec in cicm.Sectors) layers.Sectors.Add(sec);
+
+ return layers;
+ }
+}
+
+[SuppressMessage("ReSharper", "InconsistentNaming")]
+[JsonConverter(typeof(JsonStringEnumMemberConverter))]
+public enum LayerType
+{
+ PTP,
+ OTP
+}
+
+public class LayeredText
+{
+ public uint? Layer { get; set; }
+ public string Text { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator LayeredText(LayeredTextType cicm) => cicm is null
+ ? null
+ : new LayeredText
+ {
+ Layer = cicm.layerSpecified
+ ? cicm.layer
+ : null,
+ Text = cicm.Value
+ };
+}
+
+public class Sectors
+{
+ public uint? Layer { get; set; }
+ public ulong Value { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator Sectors(SectorsType cicm) => cicm is null
+ ? null
+ : new Sectors
+ {
+ Layer =
+ cicm.layerSpecified ? cicm.layer : null,
+ Value = cicm.Value
+ };
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/LinearMedia.cs b/Aaru.CommonTypes/AaruMetadata/LinearMedia.cs
new file mode 100644
index 000000000..68cacc6bc
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/LinearMedia.cs
@@ -0,0 +1,117 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : LinearMedia.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using Schemas;
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+public class LinearMedia
+{
+ public Image Image { get; set; }
+ public ulong Size { get; set; }
+ public List ImageChecksums { get; set; }
+ public List Checksums { get; set; }
+ public string PartNumber { get; set; }
+ public string SerialNumber { get; set; }
+ public string Title { get; set; }
+ public uint? Sequence { get; set; }
+ public uint? ImageInterleave { get; set; }
+ public uint? Interleave { get; set; }
+ public string Manufacturer { get; set; }
+ public string Model { get; set; }
+ public string Package { get; set; }
+ public string Interface { get; set; }
+ public Dimensions Dimensions { get; set; }
+ public Scans Scans { get; set; }
+ public List DumpHardware { get; set; }
+ public Pcmcia Pcmcia { get; set; }
+ public string CopyProtection { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator LinearMedia(LinearMediaType cicm)
+ {
+ if(cicm is null) return null;
+
+ var linearMedia = new LinearMedia
+ {
+ Image = cicm.Image,
+ Size = cicm.Size,
+ PartNumber = cicm.PartNumber,
+ SerialNumber = cicm.SerialNumber,
+ Title = cicm.Title,
+ Sequence = cicm.SequenceSpecified ? cicm.Sequence : null,
+ ImageInterleave = cicm.ImageInterleaveSpecified ? cicm.ImageInterleave : null,
+ Interleave = cicm.InterleaveSpecified ? cicm.Interleave : null,
+ Manufacturer = cicm.Manufacturer,
+ Model = cicm.Model,
+ Package = cicm.Package,
+ Interface = cicm.Interface,
+ Dimensions = cicm.Dimensions,
+ Scans = cicm.Scans,
+ Pcmcia = cicm.PCMCIA,
+ CopyProtection = cicm.CopyProtection
+ };
+
+ if(cicm.ImageChecksums is not null)
+ {
+ linearMedia.ImageChecksums = [];
+
+ foreach(Schemas.ChecksumType chk in cicm.ImageChecksums) linearMedia.ImageChecksums.Add(chk);
+ }
+
+ if(cicm.Checksums is not null)
+ {
+ linearMedia.Checksums = [];
+
+ foreach(Schemas.ChecksumType chk in cicm.Checksums) linearMedia.Checksums.Add(chk);
+ }
+
+ if(cicm.DumpHardwareArray is null) return linearMedia;
+
+ linearMedia.DumpHardware = [];
+
+ foreach(DumpHardwareType hw in cicm.DumpHardwareArray) linearMedia.DumpHardware.Add(hw);
+
+ return linearMedia;
+ }
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/Magazine.cs b/Aaru.CommonTypes/AaruMetadata/Magazine.cs
new file mode 100644
index 000000000..dc7c99bbd
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/Magazine.cs
@@ -0,0 +1,90 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : Magazine.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using Schemas;
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+public class Magazine
+{
+ public List Barcodes { get; set; }
+ public Cover Cover { get; set; }
+ public string Name { get; set; }
+ public string Editorial { get; set; }
+ public DateTime? PublicationDate { get; set; }
+ public uint? Number { get; set; }
+ public List Languages { get; set; }
+ public uint? Pages { get; set; }
+ public string PageSize { get; set; }
+ public Scan Scan { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator Magazine(MagazineType cicm)
+ {
+ if(cicm is null) return null;
+
+ var magazine = new Magazine
+ {
+ Cover = cicm.Cover,
+ Name = cicm.Name,
+ Editorial = cicm.Editorial,
+ PublicationDate = cicm.PublicationDateSpecified ? cicm.PublicationDate : null,
+ Number = cicm.NumberSpecified ? cicm.Number : null,
+ Pages = cicm.PagesSpecified ? cicm.Pages : null,
+ Scan = cicm.Scan
+ };
+
+ if(cicm.Barcodes is not null)
+ {
+ magazine.Barcodes = [];
+
+ foreach(Schemas.BarcodeType code in cicm.Barcodes) magazine.Barcodes.Add(code);
+ }
+
+ if(cicm.Language is null) return magazine;
+
+ foreach(LanguagesTypeLanguage lng in cicm.Language) magazine.Languages.Add((Language)lng);
+
+ return magazine;
+ }
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/MultiMediaCard.cs b/Aaru.CommonTypes/AaruMetadata/MultiMediaCard.cs
new file mode 100644
index 000000000..936d0ab08
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/MultiMediaCard.cs
@@ -0,0 +1,64 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : MultiMediaCard.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+using System;
+using Schemas;
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+public class MultiMediaCard
+{
+ public Dump CID { get; set; }
+ public Dump CSD { get; set; }
+ public Dump ExtendedCSD { get; set; }
+ public Dump OCR { get; set; }
+
+ [Obsolete("Will be removed in Aaru 7")]
+ public static implicit operator MultiMediaCard(MultiMediaCardType cicm) => cicm is null
+ ? null
+ : new MultiMediaCard
+ {
+ CSD = cicm.CSD,
+ CID = cicm.CID,
+ ExtendedCSD = cicm.ExtendedCSD,
+ OCR = cicm.OCR
+ };
+}
\ No newline at end of file
diff --git a/Aaru.CommonTypes/AaruMetadata/OpticalDisc.cs b/Aaru.CommonTypes/AaruMetadata/OpticalDisc.cs
new file mode 100644
index 000000000..6afca5f5d
--- /dev/null
+++ b/Aaru.CommonTypes/AaruMetadata/OpticalDisc.cs
@@ -0,0 +1,377 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Filename : OpticalDisc.cs
+// Author(s) : Natalia Portillo
+//
+// Component : Metadata.
+//
+// --[ Description ] ----------------------------------------------------------
+//
+// Defines format for metadata.
+//
+// --[ License ] --------------------------------------------------------------
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2024 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Text.Json.Serialization;
+using Schemas;
+
+// ReSharper disable UnusedMember.Global
+// ReSharper disable ClassNeverInstantiated.Global
+
+namespace Aaru.CommonTypes.AaruMetadata;
+
+public class OpticalDisc
+{
+ public Image Image { get; set; }
+ public ulong Size { get; set; }
+ public Sequence Sequence { get; set; }
+ public Layers Layers { get; set; }
+ public List Checksums { get; set; }
+ public string PartNumber { get; set; }
+ public string SerialNumber { get; set; }
+ public List RingCode { get; set; }
+ public List MasteringSid { get; set; }
+ public List Toolstamp { get; set; }
+ public List MouldSid { get; set; }
+ public List MouldText { get; set; }
+ public string DiscType { get; set; }
+ public string DiscSubType { get; set; }
+ public int? Offset { get; set; }
+ public uint[] Tracks { get; set; }
+ public uint Sessions { get; set; }
+ public string CopyProtection { get; set; }
+ public Dimensions Dimensions { get; set; }
+ public Case Case { get; set; }
+ public Scans Scans { get; set; }
+ public Dump Pfi { get; set; }
+ public Dump Dmi { get; set; }
+ public Dump Cmi { get; set; }
+ public Dump Bca { get; set; }
+ public Dump Atip { get; set; }
+ public Dump Adip { get; set; }
+ public Dump Pma { get; set; }
+ public Dump Dds { get; set; }
+ public Dump Sai { get; set; }
+ public Dump LastRmd { get; set; }
+ public Dump Pri { get; set; }
+ public Dump MediaID { get; set; }
+ public Dump Pfir { get; set; }
+ public Dump Dcb { get; set; }
+ public Dump Di { get; set; }
+ public Dump Pac { get; set; }
+ public Dump Toc { get; set; }
+ public Dump LeadInCdText { get; set; }
+ public List