diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a3b322e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,280 @@ +# Remove the line below if you want to inherit .editorconfig settings from higher directories +root = true + +[*] +end_of_line = crlf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +tab_width = 4 + +[*.{css,js,json,less,html}] +indent_size = 2 +charset = utf-8 + +# Xml project files +[*.{sln,csproj,vbproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj,yml}] +indent_size = 2 +charset = utf-8 + +# Xml build files +[*.builds] +indent_size = 2 +charset = utf-8 + +# Xml files +[*.{xml,stylecop,resx,ruleset}] +indent_size = 2 +charset = utf-8 + +# Xml config files +[*.{props,targets,config,nuspec}] +indent_size = 2 +charset = utf-8 + +# Shell scripts +[*.sh] +end_of_line = lf +charset = utf-8 + +[*.{cmd,bat,ps,ps1}] +end_of_line = crlf +charset = utf-8 + +# C# files +[*.cs] + +#### 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 + +# Charset +charset = utf-8 + +#### .NET Coding Conventions #### + +# Organize usings +dotnet_separate_import_directive_groups = false +dotnet_sort_system_directives_first = true +file_header_template = unset + +# this. and Me. preferences +dotnet_style_qualification_for_field = false : suggestion +dotnet_style_qualification_for_property = false : suggestion +dotnet_style_qualification_for_method = false : suggestion +dotnet_style_qualification_for_event = false : suggestion + +# 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 : silent + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members : silent + +# 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 = when_types_loosely_match +dotnet_style_prefer_compound_assignment = true +dotnet_style_prefer_conditional_expression_over_assignment = true +dotnet_style_prefer_conditional_expression_over_return = true +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 + +# 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 = false +csharp_style_var_for_built_in_types = false +csharp_style_var_when_type_is_apparent = false + +# 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 = false:silent +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,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async +csharp_style_prefer_readonly_struct = true +csharp_style_prefer_readonly_struct_member = true + +# Code-block preferences +csharp_prefer_braces = true:silent +csharp_prefer_simple_using_statement = true:suggestion +csharp_style_namespace_declarations = block_scoped:silent +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_primary_constructors = true:suggestion +csharp_style_prefer_top_level_statements = true:silent + +# Expression-level preferences +csharp_prefer_simple_default_expression = true +csharp_style_deconstructed_variable_declaration = true : suggestion +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:silent + +# 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 + +[*.{cs,vb}] +dotnet_style_op +erator_placement_when_wrapping = beginning_of_line +tab_width = 4 +indent_size = 4 diff --git a/.gitignore b/.gitignore index 57a1574..0434df8 100644 --- a/.gitignore +++ b/.gitignore @@ -129,7 +129,7 @@ publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings +# TODO: Comment the next line if you want to checkin your web deploy settings # but database connection strings (with potential passwords) will be unencrypted *.pubxml *.publishproj @@ -194,3 +194,5 @@ FakesAssemblies/ # Visual Studio 6 workspace options file *.opt + +TestResults/ diff --git a/.globalconfig b/.globalconfig new file mode 100644 index 0000000..895f5aa --- /dev/null +++ b/.globalconfig @@ -0,0 +1,7 @@ +is_global = true +# Top level entry required to mark this as a global AnalyzerConfig file +# more info here https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/configuration-files +# -------------------------------------------------------------------------------------------------------- + +# Analyzers +dotnet_code_quality.ca1802.api_surface = private, internal diff --git a/GSMEncoding.sln b/GSMEncoding.sln index acec2b0..d1a39eb 100644 --- a/GSMEncoding.sln +++ b/GSMEncoding.sln @@ -1,9 +1,24 @@  -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mediaburst.Text", "Mediaburst.Text.csproj", "{695DABE3-1699-452B-A633-9649E1CADE4B}" +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34714.143 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mediaburst.Text", "src\Mediaburst.Text\Mediaburst.Text.csproj", "{695DABE3-1699-452B-A633-9649E1CADE4B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mediaburst.Text.Tests", "Tests\Mediaburst.Text.Tests.csproj", "{3427C04B-0634-45BD-B516-7DD7A8E645FB}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mediaburst.Text.Tests", "Tests\Mediaburst.Text.Tests\Mediaburst.Text.Tests.csproj", "{3427C04B-0634-45BD-B516-7DD7A8E645FB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBurst.TextCore", "src\MediaBurst.TextCore\MediaBurst.TextCore.csproj", "{51A398B9-6D71-425D-9C81-16B53A469DAD}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CBB4B625-ADD6-417C-83A5-410C577F15D3}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + .gitignore = .gitignore + .globalconfig = .globalconfig + License.txt = License.txt + README.md = README.md + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mediaburst.TextCore.Tests", "Tests\Mediaburst.TextCore.Tests\Mediaburst.TextCore.Tests.csproj", "{C69A09D1-609A-4D5E-859E-993AA706398F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -19,8 +34,19 @@ Global {3427C04B-0634-45BD-B516-7DD7A8E645FB}.Debug|Any CPU.Build.0 = Debug|Any CPU {3427C04B-0634-45BD-B516-7DD7A8E645FB}.Release|Any CPU.ActiveCfg = Release|Any CPU {3427C04B-0634-45BD-B516-7DD7A8E645FB}.Release|Any CPU.Build.0 = Release|Any CPU + {51A398B9-6D71-425D-9C81-16B53A469DAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {51A398B9-6D71-425D-9C81-16B53A469DAD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {51A398B9-6D71-425D-9C81-16B53A469DAD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {51A398B9-6D71-425D-9C81-16B53A469DAD}.Release|Any CPU.Build.0 = Release|Any CPU + {C69A09D1-609A-4D5E-859E-993AA706398F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C69A09D1-609A-4D5E-859E-993AA706398F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C69A09D1-609A-4D5E-859E-993AA706398F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C69A09D1-609A-4D5E-859E-993AA706398F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {EC3854D7-089E-4D1A-8FFA-43CA335F8E67} + EndGlobalSection EndGlobal diff --git a/Tests/Mediaburst.Text.Tests.csproj b/Tests/Mediaburst.Text.Tests.csproj deleted file mode 100644 index b19f04c..0000000 --- a/Tests/Mediaburst.Text.Tests.csproj +++ /dev/null @@ -1,68 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {3427C04B-0634-45BD-B516-7DD7A8E645FB} - Library - Properties - Mediaburst.Text.Tests - Mediaburst.Text.Tests - v4.0 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\NUnit.2.6.4\lib\nunit.framework.dll - True - - - - - - - - - - - - - - - - {695DABE3-1699-452B-A633-9649E1CADE4B} - Mediaburst.Text - - - - - - - - \ No newline at end of file diff --git a/Tests/GsmEncodingTests.cs b/Tests/Mediaburst.Text.Tests/GsmEncodingTests.cs similarity index 78% rename from Tests/GsmEncodingTests.cs rename to Tests/Mediaburst.Text.Tests/GsmEncodingTests.cs index a40e9e7..c6ba13d 100644 --- a/Tests/GsmEncodingTests.cs +++ b/Tests/Mediaburst.Text.Tests/GsmEncodingTests.cs @@ -1,5 +1,4 @@ -using NUnit.Framework; - +using NUnit.Framework; namespace Mediaburst.Text.Tests { @@ -31,7 +30,7 @@ public class GsmEncodingTests /// /// Regular string encoding - /// + /// [Test] public void GetBytes_NormalString_Success() { @@ -40,15 +39,15 @@ public void GetBytes_NormalString_Success() var result = m_GsmEncoding.GetBytes(input); - Assert.AreEqual(expectedResult, result); + Assert.That(result, Is.EqualTo(expectedResult)); } #region NULL tests /// /// NULL character in the middle of string should be replaced with space (0x20) - /// - [Test, Ignore] // Need to check expected behaviour on this + /// + [Test, Ignore("Need to check expected behaviour on this")] public void GetBytes_NullInsideString_Success() { const string input = "a\0b"; @@ -56,13 +55,13 @@ public void GetBytes_NullInsideString_Success() var result = m_GsmEncoding.GetBytes(input); - Assert.AreEqual(expectedResult, result); + Assert.That(result, Is.EqualTo(expectedResult)); } /// /// NULL character in the middle of string should not be replaced with space (32) if followed by FORM FEED - /// - [Test, Ignore] // Need to check expected behaviour on this + /// + [Test, Ignore("Need to check expected behaviour on this")] public void GetBytes_NullFollowedByFormFeedInsideString_Success() { string input = "a\0" + _FF + "b"; @@ -70,13 +69,13 @@ public void GetBytes_NullFollowedByFormFeedInsideString_Success() var result = m_GsmEncoding.GetBytes(input); - Assert.AreEqual(expectedResult, result); + Assert.That(result, Is.EqualTo(expectedResult)); } /// /// Sequence of NULL characters in the middle of string should be replaced with spaces (32) - /// - [Test, Ignore] // Need to check expected behaviour on this + /// + [Test, Ignore("Need to check expected behaviour on this")] public void GetBytes_SequenceOfNullsInsideString_Success() { const string input = "a\0\0\0b"; @@ -84,27 +83,27 @@ public void GetBytes_SequenceOfNullsInsideString_Success() var result = m_GsmEncoding.GetBytes(input); - Assert.AreEqual(expectedResult, result); + Assert.That(result, Is.EqualTo(expectedResult)); } /// /// Sequence of NULL characters followed by form feed in the middle of string should not be replaced with spaces (32) - /// - [Test, Ignore] // Need to check expected behaviour on this + /// + [Test, Ignore("Need to check expected behaviour on this")] public void GetBytes_SequenceOfNullsFollowedByFormFeedInsideString_Success() { var input = "a\0\0\0" + _FF + "b"; var expectedResult = new byte[] { 97, 0, 0, 0, 27, 10, 98 }; - + var result = m_GsmEncoding.GetBytes(input); - Assert.AreEqual(expectedResult, result); + Assert.That(result, Is.EqualTo(expectedResult)); } /// /// NULL character in the end of string should be encoded as NULL - /// - [Test, Ignore] // Need to check expected behaviour on this + /// + [Test, Ignore("Need to check expected behaviour on this")] public void GetBytes_NullInTheEndOfString_Success() { const string input = "ab\0"; @@ -112,7 +111,7 @@ public void GetBytes_NullInTheEndOfString_Success() var result = m_GsmEncoding.GetBytes(input); - Assert.AreEqual(expectedResult, result); + Assert.That(result, Is.EqualTo(expectedResult)); } #endregion NULL tests @@ -121,7 +120,7 @@ public void GetBytes_NullInTheEndOfString_Success() /// /// COMMERCIAL AT character in the middle of string and not followed by NULL - /// + /// [Test] public void GetBytes_AtInTheMiddleOfString_Success() { @@ -130,13 +129,13 @@ public void GetBytes_AtInTheMiddleOfString_Success() var result = m_GsmEncoding.GetBytes(input); - Assert.AreEqual(expectedResult, result); + Assert.That(result, Is.EqualTo(expectedResult)); } /// /// COMMERCIAL AT character in the end of string. Encoder should append CARRIAGE RETURN - /// - [Test, Ignore] // Think the behaviour is wrong here + /// + [Test, Ignore("Think the behaviour is wrong here")] public void GetBytes_AtInTheEndOfString_Success() { const string input = "ab@"; @@ -144,14 +143,14 @@ public void GetBytes_AtInTheEndOfString_Success() var result = m_GsmEncoding.GetBytes(input); - Assert.AreEqual(expectedResult, result); + Assert.That(result, Is.EqualTo(expectedResult)); } /// - /// COMMERCIAL AT character in the middle of string followed by NULL. + /// COMMERCIAL AT character in the middle of string followed by NULL. /// Encoder should not append CARRIAGE RETURN because this NULL will be converted to space - /// - [Test, Ignore] // Need to check expected behaviour on this + /// + [Test, Ignore("Need to check expected behaviour on this")] public void GetBytes_AtFollowedByNullInTheMiddleOfString_Success() { const string input = "a@\0b"; @@ -159,14 +158,14 @@ public void GetBytes_AtFollowedByNullInTheMiddleOfString_Success() var result = m_GsmEncoding.GetBytes(input); - Assert.AreEqual(expectedResult, result); + Assert.That(result, Is.EqualTo(expectedResult)); } /// - /// COMMERCIAL AT character in the end of string followed by NULL. + /// COMMERCIAL AT character in the end of string followed by NULL. /// Encoder should append CARRIAGE RETURN because this NULL will not be converted to space - /// - [Test, Ignore] // Need to check expected behaviour on this + /// + [Test, Ignore("Need to check expected behaviour on this")] public void GetBytes_AtFollowedByNullInTheEndOfString_Success() { const string input = "ab@\0"; @@ -174,18 +173,18 @@ public void GetBytes_AtFollowedByNullInTheEndOfString_Success() var result = m_GsmEncoding.GetBytes(input); - Assert.AreEqual(expectedResult, result); + Assert.That(result, Is.EqualTo(expectedResult)); } /// - /// COMMERCIAL AT character in the middle of string followed by NULL and FORM FEED. + /// COMMERCIAL AT character in the middle of string followed by NULL and FORM FEED. /// Encoder should append CARRIAGE RETURN and not replace NULL with space - /// - [Test, Ignore] // Need to check expected behaviour on this + /// + [Test, Ignore("Need to check expected behaviour on this")] public void GetBytes_AtFollowedByNullAndFormFeedInTheMiddleOfString_Success() { var input = "a@\0" + _FF + "b"; - var expectedResult = new byte[] { + var expectedResult = new byte[] { 97, // a 0, 13, // @ 0, // \0 @@ -195,7 +194,7 @@ public void GetBytes_AtFollowedByNullAndFormFeedInTheMiddleOfString_Success() var result = m_GsmEncoding.GetBytes(input); - Assert.AreEqual(expectedResult, result); + Assert.That(result, Is.EqualTo(expectedResult)); } #endregion COMMERCIAL AT tests @@ -206,31 +205,31 @@ public void GetBytes_AtFollowedByNullAndFormFeedInTheMiddleOfString_Success() /// /// Chars from default extended table - /// + /// [Test] public void GetBytesGetString_ExtendedTableChars_Success() { var encoded = m_GsmEncoding.GetBytes(_AllExtTableChars); var decoded = m_GsmEncoding.GetString(encoded); - Assert.AreEqual(_AllExtTableChars, decoded); + Assert.That(decoded, Is.EqualTo(_AllExtTableChars)); } /// /// Main table chars - /// + /// [Test] public void GetBytesGetString_MainTableChars_Success() { var encoded = m_GsmEncoding.GetBytes(_AllMainTableChars); var decoded = m_GsmEncoding.GetString(encoded); - Assert.AreEqual(_AllMainTableChars, decoded); + Assert.That(decoded, Is.EqualTo(_AllMainTableChars)); } /// /// Currency symbols - /// + /// [Test] public void GetBytesGetString_CurrencySymbols_Success() { @@ -239,10 +238,9 @@ public void GetBytesGetString_CurrencySymbols_Success() var encoded = m_GsmEncoding.GetBytes(input); var decoded = m_GsmEncoding.GetString(encoded); - Assert.AreEqual(input, decoded); + Assert.That(decoded, Is.EqualTo(input)); } - #endregion Encode and decode } } diff --git a/Tests/Mediaburst.Text.Tests/Mediaburst.Text.Tests.csproj b/Tests/Mediaburst.Text.Tests/Mediaburst.Text.Tests.csproj new file mode 100644 index 0000000..34d9db4 --- /dev/null +++ b/Tests/Mediaburst.Text.Tests/Mediaburst.Text.Tests.csproj @@ -0,0 +1,90 @@ + + + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {3427C04B-0634-45BD-B516-7DD7A8E645FB} + Library + Properties + Mediaburst.Text.Tests + Mediaburst.Text.Tests + v4.8 + 512 + + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + true + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + + ..\..\packages\NUnit.4.1.0\lib\net462\nunit.framework.dll + + + ..\..\packages\NUnit.4.1.0\lib\net462\nunit.framework.legacy.dll + + + + + ..\..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + + + + + + + + + + + + + {695DABE3-1699-452B-A633-9649E1CADE4B} + Mediaburst.Text + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/Tests/Properties/AssemblyInfo.cs b/Tests/Mediaburst.Text.Tests/Properties/AssemblyInfo.cs similarity index 97% rename from Tests/Properties/AssemblyInfo.cs rename to Tests/Mediaburst.Text.Tests/Properties/AssemblyInfo.cs index 4747fae..3098f18 100644 --- a/Tests/Properties/AssemblyInfo.cs +++ b/Tests/Mediaburst.Text.Tests/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/Tests/Mediaburst.Text.Tests/packages.config b/Tests/Mediaburst.Text.Tests/packages.config new file mode 100644 index 0000000..bd45868 --- /dev/null +++ b/Tests/Mediaburst.Text.Tests/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Tests/Mediaburst.TextCore.Tests/GsmEncodingTests.cs b/Tests/Mediaburst.TextCore.Tests/GsmEncodingTests.cs new file mode 100644 index 0000000..8860777 --- /dev/null +++ b/Tests/Mediaburst.TextCore.Tests/GsmEncodingTests.cs @@ -0,0 +1,249 @@ +using System.Security.Cryptography; +using NUnit.Framework; + + +namespace Mediaburst.TextCore.Tests +{ + [TestFixture] + public class GsmEncodingTests + { + /// + /// FORM FEED unicode character + /// + private const char _FF = '\u000C'; + + /// + /// Contains all characters encodable as 1 byte + /// + private const string _AllMainTableChars = + "\u0040\u00A3\u0024\u00A5\u00E8\u00E9\u00F9\u00EC\u00F2\u00C7\u000A\u00D8\u00F8\u000D\u00C5\u00E5\u0394\u005F\u03A6\u0393\u039B\u03A9\u03A0\u03A8\u03A3\u0398\u039E\u00C6\u00E6\u00DF\u00C9\u0020\u0021\u0022\u0023\u00A4\u0025\u0026\u0027\u0028\u0029\u002A\u002B\u002C\u002D\u002E\u002F\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u003A\u003B\u003C\u003D\u003E\u003F\u00A1\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004A\u004B\u004C\u004D\u004E\u004F\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057\u0058\u0059\u005A\u00C4\u00D6\u00D1\u00DC\u00A7\u00BF\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068\u0069\u006A\u006B\u006C\u006D\u006E\u006F\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077\u0078\u0079\u007A\u00E4\u00F6\u00F1\u00FC\u00E0"; + + /// + /// Contains all characters encodable using default extension table + /// + private const string _AllExtTableChars = "\u000C\u005E\u007B\u007D\u005C\u005B\u007E\u005D\u007C\u20AC"; + + /// + /// Encoding instance to be used in tests + /// + private readonly GSMEncoding m_GsmEncoding = new GSMEncoding(); + + #region GetBytes + + /// + /// Regular string encoding + /// + [Test] + public void GetBytes_NormalString_Success() + { + const string input = "abcd"; + var expectedResult = new byte[] { 97, 98, 99, 100 }; + + var result = m_GsmEncoding.GetBytes(input); + + Assert.That(result, Is.EqualTo(expectedResult)); + } + + #region NULL tests + + /// + /// NULL character in the middle of string should be replaced with space (0x20) + /// + [Test, Ignore("Need to check expected behaviour on this")] + public void GetBytes_NullInsideString_Success() + { + const string input = "a\0b"; + var expectedResult = new byte[] { 97, 32, 98 }; + + var result = m_GsmEncoding.GetBytes(input); + + Assert.That(result, Is.EqualTo(expectedResult)); + } + + /// + /// NULL character in the middle of string should not be replaced with space (32) if followed by FORM FEED + /// + [Test, Ignore("Need to check expected behaviour on this")] + public void GetBytes_NullFollowedByFormFeedInsideString_Success() + { + string input = "a\0" + _FF + "b"; + var expectedResult = new byte[] { 97, 0, 27, 10, 98 }; + + var result = m_GsmEncoding.GetBytes(input); + + Assert.That(result, Is.EqualTo(expectedResult)); + } + + /// + /// Sequence of NULL characters in the middle of string should be replaced with spaces (32) + /// + [Test, Ignore("Need to check expected behaviour on this")] + public void GetBytes_SequenceOfNullsInsideString_Success() + { + const string input = "a\0\0\0b"; + var expectedResult = new byte[] { 97, 32, 32, 32, 98 }; + + var result = m_GsmEncoding.GetBytes(input); + + Assert.That(result, Is.EqualTo(expectedResult)); + } + + /// + /// Sequence of NULL characters followed by form feed in the middle of string should not be replaced with spaces (32) + /// + [Test, Ignore("Need to check expected behaviour on this")] + public void GetBytes_SequenceOfNullsFollowedByFormFeedInsideString_Success() + { + var input = "a\0\0\0" + _FF + "b"; + var expectedResult = new byte[] { 97, 0, 0, 0, 27, 10, 98 }; + + var result = m_GsmEncoding.GetBytes(input); + + Assert.That(result, Is.EqualTo(expectedResult)); + } + + /// + /// NULL character in the end of string should be encoded as NULL + /// + [Test, Ignore("Need to check expected behaviour on this")] + public void GetBytes_NullInTheEndOfString_Success() + { + const string input = "ab\0"; + var expectedResult = new byte[] { 97, 98, 0 }; + + var result = m_GsmEncoding.GetBytes(input); + + Assert.That(result, Is.EqualTo(expectedResult)); + } + + #endregion NULL tests + + #region COMMERCIAL AT tests + + /// + /// COMMERCIAL AT character in the middle of string and not followed by NULL + /// + [Test] + public void GetBytes_AtInTheMiddleOfString_Success() + { + const string input = "a@b"; + var expectedResult = new byte[] { 97, 0, 98 }; + + var result = m_GsmEncoding.GetBytes(input); + + Assert.That(result, Is.EqualTo(expectedResult)); + } + + /// + /// COMMERCIAL AT character in the end of string. Encoder should append CARRIAGE RETURN + /// + [Test, Ignore("Think the behaviour is wrong here")] + public void GetBytes_AtInTheEndOfString_Success() + { + const string input = "ab@"; + var expectedResult = new byte[] { 97, 98, 0, 13 }; + + var result = m_GsmEncoding.GetBytes(input); + + Assert.That(result, Is.EqualTo(expectedResult)); + } + + /// + /// COMMERCIAL AT character in the middle of string followed by NULL. + /// Encoder should not append CARRIAGE RETURN because this NULL will be converted to space + /// + [Test, Ignore("Need to check expected behaviour on this")] + public void GetBytes_AtFollowedByNullInTheMiddleOfString_Success() + { + const string input = "a@\0b"; + var expectedResult = new byte[] { 97, 0, 32, 98 }; + + var result = m_GsmEncoding.GetBytes(input); + + Assert.That(result, Is.EqualTo(expectedResult)); + } + + /// + /// COMMERCIAL AT character in the end of string followed by NULL. + /// Encoder should append CARRIAGE RETURN because this NULL will not be converted to space + /// + [Test, Ignore("Need to check expected behaviour on this")] + public void GetBytes_AtFollowedByNullInTheEndOfString_Success() + { + const string input = "ab@\0"; + var expectedResult = new byte[] { 97, 98, 0, 13, 0 }; + + var result = m_GsmEncoding.GetBytes(input); + + Assert.That(result, Is.EqualTo(expectedResult)); + } + + /// + /// COMMERCIAL AT character in the middle of string followed by NULL and FORM FEED. + /// Encoder should append CARRIAGE RETURN and not replace NULL with space + /// + [Test, Ignore("Need to check expected behaviour on this")] + public void GetBytes_AtFollowedByNullAndFormFeedInTheMiddleOfString_Success() + { + var input = "a@\0" + _FF + "b"; + var expectedResult = new byte[] { + 97, // a + 0, 13, // @ + 0, // \0 + 27, 10, // \u000C + 98 // b + }; + + var result = m_GsmEncoding.GetBytes(input); + + Assert.That(result, Is.EqualTo(expectedResult)); + } + + #endregion COMMERCIAL AT tests + + #endregion GetBytes + + #region Encode and decode + + /// + /// Chars from default extended table + /// + [Test] + public void GetBytesGetString_ExtendedTableChars_Success() + { + var encoded = m_GsmEncoding.GetBytes(_AllExtTableChars); + var decoded = m_GsmEncoding.GetString(encoded); + + Assert.That(decoded, Is.EqualTo(_AllExtTableChars)); + } + + /// + /// Main table chars + /// + [Test] + public void GetBytesGetString_MainTableChars_Success() + { + var encoded = m_GsmEncoding.GetBytes(_AllMainTableChars); + var decoded = m_GsmEncoding.GetString(encoded); + + Assert.That(decoded, Is.EqualTo(_AllMainTableChars)); + } + + /// + /// Currency symbols + /// + [Test] + public void GetBytesGetString_CurrencySymbols_Success() + { + const string input = "£$€¥¤"; + + var encoded = m_GsmEncoding.GetBytes(input); + var decoded = m_GsmEncoding.GetString(encoded); + + Assert.That(decoded, Is.EqualTo(input)); + } + + + #endregion Encode and decode + } +} diff --git a/Tests/Mediaburst.TextCore.Tests/Mediaburst.TextCore.Tests.csproj b/Tests/Mediaburst.TextCore.Tests/Mediaburst.TextCore.Tests.csproj new file mode 100644 index 0000000..9991231 --- /dev/null +++ b/Tests/Mediaburst.TextCore.Tests/Mediaburst.TextCore.Tests.csproj @@ -0,0 +1,29 @@ + + + + net8.0 + enable + enable + + false + true + True + + + + + + + + + + + + + + + + + + + diff --git a/Tests/packages.config b/Tests/packages.config deleted file mode 100644 index 904dc42..0000000 --- a/Tests/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/GSMEncoding.cs b/src/MediaBurst.Text/GSMEncoding.cs similarity index 100% rename from GSMEncoding.cs rename to src/MediaBurst.Text/GSMEncoding.cs diff --git a/Mediaburst.Text.csproj b/src/MediaBurst.Text/Mediaburst.Text.csproj similarity index 86% rename from Mediaburst.Text.csproj rename to src/MediaBurst.Text/Mediaburst.Text.csproj index 0daaa55..91cd33d 100644 --- a/Mediaburst.Text.csproj +++ b/src/MediaBurst.Text/Mediaburst.Text.csproj @@ -1,5 +1,5 @@  - + Debug AnyCPU @@ -10,12 +10,13 @@ Properties Mediaburst.Text Mediaburst.Text - v4.0 + v4.8 512 SAK SAK SAK SAK + true @@ -25,6 +26,9 @@ DEBUG;TRACE prompt 4 + false + MinimumRecommendedRules.ruleset + true pdbonly @@ -33,6 +37,7 @@ TRACE prompt 4 + false true diff --git a/Mediaburst.Text.nuspec b/src/MediaBurst.Text/Mediaburst.Text.nuspec similarity index 82% rename from Mediaburst.Text.nuspec rename to src/MediaBurst.Text/Mediaburst.Text.nuspec index 72cb6ba..9d86c76 100644 --- a/Mediaburst.Text.nuspec +++ b/src/MediaBurst.Text/Mediaburst.Text.nuspec @@ -2,21 +2,22 @@ Mediaburst.Text.GSMEncoding - 1.0 + 2.0 Mediaburst.Text.GSMEncoding Mediaburst Ltd https://github.com/mediaburst/.NET-GSM-Encoding/blob/master/License.txt https://www.clockworksms.com/ http://www.mediaburst.co.uk/downloads/clockwork-nuget.png + false Converts characters between the .NET internal Unicode encoding and the GSM03.38 alphabet. System.Text encoder for the GSM character set. Mediaburst Ltd 2015 en-GB - gsm sms mediaburst + gsm sms mediaburst gsm7 gsm03.38 - * 1.0 - First release on NuGet (on GitHub for 5 years) + * 2.0 - Upgrade to newer .Net Framework version support diff --git a/Properties/AssemblyInfo.cs b/src/MediaBurst.Text/Properties/AssemblyInfo.cs similarity index 94% rename from Properties/AssemblyInfo.cs rename to src/MediaBurst.Text/Properties/AssemblyInfo.cs index d4fe8b6..34245de 100644 --- a/Properties/AssemblyInfo.cs +++ b/src/MediaBurst.Text/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: AssemblyVersion("2.0.0.0")] +[assembly: AssemblyFileVersion("2.0.0.0")] diff --git a/src/MediaBurst.TextCore/GSMEncoding.cs b/src/MediaBurst.TextCore/GSMEncoding.cs new file mode 100644 index 0000000..7bf8c90 --- /dev/null +++ b/src/MediaBurst.TextCore/GSMEncoding.cs @@ -0,0 +1,392 @@ +using System; +using System.Collections.Generic; + +/* + * Copyright (c) 2010 Mediaburst Ltd + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +namespace Mediaburst.TextCore +{ + /// + /// Text encoding class for the GSM 03.38 alphabet. + /// Converts between GSM and the internal .NET Unicode character representation + /// + public class GSMEncoding : System.Text.Encoding + { + private SortedDictionary _charToByte; + private SortedDictionary _byteToChar; + + public GSMEncoding() + : base() + { + PopulateDictionaries(); + } + + public override int GetByteCount(char[] chars, int index, int count) + { + int byteCount = 0; + + if (chars == null) + { + throw new ArgumentNullException("chars"); + } + if (index < 0 || index > chars.Length) + { + throw new ArgumentOutOfRangeException("index"); + } + if (count < 0 || count > (chars.Length - index)) + { + throw new ArgumentOutOfRangeException("count"); + } + + for (int i = index; i < count; i++) + { + if (_charToByte.ContainsKey(chars[i])) + { + byteCount += _charToByte[chars[i]].Length; + } + } + + return byteCount; + } + + public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) + { + int byteCount = 0; + + // Validate the parameters. + if (chars == null) + { + throw new ArgumentNullException("chars"); + } + if (bytes == null) + { + throw new ArgumentNullException("bytes"); + } + if (charIndex < 0 || charIndex > chars.Length) + { + throw new ArgumentOutOfRangeException("charIndex"); + } + if (charCount < 0 || charCount > (chars.Length - charIndex)) + { + throw new ArgumentOutOfRangeException("charCount"); + } + if (byteIndex < 0 || byteIndex > bytes.Length) + { + throw new ArgumentOutOfRangeException("byteIndex"); + } + if (byteIndex + GetByteCount(chars, charIndex, charCount) > bytes.Length) + { + throw new ArgumentException("bytes array too small", "bytes"); + } + for (int i = charIndex; i < charIndex + charCount; i++) + { + byte[] charByte; + if (_charToByte.TryGetValue(chars[i], out charByte)) + { + charByte.CopyTo(bytes, byteIndex + byteCount); + byteCount += charByte.Length; + } + } + return byteCount; + } + + public override int GetCharCount(byte[] bytes, int index, int count) + { + int charCount = 0; + + if (bytes == null) + { + throw new ArgumentNullException("bytes"); + } + if (index < 0 || index > bytes.Length) + { + throw new ArgumentOutOfRangeException("index"); + } + if (count < 0 || count > (bytes.Length - index)) + { + throw new ArgumentOutOfRangeException("count"); + } + + int i = index; + while (i < index + count) + { + if (bytes[i] <= 0x7F) + { + if (bytes[i] == 0x1B) + { + i++; + if (i < bytes.Length && bytes[i] <= 0x7F) + { + charCount++; // GSM Spec says replace 1B 1B with space + } + } + else + { + charCount++; + } + } + i++; + } + + return charCount; + } + + public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) + { + int charCount = 0; + + // Validate the parameters. + if (bytes == null) + { + throw new ArgumentNullException("bytes"); + } + if (chars == null) + { + throw new ArgumentNullException("chars"); + } + if (byteIndex < 0 || byteIndex > bytes.Length) + { + throw new ArgumentOutOfRangeException("byteIndex"); + } + if (byteCount < 0 || byteCount > (bytes.Length - byteIndex)) + { + throw new ArgumentOutOfRangeException("byteCount"); + } + if (charIndex < 0 || charIndex > chars.Length) + { + throw new ArgumentOutOfRangeException("charIndex"); + } + if (charIndex + GetCharCount(bytes, byteIndex, byteCount) > chars.Length) + { + throw new ArgumentException("chars array too small", "chars"); + } + + + int i = byteIndex; + while (i < byteIndex + byteCount) + { + if (bytes[i] <= 0x7F) + { + if (bytes[i] == 0x1B) + { + i++; + if (i < bytes.Length && bytes[i] <= 0x7F) + { + char nextChar; + uint extendedChar = (0x1B * 255) + (uint)bytes[i]; + if (_byteToChar.TryGetValue(extendedChar, out nextChar)) + { + chars[charCount] = nextChar; + charCount++; + } + // GSM Spec says to try for normal character if escaped one doesn't exist + else if (_byteToChar.TryGetValue((uint)bytes[i], out nextChar)) + { + chars[charCount] = nextChar; + charCount++; + } + } + } + else + { + chars[charCount] = _byteToChar[(uint)bytes[i]]; + charCount++; + } + } + i++; + } + + return charCount; + } + + public override int GetMaxByteCount(int charCount) + { + if (charCount < 0) + throw new ArgumentOutOfRangeException("charCount"); + + return charCount * 2; + } + + public override int GetMaxCharCount(int byteCount) + { + if (byteCount < 0) + throw new ArgumentOutOfRangeException("byteCount"); + + return byteCount; + } + + + private void PopulateDictionaries() + { + // Unicode char to GSM bytes + _charToByte = new SortedDictionary(); + // GSM bytes to Unicode char + _byteToChar = new SortedDictionary(); + + _charToByte.Add('\u0040', new byte[] { 0x00 }); + _charToByte.Add('\u00A3', new byte[] { 0x01 }); + _charToByte.Add('\u0024', new byte[] { 0x02 }); + _charToByte.Add('\u00A5', new byte[] { 0x03 }); + _charToByte.Add('\u00E8', new byte[] { 0x04 }); + _charToByte.Add('\u00E9', new byte[] { 0x05 }); + _charToByte.Add('\u00F9', new byte[] { 0x06 }); + _charToByte.Add('\u00EC', new byte[] { 0x07 }); + _charToByte.Add('\u00F2', new byte[] { 0x08 }); + _charToByte.Add('\u00C7', new byte[] { 0x09 }); + _charToByte.Add('\u000A', new byte[] { 0x0A }); + _charToByte.Add('\u00D8', new byte[] { 0x0B }); + _charToByte.Add('\u00F8', new byte[] { 0x0C }); + _charToByte.Add('\u000D', new byte[] { 0x0D }); + _charToByte.Add('\u00C5', new byte[] { 0x0E }); + _charToByte.Add('\u00E5', new byte[] { 0x0F }); + _charToByte.Add('\u0394', new byte[] { 0x10 }); + _charToByte.Add('\u005F', new byte[] { 0x11 }); + _charToByte.Add('\u03A6', new byte[] { 0x12 }); + _charToByte.Add('\u0393', new byte[] { 0x13 }); + _charToByte.Add('\u039B', new byte[] { 0x14 }); + _charToByte.Add('\u03A9', new byte[] { 0x15 }); + _charToByte.Add('\u03A0', new byte[] { 0x16 }); + _charToByte.Add('\u03A8', new byte[] { 0x17 }); + _charToByte.Add('\u03A3', new byte[] { 0x18 }); + _charToByte.Add('\u0398', new byte[] { 0x19 }); + _charToByte.Add('\u039E', new byte[] { 0x1A }); + //_charToByte.Add('\u001B', new byte[] { 0x1B }); // Should we convert Unicode escape to GSM? + _charToByte.Add('\u00C6', new byte[] { 0x1C }); + _charToByte.Add('\u00E6', new byte[] { 0x1D }); + _charToByte.Add('\u00DF', new byte[] { 0x1E }); + _charToByte.Add('\u00C9', new byte[] { 0x1F }); + _charToByte.Add('\u0020', new byte[] { 0x20 }); + _charToByte.Add('\u0021', new byte[] { 0x21 }); + _charToByte.Add('\u0022', new byte[] { 0x22 }); + _charToByte.Add('\u0023', new byte[] { 0x23 }); + _charToByte.Add('\u00A4', new byte[] { 0x24 }); + _charToByte.Add('\u0025', new byte[] { 0x25 }); + _charToByte.Add('\u0026', new byte[] { 0x26 }); + _charToByte.Add('\u0027', new byte[] { 0x27 }); + _charToByte.Add('\u0028', new byte[] { 0x28 }); + _charToByte.Add('\u0029', new byte[] { 0x29 }); + _charToByte.Add('\u002A', new byte[] { 0x2A }); + _charToByte.Add('\u002B', new byte[] { 0x2B }); + _charToByte.Add('\u002C', new byte[] { 0x2C }); + _charToByte.Add('\u002D', new byte[] { 0x2D }); + _charToByte.Add('\u002E', new byte[] { 0x2E }); + _charToByte.Add('\u002F', new byte[] { 0x2F }); + _charToByte.Add('\u0030', new byte[] { 0x30 }); + _charToByte.Add('\u0031', new byte[] { 0x31 }); + _charToByte.Add('\u0032', new byte[] { 0x32 }); + _charToByte.Add('\u0033', new byte[] { 0x33 }); + _charToByte.Add('\u0034', new byte[] { 0x34 }); + _charToByte.Add('\u0035', new byte[] { 0x35 }); + _charToByte.Add('\u0036', new byte[] { 0x36 }); + _charToByte.Add('\u0037', new byte[] { 0x37 }); + _charToByte.Add('\u0038', new byte[] { 0x38 }); + _charToByte.Add('\u0039', new byte[] { 0x39 }); + _charToByte.Add('\u003A', new byte[] { 0x3A }); + _charToByte.Add('\u003B', new byte[] { 0x3B }); + _charToByte.Add('\u003C', new byte[] { 0x3C }); + _charToByte.Add('\u003D', new byte[] { 0x3D }); + _charToByte.Add('\u003E', new byte[] { 0x3E }); + _charToByte.Add('\u003F', new byte[] { 0x3F }); + _charToByte.Add('\u00A1', new byte[] { 0x40 }); + _charToByte.Add('\u0041', new byte[] { 0x41 }); + _charToByte.Add('\u0042', new byte[] { 0x42 }); + _charToByte.Add('\u0043', new byte[] { 0x43 }); + _charToByte.Add('\u0044', new byte[] { 0x44 }); + _charToByte.Add('\u0045', new byte[] { 0x45 }); + _charToByte.Add('\u0046', new byte[] { 0x46 }); + _charToByte.Add('\u0047', new byte[] { 0x47 }); + _charToByte.Add('\u0048', new byte[] { 0x48 }); + _charToByte.Add('\u0049', new byte[] { 0x49 }); + _charToByte.Add('\u004A', new byte[] { 0x4A }); + _charToByte.Add('\u004B', new byte[] { 0x4B }); + _charToByte.Add('\u004C', new byte[] { 0x4C }); + _charToByte.Add('\u004D', new byte[] { 0x4D }); + _charToByte.Add('\u004E', new byte[] { 0x4E }); + _charToByte.Add('\u004F', new byte[] { 0x4F }); + _charToByte.Add('\u0050', new byte[] { 0x50 }); + _charToByte.Add('\u0051', new byte[] { 0x51 }); + _charToByte.Add('\u0052', new byte[] { 0x52 }); + _charToByte.Add('\u0053', new byte[] { 0x53 }); + _charToByte.Add('\u0054', new byte[] { 0x54 }); + _charToByte.Add('\u0055', new byte[] { 0x55 }); + _charToByte.Add('\u0056', new byte[] { 0x56 }); + _charToByte.Add('\u0057', new byte[] { 0x57 }); + _charToByte.Add('\u0058', new byte[] { 0x58 }); + _charToByte.Add('\u0059', new byte[] { 0x59 }); + _charToByte.Add('\u005A', new byte[] { 0x5A }); + _charToByte.Add('\u00C4', new byte[] { 0x5B }); + _charToByte.Add('\u00D6', new byte[] { 0x5C }); + _charToByte.Add('\u00D1', new byte[] { 0x5D }); + _charToByte.Add('\u00DC', new byte[] { 0x5E }); + _charToByte.Add('\u00A7', new byte[] { 0x5F }); + _charToByte.Add('\u00BF', new byte[] { 0x60 }); + _charToByte.Add('\u0061', new byte[] { 0x61 }); + _charToByte.Add('\u0062', new byte[] { 0x62 }); + _charToByte.Add('\u0063', new byte[] { 0x63 }); + _charToByte.Add('\u0064', new byte[] { 0x64 }); + _charToByte.Add('\u0065', new byte[] { 0x65 }); + _charToByte.Add('\u0066', new byte[] { 0x66 }); + _charToByte.Add('\u0067', new byte[] { 0x67 }); + _charToByte.Add('\u0068', new byte[] { 0x68 }); + _charToByte.Add('\u0069', new byte[] { 0x69 }); + _charToByte.Add('\u006A', new byte[] { 0x6A }); + _charToByte.Add('\u006B', new byte[] { 0x6B }); + _charToByte.Add('\u006C', new byte[] { 0x6C }); + _charToByte.Add('\u006D', new byte[] { 0x6D }); + _charToByte.Add('\u006E', new byte[] { 0x6E }); + _charToByte.Add('\u006F', new byte[] { 0x6F }); + _charToByte.Add('\u0070', new byte[] { 0x70 }); + _charToByte.Add('\u0071', new byte[] { 0x71 }); + _charToByte.Add('\u0072', new byte[] { 0x72 }); + _charToByte.Add('\u0073', new byte[] { 0x73 }); + _charToByte.Add('\u0074', new byte[] { 0x74 }); + _charToByte.Add('\u0075', new byte[] { 0x75 }); + _charToByte.Add('\u0076', new byte[] { 0x76 }); + _charToByte.Add('\u0077', new byte[] { 0x77 }); + _charToByte.Add('\u0078', new byte[] { 0x78 }); + _charToByte.Add('\u0079', new byte[] { 0x79 }); + _charToByte.Add('\u007A', new byte[] { 0x7A }); + _charToByte.Add('\u00E4', new byte[] { 0x7B }); + _charToByte.Add('\u00F6', new byte[] { 0x7C }); + _charToByte.Add('\u00F1', new byte[] { 0x7D }); + _charToByte.Add('\u00FC', new byte[] { 0x7E }); + _charToByte.Add('\u00E0', new byte[] { 0x7F }); + // Extended GSM + _charToByte.Add('\u20AC', new byte[] { 0x1B, 0x65 }); + _charToByte.Add('\u000C', new byte[] { 0x1B, 0x0A }); + _charToByte.Add('\u005B', new byte[] { 0x1B, 0x3C }); + _charToByte.Add('\u005C', new byte[] { 0x1B, 0x2F }); + _charToByte.Add('\u005D', new byte[] { 0x1B, 0x3E }); + _charToByte.Add('\u005E', new byte[] { 0x1B, 0x14 }); + _charToByte.Add('\u007B', new byte[] { 0x1B, 0x28 }); + _charToByte.Add('\u007C', new byte[] { 0x1B, 0x40 }); + _charToByte.Add('\u007D', new byte[] { 0x1B, 0x29 }); + _charToByte.Add('\u007E', new byte[] { 0x1B, 0x3D }); + + foreach (KeyValuePair charToByte in _charToByte) + { + uint charByteVal = 0; + if (charToByte.Value.Length == 1) + charByteVal = (uint)charToByte.Value[0]; + else if (charToByte.Value.Length == 2) + charByteVal = ((uint)charToByte.Value[0] * 255) + (uint)charToByte.Value[1]; + _byteToChar.Add(charByteVal, charToByte.Key); + } + _byteToChar.Add(0x1B1B, '\u0020'); // GSM char set says to map 1B1B to a space + } + } +} diff --git a/src/MediaBurst.TextCore/MediaBurst.TextCore.csproj b/src/MediaBurst.TextCore/MediaBurst.TextCore.csproj new file mode 100644 index 0000000..85a3abf --- /dev/null +++ b/src/MediaBurst.TextCore/MediaBurst.TextCore.csproj @@ -0,0 +1,26 @@ + + + + netstandard2.0 + Text.GSMEncodingCore + Converts characters between the .NET internal Unicode encoding and the GSM03.38 alphabet. + README.md + https://github.com/mediaburst/.NET-GSM-Encoding + gsm,sms,mediaburst + True + MIT + True + snupkg + True + True + latest + + + + + True + \ + + + +