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
+ \
+
+
+
+