gsm_texting 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/gsm_texting.rb +38 -11
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 933264662ecb13ee743db2c7b9910c8c037b7205c3f6f42f0c73ea845d0e3122
|
4
|
+
data.tar.gz: 493de2a7c06e968508c242170d24244d66da7605f4af885e96510bf28459d04f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 913eddd3409475dffe4e4950119900c94a58640cd1944fc0095a2838282e7fa5f512ff7a38c8a0d68bb8b95e9a1b75f2241f4015c124097c443cd25a02b4e806
|
7
|
+
data.tar.gz: 1e2205456987355c317e17ecb599fe48d56d3525718a99ae7edbd6f1abc1c184fb308f11655491bba1747bde492a600dd0651c94f2508f973bbae576085205fb
|
data/lib/gsm_texting.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'character_constants'
|
2
4
|
require 'compatibility_table'
|
3
5
|
require 'conversion_table'
|
@@ -8,23 +10,25 @@ module GSMTexting
|
|
8
10
|
include ConversionTable
|
9
11
|
extend self
|
10
12
|
|
11
|
-
|
13
|
+
class InvalidGSMString < StandardError; end
|
14
|
+
|
15
|
+
DEFAULT_REPLACE_CHAR = '?'
|
12
16
|
|
13
17
|
BASIC_CHARACTER_SET = [
|
14
|
-
'@', 'Δ',
|
18
|
+
'@', 'Δ', SP, '0', '¡', 'P', '¿', 'p',
|
15
19
|
'£', '_', '!', '1', 'A', 'Q', 'a', 'q',
|
16
|
-
'$', 'Φ',
|
20
|
+
'$', 'Φ', DQ, '2', 'B', 'R', 'b', 'r',
|
17
21
|
'¥', 'Γ', '#', '3', 'C', 'S', 'c', 's',
|
18
22
|
'è', 'Λ', '¤', '4', 'D', 'T', 'd', 't',
|
19
23
|
'é', 'Ω', '%', '5', 'E', 'U', 'e', 'u',
|
20
24
|
'ù', 'Π', '&', '6', 'F', 'V', 'f', 'v',
|
21
|
-
'ì', 'Ψ',
|
25
|
+
'ì', 'Ψ', SQ, '7', 'G', 'W', 'g', 'w',
|
22
26
|
'ò', 'Σ', '(', '8', 'H', 'X', 'h', 'x',
|
23
27
|
'Ç', 'Θ', ')', '9', 'I', 'Y', 'i', 'y',
|
24
|
-
|
28
|
+
LF, 'Ξ', '*', ':', 'J', 'Z', 'j', 'z',
|
25
29
|
'Ø', ESC, '+', ';', 'K', 'Ä', 'k', 'ä',
|
26
30
|
'ø', 'Æ', ',', '<', 'L', 'Ö', 'l', 'ö',
|
27
|
-
|
31
|
+
CR, 'æ', '-', '=', 'M', 'Ñ', 'm', 'ñ',
|
28
32
|
'Å', 'ß', '.', '>', 'N', 'Ü', 'n', 'ü',
|
29
33
|
'å', 'É', '/', '?', 'O', '§', 'o', 'à'
|
30
34
|
].freeze
|
@@ -34,9 +38,19 @@ module GSMTexting
|
|
34
38
|
].freeze
|
35
39
|
|
36
40
|
CHARACTER_SET_REGEX = Regexp.escape(BASIC_CHARACTER_SET.join)
|
37
|
-
CHARACTER_EXTENSION_REGEX = Regexp.escape(BASIC_CHARACTER_SET_EXTENSION.
|
38
|
-
|
41
|
+
CHARACTER_EXTENSION_REGEX = Regexp.escape(BASIC_CHARACTER_SET_EXTENSION.join)
|
39
42
|
GSM_REGEX = /\A[#{CHARACTER_SET_REGEX}#{CHARACTER_EXTENSION_REGEX}]*\z/.freeze
|
43
|
+
GSM_NOT_EXTENDED_REGEX = /[^#{CHARACTER_EXTENSION_REGEX}]/.freeze
|
44
|
+
|
45
|
+
GSM_SEGMENT_LENGTH = 160
|
46
|
+
|
47
|
+
# Check if string fits into a single gsm sms segment (1120 bits)
|
48
|
+
def single_segment?(str)
|
49
|
+
raise InvalidGSMString unless can_encode?(str)
|
50
|
+
|
51
|
+
extended_chars = str.gsub(GSM_NOT_EXTENDED_REGEX, '').length
|
52
|
+
(str.length + extended_chars) <= GSM_SEGMENT_LENGTH
|
53
|
+
end
|
40
54
|
|
41
55
|
# Verifies if string can be encoded in GSM-7 without loosing information
|
42
56
|
def can_encode?(str)
|
@@ -44,17 +58,20 @@ module GSMTexting
|
|
44
58
|
end
|
45
59
|
|
46
60
|
# Convert unicode chars to GSM-7 compatible equivalents if possible
|
47
|
-
def encode(str, transliterate: false, replace_char: nil)
|
61
|
+
def encode(str, transliterate: false, replace_char: nil, truncate: false)
|
48
62
|
return if str.nil?
|
63
|
+
|
49
64
|
replace_char = canonicalize_replace_char(replace_char)
|
50
65
|
|
51
|
-
str.unpack(
|
66
|
+
processed_str = str.unpack('U*').map do |char|
|
52
67
|
utf8_char = char.chr(Encoding::UTF_8)
|
53
68
|
|
54
69
|
compatible_char = compatible_char_for(char)
|
55
70
|
transformed_char = transformed_char_for(char) if transliterate
|
56
71
|
gsm_char_for(compatible_char || transformed_char || utf8_char, replace_char)
|
57
|
-
|
72
|
+
end.join
|
73
|
+
|
74
|
+
truncate ? truncate_into_single_segment(processed_str) : processed_str
|
58
75
|
end
|
59
76
|
|
60
77
|
private
|
@@ -74,4 +91,14 @@ module GSMTexting
|
|
74
91
|
def gsm_char_for(char, replace_char)
|
75
92
|
can_encode?(char) ? char : replace_char
|
76
93
|
end
|
94
|
+
|
95
|
+
# Truncates string to fit into a single SMS Segment of 1120 bits
|
96
|
+
# Each basic character takes a septet and extended characters take two.
|
97
|
+
def truncate_into_single_segment(str)
|
98
|
+
return str if single_segment?(str)
|
99
|
+
|
100
|
+
extended_chars = str.gsub(GSM_NOT_EXTENDED_REGEX, '').length
|
101
|
+
final_length = GSM_SEGMENT_LENGTH - extended_chars - 3
|
102
|
+
str[0..final_length].concat('...')
|
103
|
+
end
|
77
104
|
end
|