From d87cc2c99c9b53595ae6efb9ee5ff583964b44ca Mon Sep 17 00:00:00 2001 From: Alexander Luzgarev Date: Thu, 10 Apr 2025 20:12:29 +0200 Subject: [PATCH] Fix all the warnings --- .editorconfig | 246 +++++++++++ .../ExtensionTestFilenameConvention.cs | 4 +- .../MatFileHandler.Tests.csproj | 3 +- MatFileHandler.Tests/MatFileReaderTests.cs | 2 +- .../MatFileWriterOptionsForTests.cs | 9 + MatFileHandler.Tests/MatFileWriterTests.cs | 94 ++--- MatFileHandler.Tests/MatFileWritingMethod.cs | 17 +- MatFileHandler.Tests/MatFileWritingMethods.cs | 58 +++ .../MatFileWritingToMemoryStream.cs | 37 -- .../MatFileWritingToUnalignedMemoryStream.cs | 43 -- .../MatFileWritingToUnseekableStream.cs | 38 -- .../PartialUnseekableReadStream.cs | 2 +- MatFileHandler.Tests/UnseekableWriteStream.cs | 2 +- MatFileHandler/ComplexOf.cs | 7 +- MatFileHandler/DataElementConverter.cs | 33 +- MatFileHandler/DataElementReader.cs | 120 ++---- MatFileHandler/DataExtraction.cs | 382 +++++++----------- MatFileHandler/DataTypeExtensions.cs | 50 +-- MatFileHandler/DatetimeAdapter.cs | 20 +- MatFileHandler/DurationAdapter.cs | 7 +- MatFileHandler/FakeWriter.cs | 9 +- MatFileHandler/Header.cs | 12 +- MatFileHandler/IMatFile.cs | 4 +- MatFileHandler/MatFile.cs | 8 +- MatFileHandler/MatFileHandler.csproj | 3 +- MatFileHandler/MatFileReader.cs | 21 +- MatFileHandler/MatFileWriter.cs | 185 ++++----- MatFileHandler/MatFileWriterOptions.cs | 4 +- MatFileHandler/MatSparseArrayOf.cs | 13 +- MatFileHandler/OpaqueLink.cs | 14 +- MatFileHandler/PositionTrackingStream.cs | 2 +- MatFileHandler/StringAdapter.cs | 7 +- MatFileHandler/Substream.cs | 2 +- MatFileHandler/SubsystemData.cs | 9 +- MatFileHandler/SubsystemDataReader.cs | 3 +- MatFileHandler/TableAdapter.cs | 2 +- 36 files changed, 724 insertions(+), 748 deletions(-) create mode 100644 .editorconfig create mode 100644 MatFileHandler.Tests/MatFileWriterOptionsForTests.cs create mode 100644 MatFileHandler.Tests/MatFileWritingMethods.cs delete mode 100644 MatFileHandler.Tests/MatFileWritingToMemoryStream.cs delete mode 100644 MatFileHandler.Tests/MatFileWritingToUnalignedMemoryStream.cs delete mode 100644 MatFileHandler.Tests/MatFileWritingToUnseekableStream.cs diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..63e0c7a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,246 @@ +# Remove the line below if you want to inherit .editorconfig settings from higher directories +root = true + +# C# files +[*.cs] + +dotnet_analyzer_diagnostic.category-Design.severity = warning +dotnet_analyzer_diagnostic.category-Documentation.severity = warning +dotnet_analyzer_diagnostic.category-Globalization.severity = warning +dotnet_analyzer_diagnostic.category-Interoperability.severity = warning +dotnet_analyzer_diagnostic.category-Maintainability.severity = warning +dotnet_analyzer_diagnostic.category-Naming.severity = warning +dotnet_analyzer_diagnostic.category-Performance.severity = warning +dotnet_analyzer_diagnostic.category-Reliability.severity = warning +dotnet_analyzer_diagnostic.category-Security.severity = warning +dotnet_analyzer_diagnostic.category-Style.severity = warning +dotnet_analyzer_diagnostic.category-Usage.severity = warning + +dotnet_diagnostic.IDE0010.severity = none +dotnet_diagnostic.IDE0072.severity = none + +#### Core EditorConfig Options #### + +# Indentation and spacing +indent_size = 4 +indent_style = space +tab_width = 4 + +# New line preferences +end_of_line = crlf +insert_final_newline = false + +#### .NET Coding Conventions #### + +# Organize usings +dotnet_separate_import_directive_groups = false +dotnet_sort_system_directives_first = false +file_header_template = unset + +# this. and Me. preferences +dotnet_style_qualification_for_event = false +dotnet_style_qualification_for_field = false +dotnet_style_qualification_for_method = false +dotnet_style_qualification_for_property = false + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true +dotnet_style_predefined_type_for_member_access = true + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_operators = never_if_unnecessary +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members + +# Expression-level preferences +dotnet_style_coalesce_expression = true +dotnet_style_collection_initializer = true +dotnet_style_explicit_tuple_names = true +dotnet_style_namespace_match_folder = true +dotnet_style_null_propagation = true +dotnet_style_object_initializer = true +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_prefer_auto_properties = true +dotnet_style_prefer_collection_expression = false +dotnet_style_prefer_compound_assignment = true +dotnet_style_prefer_conditional_expression_over_assignment = false +dotnet_style_prefer_conditional_expression_over_return = false +dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed +dotnet_style_prefer_inferred_anonymous_type_member_names = true +dotnet_style_prefer_inferred_tuple_names = true +dotnet_style_prefer_is_null_check_over_reference_equality_method = true +dotnet_style_prefer_simplified_boolean_expressions = true +dotnet_style_prefer_simplified_interpolation = true + +# Field preferences +dotnet_style_readonly_field = true + +# Parameter preferences +dotnet_code_quality_unused_parameters = all:silent + +# Suppression preferences +dotnet_remove_unnecessary_suppression_exclusions = none + +# New line preferences +dotnet_style_allow_multiple_blank_lines_experimental = true +dotnet_style_allow_statement_immediately_after_block_experimental = true + +#### C# Coding Conventions #### + +# var preferences +csharp_style_var_elsewhere = true +csharp_style_var_for_built_in_types = true +csharp_style_var_when_type_is_apparent = true + +# Expression-bodied members +csharp_style_expression_bodied_accessors = true +csharp_style_expression_bodied_constructors = false +csharp_style_expression_bodied_indexers = true +csharp_style_expression_bodied_lambdas = true +csharp_style_expression_bodied_local_functions = false +csharp_style_expression_bodied_methods = true:none +csharp_style_expression_bodied_operators = false +csharp_style_expression_bodied_properties = true + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true +csharp_style_pattern_matching_over_is_with_cast_check = true +csharp_style_prefer_extended_property_pattern = true +csharp_style_prefer_not_pattern = true +csharp_style_prefer_pattern_matching = true +csharp_style_prefer_switch_expression = true + +# Null-checking preferences +csharp_style_conditional_delegate_call = true + +# Modifier preferences +csharp_prefer_static_local_function = true +csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async +csharp_style_prefer_readonly_struct = true +csharp_style_prefer_readonly_struct_member = true + +# Code-block preferences +csharp_prefer_braces = true +csharp_prefer_simple_using_statement = true +csharp_style_namespace_declarations = file_scoped:none +csharp_style_prefer_method_group_conversion = true +csharp_style_prefer_primary_constructors = false +csharp_style_prefer_top_level_statements = true + +# Expression-level preferences +csharp_prefer_simple_default_expression = true +csharp_style_deconstructed_variable_declaration = true +csharp_style_implicit_object_creation_when_type_is_apparent = true +csharp_style_inlined_variable_declaration = true +csharp_style_prefer_index_operator = true +csharp_style_prefer_local_over_anonymous_function = true +csharp_style_prefer_null_check_over_type_check = true +csharp_style_prefer_range_operator = true +csharp_style_prefer_tuple_swap = true +csharp_style_prefer_utf8_string_literals = true +csharp_style_throw_expression = true +csharp_style_unused_value_assignment_preference = discard_variable +csharp_style_unused_value_expression_statement_preference = discard_variable + +# 'using' directive preferences +csharp_using_directive_placement = outside_namespace + +# New line preferences +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true +csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true +csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true +csharp_style_allow_embedded_statements_on_same_line_experimental = true + +#### C# Formatting Rules #### + +# New line preferences +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = all +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = true +csharp_indent_labels = one_less_than_current +csharp_indent_switch_labels = true + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +# Wrapping preferences +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true + +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +# Symbol specifications + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +# Naming styles + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case diff --git a/MatFileHandler.Tests/ExtensionTestFilenameConvention.cs b/MatFileHandler.Tests/ExtensionTestFilenameConvention.cs index 08ebd80..4ec2591 100755 --- a/MatFileHandler.Tests/ExtensionTestFilenameConvention.cs +++ b/MatFileHandler.Tests/ExtensionTestFilenameConvention.cs @@ -7,7 +7,7 @@ namespace MatFileHandler.Tests /// /// A filename convention based on file extensions. /// - internal class ExtensionTestFilenameConvention : ITestFilenameConvention + internal sealed class ExtensionTestFilenameConvention : ITestFilenameConvention { /// /// Initializes a new instance of the class. @@ -40,4 +40,4 @@ namespace MatFileHandler.Tests return Path.GetExtension(filename) == "." + Extension; } } -} \ No newline at end of file +} diff --git a/MatFileHandler.Tests/MatFileHandler.Tests.csproj b/MatFileHandler.Tests/MatFileHandler.Tests.csproj index 5a46d00..d0c201d 100755 --- a/MatFileHandler.Tests/MatFileHandler.Tests.csproj +++ b/MatFileHandler.Tests/MatFileHandler.Tests.csproj @@ -2,10 +2,9 @@ net461;net472;net8.0 false - 10.0 + latest - ..\MatFileHandler.ruleset bin\Debug\net5.0\MatFileHandler.Tests.xml diff --git a/MatFileHandler.Tests/MatFileReaderTests.cs b/MatFileHandler.Tests/MatFileReaderTests.cs index f4d291d..91d597c 100755 --- a/MatFileHandler.Tests/MatFileReaderTests.cs +++ b/MatFileHandler.Tests/MatFileReaderTests.cs @@ -590,7 +590,7 @@ namespace MatFileHandler.Tests /// Test four-dimensional arrays. /// [Theory, MemberData(nameof(TestDataFactories))] - public void Test_4DArrays(AbstractTestDataFactory testFactory) + public void Test4DArrays(AbstractTestDataFactory testFactory) { var matFile = testFactory["issue20.mat"]; var obj = matFile["a4d"].Value; diff --git a/MatFileHandler.Tests/MatFileWriterOptionsForTests.cs b/MatFileHandler.Tests/MatFileWriterOptionsForTests.cs new file mode 100644 index 0000000..3d8a158 --- /dev/null +++ b/MatFileHandler.Tests/MatFileWriterOptionsForTests.cs @@ -0,0 +1,9 @@ +namespace MatFileHandler.Tests; + +public enum MatFileWriterOptionsForTests +{ + Undefined = 0, + None, + Always, + Never, +} diff --git a/MatFileHandler.Tests/MatFileWriterTests.cs b/MatFileHandler.Tests/MatFileWriterTests.cs index a2da405..c3c2aae 100755 --- a/MatFileHandler.Tests/MatFileWriterTests.cs +++ b/MatFileHandler.Tests/MatFileWriterTests.cs @@ -17,8 +17,8 @@ namespace MatFileHandler.Tests /// /// Test writing a simple Double array. /// - [Theory, MemberData(nameof(MatFileWritingMethods))] - public void TestWrite(MatFileWritingMethod method) + [Theory, MemberData(nameof(MatFileWritingTestData))] + public void TestWrite(MatFileWritingMethod method, MatFileWriterOptionsForTests options) { var builder = new DataBuilder(); var array = builder.NewArray(1, 2); @@ -26,7 +26,7 @@ namespace MatFileHandler.Tests array[1] = 17.0; var variable = builder.NewVariable("test", array); var actual = builder.NewFile(new[] { variable }); - MatCompareWithTestData("good", "double-array", actual, method); + MatCompareWithTestData("good", "double-array", actual, method, options); } /// @@ -51,8 +51,8 @@ namespace MatFileHandler.Tests /// /// Test writing lower and upper limits of integer data types. /// - [Theory, MemberData(nameof(MatFileWritingMethods))] - public void TestLimits(MatFileWritingMethod method) + [Theory, MemberData(nameof(MatFileWritingTestData))] + public void TestLimits(MatFileWritingMethod method, MatFileWriterOptionsForTests options) { var builder = new DataBuilder(); var int8 = builder.NewVariable("int8_", builder.NewArray(CommonData.Int8Limits, 1, 2)); @@ -64,14 +64,14 @@ namespace MatFileHandler.Tests var int64 = builder.NewVariable("int64_", builder.NewArray(CommonData.Int64Limits, 1, 2)); var uint64 = builder.NewVariable("uint64_", builder.NewArray(CommonData.UInt64Limits, 1, 2)); var actual = builder.NewFile(new[] { int16, int32, int64, int8, uint16, uint32, uint64, uint8 }); - MatCompareWithTestData("good", "limits", actual, method); + MatCompareWithTestData("good", "limits", actual, method, options); } /// /// Test writing lower and upper limits of integer-based complex data types. /// - [Theory, MemberData(nameof(MatFileWritingMethods))] - public void TestLimitsComplex(MatFileWritingMethod method) + [Theory, MemberData(nameof(MatFileWritingTestData))] + public void TestLimitsComplex(MatFileWritingMethod method, MatFileWriterOptionsForTests options) { var builder = new DataBuilder(); var int8Complex = builder.NewVariable( @@ -103,26 +103,26 @@ namespace MatFileHandler.Tests int16Complex, int32Complex, int64Complex, int8Complex, uint16Complex, uint32Complex, uint64Complex, uint8Complex, }); - MatCompareWithTestData("good", "limits_complex", actual, method); + MatCompareWithTestData("good", "limits_complex", actual, method, options); } /// /// Test writing a wide-Unicode symbol. /// - [Theory, MemberData(nameof(MatFileWritingMethods))] - public void TestUnicodeWide(MatFileWritingMethod method) + [Theory, MemberData(nameof(MatFileWritingTestData))] + public void TestUnicodeWide(MatFileWritingMethod method, MatFileWriterOptionsForTests options) { var builder = new DataBuilder(); var s = builder.NewVariable("s", builder.NewCharArray("🍆")); var actual = builder.NewFile(new[] { s }); - MatCompareWithTestData("good", "unicode-wide", actual, method); + MatCompareWithTestData("good", "unicode-wide", actual, method, options); } /// /// Test writing a sparse array. /// - [Theory, MemberData(nameof(MatFileWritingMethods))] - public void TestSparseArray(MatFileWritingMethod method) + [Theory, MemberData(nameof(MatFileWritingTestData))] + public void TestSparseArray(MatFileWritingMethod method, MatFileWriterOptionsForTests options) { var builder = new DataBuilder(); var sparseArray = builder.NewSparseArray(4, 5); @@ -132,14 +132,14 @@ namespace MatFileHandler.Tests sparseArray[2, 3] = 4; var sparse = builder.NewVariable("sparse_", sparseArray); var actual = builder.NewFile(new[] { sparse }); - MatCompareWithTestData("good", "sparse", actual, method); + MatCompareWithTestData("good", "sparse", actual, method, options); } /// /// Test writing a structure array. /// - [Theory, MemberData(nameof(MatFileWritingMethods))] - public void TestStructure(MatFileWritingMethod method) + [Theory, MemberData(nameof(MatFileWritingTestData))] + public void TestStructure(MatFileWritingMethod method, MatFileWriterOptionsForTests options) { var builder = new DataBuilder(); var structure = builder.NewStructureArray(new[] { "x", "y" }, 2, 3); @@ -160,27 +160,27 @@ namespace MatFileHandler.Tests structure["y", 1, 2] = builder.NewEmpty(); var struct_ = builder.NewVariable("struct_", structure); var actual = builder.NewFile(new[] { struct_ }); - MatCompareWithTestData("good", "struct", actual, method); + MatCompareWithTestData("good", "struct", actual, method, options); } /// /// Test writing a logical array. /// - [Theory, MemberData(nameof(MatFileWritingMethods))] - public void TestLogical(MatFileWritingMethod method) + [Theory, MemberData(nameof(MatFileWritingTestData))] + public void TestLogical(MatFileWritingMethod method, MatFileWriterOptionsForTests options) { var builder = new DataBuilder(); var logical = builder.NewArray(new[] { true, false, true, true, false, true }, 2, 3); var logicalVariable = builder.NewVariable("logical_", logical); var actual = builder.NewFile(new[] { logicalVariable }); - MatCompareWithTestData("good", "logical", actual, method); + MatCompareWithTestData("good", "logical", actual, method, options); } /// /// Test writing a sparse logical array. /// - [Theory, MemberData(nameof(MatFileWritingMethods))] - public void TestSparseLogical(MatFileWritingMethod method) + [Theory, MemberData(nameof(MatFileWritingTestData))] + public void TestSparseLogical(MatFileWritingMethod method, MatFileWriterOptionsForTests options) { var builder = new DataBuilder(); var array = builder.NewSparseArray(2, 3); @@ -190,14 +190,14 @@ namespace MatFileHandler.Tests array[1, 2] = true; var sparseLogical = builder.NewVariable("sparse_logical", array); var actual = builder.NewFile(new[] { sparseLogical }); - MatCompareWithTestData("good", "sparse_logical", actual, method); + MatCompareWithTestData("good", "sparse_logical", actual, method, options); } /// /// Test writing a sparse complex array. /// - [Theory, MemberData(nameof(MatFileWritingMethods))] - public void TestSparseComplex(MatFileWritingMethod method) + [Theory, MemberData(nameof(MatFileWritingTestData))] + public void TestSparseComplex(MatFileWritingMethod method, MatFileWriterOptionsForTests options) { var builder = new DataBuilder(); var array = builder.NewSparseArray(2, 2); @@ -206,41 +206,44 @@ namespace MatFileHandler.Tests array[1, 1] = 0.5 + Complex.ImaginaryOne; var sparseComplex = builder.NewVariable("sparse_complex", array); var actual = builder.NewFile(new[] { sparseComplex }); - MatCompareWithTestData("good", "sparse_complex", actual, method); + MatCompareWithTestData("good", "sparse_complex", actual, method, options); } /// /// Test writing a global variable. /// - [Theory, MemberData(nameof(MatFileWritingMethods))] - public void TestGlobal(MatFileWritingMethod method) + [Theory, MemberData(nameof(MatFileWritingTestData))] + public void TestGlobal(MatFileWritingMethod method, MatFileWriterOptionsForTests options) { var builder = new DataBuilder(); var array = builder.NewArray(new double[] { 1, 3, 5 }, 1, 3); var global = builder.NewVariable("global_", array, true); var actual = builder.NewFile(new[] { global }); - MatCompareWithTestData("good", "global", actual, method); + MatCompareWithTestData("good", "global", actual, method, options); } /// /// Various writing methods for testing writing of .mat files. /// - public static TheoryData MatFileWritingMethods + public static TheoryData MatFileWritingTestData { get { - return new TheoryData + var always = new MatFileWriterOptions { UseCompression = CompressionUsage.Always}; + var never = new MatFileWriterOptions { UseCompression = CompressionUsage.Never }; + var data = new TheoryData { - new MatFileWritingToMemoryStream(null), - new MatFileWritingToMemoryStream(new MatFileWriterOptions { UseCompression = CompressionUsage.Always }), - new MatFileWritingToMemoryStream(new MatFileWriterOptions { UseCompression = CompressionUsage.Never }), - new MatFileWritingToUnseekableStream(null), - new MatFileWritingToUnseekableStream(new MatFileWriterOptions { UseCompression = CompressionUsage.Always }), - new MatFileWritingToUnseekableStream(new MatFileWriterOptions { UseCompression = CompressionUsage.Never }), - new MatFileWritingToUnalignedMemoryStream(null), - new MatFileWritingToUnalignedMemoryStream(new MatFileWriterOptions { UseCompression = CompressionUsage.Always }), - new MatFileWritingToUnalignedMemoryStream(new MatFileWriterOptions { UseCompression = CompressionUsage.Never }), + { MatFileWritingMethod.NormalStream, MatFileWriterOptionsForTests.None }, + { MatFileWritingMethod.NormalStream, MatFileWriterOptionsForTests.Always }, + { MatFileWritingMethod.NormalStream, MatFileWriterOptionsForTests.Never }, + { MatFileWritingMethod.UnseekableStream, MatFileWriterOptionsForTests.None }, + { MatFileWritingMethod.UnseekableStream, MatFileWriterOptionsForTests.Always }, + { MatFileWritingMethod.UnseekableStream, MatFileWriterOptionsForTests.Never }, + { MatFileWritingMethod.UnalignedStream, MatFileWriterOptionsForTests.None }, + { MatFileWritingMethod.UnalignedStream, MatFileWriterOptionsForTests.Always }, + { MatFileWritingMethod.UnalignedStream, MatFileWriterOptionsForTests.Never }, }; + return data; } } @@ -401,10 +404,11 @@ namespace MatFileHandler.Tests string factoryName, string testName, IMatFile actual, - MatFileWritingMethod method) + MatFileWritingMethod method, + MatFileWriterOptionsForTests options) { var expected = GetMatTestData(factoryName)[testName]; - var buffer = method.WriteMatFile(actual); + var buffer = MatFileWritingMethods.WriteMatFile(method, options, actual); using var stream = new MemoryStream(buffer); var reader = new MatFileReader(stream); var actualRead = reader.Read(); @@ -412,9 +416,9 @@ namespace MatFileHandler.Tests } private ComplexOf[] CreateComplexLimits(T[] limits) - where T : struct + where T : struct { return new[] { new ComplexOf(limits[0], limits[1]), new ComplexOf(limits[1], limits[0]) }; } } -} \ No newline at end of file +} diff --git a/MatFileHandler.Tests/MatFileWritingMethod.cs b/MatFileHandler.Tests/MatFileWritingMethod.cs index b5ba772..225a550 100644 --- a/MatFileHandler.Tests/MatFileWritingMethod.cs +++ b/MatFileHandler.Tests/MatFileWritingMethod.cs @@ -2,16 +2,11 @@ namespace MatFileHandler.Tests { - /// - /// A method of writing IMatFile into a byte buffer. - /// - public abstract class MatFileWritingMethod + public enum MatFileWritingMethod { - /// - /// Write an IMatFile into a byte buffer. - /// - /// - /// - public abstract byte[] WriteMatFile(IMatFile matFile); + Undefined, + NormalStream, + UnseekableStream, + UnalignedStream, } -} \ No newline at end of file +} diff --git a/MatFileHandler.Tests/MatFileWritingMethods.cs b/MatFileHandler.Tests/MatFileWritingMethods.cs new file mode 100644 index 0000000..3d8c1bb --- /dev/null +++ b/MatFileHandler.Tests/MatFileWritingMethods.cs @@ -0,0 +1,58 @@ +using System; +using System.IO; + +namespace MatFileHandler.Tests; + +internal static class MatFileWritingMethods +{ + public static byte[] WriteMatFile(MatFileWritingMethod method, MatFileWriterOptionsForTests options, IMatFile matFile) + { + switch (method) + { + case MatFileWritingMethod.NormalStream: + { + using var memoryStream = new MemoryStream(); + var matFileWriter = CreateWriter(options, memoryStream); + matFileWriter.Write(matFile); + return memoryStream.ToArray(); + } + case MatFileWritingMethod.UnseekableStream: + { + using var memoryStream = new MemoryStream(); + using var unseekableStream = new UnseekableWriteStream(memoryStream); + var matFileWriter = CreateWriter(options, unseekableStream); + matFileWriter.Write(matFile); + return memoryStream.ToArray(); + } + case MatFileWritingMethod.UnalignedStream: + { + using var memoryStream = new MemoryStream(); + memoryStream.Seek(3, SeekOrigin.Begin); + var matFileWriter = CreateWriter(options, memoryStream); + matFileWriter.Write(matFile); + var fullArray = memoryStream.ToArray(); + var length = fullArray.Length - 3; + var result = new byte[length]; + Buffer.BlockCopy(fullArray, 3, result, 0, length); + return result; + } + default: + throw new NotImplementedException(); + } + } + + private static MatFileWriter CreateWriter(MatFileWriterOptionsForTests options, Stream stream) + { + return options switch + { + MatFileWriterOptionsForTests.None => new MatFileWriter(stream), + MatFileWriterOptionsForTests.Always => new MatFileWriter( + stream, + new MatFileWriterOptions { UseCompression = CompressionUsage.Always }), + MatFileWriterOptionsForTests.Never => new MatFileWriter( + stream, + new MatFileWriterOptions { UseCompression = CompressionUsage.Never }), + _ => throw new NotImplementedException(), + }; + } +} diff --git a/MatFileHandler.Tests/MatFileWritingToMemoryStream.cs b/MatFileHandler.Tests/MatFileWritingToMemoryStream.cs deleted file mode 100644 index 5efb26a..0000000 --- a/MatFileHandler.Tests/MatFileWritingToMemoryStream.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2017-2018 Alexander Luzgarev - -using System.IO; - -namespace MatFileHandler.Tests -{ - /// - /// A method of writing an IMatFile into a MemoryStream. - /// - public class MatFileWritingToMemoryStream : MatFileWritingMethod - { - private readonly MatFileWriterOptions? _maybeOptions; - - /// - /// Initializes a new instance of the class. - /// - /// Options for the . - public MatFileWritingToMemoryStream(MatFileWriterOptions? maybeOptions) - { - _maybeOptions = maybeOptions; - } - - /// - public override byte[] WriteMatFile(IMatFile matFile) - { - using var memoryStream = new MemoryStream(); - var matFileWriter = _maybeOptions switch - { - { } options => new MatFileWriter(memoryStream, options), - _ => new MatFileWriter(memoryStream), - }; - - matFileWriter.Write(matFile); - return memoryStream.ToArray(); - } - } -} \ No newline at end of file diff --git a/MatFileHandler.Tests/MatFileWritingToUnalignedMemoryStream.cs b/MatFileHandler.Tests/MatFileWritingToUnalignedMemoryStream.cs deleted file mode 100644 index a419974..0000000 --- a/MatFileHandler.Tests/MatFileWritingToUnalignedMemoryStream.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2017-2018 Alexander Luzgarev - -using System; -using System.IO; - -namespace MatFileHandler.Tests -{ - /// - /// A method of writing an IMatFile into a stream that is "unaligned". - /// - public class MatFileWritingToUnalignedMemoryStream : MatFileWritingMethod - { - private readonly MatFileWriterOptions? _maybeOptions; - - /// - /// Initializes a new instance of the class. - /// - /// Options for the . - public MatFileWritingToUnalignedMemoryStream(MatFileWriterOptions? maybeOptions) - { - _maybeOptions = maybeOptions; - } - - /// - public override byte[] WriteMatFile(IMatFile matFile) - { - using var memoryStream = new MemoryStream(); - memoryStream.Seek(3, SeekOrigin.Begin); - var matFileWriter = _maybeOptions switch - { - { } options => new MatFileWriter(memoryStream, options), - _ => new MatFileWriter(memoryStream), - }; - - matFileWriter.Write(matFile); - var fullArray = memoryStream.ToArray(); - var length = fullArray.Length - 3; - var result = new byte[length]; - Buffer.BlockCopy(fullArray, 3, result, 0, length); - return result; - } - } -} \ No newline at end of file diff --git a/MatFileHandler.Tests/MatFileWritingToUnseekableStream.cs b/MatFileHandler.Tests/MatFileWritingToUnseekableStream.cs deleted file mode 100644 index 1a2c2d8..0000000 --- a/MatFileHandler.Tests/MatFileWritingToUnseekableStream.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2017-2018 Alexander Luzgarev - -using System.IO; - -namespace MatFileHandler.Tests -{ - /// - /// A method of writing an IMatFile into a stream that is not seekable. - /// - public class MatFileWritingToUnseekableStream : MatFileWritingMethod - { - private readonly MatFileWriterOptions? _maybeOptions; - - /// - /// Initializes a new instance of the class. - /// - /// Options for the . - public MatFileWritingToUnseekableStream(MatFileWriterOptions? maybeOptions) - { - _maybeOptions = maybeOptions; - } - - /// - public override byte[] WriteMatFile(IMatFile matFile) - { - using var memoryStream = new MemoryStream(); - using var unseekableStream = new UnseekableWriteStream(memoryStream); - var matFileWriter = _maybeOptions switch - { - { } options => new MatFileWriter(unseekableStream, options), - _ => new MatFileWriter(unseekableStream), - }; - - matFileWriter.Write(matFile); - return memoryStream.ToArray(); - } - } -} \ No newline at end of file diff --git a/MatFileHandler.Tests/PartialUnseekableReadStream.cs b/MatFileHandler.Tests/PartialUnseekableReadStream.cs index a78104c..00c3484 100644 --- a/MatFileHandler.Tests/PartialUnseekableReadStream.cs +++ b/MatFileHandler.Tests/PartialUnseekableReadStream.cs @@ -9,7 +9,7 @@ namespace MatFileHandler.Tests /// A stream which wraps another stream and only reads one byte at a time, /// while forbidding seeking in it. /// - internal class PartialUnseekableReadStream : Stream + internal sealed class PartialUnseekableReadStream : Stream { private readonly Stream _baseStream; diff --git a/MatFileHandler.Tests/UnseekableWriteStream.cs b/MatFileHandler.Tests/UnseekableWriteStream.cs index 2133768..9618f00 100644 --- a/MatFileHandler.Tests/UnseekableWriteStream.cs +++ b/MatFileHandler.Tests/UnseekableWriteStream.cs @@ -8,7 +8,7 @@ namespace MatFileHandler.Tests /// /// A stream which wraps another stream and forbids seeking in it. /// - internal class UnseekableWriteStream : Stream + internal sealed class UnseekableWriteStream : Stream { public UnseekableWriteStream(Stream baseStream) { diff --git a/MatFileHandler/ComplexOf.cs b/MatFileHandler/ComplexOf.cs index cbf7317..e969d5a 100755 --- a/MatFileHandler/ComplexOf.cs +++ b/MatFileHandler/ComplexOf.cs @@ -8,7 +8,7 @@ namespace MatFileHandler /// A structure representing a complex number where real and imaginary parts are of type T. /// /// Type of real and imaginary parts. - public struct ComplexOf : IEquatable> + public readonly struct ComplexOf : IEquatable> where T : struct { /// @@ -71,10 +71,11 @@ namespace MatFileHandler /// True iff another object is a complex number equal to this. public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) + if (obj is null) { return false; } + return obj is ComplexOf other && Equals(other); } @@ -90,4 +91,4 @@ namespace MatFileHandler } } } -} \ No newline at end of file +} diff --git a/MatFileHandler/DataElementConverter.cs b/MatFileHandler/DataElementConverter.cs index 040f2ec..5fb9fe4 100755 --- a/MatFileHandler/DataElementConverter.cs +++ b/MatFileHandler/DataElementConverter.cs @@ -75,12 +75,17 @@ namespace MatFileHandler { throw new ArgumentException("Null data found.", nameof(data)); } - var elements = + + + + + var maybeElements = ConvertDataToSparseProperType(data, flags.ArrayFlags.Variable.HasFlag(Variable.IsLogical)); - if (elements == null) + if (maybeElements is not { } elements) { throw new HandlerException("Couldn't read sparse array."); } + var dataDictionary = ConvertMatlabSparseToDictionary(rowIndex, columnIndex, j => elements[j]); return new MatSparseArrayOf(flags, dimensions, name, dataDictionary); @@ -117,15 +122,12 @@ namespace MatFileHandler switch (flags.Class) { case ArrayType.MxChar: - switch (realData) + return realData switch { - case MiNum dataByte: - return ConvertToMatCharArray(flags, dimensions, name, dataByte); - case MiNum dataUshort: - return ConvertToMatCharArray(flags, dimensions, name, dataUshort); - default: - throw new NotSupportedException("Only utf8, utf16 or ushort char arrays are supported."); - } + MiNum dataByte => ConvertToMatCharArray(flags, dimensions, name, dataByte), + MiNum dataUshort => ConvertToMatCharArray(flags, dimensions, name, dataUshort), + _ => throw new NotSupportedException("Only utf8, utf16 or ushort char arrays are supported."), + }; case ArrayType.MxDouble: case ArrayType.MxSingle: case ArrayType.MxInt8: @@ -184,13 +186,12 @@ namespace MatFileHandler { return DataExtraction.GetDataAsUInt8(data).Select(x => x != 0).ToArray() as T[]; } - switch (data) + + return data switch { - case MiNum _: - return DataExtraction.GetDataAsDouble(data) as T[]; - default: - throw new NotSupportedException(); - } + MiNum => DataExtraction.GetDataAsDouble(data) as T[], + _ => throw new NotSupportedException(), + }; } private static MatCharArrayOf ConvertToMatCharArray( diff --git a/MatFileHandler/DataElementReader.cs b/MatFileHandler/DataElementReader.cs index a5b280f..8a4ae9c 100755 --- a/MatFileHandler/DataElementReader.cs +++ b/MatFileHandler/DataElementReader.cs @@ -33,50 +33,23 @@ namespace MatFileHandler public DataElement Read(BinaryReader reader) { var (dataReader, tag) = ReadTag(reader); - DataElement result; - switch (tag.Type) + + var result = tag.Type switch { - case DataType.MiInt8: - result = ReadNum(tag, dataReader); - break; - case DataType.MiUInt8: - case DataType.MiUtf8: - result = ReadNum(tag, dataReader); - break; - case DataType.MiInt16: - result = ReadNum(tag, dataReader); - break; - case DataType.MiUInt16: - case DataType.MiUtf16: - result = ReadNum(tag, dataReader); - break; - case DataType.MiInt32: - result = ReadNum(tag, dataReader); - break; - case DataType.MiUInt32: - result = ReadNum(tag, dataReader); - break; - case DataType.MiSingle: - result = ReadNum(tag, dataReader); - break; - case DataType.MiDouble: - result = ReadNum(tag, dataReader); - break; - case DataType.MiInt64: - result = ReadNum(tag, dataReader); - break; - case DataType.MiUInt64: - result = ReadNum(tag, dataReader); - break; - case DataType.MiMatrix: - result = ReadMatrix(tag, dataReader); - break; - case DataType.MiCompressed: - result = ReadCompressed(tag, dataReader); - break; - default: - throw new NotSupportedException("Unknown element."); - } + DataType.MiInt8 => ReadNum(tag, dataReader), + DataType.MiUInt8 or DataType.MiUtf8 => ReadNum(tag, dataReader), + DataType.MiInt16 => ReadNum(tag, dataReader), + DataType.MiUInt16 or DataType.MiUtf16 => ReadNum(tag, dataReader), + DataType.MiInt32 => ReadNum(tag, dataReader), + DataType.MiUInt32 => ReadNum(tag, dataReader), + DataType.MiSingle => ReadNum(tag, dataReader), + DataType.MiDouble => ReadNum(tag, dataReader), + DataType.MiInt64 => ReadNum(tag, dataReader), + DataType.MiUInt64 => ReadNum(tag, dataReader), + DataType.MiMatrix => ReadMatrix(tag, dataReader), + DataType.MiCompressed => ReadCompressed(tag, dataReader), + _ => throw new NotSupportedException("Unknown element."), + }; if (tag.Type != DataType.MiCompressed) { @@ -122,7 +95,7 @@ namespace MatFileHandler private static ArrayFlags ReadArrayFlags(DataElement element) { var flagData = (element as MiNum)?.Data ?? - throw new HandlerException("Unexpected type in array flags."); + throw new HandlerException("Unexpected type in array flags."); var class_ = (ArrayType)(flagData[0] & 0xff); var variableFlags = (flagData[0] >> 8) & 0x0e; return new ArrayFlags @@ -206,7 +179,7 @@ namespace MatFileHandler else { var length = typeHi; - type = type & 0xffff; + type &= 0xffff; var smallReader = new BinaryReader(new MemoryStream(reader.ReadBytes(4))); return (smallReader, new Tag((DataType)type, length)); } @@ -298,19 +271,17 @@ namespace MatFileHandler imaginaryData); } - switch (data) + return data switch { - case MiNum _: - return DataElementConverter.ConvertToMatSparseArrayOf( - sparseArrayFlags, - dimensions, - name, - rowIndex.Data, - columnIndex.Data, - data); - default: - throw new NotSupportedException("Only double and logical sparse arrays are supported."); - } + MiNum => DataElementConverter.ConvertToMatSparseArrayOf( + sparseArrayFlags, + dimensions, + name, + rowIndex.Data, + columnIndex.Data, + data), + _ => throw new NotSupportedException("Only double and logical sparse arrays are supported."), + }; } private MatStructureArray ContinueReadingStructure( @@ -421,26 +392,23 @@ namespace MatFileHandler switch (flags.Class) { case ArrayType.MxChar: - switch (data) + return data switch { - case MiNum _: - return DataElementConverter.ConvertToMatNumericalArrayOf( - flags, - dimensions, - name, - data, - imaginaryData); - case MiNum _: - return DataElementConverter.ConvertToMatNumericalArrayOf( - flags, - dimensions, - name, - data, - imaginaryData); - default: - throw new NotSupportedException( - $"This type of char array ({data.GetType()}) is not supported."); - } + MiNum => DataElementConverter.ConvertToMatNumericalArrayOf( + flags, + dimensions, + name, + data, + imaginaryData), + MiNum => DataElementConverter.ConvertToMatNumericalArrayOf( + flags, + dimensions, + name, + data, + imaginaryData), + _ => throw new NotSupportedException( + $"This type of char array ({data.GetType()}) is not supported."), + }; case ArrayType.MxInt8: return DataElementConverter.ConvertToMatNumericalArrayOf( flags, diff --git a/MatFileHandler/DataExtraction.cs b/MatFileHandler/DataExtraction.cs index 455fd92..00fd915 100755 --- a/MatFileHandler/DataExtraction.cs +++ b/MatFileHandler/DataExtraction.cs @@ -16,31 +16,21 @@ namespace MatFileHandler /// Contents of the elements, converted to Double. public static double[] GetDataAsDouble(DataElement element) { - switch (element) + return element switch { - case MiNum sbyteElement: - return SbyteToDouble(sbyteElement.Data); - case MiNum byteElement: - return ByteToDouble(byteElement.Data); - case MiNum intElement: - return IntToDouble(intElement.Data); - case MiNum uintElement: - return UintToDouble(uintElement.Data); - case MiNum shortElement: - return ShortToDouble(shortElement.Data); - case MiNum ushortElement: - return UshortToDouble(ushortElement.Data); - case MiNum longElement: - return LongToDouble(longElement.Data); - case MiNum ulongElement: - return UlongToDouble(ulongElement.Data); - case MiNum floatElement: - return FloatToDouble(floatElement.Data); - case MiNum doubleElement: - return doubleElement.Data; - } - throw new HandlerException( - $"Expected data element that would be convertible to double, found {element.GetType()}."); + MiNum sbyteElement => SbyteToDouble(sbyteElement.Data), + MiNum byteElement => ByteToDouble(byteElement.Data), + MiNum intElement => IntToDouble(intElement.Data), + MiNum uintElement => UintToDouble(uintElement.Data), + MiNum shortElement => ShortToDouble(shortElement.Data), + MiNum ushortElement => UshortToDouble(ushortElement.Data), + MiNum longElement => LongToDouble(longElement.Data), + MiNum ulongElement => UlongToDouble(ulongElement.Data), + MiNum floatElement => FloatToDouble(floatElement.Data), + MiNum doubleElement => doubleElement.Data, + _ => throw new HandlerException( + $"Expected data element that would be convertible to double, found {element.GetType()}."), + }; } /// @@ -50,31 +40,21 @@ namespace MatFileHandler /// Contents of the elements, converted to Single. public static float[] GetDataAsSingle(DataElement element) { - switch (element) + return element switch { - case MiNum sbyteElement: - return SbyteToSingle(sbyteElement.Data); - case MiNum byteElement: - return ByteToSingle(byteElement.Data); - case MiNum intElement: - return IntToSingle(intElement.Data); - case MiNum uintElement: - return UintToSingle(uintElement.Data); - case MiNum shortElement: - return ShortToSingle(shortElement.Data); - case MiNum ushortElement: - return UshortToSingle(ushortElement.Data); - case MiNum longElement: - return LongToSingle(longElement.Data); - case MiNum ulongElement: - return UlongToSingle(ulongElement.Data); - case MiNum floatElement: - return floatElement.Data; - case MiNum doubleElement: - return DoubleToSingle(doubleElement.Data); - } - throw new HandlerException( - $"Expected data element that would be convertible to float, found {element.GetType()}."); + MiNum sbyteElement => SbyteToSingle(sbyteElement.Data), + MiNum byteElement => ByteToSingle(byteElement.Data), + MiNum intElement => IntToSingle(intElement.Data), + MiNum uintElement => UintToSingle(uintElement.Data), + MiNum shortElement => ShortToSingle(shortElement.Data), + MiNum ushortElement => UshortToSingle(ushortElement.Data), + MiNum longElement => LongToSingle(longElement.Data), + MiNum ulongElement => UlongToSingle(ulongElement.Data), + MiNum floatElement => floatElement.Data, + MiNum doubleElement => DoubleToSingle(doubleElement.Data), + _ => throw new HandlerException( + $"Expected data element that would be convertible to float, found {element.GetType()}."), + }; } /// @@ -84,31 +64,21 @@ namespace MatFileHandler /// Contents of the elements, converted to Int8. public static sbyte[] GetDataAsInt8(DataElement element) { - switch (element) + return element switch { - case MiNum sbyteElement: - return sbyteElement.Data; - case MiNum byteElement: - return ByteToSByte(byteElement.Data); - case MiNum intElement: - return IntToSByte(intElement.Data); - case MiNum uintElement: - return UintToSByte(uintElement.Data); - case MiNum shortElement: - return ShortToSByte(shortElement.Data); - case MiNum ushortElement: - return UshortToSByte(ushortElement.Data); - case MiNum longElement: - return LongToSByte(longElement.Data); - case MiNum ulongElement: - return UlongToSByte(ulongElement.Data); - case MiNum floatElement: - return SingleToSByte(floatElement.Data); - case MiNum doubleElement: - return DoubleToSByte(doubleElement.Data); - } - throw new HandlerException( - $"Expected data element that would be convertible to int8, found {element.GetType()}."); + MiNum sbyteElement => sbyteElement.Data, + MiNum byteElement => ByteToSByte(byteElement.Data), + MiNum intElement => IntToSByte(intElement.Data), + MiNum uintElement => UintToSByte(uintElement.Data), + MiNum shortElement => ShortToSByte(shortElement.Data), + MiNum ushortElement => UshortToSByte(ushortElement.Data), + MiNum longElement => LongToSByte(longElement.Data), + MiNum ulongElement => UlongToSByte(ulongElement.Data), + MiNum floatElement => SingleToSByte(floatElement.Data), + MiNum doubleElement => DoubleToSByte(doubleElement.Data), + _ => throw new HandlerException( + $"Expected data element that would be convertible to int8, found {element.GetType()}."), + }; } /// @@ -118,31 +88,21 @@ namespace MatFileHandler /// Contents of the elements, converted to UInt8. public static byte[] GetDataAsUInt8(DataElement element) { - switch (element) + return element switch { - case MiNum sbyteElement: - return SbyteToByte(sbyteElement.Data); - case MiNum byteElement: - return byteElement.Data; - case MiNum intElement: - return IntToByte(intElement.Data); - case MiNum uintElement: - return UintToByte(uintElement.Data); - case MiNum shortElement: - return ShortToByte(shortElement.Data); - case MiNum ushortElement: - return UshortToByte(ushortElement.Data); - case MiNum longElement: - return LongToByte(longElement.Data); - case MiNum ulongElement: - return UlongToByte(ulongElement.Data); - case MiNum floatElement: - return SingleToByte(floatElement.Data); - case MiNum doubleElement: - return DoubleToByte(doubleElement.Data); - } - throw new HandlerException( - $"Expected data element that would be convertible to uint8, found {element.GetType()}."); + MiNum sbyteElement => SbyteToByte(sbyteElement.Data), + MiNum byteElement => byteElement.Data, + MiNum intElement => IntToByte(intElement.Data), + MiNum uintElement => UintToByte(uintElement.Data), + MiNum shortElement => ShortToByte(shortElement.Data), + MiNum ushortElement => UshortToByte(ushortElement.Data), + MiNum longElement => LongToByte(longElement.Data), + MiNum ulongElement => UlongToByte(ulongElement.Data), + MiNum floatElement => SingleToByte(floatElement.Data), + MiNum doubleElement => DoubleToByte(doubleElement.Data), + _ => throw new HandlerException( + $"Expected data element that would be convertible to uint8, found {element.GetType()}."), + }; } /// @@ -152,31 +112,21 @@ namespace MatFileHandler /// Contents of the elements, converted to Int16. public static short[] GetDataAsInt16(DataElement element) { - switch (element) + return element switch { - case MiNum sbyteElement: - return SbyteToInt16(sbyteElement.Data); - case MiNum byteElement: - return ByteToInt16(byteElement.Data); - case MiNum intElement: - return IntToInt16(intElement.Data); - case MiNum uintElement: - return UintToInt16(uintElement.Data); - case MiNum shortElement: - return shortElement.Data; - case MiNum ushortElement: - return UshortToInt16(ushortElement.Data); - case MiNum longElement: - return LongToInt16(longElement.Data); - case MiNum ulongElement: - return UlongToInt16(ulongElement.Data); - case MiNum floatElement: - return SingleToInt16(floatElement.Data); - case MiNum doubleElement: - return DoubleToInt16(doubleElement.Data); - } - throw new HandlerException( - $"Expected data element that would be convertible to int16, found {element.GetType()}."); + MiNum sbyteElement => SbyteToInt16(sbyteElement.Data), + MiNum byteElement => ByteToInt16(byteElement.Data), + MiNum intElement => IntToInt16(intElement.Data), + MiNum uintElement => UintToInt16(uintElement.Data), + MiNum shortElement => shortElement.Data, + MiNum ushortElement => UshortToInt16(ushortElement.Data), + MiNum longElement => LongToInt16(longElement.Data), + MiNum ulongElement => UlongToInt16(ulongElement.Data), + MiNum floatElement => SingleToInt16(floatElement.Data), + MiNum doubleElement => DoubleToInt16(doubleElement.Data), + _ => throw new HandlerException( + $"Expected data element that would be convertible to int16, found {element.GetType()}."), + }; } /// @@ -186,31 +136,21 @@ namespace MatFileHandler /// Contents of the elements, converted to UInt16. public static ushort[] GetDataAsUInt16(DataElement element) { - switch (element) + return element switch { - case MiNum sbyteElement: - return SbyteToUInt16(sbyteElement.Data); - case MiNum byteElement: - return ByteToUInt16(byteElement.Data); - case MiNum intElement: - return IntToUInt16(intElement.Data); - case MiNum uintElement: - return UintToUInt16(uintElement.Data); - case MiNum shortElement: - return ShortToUInt16(shortElement.Data); - case MiNum ushortElement: - return ushortElement.Data; - case MiNum longElement: - return LongToUInt16(longElement.Data); - case MiNum ulongElement: - return UlongToUInt16(ulongElement.Data); - case MiNum floatElement: - return SingleToUInt16(floatElement.Data); - case MiNum doubleElement: - return DoubleToUInt16(doubleElement.Data); - } - throw new HandlerException( - $"Expected data element that would be convertible to uint16, found {element.GetType()}."); + MiNum sbyteElement => SbyteToUInt16(sbyteElement.Data), + MiNum byteElement => ByteToUInt16(byteElement.Data), + MiNum intElement => IntToUInt16(intElement.Data), + MiNum uintElement => UintToUInt16(uintElement.Data), + MiNum shortElement => ShortToUInt16(shortElement.Data), + MiNum ushortElement => ushortElement.Data, + MiNum longElement => LongToUInt16(longElement.Data), + MiNum ulongElement => UlongToUInt16(ulongElement.Data), + MiNum floatElement => SingleToUInt16(floatElement.Data), + MiNum doubleElement => DoubleToUInt16(doubleElement.Data), + _ => throw new HandlerException( + $"Expected data element that would be convertible to uint16, found {element.GetType()}."), + }; } /// @@ -220,31 +160,21 @@ namespace MatFileHandler /// Contents of the elements, converted to Int32. public static int[] GetDataAsInt32(DataElement element) { - switch (element) + return element switch { - case MiNum sbyteElement: - return SbyteToInt32(sbyteElement.Data); - case MiNum byteElement: - return ByteToInt32(byteElement.Data); - case MiNum intElement: - return intElement.Data; - case MiNum uintElement: - return UintToInt32(uintElement.Data); - case MiNum shortElement: - return ShortToInt32(shortElement.Data); - case MiNum ushortElement: - return UshortToInt32(ushortElement.Data); - case MiNum longElement: - return LongToInt32(longElement.Data); - case MiNum ulongElement: - return UlongToInt32(ulongElement.Data); - case MiNum floatElement: - return SingleToInt32(floatElement.Data); - case MiNum doubleElement: - return DoubleToInt32(doubleElement.Data); - } - throw new HandlerException( - $"Expected data element that would be convertible to int32, found {element.GetType()}."); + MiNum sbyteElement => SbyteToInt32(sbyteElement.Data), + MiNum byteElement => ByteToInt32(byteElement.Data), + MiNum intElement => intElement.Data, + MiNum uintElement => UintToInt32(uintElement.Data), + MiNum shortElement => ShortToInt32(shortElement.Data), + MiNum ushortElement => UshortToInt32(ushortElement.Data), + MiNum longElement => LongToInt32(longElement.Data), + MiNum ulongElement => UlongToInt32(ulongElement.Data), + MiNum floatElement => SingleToInt32(floatElement.Data), + MiNum doubleElement => DoubleToInt32(doubleElement.Data), + _ => throw new HandlerException( + $"Expected data element that would be convertible to int32, found {element.GetType()}."), + }; } /// @@ -254,31 +184,21 @@ namespace MatFileHandler /// Contents of the elements, converted to UInt32. public static uint[] GetDataAsUInt32(DataElement element) { - switch (element) + return element switch { - case MiNum sbyteElement: - return SbyteToUInt32(sbyteElement.Data); - case MiNum byteElement: - return ByteToUInt32(byteElement.Data); - case MiNum intElement: - return IntToUInt32(intElement.Data); - case MiNum uintElement: - return uintElement.Data; - case MiNum shortElement: - return ShortToUInt32(shortElement.Data); - case MiNum ushortElement: - return UshortToUInt32(ushortElement.Data); - case MiNum longElement: - return LongToUInt32(longElement.Data); - case MiNum ulongElement: - return UlongToUInt32(ulongElement.Data); - case MiNum floatElement: - return SingleToUInt32(floatElement.Data); - case MiNum doubleElement: - return DoubleToUInt32(doubleElement.Data); - } - throw new HandlerException( - $"Expected data element that would be convertible to uint32, found {element.GetType()}."); + MiNum sbyteElement => SbyteToUInt32(sbyteElement.Data), + MiNum byteElement => ByteToUInt32(byteElement.Data), + MiNum intElement => IntToUInt32(intElement.Data), + MiNum uintElement => uintElement.Data, + MiNum shortElement => ShortToUInt32(shortElement.Data), + MiNum ushortElement => UshortToUInt32(ushortElement.Data), + MiNum longElement => LongToUInt32(longElement.Data), + MiNum ulongElement => UlongToUInt32(ulongElement.Data), + MiNum floatElement => SingleToUInt32(floatElement.Data), + MiNum doubleElement => DoubleToUInt32(doubleElement.Data), + _ => throw new HandlerException( + $"Expected data element that would be convertible to uint32, found {element.GetType()}."), + }; } /// @@ -288,31 +208,21 @@ namespace MatFileHandler /// Contents of the elements, converted to Int64. public static long[] GetDataAsInt64(DataElement element) { - switch (element) + return element switch { - case MiNum sbyteElement: - return SbyteToInt64(sbyteElement.Data); - case MiNum byteElement: - return ByteToInt64(byteElement.Data); - case MiNum intElement: - return IntToInt64(intElement.Data); - case MiNum uintElement: - return UintToInt64(uintElement.Data); - case MiNum shortElement: - return ShortToInt64(shortElement.Data); - case MiNum ushortElement: - return UshortToInt64(ushortElement.Data); - case MiNum longElement: - return longElement.Data; - case MiNum ulongElement: - return UlongToInt64(ulongElement.Data); - case MiNum floatElement: - return SingleToInt64(floatElement.Data); - case MiNum doubleElement: - return DoubleToInt64(doubleElement.Data); - } - throw new HandlerException( - $"Expected data element that would be convertible to int64, found {element.GetType()}."); + MiNum sbyteElement => SbyteToInt64(sbyteElement.Data), + MiNum byteElement => ByteToInt64(byteElement.Data), + MiNum intElement => IntToInt64(intElement.Data), + MiNum uintElement => UintToInt64(uintElement.Data), + MiNum shortElement => ShortToInt64(shortElement.Data), + MiNum ushortElement => UshortToInt64(ushortElement.Data), + MiNum longElement => longElement.Data, + MiNum ulongElement => UlongToInt64(ulongElement.Data), + MiNum floatElement => SingleToInt64(floatElement.Data), + MiNum doubleElement => DoubleToInt64(doubleElement.Data), + _ => throw new HandlerException( + $"Expected data element that would be convertible to int64, found {element.GetType()}."), + }; } /// @@ -322,31 +232,21 @@ namespace MatFileHandler /// Contents of the elements, converted to UInt64. public static ulong[] GetDataAsUInt64(DataElement element) { - switch (element) + return element switch { - case MiNum sbyteElement: - return SbyteToUInt64(sbyteElement.Data); - case MiNum byteElement: - return ByteToUInt64(byteElement.Data); - case MiNum intElement: - return IntToUInt64(intElement.Data); - case MiNum uintElement: - return UintToUInt64(uintElement.Data); - case MiNum shortElement: - return ShortToUInt64(shortElement.Data); - case MiNum ushortElement: - return UshortToUInt64(ushortElement.Data); - case MiNum longElement: - return LongToUInt64(longElement.Data); - case MiNum ulongElement: - return ulongElement.Data; - case MiNum floatElement: - return SingleToUInt64(floatElement.Data); - case MiNum doubleElement: - return DoubleToUInt64(doubleElement.Data); - } - throw new HandlerException( - $"Expected data element that would be convertible to uint64, found {element.GetType()}."); + MiNum sbyteElement => SbyteToUInt64(sbyteElement.Data), + MiNum byteElement => ByteToUInt64(byteElement.Data), + MiNum intElement => IntToUInt64(intElement.Data), + MiNum uintElement => UintToUInt64(uintElement.Data), + MiNum shortElement => ShortToUInt64(shortElement.Data), + MiNum ushortElement => UshortToUInt64(ushortElement.Data), + MiNum longElement => LongToUInt64(longElement.Data), + MiNum ulongElement => ulongElement.Data, + MiNum floatElement => SingleToUInt64(floatElement.Data), + MiNum doubleElement => DoubleToUInt64(doubleElement.Data), + _ => throw new HandlerException( + $"Expected data element that would be convertible to uint64, found {element.GetType()}."), + }; } // * to double @@ -1395,4 +1295,4 @@ namespace MatFileHandler return result; } } -} \ No newline at end of file +} diff --git a/MatFileHandler/DataTypeExtensions.cs b/MatFileHandler/DataTypeExtensions.cs index 2b923b4..b1201be 100755 --- a/MatFileHandler/DataTypeExtensions.cs +++ b/MatFileHandler/DataTypeExtensions.cs @@ -16,41 +16,21 @@ namespace MatFileHandler /// Size in bytes. public static int Size(this DataType type) { - switch (type) + return type switch { - case DataType.MiInt8: - return 1; - case DataType.MiUInt8: - return 1; - case DataType.MiInt16: - return 2; - case DataType.MiUInt16: - return 2; - case DataType.MiInt32: - return 4; - case DataType.MiUInt32: - return 4; - case DataType.MiSingle: - return 4; - case DataType.MiDouble: - return 8; - case DataType.MiInt64: - return 8; - case DataType.MiUInt64: - return 8; - case DataType.MiMatrix: - return 0; - case DataType.MiCompressed: - return 0; - case DataType.MiUtf8: - return 1; - case DataType.MiUtf16: - return 2; - case DataType.MiUtf32: - return 4; - default: - throw new ArgumentOutOfRangeException(nameof(type), type, null); - } + DataType.MiInt8 or DataType.MiUInt8 => 1, + DataType.MiInt16 or DataType.MiUInt16 => 2, + DataType.MiInt32 or DataType.MiUInt32 => 4, + DataType.MiSingle => 4, + DataType.MiDouble => 8, + DataType.MiInt64 or DataType.MiUInt64 => 8, + DataType.MiMatrix => 0, + DataType.MiCompressed => 0, + DataType.MiUtf8 => 1, + DataType.MiUtf16 => 2, + DataType.MiUtf32 => 4, + _ => throw new ArgumentOutOfRangeException(nameof(type), type, null), + }; } } -} \ No newline at end of file +} diff --git a/MatFileHandler/DatetimeAdapter.cs b/MatFileHandler/DatetimeAdapter.cs index 5f0f604..55c86d3 100644 --- a/MatFileHandler/DatetimeAdapter.cs +++ b/MatFileHandler/DatetimeAdapter.cs @@ -12,8 +12,6 @@ namespace MatFileHandler public class DatetimeAdapter { private readonly double[] data; - private readonly double[] data2; - private readonly int[] dimensions; private readonly DateTimeOffset epoch; @@ -36,15 +34,13 @@ namespace MatFileHandler case IArrayOf dataArray: data = dataArray.ConvertToDoubleArray() ?? throw new HandlerException("Cannot extract data for the datetime adapter."); - data2 = new double[data.Length]; - dimensions = dataArray.Dimensions; + Dimensions = dataArray.Dimensions; break; case IArrayOf dataComplex: var complexData = dataComplex.ConvertToComplexArray() ?? throw new HandlerException("Cannot extract data for the datetime adapter."); data = complexData.Select(c => c.Real).ToArray(); - data2 = complexData.Select(c => c.Imaginary).ToArray(); - dimensions = dataComplex.Dimensions; + Dimensions = dataComplex.Dimensions; break; default: throw new HandlerException("Datetime data not found."); @@ -54,7 +50,7 @@ namespace MatFileHandler /// /// Gets datetime array dimensions. /// - public int[] Dimensions => dimensions; + public int[] Dimensions { get; } /// /// Gets values of datetime object at given position in the array converted to . @@ -66,12 +62,12 @@ namespace MatFileHandler get { var milliseconds = data[Dimensions.DimFlatten(list)]; - if (milliseconds < -62_135_596_800_000.0 || milliseconds > 253_402_300_799_999.0) + return milliseconds switch { - return null; - } - return epoch.AddMilliseconds(milliseconds); + < -62_135_596_800_000.0 or > 253_402_300_799_999.0 => null, + _ => epoch.AddMilliseconds(milliseconds), + }; } } } -} \ No newline at end of file +} diff --git a/MatFileHandler/DurationAdapter.cs b/MatFileHandler/DurationAdapter.cs index aad282e..ecafe63 100644 --- a/MatFileHandler/DurationAdapter.cs +++ b/MatFileHandler/DurationAdapter.cs @@ -9,7 +9,6 @@ namespace MatFileHandler /// public class DurationAdapter { - private readonly int[] dimensions; private readonly double[] data; /// @@ -27,13 +26,13 @@ namespace MatFileHandler var dataObject = matObject["millis", 0]; data = dataObject.ConvertToDoubleArray() ?? throw new HandlerException("Cannot extract data for the duration adapter."); - dimensions = dataObject.Dimensions; + Dimensions = dataObject.Dimensions; } /// /// Gets duration array dimensions. /// - public int[] Dimensions => dimensions; + public int[] Dimensions { get; } /// /// Gets duration object at given position. @@ -42,4 +41,4 @@ namespace MatFileHandler /// Value. public TimeSpan this[params int[] list] => TimeSpan.FromTicks((long)(10000.0 * data[Dimensions.DimFlatten(list)])); } -} \ No newline at end of file +} diff --git a/MatFileHandler/FakeWriter.cs b/MatFileHandler/FakeWriter.cs index e00e974..ea44d0a 100644 --- a/MatFileHandler/FakeWriter.cs +++ b/MatFileHandler/FakeWriter.cs @@ -222,12 +222,7 @@ namespace MatFileHandler private static int CalculatePadding(int length) { var rem = length % 8; - if (rem == 0) - { - return 0; - } - - return 8 - rem; + return rem == 0 ? 0 : 8 - rem; } private void WriteDataElement(int dataLength) @@ -293,7 +288,7 @@ namespace MatFileHandler private void WriteFieldNames(IEnumerable fieldNames) { var fieldNamesArray = fieldNames.Select(name => Encoding.ASCII.GetBytes(name)).ToArray(); - var maxFieldName = fieldNamesArray.Select(name => name.Length).Max() + 1; + var maxFieldName = fieldNamesArray.Max(name => name.Length) + 1; WriteDataElement(GetLengthOfByteArray(1)); var buffer = new byte[fieldNamesArray.Length * maxFieldName]; var startPosition = 0; diff --git a/MatFileHandler/Header.cs b/MatFileHandler/Header.cs index 06b68ce..a1452ca 100755 --- a/MatFileHandler/Header.cs +++ b/MatFileHandler/Header.cs @@ -4,7 +4,9 @@ using System; using System.Globalization; using System.IO; using System.Linq; +#if !NET461 using System.Runtime.InteropServices; +#endif namespace MatFileHandler { @@ -72,11 +74,9 @@ namespace MatFileHandler var version = reader.ReadInt16(); var endian = reader.ReadInt16(); var isLittleEndian = endian == 19785; - if (!isLittleEndian) - { - throw new NotSupportedException("Big-endian files are not supported."); - } - return new Header(text, subsystemDataOffset, version); + return isLittleEndian + ? new Header(text, subsystemDataOffset, version) + : throw new NotSupportedException("Big-endian files are not supported."); } private static string GetOperatingSystem() @@ -100,4 +100,4 @@ namespace MatFileHandler #endif } } -} \ No newline at end of file +} diff --git a/MatFileHandler/IMatFile.cs b/MatFileHandler/IMatFile.cs index f961286..c4df7e7 100755 --- a/MatFileHandler/IMatFile.cs +++ b/MatFileHandler/IMatFile.cs @@ -27,6 +27,6 @@ namespace MatFileHandler /// The name of the variable to get. /// When this method returns, contains the variable with the specified name, if it is found; otherwise, null. /// True if the file contains a variable with the specified name; otherwise, false. - public bool TryGetVariable(string name, out IVariable? variable); + bool TryGetVariable(string name, out IVariable? variable); } -} \ No newline at end of file +} diff --git a/MatFileHandler/MatFile.cs b/MatFileHandler/MatFile.cs index 4b01602..1c9f71c 100755 --- a/MatFileHandler/MatFile.cs +++ b/MatFileHandler/MatFile.cs @@ -18,11 +18,7 @@ namespace MatFileHandler /// List of variables. public MatFile(IEnumerable variables) { - _variables = new Dictionary(); - foreach (var variable in variables) - { - _variables[variable.Name] = variable; - } + _variables = variables.ToDictionary(v => v.Name, v => v); } /// @@ -41,4 +37,4 @@ namespace MatFileHandler return _variables.TryGetValue(name, out value); } } -} \ No newline at end of file +} diff --git a/MatFileHandler/MatFileHandler.csproj b/MatFileHandler/MatFileHandler.csproj index cdb1070..87470c6 100755 --- a/MatFileHandler/MatFileHandler.csproj +++ b/MatFileHandler/MatFileHandler.csproj @@ -16,7 +16,8 @@ bin\$(Configuration)\ $(OutputPath)\$(TargetFramework)\$(AssemblyName).xml true - 10.0 + true + latest enable true true diff --git a/MatFileHandler/MatFileReader.cs b/MatFileHandler/MatFileReader.cs index 8feb9ef..af48d17 100755 --- a/MatFileHandler/MatFileReader.cs +++ b/MatFileHandler/MatFileReader.cs @@ -1,6 +1,5 @@ // Copyright 2017-2018 Alexander Luzgarev -using System; using System.Collections.Generic; using System.IO; @@ -28,10 +27,8 @@ namespace MatFileHandler /// Contents of the file. public IMatFile Read() { - using (var reader = new BinaryReader(new PositionTrackingStream(Stream))) - { - return Read(reader); - } + using var reader = new BinaryReader(new PositionTrackingStream(Stream)); + return Read(reader); } /// @@ -95,16 +92,14 @@ namespace MatFileHandler var variables = new List(); foreach (var variable in rawVariables) { - var array = variable.DataElement as MatArray; - if (array is null) + if (variable.DataElement is MatArray array) { - continue; + variables.Add( + new MatVariable( + array, + array.Name, + array.Flags.Variable.HasFlag(Variable.IsGlobal))); } - - variables.Add(new MatVariable( - array, - array.Name, - array.Flags.Variable.HasFlag(Variable.IsGlobal))); } return new MatFile(variables); diff --git a/MatFileHandler/MatFileWriter.cs b/MatFileHandler/MatFileWriter.cs index 3d32afb..67e9d8e 100755 --- a/MatFileHandler/MatFileWriter.cs +++ b/MatFileHandler/MatFileWriter.cs @@ -47,30 +47,28 @@ namespace MatFileHandler public void Write(IMatFile file) { var header = Header.CreateNewHeader(); - using (var writer = new BinaryWriter(Stream)) + using var writer = new BinaryWriter(Stream); + WriteHeader(writer, header); + foreach (var variable in file.Variables) { - WriteHeader(writer, header); - foreach (var variable in file.Variables) + switch (_options.UseCompression) { - switch (_options.UseCompression) - { - case CompressionUsage.Always: - if (Stream.CanSeek) - { - WriteCompressedVariableToSeekableStream(writer, variable); - } - else - { - WriteCompressedVariableToUnseekableStream(writer, variable); - } + case CompressionUsage.Always: + if (Stream.CanSeek) + { + WriteCompressedVariableToSeekableStream(writer, variable); + } + else + { + WriteCompressedVariableToUnseekableStream(writer, variable); + } - break; - case CompressionUsage.Never: - WriteVariable(writer, variable); - break; - default: - throw new NotImplementedException(); - } + break; + case CompressionUsage.Never: + WriteVariable(writer, variable); + break; + default: + throw new NotImplementedException(); } } } @@ -150,7 +148,7 @@ namespace MatFileHandler } private static byte[] ConvertToByteArray(T[] data) - where T : struct + where T : struct { int size; if (typeof(T) == typeof(sbyte)) @@ -193,6 +191,10 @@ namespace MatFileHandler { size = sizeof(double); } + else if (typeof(T) == typeof(bool)) + { + size = sizeof(bool); + } else { throw new NotSupportedException(); @@ -227,7 +229,7 @@ namespace MatFileHandler WriteTag(writer, new Tag(DataType.MiUInt32, 8)); writer.Write((byte)flags.Class); writer.Write(flag); - writer.Write(new byte[] { 0, 0, 0, 0, 0, 0 }); + writer.Write([0, 0, 0, 0, 0, 0]); } private static void WriteSparseArrayFlags(BinaryWriter writer, SparseArrayFlags flags) @@ -236,7 +238,7 @@ namespace MatFileHandler WriteTag(writer, new Tag(DataType.MiUInt32, 8)); writer.Write((byte)flags.ArrayFlags.Class); writer.Write(flag); - writer.Write(new byte[] { 0, 0 }); + writer.Write([0, 0]); writer.Write(flags.NzMax); } @@ -281,10 +283,7 @@ namespace MatFileHandler WriteDataElement(writer, DataType.MiDouble, ConvertToByteArray(doubleArray.Data)); break; case IArrayOf boolArray: - WriteDataElement( - writer, - DataType.MiUInt8, - boolArray.Data.Select(element => element ? (byte)1 : (byte)0).ToArray()); + WriteDataElement(writer, DataType.MiUInt8, ConvertToByteArray(boolArray.Data)); break; case IArrayOf> complexSbyteArray: WriteComplexValues(writer, DataType.MiInt8, ConvertToPairOfByteArrays(complexSbyteArray.Data)); @@ -324,57 +323,33 @@ namespace MatFileHandler private static ArrayFlags GetArrayFlags(IArray array, bool isGlobal) { var variableFlags = isGlobal ? Variable.IsGlobal : 0; - switch (array) + return array switch { - case IArrayOf _: - return new ArrayFlags(ArrayType.MxInt8, variableFlags); - case IArrayOf _: - return new ArrayFlags(ArrayType.MxUInt8, variableFlags); - case IArrayOf _: - return new ArrayFlags(ArrayType.MxInt16, variableFlags); - case IArrayOf _: - return new ArrayFlags(ArrayType.MxUInt16, variableFlags); - case IArrayOf _: - return new ArrayFlags(ArrayType.MxInt32, variableFlags); - case IArrayOf _: - return new ArrayFlags(ArrayType.MxUInt32, variableFlags); - case IArrayOf _: - return new ArrayFlags(ArrayType.MxInt64, variableFlags); - case IArrayOf _: - return new ArrayFlags(ArrayType.MxUInt64, variableFlags); - case IArrayOf _: - return new ArrayFlags(ArrayType.MxSingle, variableFlags); - case IArrayOf _: - return new ArrayFlags(ArrayType.MxDouble, variableFlags); - case IArrayOf _: - return new ArrayFlags(ArrayType.MxUInt8, variableFlags | Variable.IsLogical); - case IArrayOf> _: - return new ArrayFlags(ArrayType.MxInt8, variableFlags | Variable.IsComplex); - case IArrayOf> _: - return new ArrayFlags(ArrayType.MxUInt8, variableFlags | Variable.IsComplex); - case IArrayOf> _: - return new ArrayFlags(ArrayType.MxInt16, variableFlags | Variable.IsComplex); - case IArrayOf> _: - return new ArrayFlags(ArrayType.MxUInt16, variableFlags | Variable.IsComplex); - case IArrayOf> _: - return new ArrayFlags(ArrayType.MxInt32, variableFlags | Variable.IsComplex); - case IArrayOf> _: - return new ArrayFlags(ArrayType.MxUInt32, variableFlags | Variable.IsComplex); - case IArrayOf> _: - return new ArrayFlags(ArrayType.MxInt64, variableFlags | Variable.IsComplex); - case IArrayOf> _: - return new ArrayFlags(ArrayType.MxUInt64, variableFlags | Variable.IsComplex); - case IArrayOf> _: - return new ArrayFlags(ArrayType.MxSingle, variableFlags | Variable.IsComplex); - case IArrayOf _: - return new ArrayFlags(ArrayType.MxDouble, variableFlags | Variable.IsComplex); - case IStructureArray _: - return new ArrayFlags(ArrayType.MxStruct, variableFlags); - case ICellArray _: - return new ArrayFlags(ArrayType.MxCell, variableFlags); - default: - throw new NotSupportedException(); - } + IArrayOf => new ArrayFlags(ArrayType.MxInt8, variableFlags), + IArrayOf => new ArrayFlags(ArrayType.MxUInt8, variableFlags), + IArrayOf => new ArrayFlags(ArrayType.MxInt16, variableFlags), + IArrayOf => new ArrayFlags(ArrayType.MxUInt16, variableFlags), + IArrayOf => new ArrayFlags(ArrayType.MxInt32, variableFlags), + IArrayOf => new ArrayFlags(ArrayType.MxUInt32, variableFlags), + IArrayOf => new ArrayFlags(ArrayType.MxInt64, variableFlags), + IArrayOf => new ArrayFlags(ArrayType.MxUInt64, variableFlags), + IArrayOf => new ArrayFlags(ArrayType.MxSingle, variableFlags), + IArrayOf => new ArrayFlags(ArrayType.MxDouble, variableFlags), + IArrayOf => new ArrayFlags(ArrayType.MxUInt8, variableFlags | Variable.IsLogical), + IArrayOf> => new ArrayFlags(ArrayType.MxInt8, variableFlags | Variable.IsComplex), + IArrayOf> => new ArrayFlags(ArrayType.MxUInt8, variableFlags | Variable.IsComplex), + IArrayOf> => new ArrayFlags(ArrayType.MxInt16, variableFlags | Variable.IsComplex), + IArrayOf> => new ArrayFlags(ArrayType.MxUInt16, variableFlags | Variable.IsComplex), + IArrayOf> => new ArrayFlags(ArrayType.MxInt32, variableFlags | Variable.IsComplex), + IArrayOf> => new ArrayFlags(ArrayType.MxUInt32, variableFlags | Variable.IsComplex), + IArrayOf> => new ArrayFlags(ArrayType.MxInt64, variableFlags | Variable.IsComplex), + IArrayOf> => new ArrayFlags(ArrayType.MxUInt64, variableFlags | Variable.IsComplex), + IArrayOf> => new ArrayFlags(ArrayType.MxSingle, variableFlags | Variable.IsComplex), + IArrayOf => new ArrayFlags(ArrayType.MxDouble, variableFlags | Variable.IsComplex), + IStructureArray => new ArrayFlags(ArrayType.MxStruct, variableFlags), + ICellArray => new ArrayFlags(ArrayType.MxCell, variableFlags), + _ => throw new NotSupportedException(), + }; } private static SparseArrayFlags GetSparseArrayFlags(ISparseArrayOf array, bool isGlobal, uint nonZero) @@ -466,9 +441,8 @@ namespace MatFileHandler { WriteDataElement(writer, DataType.MiDouble, ConvertToByteArray(data)); } - else if (data is Complex[]) + else if (data is Complex[] complexData) { - var complexData = data as Complex[]; WriteDataElement( writer, DataType.MiDouble, @@ -478,13 +452,12 @@ namespace MatFileHandler DataType.MiDouble, ConvertToByteArray(complexData.Select(c => c.Imaginary).ToArray())); } - else if (data is bool[]) + else if (data is bool[] boolData) { - var boolData = data as bool[]; WriteDataElement( writer, DataType.MiUInt8, - boolData.Select(element => element ? (byte)1 : (byte)0).ToArray()); + ConvertToByteArray(boolData)); } } @@ -538,8 +511,8 @@ namespace MatFileHandler private static void WriteFieldNames(BinaryWriter writer, IEnumerable fieldNames) { var fieldNamesArray = fieldNames.Select(name => Encoding.ASCII.GetBytes(name)).ToArray(); - var maxFieldName = fieldNamesArray.Select(name => name.Length).Max() + 1; - WriteDataElement(writer, DataType.MiInt32, ConvertToByteArray(new[] { maxFieldName })); + var maxFieldName = fieldNamesArray.Max(name => name.Length) + 1; + WriteDataElement(writer, DataType.MiInt32, ConvertToByteArray([maxFieldName])); var buffer = new byte[fieldNamesArray.Length * maxFieldName]; var startPosition = 0; foreach (var name in fieldNamesArray) @@ -672,31 +645,27 @@ namespace MatFileHandler private void WriteCompressedVariableToUnseekableStream(BinaryWriter writer, IVariable variable) { - using (var compressedStream = new MemoryStream()) + using var compressedStream = new MemoryStream(); + uint crc; + using (var originalStream = new MemoryStream()) { - uint crc; - using (var originalStream = new MemoryStream()) - { - using (var internalWriter = new BinaryWriter(originalStream)) - { - WriteVariable(internalWriter, variable); - originalStream.Position = 0; - crc = CalculateAdler32Checksum(originalStream); - originalStream.Position = 0; - using (var compressionStream = - new DeflateStream(compressedStream, CompressionMode.Compress, leaveOpen: true)) - { - originalStream.CopyTo(compressionStream); - } - } - } - compressedStream.Position = 0; - WriteTag(writer, new Tag(DataType.MiCompressed, (int)(compressedStream.Length + 6))); - writer.Write((byte)0x78); - writer.Write((byte)0x9c); - compressedStream.CopyTo(writer.BaseStream); - writer.Write(BitConverter.GetBytes(crc).Reverse().ToArray()); + using var internalWriter = new BinaryWriter(originalStream); + WriteVariable(internalWriter, variable); + originalStream.Position = 0; + crc = CalculateAdler32Checksum(originalStream); + originalStream.Position = 0; + using var compressionStream = new DeflateStream( + compressedStream, + CompressionMode.Compress, + leaveOpen: true); + originalStream.CopyTo(compressionStream); } + compressedStream.Position = 0; + WriteTag(writer, new Tag(DataType.MiCompressed, (int)(compressedStream.Length + 6))); + writer.Write((byte)0x78); + writer.Write((byte)0x9c); + compressedStream.CopyTo(writer.BaseStream); + writer.Write(BitConverter.GetBytes(crc).Reverse().ToArray()); } } } diff --git a/MatFileHandler/MatFileWriterOptions.cs b/MatFileHandler/MatFileWriterOptions.cs index 07b09f2..11b0ff1 100644 --- a/MatFileHandler/MatFileWriterOptions.cs +++ b/MatFileHandler/MatFileWriterOptions.cs @@ -10,7 +10,7 @@ namespace MatFileHandler /// /// Gets default options. /// - public static MatFileWriterOptions Default => new MatFileWriterOptions + public static MatFileWriterOptions Default => new() { UseCompression = CompressionUsage.Always, }; @@ -20,4 +20,4 @@ namespace MatFileHandler /// public CompressionUsage UseCompression { get; set; } } -} \ No newline at end of file +} diff --git a/MatFileHandler/MatSparseArrayOf.cs b/MatFileHandler/MatSparseArrayOf.cs index 4cc8fa8..dd52d37 100755 --- a/MatFileHandler/MatSparseArrayOf.cs +++ b/MatFileHandler/MatSparseArrayOf.cs @@ -93,15 +93,12 @@ namespace MatFileHandler private (int row, int column) GetRowAndColumn(int[] indices) { - switch (indices.Length) + return indices.Length switch { - case 1: - return (indices[0] % Dimensions[0], indices[0] / Dimensions[0]); - case 2: - return (indices[0], indices[1]); - default: - throw new NotSupportedException("Invalid index for sparse array."); - } + 1 => (indices[0] % Dimensions[0], indices[0] / Dimensions[0]), + 2 => (indices[0], indices[1]), + _ => throw new NotSupportedException("Invalid index for sparse array."), + }; } } } diff --git a/MatFileHandler/OpaqueLink.cs b/MatFileHandler/OpaqueLink.cs index c94a53e..0bc242b 100644 --- a/MatFileHandler/OpaqueLink.cs +++ b/MatFileHandler/OpaqueLink.cs @@ -78,15 +78,7 @@ namespace MatFileHandler /// public IArray this[string field, params int[] list] { - get - { - if (TryGetValue(field, out var result, list)) - { - return result!; - } - - throw new ArgumentOutOfRangeException(nameof(list)); - } + get => TryGetValue(field, out var result, list) ? result! : throw new ArgumentOutOfRangeException(nameof(list)); set => throw new NotImplementedException(); } @@ -106,7 +98,7 @@ namespace MatFileHandler { var index = Dimensions.DimFlatten(list); var maybeFieldIndex = SubsystemData.ClassInformation[ClassIndex].FindField(field); - if (!(maybeFieldIndex is int fieldIndex)) + if (maybeFieldIndex is not int fieldIndex) { output = default; return false; @@ -171,8 +163,8 @@ namespace MatFileHandler } } - /// #pragma warning disable CS8767 + /// public bool TryGetValue(string key, out IArray? value) #pragma warning restore CS8767 { diff --git a/MatFileHandler/PositionTrackingStream.cs b/MatFileHandler/PositionTrackingStream.cs index f62b931..b190397 100644 --- a/MatFileHandler/PositionTrackingStream.cs +++ b/MatFileHandler/PositionTrackingStream.cs @@ -48,7 +48,7 @@ internal sealed class PositionTrackingStream : Stream /// public override int Read(byte[] buffer, int offset, int count) { - int bytesRead = _baseStream.Read(buffer, offset, count); + var bytesRead = _baseStream.Read(buffer, offset, count); _position += bytesRead; diff --git a/MatFileHandler/StringAdapter.cs b/MatFileHandler/StringAdapter.cs index 8815d1c..6db7f87 100644 --- a/MatFileHandler/StringAdapter.cs +++ b/MatFileHandler/StringAdapter.cs @@ -10,7 +10,6 @@ namespace MatFileHandler /// public class StringAdapter { - private readonly int[] dimensions; private readonly string[] strings; /// @@ -28,13 +27,13 @@ namespace MatFileHandler var binaryData = matObject["any", 0] as IArrayOf ?? throw new HandlerException("Cannot extract string data."); - (dimensions, strings) = ParseBinaryData(binaryData.Data); + (Dimensions, strings) = ParseBinaryData(binaryData.Data); } /// /// Gets string array dimensions. /// - public int[] Dimensions => dimensions; + public int[] Dimensions { get; } /// /// Gets string object at given position. @@ -76,4 +75,4 @@ namespace MatFileHandler return (d, strings); } } -} \ No newline at end of file +} diff --git a/MatFileHandler/Substream.cs b/MatFileHandler/Substream.cs index df32ef0..f59b744 100644 --- a/MatFileHandler/Substream.cs +++ b/MatFileHandler/Substream.cs @@ -49,7 +49,7 @@ namespace MatFileHandler /// public override int Read(byte[] buffer, int offset, int count) { - int bytesRead = _baseStream.Read(buffer, offset, (int)Math.Min(count, Length - _bytesRead)); + var bytesRead = _baseStream.Read(buffer, offset, (int)Math.Min(count, Length - _bytesRead)); _bytesRead += bytesRead; diff --git a/MatFileHandler/SubsystemData.cs b/MatFileHandler/SubsystemData.cs index fe1947e..6fa3a02 100644 --- a/MatFileHandler/SubsystemData.cs +++ b/MatFileHandler/SubsystemData.cs @@ -119,12 +119,7 @@ namespace MatFileHandler /// Field index. public int? FindField(string fieldName) { - if (fieldToIndex.TryGetValue(fieldName, out var index)) - { - return index; - } - - return null; + return fieldToIndex.TryGetValue(fieldName, out var index) ? index : null; } } @@ -192,4 +187,4 @@ namespace MatFileHandler public string[] FieldNames { get; } } } -} \ No newline at end of file +} diff --git a/MatFileHandler/SubsystemDataReader.cs b/MatFileHandler/SubsystemDataReader.cs index 980fabc..b6bfd7b 100644 --- a/MatFileHandler/SubsystemDataReader.cs +++ b/MatFileHandler/SubsystemDataReader.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; using System.Text; @@ -357,7 +356,7 @@ namespace MatFileHandler return array; } - private struct ObjectClassInformation + private readonly struct ObjectClassInformation { public ObjectClassInformation(int embeddedObjectPosition, int objectPosition, int loadingOrder, int classId) { diff --git a/MatFileHandler/TableAdapter.cs b/MatFileHandler/TableAdapter.cs index c506133..814ff9f 100644 --- a/MatFileHandler/TableAdapter.cs +++ b/MatFileHandler/TableAdapter.cs @@ -87,7 +87,7 @@ namespace MatFileHandler .Where(i => VariableNames[i] == variableName) .Select(i => (int?)i) .FirstOrDefault(); - if (!(maybeIndex is int index)) + if (maybeIndex is not int index) { throw new ArgumentOutOfRangeException(nameof(variableName), $"Variable '{variableName}' not found."); }