diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..28ede258
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,543 @@
+# Version: 2.0.1 (Using https://semver.org/)
+# Updated: 2020-12-11
+# See https://github.com/RehanSaeed/EditorConfig/releases for release notes.
+# See https://github.com/RehanSaeed/EditorConfig for updates to this file.
+# See http://EditorConfig.org for more information about .editorconfig files.
+
+##########################################
+# Common Settings
+##########################################
+
+# This file is the top-most EditorConfig file
+root = true
+
+# All Files
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 4
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+##########################################
+# File Extension Settings
+##########################################
+
+# Visual Studio Solution Files
+[*.sln]
+indent_style = tab
+
+# Visual Studio XML Project Files
+[*.{csproj,vbproj,vcxproj.filters,proj,projitems,shproj}]
+indent_size = 2
+
+# XML Configuration Files
+[*.{xml,config,props,targets,nuspec,resx,ruleset,vsixmanifest,vsct}]
+indent_size = 2
+
+# JSON Files
+[*.{json,json5,webmanifest}]
+indent_size = 2
+
+# YAML Files
+[*.{yml,yaml}]
+indent_size = 2
+
+# Markdown Files
+[*.md]
+trim_trailing_whitespace = false
+
+# Web Files
+[*.{htm,html,js,jsm,ts,tsx,css,sass,scss,less,svg,vue}]
+indent_size = 2
+
+# Batch Files
+[*.{cmd,bat}]
+end_of_line = crlf
+
+# Bash Files
+[*.sh]
+end_of_line = lf
+
+# Makefiles
+[Makefile]
+indent_style = tab
+
+##########################################
+# Default .NET Code Style Severities
+# https://docs.microsoft.com/dotnet/fundamentals/code-analysis/configuration-options#scope
+##########################################
+
+[*.{cs,csx,cake,vb,vbx}]
+# Default Severity for all .NET Code Style rules below
+dotnet_analyzer_diagnostic.severity = warning
+
+##########################################
+# File Header (Uncomment to support file headers)
+# https://docs.microsoft.com/visualstudio/ide/reference/add-file-header
+##########################################
+
+# [*.{cs,csx,cake,vb,vbx}]
+# file_header_template = \n© PROJECT-AUTHOR\n
+
+# SA1636: File header copyright text should match
+# Justification: .editorconfig supports file headers. If this is changed to a value other than "none", a stylecop.json file will need to added to the project.
+# dotnet_diagnostic.SA1636.severity = none
+
+##########################################
+# .NET Language Conventions
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions
+##########################################
+
+# .NET Code Style Settings
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#net-code-style-settings
+[*.{cs,csx,cake,vb,vbx}]
+# "this." and "Me." qualifiers
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#this-and-me
+#dotnet_style_qualification_for_field = true:warning
+#dotnet_style_qualification_for_property = true:warning
+#dotnet_style_qualification_for_method = true:warning
+#dotnet_style_qualification_for_event = true:warning
+# Language keywords instead of framework type names for type references
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#language-keywords
+dotnet_style_predefined_type_for_locals_parameters_members = true:warning
+dotnet_style_predefined_type_for_member_access = true:warning
+# Modifier preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#normalize-modifiers
+dotnet_style_require_accessibility_modifiers = always:warning
+csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:warning
+visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:warning
+dotnet_style_readonly_field = true:warning
+# Parentheses preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#parentheses-preferences
+dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:warning
+dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:warning
+dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:warning
+dotnet_style_parentheses_in_other_operators = always_for_clarity:suggestion
+# Expression-level preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#expression-level-preferences
+dotnet_style_object_initializer = true:warning
+dotnet_style_collection_initializer = true:warning
+dotnet_style_explicit_tuple_names = true:warning
+dotnet_style_prefer_inferred_tuple_names = true:warning
+dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
+dotnet_style_prefer_auto_properties = true:warning
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning
+dotnet_style_prefer_conditional_expression_over_assignment = false:suggestion
+dotnet_diagnostic.IDE0045.severity = suggestion
+dotnet_style_prefer_conditional_expression_over_return = false:suggestion
+dotnet_diagnostic.IDE0046.severity = suggestion
+dotnet_style_prefer_compound_assignment = true:warning
+# Null-checking preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#null-checking-preferences
+dotnet_style_coalesce_expression = true:warning
+dotnet_style_null_propagation = true:warning
+# Parameter preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#parameter-preferences
+dotnet_code_quality_unused_parameters = all:warning
+# More style options (Undocumented)
+# https://github.com/MicrosoftDocs/visualstudio-docs/issues/3641
+dotnet_style_operator_placement_when_wrapping = end_of_line
+# https://github.com/dotnet/roslyn/pull/40070
+dotnet_style_prefer_simplified_interpolation = true:warning
+
+# C# Code Style Settings
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#c-code-style-settings
+[*.{cs,csx,cake}]
+# Implicit and explicit types
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#implicit-and-explicit-types
+csharp_style_var_for_built_in_types = true:warning
+csharp_style_var_when_type_is_apparent = true:warning
+csharp_style_var_elsewhere = true:warning
+# Expression-bodied members
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#expression-bodied-members
+csharp_style_expression_bodied_methods = true:warning
+csharp_style_expression_bodied_constructors = true:warning
+csharp_style_expression_bodied_operators = true:warning
+csharp_style_expression_bodied_properties = true:warning
+csharp_style_expression_bodied_indexers = true:warning
+csharp_style_expression_bodied_accessors = true:warning
+csharp_style_expression_bodied_lambdas = true:warning
+csharp_style_expression_bodied_local_functions = true:warning
+# Pattern matching
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#pattern-matching
+csharp_style_pattern_matching_over_is_with_cast_check = true:warning
+csharp_style_pattern_matching_over_as_with_null_check = true:warning
+# Inlined variable declarations
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#inlined-variable-declarations
+csharp_style_inlined_variable_declaration = true:warning
+# Expression-level preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#expression-level-preferences
+csharp_prefer_simple_default_expression = true:warning
+# "Null" checking preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#c-null-checking-preferences
+csharp_style_throw_expression = true:warning
+csharp_style_conditional_delegate_call = true:warning
+# Code block preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#code-block-preferences
+csharp_prefer_braces = true:warning
+# Unused value preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#unused-value-preferences
+csharp_style_unused_value_expression_statement_preference = discard_variable:suggestion
+dotnet_diagnostic.IDE0058.severity = suggestion
+csharp_style_unused_value_assignment_preference = discard_variable:suggestion
+dotnet_diagnostic.IDE0059.severity = suggestion
+# Index and range preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#index-and-range-preferences
+csharp_style_prefer_index_operator = true:warning
+csharp_style_prefer_range_operator = true:warning
+# Miscellaneous preferences
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#miscellaneous-preferences
+csharp_style_deconstructed_variable_declaration = true:warning
+csharp_style_pattern_local_over_anonymous_function = true:warning
+csharp_using_directive_placement = outside_namespace:warning
+csharp_prefer_static_local_function = true:warning
+csharp_prefer_simple_using_statement = true:suggestion
+dotnet_diagnostic.IDE0063.severity = suggestion
+
+csharp_style_namespace_declarations = file_scoped
+
+##########################################
+# .NET Formatting Conventions
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-code-style-settings-reference#formatting-conventions
+##########################################
+
+# Organize usings
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#organize-using-directives
+dotnet_sort_system_directives_first = true
+# Newline options
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#new-line-options
+csharp_new_line_before_open_brace = all
+csharp_new_line_before_else = true
+csharp_new_line_before_catch = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_between_query_expression_clauses = true
+# Indentation options
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#indentation-options
+csharp_indent_case_contents = true
+csharp_indent_switch_labels = true
+csharp_indent_labels = no_change
+csharp_indent_block_contents = true
+csharp_indent_braces = false
+csharp_indent_case_contents_when_block = false
+# Spacing options
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#spacing-options
+csharp_space_after_cast = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_between_parentheses = false
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_declaration_name_and_open_parenthesis = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_after_comma = true
+csharp_space_before_comma = false
+csharp_space_after_dot = false
+csharp_space_before_dot = false
+csharp_space_after_semicolon_in_for_statement = true
+csharp_space_before_semicolon_in_for_statement = false
+csharp_space_around_declaration_statements = false
+csharp_space_before_open_square_brackets = false
+csharp_space_between_empty_square_brackets = false
+csharp_space_between_square_brackets = false
+# Wrapping options
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#wrap-options
+csharp_preserve_single_line_statements = false
+csharp_preserve_single_line_blocks = true
+
+##########################################
+# .NET Naming Conventions
+# https://docs.microsoft.com/visualstudio/ide/editorconfig-naming-conventions
+##########################################
+
+[*.{cs,csx,cake,vb,vbx}]
+dotnet_diagnostic.CA1000.severity = suggestion
+dotnet_diagnostic.CA1001.severity = error
+dotnet_diagnostic.CA1018.severity = error
+dotnet_diagnostic.CA1051.severity = suggestion
+dotnet_diagnostic.CA1068.severity = error
+dotnet_diagnostic.CA1069.severity = error
+dotnet_diagnostic.CA1304.severity = error
+dotnet_diagnostic.CA1305.severity = suggestion
+dotnet_diagnostic.CA1309.severity = suggestion
+dotnet_diagnostic.CA1310.severity = error
+dotnet_diagnostic.CA1707.severity = suggestion
+dotnet_diagnostic.CA1708.severity = suggestion
+dotnet_diagnostic.CA1711.severity = suggestion
+dotnet_diagnostic.CA1716.severity = suggestion
+dotnet_diagnostic.CA1720.severity = suggestion
+dotnet_diagnostic.CA1725.severity = suggestion
+dotnet_diagnostic.CA1805.severity = suggestion
+dotnet_diagnostic.CA1816.severity = suggestion
+dotnet_diagnostic.CA1822.severity = suggestion
+dotnet_diagnostic.CA1825.severity = error
+dotnet_diagnostic.CA1826.severity = silent
+dotnet_diagnostic.CA1827.severity = error
+dotnet_diagnostic.CA1829.severity = suggestion
+dotnet_diagnostic.CA1834.severity = error
+dotnet_diagnostic.CA1845.severity = suggestion
+dotnet_diagnostic.CA1848.severity = suggestion
+dotnet_diagnostic.CA2016.severity = suggestion
+dotnet_diagnostic.CA2201.severity = error
+dotnet_diagnostic.CA2206.severity = error
+dotnet_diagnostic.CA2208.severity = error
+dotnet_diagnostic.CA2211.severity = error
+dotnet_diagnostic.CA2249.severity = error
+dotnet_diagnostic.CA2251.severity = error
+dotnet_diagnostic.CA2252.severity = none
+dotnet_diagnostic.CA2254.severity = suggestion
+
+dotnet_diagnostic.CS0169.severity = error
+dotnet_diagnostic.CS0219.severity = error
+dotnet_diagnostic.CS1998.severity = error
+dotnet_diagnostic.CS8602.severity = error
+dotnet_diagnostic.CS8604.severity = error
+dotnet_diagnostic.CS8618.severity = error
+dotnet_diagnostic.CS0618.severity = error
+dotnet_diagnostic.CS1998.severity = error
+dotnet_diagnostic.CS4014.severity = error
+dotnet_diagnostic.CS8600.severity = error
+dotnet_diagnostic.CS8603.severity = error
+dotnet_diagnostic.CS8625.severity = error
+
+dotnet_diagnostic.BL0005.severity = suggestion
+
+dotnet_diagnostic.MVC1000.severity = suggestion
+
+dotnet_diagnostic.IDE0055.severity = suggestion # Fix formatting
+dotnet_diagnostic.IDE0023.severity = suggestion # use expression body for operators
+dotnet_diagnostic.IDE0025.severity = suggestion # use expression body for properties
+dotnet_diagnostic.IDE1006.severity = suggestion # Naming rule violation: These words cannot contain lower case characters
+dotnet_diagnostic.IDE0072.severity = suggestion # Populate switch - forces population of all cases even when default specified
+dotnet_diagnostic.IDE0027.severity = suggestion # Use expression body for accessors
+dotnet_diagnostic.IDE0032.severity = suggestion # Use auto property
+dotnet_diagnostic.IDE0007.severity = error # Use var
+dotnet_diagnostic.IDE0160.severity = suggestion # Use block scoped
+dotnet_diagnostic.IDE0011.severity = error # Use braces on if statements
+dotnet_diagnostic.IDE0057.severity = suggestion # substring can be simplified
+dotnet_diagnostic.IDE0004.severity = error # redundant cast
+dotnet_diagnostic.IDE0010.severity = silent # populate switch
+dotnet_diagnostic.IDE0021.severity = silent # expression body for constructors
+dotnet_diagnostic.IDE0022.severity = silent # expression body for methods
+dotnet_diagnostic.IDE0024.severity = silent # expression body for operators
+dotnet_diagnostic.IDE0028.severity = silent
+dotnet_diagnostic.IDE0033.severity = error # prefer tuple name
+dotnet_diagnostic.IDE0040.severity = error # modifiers required
+dotnet_diagnostic.IDE0041.severity = error # simplify null
+dotnet_diagnostic.IDE0042.severity = error # deconstruct variable
+dotnet_diagnostic.IDE0044.severity = error # make field only when possible
+dotnet_diagnostic.IDE0047.severity = suggestion # paratemeter name
+dotnet_diagnostic.IDE0051.severity = error # unused field
+dotnet_diagnostic.IDE0052.severity = error # unused member
+dotnet_diagnostic.IDE0060.severity = suggestion # unused parameters
+dotnet_diagnostic.IDE0066.severity = suggestion # switch expression
+dotnet_diagnostic.IDE0078.severity = suggestion # use pattern matching
+dotnet_diagnostic.IDE0090.severity = suggestion # new can be simplified
+dotnet_diagnostic.IDE0130.severity = suggestion # namespace folder structure
+dotnet_diagnostic.IDE0160.severity = silent # Use block namespaces ARE NOT required
+dotnet_diagnostic.IDE0161.severity = suggestion # Please use file namespaces
+
+##########################################
+# Styles
+##########################################
+
+# camel_case_style - Define the camelCase style
+dotnet_naming_style.camel_case_style.capitalization = camel_case
+# pascal_case_style - Define the PascalCase style
+dotnet_naming_style.pascal_case_style.capitalization = pascal_case
+# constant_case - Define the CONSTANT_CASE style
+dotnet_naming_style.constant_case.capitalization = all_upper
+dotnet_naming_style.constant_case.word_separator = _
+# first_upper_style - The first character must start with an upper-case character
+dotnet_naming_style.first_upper_style.capitalization = first_word_upper
+# prefix_interface_with_i_style - Interfaces must be PascalCase and the first character of an interface must be an 'I'
+dotnet_naming_style.prefix_interface_with_i_style.capitalization = pascal_case
+dotnet_naming_style.prefix_interface_with_i_style.required_prefix = I
+# prefix_type_parameters_with_t_style - Generic Type Parameters must be PascalCase and the first character must be a 'T'
+dotnet_naming_style.prefix_type_parameters_with_t_style.capitalization = pascal_case
+dotnet_naming_style.prefix_type_parameters_with_t_style.required_prefix = T
+# disallowed_style - Anything that has this style applied is marked as disallowed
+dotnet_naming_style.disallowed_style.capitalization = pascal_case
+dotnet_naming_style.disallowed_style.required_prefix = ____RULE_VIOLATION____
+dotnet_naming_style.disallowed_style.required_suffix = ____RULE_VIOLATION____
+# internal_error_style - This style should never occur... if it does, it indicates a bug in file or in the parser using the file
+dotnet_naming_style.internal_error_style.capitalization = pascal_case
+dotnet_naming_style.internal_error_style.required_prefix = ____INTERNAL_ERROR____
+dotnet_naming_style.internal_error_style.required_suffix = ____INTERNAL_ERROR____
+
+# prefix_interface_with_i_style - Interfaces must be PascalCase and the first character of an interface must be an 'I'
+dotnet_naming_style.underscore_camel_case_style.capitalization = camel_case
+dotnet_naming_style.underscore_camel_case_style.required_prefix = _
+
+##########################################
+# .NET Design Guideline Field Naming Rules
+# Naming rules for fields follow the .NET Framework design guidelines
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/index
+##########################################
+
+# All public/protected/protected_internal constant fields must be constant_case
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/field
+dotnet_naming_symbols.public_protected_constant_fields_group.applicable_accessibilities = public, protected, protected_internal
+dotnet_naming_symbols.public_protected_constant_fields_group.required_modifiers = const
+dotnet_naming_symbols.public_protected_constant_fields_group.applicable_kinds = field
+dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.symbols = public_protected_constant_fields_group
+dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.style = constant_case
+dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.severity = warning
+
+# All public/protected/protected_internal static readonly fields must be constant_case
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/field
+dotnet_naming_symbols.public_protected_static_readonly_fields_group.applicable_accessibilities = public, protected, protected_internal
+dotnet_naming_symbols.public_protected_static_readonly_fields_group.required_modifiers = static, readonly
+dotnet_naming_symbols.public_protected_static_readonly_fields_group.applicable_kinds = field
+dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.symbols = public_protected_static_readonly_fields_group
+dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.style = constant_case
+dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.severity = warning
+
+# No other public/protected/protected_internal fields are allowed
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/field
+dotnet_naming_symbols.other_public_protected_fields_group.applicable_accessibilities = public, protected, protected_internal
+dotnet_naming_symbols.other_public_protected_fields_group.applicable_kinds = field
+dotnet_naming_rule.other_public_protected_fields_disallowed_rule.symbols = other_public_protected_fields_group
+dotnet_naming_rule.other_public_protected_fields_disallowed_rule.style = disallowed_style
+dotnet_naming_rule.other_public_protected_fields_disallowed_rule.severity = error
+
+##########################################
+# StyleCop Field Naming Rules
+# Naming rules for fields follow the StyleCop analyzers
+# This does not override any rules using disallowed_style above
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers
+##########################################
+
+# All constant fields must be constant_case
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1303.md
+dotnet_naming_symbols.stylecop_constant_fields_group.applicable_accessibilities = public, internal, protected_internal, protected, private_protected, private
+dotnet_naming_symbols.stylecop_constant_fields_group.required_modifiers = const
+dotnet_naming_symbols.stylecop_constant_fields_group.applicable_kinds = field
+dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.symbols = stylecop_constant_fields_group
+dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.style = constant_case
+dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.severity = warning
+
+# All static readonly fields must be constant_case
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1311.md
+dotnet_naming_symbols.stylecop_static_readonly_fields_group.applicable_accessibilities = public, internal, protected_internal, protected, private_protected, private
+dotnet_naming_symbols.stylecop_static_readonly_fields_group.required_modifiers = static, readonly
+dotnet_naming_symbols.stylecop_static_readonly_fields_group.applicable_kinds = field
+dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.symbols = stylecop_static_readonly_fields_group
+dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.style = constant_case
+dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.severity = warning
+
+# No non-private instance fields are allowed
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1401.md
+dotnet_naming_symbols.stylecop_fields_must_be_private_group.applicable_accessibilities = public, internal, protected_internal, protected, private_protected
+dotnet_naming_symbols.stylecop_fields_must_be_private_group.applicable_kinds = field
+dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.symbols = stylecop_fields_must_be_private_group
+dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.style = disallowed_style
+dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.severity = error
+
+# Private fields must be camelCase
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1306.md
+dotnet_naming_symbols.stylecop_private_fields_group.applicable_accessibilities = private
+dotnet_naming_symbols.stylecop_private_fields_group.applicable_kinds = field
+dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.symbols = stylecop_private_fields_group
+dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.style = underscore_camel_case_style
+dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.severity = warning
+
+# Local variables must be camelCase
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1312.md
+dotnet_naming_symbols.stylecop_local_fields_group.applicable_accessibilities = local
+dotnet_naming_symbols.stylecop_local_fields_group.applicable_kinds = local
+dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.symbols = stylecop_local_fields_group
+dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.style = camel_case_style
+dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.severity = warning
+
+# This rule should never fire. However, it's included for at least two purposes:
+# First, it helps to understand, reason about, and root-case certain types of issues, such as bugs in .editorconfig parsers.
+# Second, it helps to raise immediate awareness if a new field type is added (as occurred recently in C#).
+dotnet_naming_symbols.sanity_check_uncovered_field_case_group.applicable_accessibilities = *
+dotnet_naming_symbols.sanity_check_uncovered_field_case_group.applicable_kinds = field
+dotnet_naming_rule.sanity_check_uncovered_field_case_rule.symbols = sanity_check_uncovered_field_case_group
+dotnet_naming_rule.sanity_check_uncovered_field_case_rule.style = internal_error_style
+dotnet_naming_rule.sanity_check_uncovered_field_case_rule.severity = error
+
+
+##########################################
+# Other Naming Rules
+##########################################
+
+# All of the following must be PascalCase:
+# - Namespaces
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-namespaces
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1300.md
+# - Classes and Enumerations
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces
+# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1300.md
+# - Delegates
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces#names-of-common-types
+# - Constructors, Properties, Events, Methods
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-type-members
+dotnet_naming_symbols.element_group.applicable_kinds = namespace, class, enum, struct, delegate, event, method, property
+dotnet_naming_rule.element_rule.symbols = element_group
+dotnet_naming_rule.element_rule.style = pascal_case_style
+dotnet_naming_rule.element_rule.severity = warning
+
+# Interfaces use PascalCase and are prefixed with uppercase 'I'
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces
+dotnet_naming_symbols.interface_group.applicable_kinds = interface
+dotnet_naming_rule.interface_rule.symbols = interface_group
+dotnet_naming_rule.interface_rule.style = prefix_interface_with_i_style
+dotnet_naming_rule.interface_rule.severity = warning
+
+# Generics Type Parameters use PascalCase and are prefixed with uppercase 'T'
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces
+dotnet_naming_symbols.type_parameter_group.applicable_kinds = type_parameter
+dotnet_naming_rule.type_parameter_rule.symbols = type_parameter_group
+dotnet_naming_rule.type_parameter_rule.style = prefix_type_parameters_with_t_style
+dotnet_naming_rule.type_parameter_rule.severity = warning
+
+# Function parameters use camelCase
+# https://docs.microsoft.com/dotnet/standard/design-guidelines/naming-parameters
+dotnet_naming_symbols.parameters_group.applicable_kinds = parameter
+dotnet_naming_rule.parameters_rule.symbols = parameters_group
+dotnet_naming_rule.parameters_rule.style = camel_case_style
+dotnet_naming_rule.parameters_rule.severity = warning
+
+##########################################
+# License
+##########################################
+# The following applies as to the .editorconfig file ONLY, and is
+# included below for reference, per the requirements of the license
+# corresponding to this .editorconfig file.
+# See: https://github.com/RehanSaeed/EditorConfig
+#
+# MIT License
+#
+# Copyright (c) 2017-2019 Muhammad Rehan Saeed
+# Copyright (c) 2019 Henry Gabryjelski
+#
+# 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.
+##########################################
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..67534058
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,6 @@
+version: 2
+updates:
+ - package-ecosystem: "github-actions" # search for actions - there are other options available
+ directory: "/" # search in .github/workflows under root `/`
+ schedule:
+ interval: "weekly" # check for action update every week
diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml
index e3eaa142..57c993b9 100644
--- a/.github/workflows/dotnetcore.yml
+++ b/.github/workflows/dotnetcore.yml
@@ -9,8 +9,8 @@ jobs:
os: [windows-latest, ubuntu-latest]
steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-dotnet@v1
+ - uses: actions/checkout@v3
+ - uses: actions/setup-dotnet@v2
with:
dotnet-version: |
5.0.x
diff --git a/build/Program.cs b/build/Program.cs
index e0a972e2..b406cdd6 100644
--- a/build/Program.cs
+++ b/build/Program.cs
@@ -6,78 +6,78 @@ using GlobExpressions;
using static Bullseye.Targets;
using static SimpleExec.Command;
-class Program
-{
- private const string Clean = "clean";
- private const string Format = "format";
- private const string Build = "build";
- private const string Test = "test";
- private const string Publish = "publish";
+const string Clean = "clean";
+const string Format = "format";
+const string Build = "build";
+const string Test = "test";
+const string Publish = "publish";
- static void Main(string[] args)
- {
- Target(Clean,
- ForEach("**/bin", "**/obj"),
- dir =>
- {
- IEnumerable GetDirectories(string d)
- {
- return Glob.Directories(".", d);
- }
+Target(Clean,
+ ForEach("**/bin", "**/obj"),
+ dir =>
+ {
+ IEnumerable GetDirectories(string d)
+ {
+ return Glob.Directories(".", d);
+ }
- void RemoveDirectory(string d)
- {
- if (Directory.Exists(d))
- {
- Console.WriteLine(d);
- Directory.Delete(d, true);
- }
- }
-
- foreach (var d in GetDirectories(dir))
- {
- RemoveDirectory(d);
- }
- });
-
- Target(Format, () =>
- {
- Run("dotnet", "tool restore");
- Run("dotnet", "format --check");
- });
-
- Target(Build, DependsOn(Format),
- framework =>
+ void RemoveDirectory(string d)
+ {
+ if (Directory.Exists(d))
{
- Run("dotnet", "build src/SharpCompress/SharpCompress.csproj -c Release");
- });
+ Console.WriteLine(d);
+ Directory.Delete(d, true);
+ }
+ }
- Target(Test, DependsOn(Build), ForEach("net5.0", "net6.0", "net461"),
- framework =>
- {
- IEnumerable GetFiles(string d)
- {
- return Glob.Files(".", d);
- }
- if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && framework == "net461")
- {
- return;
- }
+ foreach (var d in GetDirectories(dir))
+ {
+ RemoveDirectory(d);
+ }
+ });
- foreach (var file in GetFiles("**/*.Test.csproj"))
- {
- Run("dotnet", $"test {file} -c Release -f {framework}");
- }
- });
+Target(Format,
+ () =>
+ {
+ Run("dotnet", "tool restore");
+ Run("dotnet", "format --check");
+ });
- Target(Publish, DependsOn(Test),
- () =>
- {
- Run("dotnet", "pack src/SharpCompress/SharpCompress.csproj -c Release -o artifacts/");
- });
+Target(Build,
+ DependsOn(Format),
+ framework =>
+ {
+ Run("dotnet", "build src/SharpCompress/SharpCompress.csproj -c Release");
+ });
- Target("default", DependsOn(Publish), () => Console.WriteLine("Done!"));
+Target(Test,
+ DependsOn(Build),
+ ForEach("net5.0", "net6.0", "net461"),
+ framework =>
+ {
+ IEnumerable GetFiles(string d)
+ {
+ return Glob.Files(".", d);
+ }
- RunTargetsAndExit(args);
- }
-}
\ No newline at end of file
+ if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && framework == "net461")
+ {
+ return;
+ }
+
+ foreach (var file in GetFiles("**/*.Test.csproj"))
+ {
+ Run("dotnet", $"test {file} -c Release -f {framework}");
+ }
+ });
+
+Target(Publish,
+ DependsOn(Test),
+ () =>
+ {
+ Run("dotnet", "pack src/SharpCompress/SharpCompress.csproj -c Release -o artifacts/");
+ });
+
+Target("default", DependsOn(Publish), () => Console.WriteLine("Done!"));
+
+await RunTargetsAndExitAsync(args);
diff --git a/build/build.csproj b/build/build.csproj
index 8326a3aa..792624f2 100644
--- a/build/build.csproj
+++ b/build/build.csproj
@@ -6,9 +6,9 @@
-
-
-
+
+
+
diff --git a/src/SharpCompress/Archives/Rar/RarArchiveVolumeFactory.cs b/src/SharpCompress/Archives/Rar/RarArchiveVolumeFactory.cs
index 7f42c89a..8740961b 100644
--- a/src/SharpCompress/Archives/Rar/RarArchiveVolumeFactory.cs
+++ b/src/SharpCompress/Archives/Rar/RarArchiveVolumeFactory.cs
@@ -71,7 +71,7 @@ namespace SharpCompress.Archives.Rar
var buffer = new StringBuilder(currentFileInfo.FullName.Length);
buffer.Append(currentFileInfo.FullName.Substring(0,
currentFileInfo.FullName.Length - extension.Length));
- if (string.Compare(extension, ".rar", StringComparison.OrdinalIgnoreCase) == 0)
+ if (string.Equals(extension, ".rar", StringComparison.OrdinalIgnoreCase))
{
buffer.Append(".r00");
}
@@ -99,11 +99,11 @@ namespace SharpCompress.Archives.Rar
{
// part1.rar, part2.rar, ...
string extension = currentFileInfo.Extension;
- if (string.Compare(extension, ".rar", StringComparison.OrdinalIgnoreCase) != 0)
+ if (!string.Equals(extension, ".rar", StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException("Invalid extension, expected 'rar': " + currentFileInfo.FullName);
}
- int startIndex = currentFileInfo.FullName.LastIndexOf(".part");
+ int startIndex = currentFileInfo.FullName.LastIndexOf(".part", StringComparison.OrdinalIgnoreCase);
if (startIndex < 0)
{
ThrowInvalidFileName(currentFileInfo);
@@ -137,4 +137,4 @@ namespace SharpCompress.Archives.Rar
+ fileInfo.FullName);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/SharpCompress/Common/SevenZip/ArchiveReader.cs b/src/SharpCompress/Common/SevenZip/ArchiveReader.cs
index 93e0ff69..6a2b8ea4 100644
--- a/src/SharpCompress/Common/SevenZip/ArchiveReader.cs
+++ b/src/SharpCompress/Common/SevenZip/ArchiveReader.cs
@@ -1248,7 +1248,7 @@ namespace SharpCompress.Common.SevenZip
if (nextHeaderOffset > _streamEnding - db._startPositionAfterHeader)
{
- throw new IndexOutOfRangeException();
+ throw new InvalidOperationException("nextHeaderOffset is invalid");
}
_stream.Seek(nextHeaderOffset, SeekOrigin.Current);
diff --git a/src/SharpCompress/Common/SevenZip/CFolder.cs b/src/SharpCompress/Common/SevenZip/CFolder.cs
index 4a68cf50..c15da80c 100644
--- a/src/SharpCompress/Common/SevenZip/CFolder.cs
+++ b/src/SharpCompress/Common/SevenZip/CFolder.cs
@@ -30,7 +30,7 @@ namespace SharpCompress.Common.SevenZip
}
}
- throw new Exception();
+ throw new InvalidOperationException();
}
public int GetNumOutStreams()
@@ -185,4 +185,4 @@ namespace SharpCompress.Common.SevenZip
return true;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/SharpCompress/Common/Zip/ZipFilePart.cs b/src/SharpCompress/Common/Zip/ZipFilePart.cs
index 47dd0d60..937c1a8f 100644
--- a/src/SharpCompress/Common/Zip/ZipFilePart.cs
+++ b/src/SharpCompress/Common/Zip/ZipFilePart.cs
@@ -174,7 +174,7 @@ namespace SharpCompress.Common.Zip
default:
{
- throw new ArgumentOutOfRangeException();
+ throw new InvalidOperationException("Header.CompressionMethod is invalid");
}
}
diff --git a/src/SharpCompress/Compressors/Deflate/Zlib.cs b/src/SharpCompress/Compressors/Deflate/Zlib.cs
index 434845ae..036d65f5 100644
--- a/src/SharpCompress/Compressors/Deflate/Zlib.cs
+++ b/src/SharpCompress/Compressors/Deflate/Zlib.cs
@@ -1,20 +1,20 @@
// Zlib.cs
// ------------------------------------------------------------------
//
-// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
+// Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
-// This code is licensed under the Microsoft Public License.
+// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
-// last saved (in emacs):
+// last saved (in emacs):
// Time-stamp: <2009-November-07 05:26:55>
//
// ------------------------------------------------------------------
@@ -27,22 +27,22 @@
// included below.
//
// ------------------------------------------------------------------
-//
+//
// Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved.
-//
+//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
-//
+//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in
+//
+// 2. 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.
-//
+//
// 3. The names of the authors may not be used to endorse or promote products
// derived from this software without specific prior written permission.
-//
+//
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 JCRAFT,
@@ -53,7 +53,7 @@
// 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.
-//
+//
// -----------------------------------------------------------------------
//
// This program is based on zlib-1.1.3; credit to authors
@@ -82,7 +82,7 @@ namespace SharpCompress.Compressors.Deflate
///
/// Same as None.
///
- Level0 = 0,
+ Level0 = None,
///
/// The fastest but least effective compression.
@@ -92,7 +92,7 @@ namespace SharpCompress.Compressors.Deflate
///
/// A synonym for BestSpeed.
///
- Level1 = 1,
+ Level1 = BestSpeed,
///
/// A little slower, but better, than level 1.
@@ -115,14 +115,14 @@ namespace SharpCompress.Compressors.Deflate
Level5 = 5,
///
- /// The default compression level, with a good balance of speed and compression efficiency.
+ /// The default compression level, with a good balance of speed and compression efficiency.
///
Default = 6,
///
/// A synonym for Default.
///
- Level6 = 6,
+ Level6 = Default,
///
/// Pretty good compression!
@@ -135,7 +135,7 @@ namespace SharpCompress.Compressors.Deflate
Level8 = 8,
///
- /// The "best" compression, where best means greatest reduction in size of the input data stream.
+ /// The "best" compression, where best means greatest reduction in size of the input data stream.
/// This is also the slowest compression.
///
BestCompression = 9,
@@ -143,7 +143,7 @@ namespace SharpCompress.Compressors.Deflate
///
/// A synonym for BestCompression.
///
- Level9 = 9
+ Level9 = BestCompression
}
///
@@ -154,7 +154,7 @@ namespace SharpCompress.Compressors.Deflate
public enum CompressionStrategy
{
///
- /// The default strategy is probably the best for normal data.
+ /// The default strategy is probably the best for normal data.
///
Default = 0,
@@ -181,7 +181,7 @@ namespace SharpCompress.Compressors.Deflate
{
///
/// The ZlibException class captures exception information generated
- /// by the Zlib library.
+ /// by the Zlib library.
///
public ZlibException()
{
@@ -233,7 +233,7 @@ namespace SharpCompress.Compressors.Deflate
/// Contains the array of characteres read from the source TextReader.
/// The starting index of the target array.
/// The maximum number of characters to read from the source TextReader.
- ///
+ ///
///
/// The number of characters read. The number will be less than or equal to
/// count depending on the data available in the source TextReader. Returns -1
@@ -405,4 +405,4 @@ namespace SharpCompress.Compressors.Deflate
BitLengths = new StaticTree(null, extra_blbits, 0, InternalConstants.BL_CODES, InternalConstants.MAX_BL_BITS);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/SharpCompress/Compressors/LZMA/AesDecoderStream.cs b/src/SharpCompress/Compressors/LZMA/AesDecoderStream.cs
index e59363df..1d1f036c 100644
--- a/src/SharpCompress/Compressors/LZMA/AesDecoderStream.cs
+++ b/src/SharpCompress/Compressors/LZMA/AesDecoderStream.cs
@@ -143,8 +143,8 @@ namespace SharpCompress.Compressors.LZMA
if ((bt & 0xC0) == 0)
{
- salt = new byte[0];
- iv = new byte[0];
+ salt = Array.Empty();
+ iv = Array.Empty();
return;
}
diff --git a/src/SharpCompress/Compressors/LZMA/LZ/LzBinTree.cs b/src/SharpCompress/Compressors/LZMA/LZ/LzBinTree.cs
index d1c29d34..37c70720 100644
--- a/src/SharpCompress/Compressors/LZMA/LZ/LzBinTree.cs
+++ b/src/SharpCompress/Compressors/LZMA/LZ/LzBinTree.cs
@@ -103,7 +103,7 @@ namespace SharpCompress.Compressors.LZMA.LZ
{
if (historySize > K_MAX_VAL_FOR_NORMALIZE - 256)
{
- throw new Exception();
+ throw new ArgumentOutOfRangeException(nameof(historySize));
}
_cutValue = 16 + (matchMaxLen >> 1);
@@ -423,4 +423,4 @@ namespace SharpCompress.Compressors.LZMA.LZ
_cutValue = cutValue;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/SharpCompress/Compressors/LZMA/LzmaEncoder.cs b/src/SharpCompress/Compressors/LZMA/LzmaEncoder.cs
index e4420f21..5dab5002 100644
--- a/src/SharpCompress/Compressors/LZMA/LzmaEncoder.cs
+++ b/src/SharpCompress/Compressors/LZMA/LzmaEncoder.cs
@@ -1649,7 +1649,7 @@ namespace SharpCompress.Compressors.LZMA
{
for (int m = 0; m < K_MATCH_FINDER_I_DS.Length; m++)
{
- if (s == K_MATCH_FINDER_I_DS[m])
+ if (string.Equals(s, K_MATCH_FINDER_I_DS[m], StringComparison.OrdinalIgnoreCase))
{
return m;
}
@@ -1696,7 +1696,7 @@ namespace SharpCompress.Compressors.LZMA
throw new InvalidParamException();
}
EMatchFinderType matchFinderIndexPrev = _matchFinderType;
- int m = FindMatchFinder(((string)prop).ToUpper());
+ int m = FindMatchFinder(((string)prop));
if (m < 0)
{
throw new InvalidParamException();
diff --git a/src/SharpCompress/Compressors/LZMA/Utilites/Utils.cs b/src/SharpCompress/Compressors/LZMA/Utilites/Utils.cs
index 97f48ea2..1b64ccb6 100644
--- a/src/SharpCompress/Compressors/LZMA/Utilites/Utils.cs
+++ b/src/SharpCompress/Compressors/LZMA/Utilites/Utils.cs
@@ -50,7 +50,7 @@ namespace SharpCompress.Compressors.LZMA.Utilites
Debugger.Break();
}
- throw new Exception("Assertion failed.");
+ throw new InvalidOperationException("Assertion failed.");
}
}
@@ -89,4 +89,4 @@ namespace SharpCompress.Compressors.LZMA.Utilites
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/SharpCompress/Compressors/PPMd/H/RangeCoder.cs b/src/SharpCompress/Compressors/PPMd/H/RangeCoder.cs
index ba1bc557..ce778e19 100644
--- a/src/SharpCompress/Compressors/PPMd/H/RangeCoder.cs
+++ b/src/SharpCompress/Compressors/PPMd/H/RangeCoder.cs
@@ -83,7 +83,7 @@ namespace SharpCompress.Compressors.PPMd.H
internal void AriDecNormalize()
{
- // while ((low ^ (low + range)) < TOP || range < BOT && ((range = -low & (BOT - 1)) != 0 ? true : true))
+ // while ((low ^ (low + range)) < TOP || range < BOT && ((range = -low & (BOT - 1)) != 0 ? true : true))
// {
// code = ((code << 8) | unpackRead.getChar()&0xff)&uintMask;
// range = (range << 8)&uintMask;
@@ -118,7 +118,7 @@ namespace SharpCompress.Compressors.PPMd.H
buffer.Append(_range);
buffer.Append("\n subrange=");
buffer.Append(SubRange);
- buffer.Append("]");
+ buffer.Append(']');
return buffer.ToString();
}
}
@@ -150,8 +150,8 @@ namespace SharpCompress.Compressors.PPMd.H
buffer.Append(_highCount);
buffer.Append("\n scale=");
buffer.Append(_scale);
- buffer.Append("]");
+ buffer.Append(']');
return buffer.ToString();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/SharpCompress/Compressors/Xz/MultiByteIntegers.cs b/src/SharpCompress/Compressors/Xz/MultiByteIntegers.cs
index 3eb83449..27f94644 100644
--- a/src/SharpCompress/Compressors/Xz/MultiByteIntegers.cs
+++ b/src/SharpCompress/Compressors/Xz/MultiByteIntegers.cs
@@ -9,7 +9,7 @@ namespace SharpCompress.Compressors.Xz
{
if (MaxBytes <= 0)
{
- throw new ArgumentOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(MaxBytes));
}
if (MaxBytes > 9)
diff --git a/src/SharpCompress/Readers/AbstractReader.cs b/src/SharpCompress/Readers/AbstractReader.cs
index dfd012a3..fe6285ff 100644
--- a/src/SharpCompress/Readers/AbstractReader.cs
+++ b/src/SharpCompress/Readers/AbstractReader.cs
@@ -38,7 +38,7 @@ namespace SharpCompress.Readers
public abstract TVolume Volume { get; }
///
- /// Current file entry
+ /// Current file entry
///
public TEntry Entry => entriesForCurrentReadStream!.Current;
@@ -160,9 +160,14 @@ namespace SharpCompress.Readers
{
throw new ArgumentException("WriteEntryTo or OpenEntryStream can only be called once.");
}
- if ((writableStream is null) || (!writableStream.CanWrite))
+
+ if (writableStream is null)
{
- throw new ArgumentNullException("A writable Stream was required. Use Cancel if that was intended.");
+ throw new ArgumentNullException(nameof(writableStream));
+ }
+ if (!writableStream.CanWrite)
+ {
+ throw new ArgumentException("A writable Stream was required. Use Cancel if that was intended.");
}
Write(writableStream);
@@ -228,4 +233,4 @@ namespace SharpCompress.Readers
EntryExtractionProgress?.Invoke(this, new ReaderExtractionEventArgs(entry, new ReaderProgress(entry, bytesTransferred, iterations)));
}
}
-}
\ No newline at end of file
+}
diff --git a/src/SharpCompress/SharpCompress.csproj b/src/SharpCompress/SharpCompress.csproj
index d742ba29..b5087f95 100644
--- a/src/SharpCompress/SharpCompress.csproj
+++ b/src/SharpCompress/SharpCompress.csproj
@@ -29,17 +29,17 @@
-
-
+
+
-
+
-
+
-
+
diff --git a/src/SharpCompress/Utility.cs b/src/SharpCompress/Utility.cs
index bae51f10..cbc5b9ae 100644
--- a/src/SharpCompress/Utility.cs
+++ b/src/SharpCompress/Utility.cs
@@ -72,17 +72,17 @@ namespace SharpCompress
{
if (sourceIndex > Int32.MaxValue || sourceIndex < Int32.MinValue)
{
- throw new ArgumentOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(sourceIndex));
}
if (destinationIndex > Int32.MaxValue || destinationIndex < Int32.MinValue)
{
- throw new ArgumentOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(destinationIndex));
}
if (length > Int32.MaxValue || length < Int32.MinValue)
{
- throw new ArgumentOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(length));
}
Array.Copy(sourceArray, (int)sourceIndex, destinationArray, (int)destinationIndex, (int)length);
diff --git a/tests/SharpCompress.Test/SharpCompress.Test.csproj b/tests/SharpCompress.Test/SharpCompress.Test.csproj
index a29b6d4a..35c3134a 100644
--- a/tests/SharpCompress.Test/SharpCompress.Test.csproj
+++ b/tests/SharpCompress.Test/SharpCompress.Test.csproj
@@ -12,8 +12,8 @@
-
-
+
+
diff --git a/tests/SharpCompress.Test/Tar/TarArchiveTests.cs b/tests/SharpCompress.Test/Tar/TarArchiveTests.cs
index 69ae3058..17da414d 100644
--- a/tests/SharpCompress.Test/Tar/TarArchiveTests.cs
+++ b/tests/SharpCompress.Test/Tar/TarArchiveTests.cs
@@ -1,4 +1,5 @@
-using System.IO;
+using System;
+using System.IO;
using System.Linq;
using SharpCompress.Archives;
using SharpCompress.Archives.Tar;
@@ -185,7 +186,7 @@ namespace SharpCompress.Test.Tar
using (var archive = TarArchive.Open(unmodified))
{
- var entry = archive.Entries.Single(x => x.Key.EndsWith("jpg"));
+ var entry = archive.Entries.Single(x => x.Key.EndsWith("jpg", StringComparison.OrdinalIgnoreCase));
archive.RemoveEntry(entry);
archive.SaveTo(scratchPath, CompressionType.None);
}
diff --git a/tests/SharpCompress.Test/TestBase.cs b/tests/SharpCompress.Test/TestBase.cs
index 0c1db9d0..76a85c49 100644
--- a/tests/SharpCompress.Test/TestBase.cs
+++ b/tests/SharpCompress.Test/TestBase.cs
@@ -156,7 +156,7 @@ namespace SharpCompress.Test
protected void CompareFilesByPath(string file1, string file2)
{
//TODO: fix line ending issues with the text file
- if (file1.EndsWith("txt"))
+ if (file1.EndsWith("txt", StringComparison.OrdinalIgnoreCase))
{
return;
}
diff --git a/tests/SharpCompress.Test/Xz/XZTestsBase.cs b/tests/SharpCompress.Test/Xz/XZTestsBase.cs
index 46a13a8f..a0e3032e 100644
--- a/tests/SharpCompress.Test/Xz/XZTestsBase.cs
+++ b/tests/SharpCompress.Test/Xz/XZTestsBase.cs
@@ -1,9 +1,10 @@
-using System.Text;
+using System;
+using System.Text;
using System.IO;
namespace SharpCompress.Test.Xz
{
- public abstract class XZTestsBase
+ public abstract class XZTestsBase : IDisposable
{
public XZTestsBase()
{
@@ -12,6 +13,13 @@ namespace SharpCompress.Test.Xz
RewindIndexed(CompressedIndexedStream);
}
+ public void Dispose()
+ {
+ CompressedEmptyStream?.Dispose();
+ CompressedStream?.Dispose();
+ CompressedIndexedStream?.Dispose();
+ }
+
protected virtual void RewindEmpty(Stream stream)
{
stream.Position = 0;
diff --git a/tests/SharpCompress.Test/Zip/Zip64Tests.cs b/tests/SharpCompress.Test/Zip/Zip64Tests.cs
index c0395684..9a5210e5 100644
--- a/tests/SharpCompress.Test/Zip/Zip64Tests.cs
+++ b/tests/SharpCompress.Test/Zip/Zip64Tests.cs
@@ -64,7 +64,7 @@ namespace SharpCompress.Test.Zip
{
// One single file, should fail
RunSingleTest(1, FOUR_GB_LIMIT, set_zip64: false, forward_only: false);
- throw new Exception("Test did not fail?");
+ throw new InvalidOperationException("Test did not fail?");
}
catch (NotSupportedException)
{
@@ -78,7 +78,7 @@ namespace SharpCompress.Test.Zip
{
// One single file, should fail (fast) with zip64
RunSingleTest(1, FOUR_GB_LIMIT, set_zip64: true, forward_only: true);
- throw new Exception("Test did not fail?");
+ throw new InvalidOperationException("Test did not fail?");
}
catch (NotSupportedException)
{
@@ -92,7 +92,7 @@ namespace SharpCompress.Test.Zip
{
// One single file, should fail once the write discovers the problem
RunSingleTest(1, FOUR_GB_LIMIT, set_zip64: false, forward_only: true);
- throw new Exception("Test did not fail?");
+ throw new InvalidOperationException("Test did not fail?");
}
catch (NotSupportedException)
{
@@ -116,23 +116,23 @@ namespace SharpCompress.Test.Zip
var resForward = ReadForwardOnly(filename);
if (resForward.Item1 != files)
{
- throw new Exception($"Incorrect number of items reported: {resForward.Item1}, should have been {files}");
+ throw new InvalidOperationException($"Incorrect number of items reported: {resForward.Item1}, should have been {files}");
}
if (resForward.Item2 != files * filesize)
{
- throw new Exception($"Incorrect combined size reported: {resForward.Item2}, should have been {files * filesize}");
+ throw new InvalidOperationException($"Incorrect combined size reported: {resForward.Item2}, should have been {files * filesize}");
}
var resArchive = ReadArchive(filename);
if (resArchive.Item1 != files)
{
- throw new Exception($"Incorrect number of items reported: {resArchive.Item1}, should have been {files}");
+ throw new InvalidOperationException($"Incorrect number of items reported: {resArchive.Item1}, should have been {files}");
}
if (resArchive.Item2 != files * filesize)
{
- throw new Exception($"Incorrect number of items reported: {resArchive.Item2}, should have been {files * filesize}");
+ throw new InvalidOperationException($"Incorrect number of items reported: {resArchive.Item2}, should have been {files * filesize}");
}
}
@@ -209,4 +209,4 @@ namespace SharpCompress.Test.Zip
}
}
}
-}
\ No newline at end of file
+}
diff --git a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs
index a514a948..244d1599 100644
--- a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs
+++ b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs
@@ -170,7 +170,7 @@ namespace SharpCompress.Test.Zip
using (var archive = ZipArchive.Open(unmodified))
{
- var entry = archive.Entries.Single(x => x.Key.EndsWith("jpg"));
+ var entry = archive.Entries.Single(x => x.Key.EndsWith("jpg", StringComparison.OrdinalIgnoreCase));
archive.RemoveEntry(entry);
WriterOptions writerOptions = new ZipWriterOptions(CompressionType.Deflate);
@@ -229,10 +229,10 @@ namespace SharpCompress.Test.Zip
using (ZipArchive vfs = (ZipArchive)ArchiveFactory.Open(scratchPath))
{
- var e = vfs.Entries.First(v => v.Key.EndsWith("jpg"));
+ var e = vfs.Entries.First(v => v.Key.EndsWith("jpg", StringComparison.OrdinalIgnoreCase));
vfs.RemoveEntry(e);
- Assert.Null(vfs.Entries.FirstOrDefault(v => v.Key.EndsWith("jpg")));
- Assert.Null(((IArchive)vfs).Entries.FirstOrDefault(v => v.Key.EndsWith("jpg")));
+ Assert.Null(vfs.Entries.FirstOrDefault(v => v.Key.EndsWith("jpg", StringComparison.OrdinalIgnoreCase)));
+ Assert.Null(((IArchive)vfs).Entries.FirstOrDefault(v => v.Key.EndsWith("jpg", StringComparison.OrdinalIgnoreCase)));
}
}
@@ -272,7 +272,7 @@ namespace SharpCompress.Test.Zip
foreach (var file in Directory.EnumerateFiles(ORIGINAL_FILES_PATH, "*.*", SearchOption.AllDirectories))
{
var newFileName = file.Substring(ORIGINAL_FILES_PATH.Length);
- if (newFileName.StartsWith(Path.DirectorySeparatorChar.ToString()))
+ if (newFileName.StartsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.OrdinalIgnoreCase))
{
newFileName = newFileName.Substring(1);
}
@@ -301,7 +301,7 @@ namespace SharpCompress.Test.Zip
}
///
- /// Creates an empty zip file and attempts to read it right afterwards.
+ /// Creates an empty zip file and attempts to read it right afterwards.
/// Ensures that parsing file headers works even in that case
///
[Fact]
@@ -328,7 +328,7 @@ namespace SharpCompress.Test.Zip
foreach (var file in Directory.EnumerateFiles(ORIGINAL_FILES_PATH, "*.*", SearchOption.AllDirectories))
{
var newFileName = file.Substring(ORIGINAL_FILES_PATH.Length);
- if (newFileName.StartsWith(Path.DirectorySeparatorChar.ToString()))
+ if (newFileName.StartsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.OrdinalIgnoreCase))
{
newFileName = newFileName.Substring(1);
}
@@ -346,7 +346,7 @@ namespace SharpCompress.Test.Zip
{
archive.AddAllFromDirectory(SCRATCH_FILES_PATH);
archive.RemoveEntry(archive.Entries.Single(x => x.Key.EndsWith("jpg", StringComparison.OrdinalIgnoreCase)));
- Assert.Null(archive.Entries.FirstOrDefault(x => x.Key.EndsWith("jpg")));
+ Assert.Null(archive.Entries.FirstOrDefault(x => x.Key.EndsWith("jpg", StringComparison.OrdinalIgnoreCase)));
}
Directory.Delete(SCRATCH_FILES_PATH, true);
}
@@ -528,7 +528,7 @@ namespace SharpCompress.Test.Zip
using (IWriter zipWriter = WriterFactory.Open(stream, ArchiveType.Zip, CompressionType.Deflate))
{
- zipWriter.Write("foo.txt", new MemoryStream(new byte[0]));
+ zipWriter.Write("foo.txt", new MemoryStream(Array.Empty()));
zipWriter.Write("foo2.txt", new MemoryStream(new byte[10]));
}
diff --git a/tests/SharpCompress.Test/Zip/ZipReaderTests.cs b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs
index 3db81542..c7eb3c41 100644
--- a/tests/SharpCompress.Test/Zip/ZipReaderTests.cs
+++ b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs
@@ -302,7 +302,7 @@ namespace SharpCompress.Test.Zip
{
var expected = new Tuple[]
{
- new Tuple("foo.txt", new byte[0]),
+ new Tuple("foo.txt", Array.Empty()),
new Tuple("foo2.txt", new byte[10])
};