Module: GSMEncoder

Defined in:
lib/gsm_encoder.rb

Overview

This class encodes and decodes Ruby Strings to and from the SMS default alphabet. It also supports the default extension table. The default alphabet and it’s extension table is defined in GSM 03.38.

Constant Summary collapse

GSM_ESCAPE =
0x1b
GSM_TABLE =
[
  '@', '£', '$', '¥', 'è', 'é', 'ù', 'ì',
  'ò', 'Ç',  nl, 'Ø', 'ø', cr , 'Å', 'å',
  'Δ', '_', 'Φ', 'Γ', 'Λ', 'Ω', 'Π', 'Ψ',
  'Σ', 'Θ', 'Ξ', nil, 'Æ', 'æ', 'ß', 'É', # 0x1b is the escape
  " ", '!', '"', '#', '¤', '%', '&', "'",
  '(', ')', '*', '+', ',', '-', '.', '/',
  '0', '1', '2', '3', '4', '5', '6', '7',
  '8', '9', ':', ';', '<', '=', '>', '?',
  '¡', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
  'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
  'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
  'X', 'Y', 'Z', 'Ä', 'Ö', 'Ñ', 'Ü', '§',
  '¿', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
  'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
  'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
  'x', 'y', 'z', 'ä', 'ö', 'ñ', 'ü', 'à',
].freeze
GSM_EXT_TABLE =
[
  nil, nil, nil, nil, nil, nil, nil, nil, nil, 'ç', nil, nil, nil, nil, nil, nil,
  nil, nil, nil, nil, '^', nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
  nil, nil, nil, nil, nil, nil, nil, nil, '{', '}', nil, nil, nil, nil, nil, bs,
  nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, '[', '~', ']', nil,
  '|', 'Á', nil, nil, nil, nil, nil, nil, nil, 'Í', nil, nil, nil, nil, nil, 'Ó',
  nil, nil, nil, nil, nil, 'Ú', nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
  nil, 'á', nil, nil, nil, '€', nil, nil, nil, 'í', nil, nil, nil, nil, nil, 'ó',
  nil, nil, nil, nil, nil, 'ú', nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
].freeze
UTF8_ARRAY_SIZE =

build UTF8 to GSM tables

128
UTF8_ARRAY =
[]
UTF8_HASH =
{}
REGEXP =
/\A[#{Regexp.escape((GSM_TABLE + GSM_EXT_TABLE).compact.join)}]*\Z/

Class Method Summary collapse

Class Method Details

.can_encode?(str) ⇒ Boolean

Verifies that the given string can be encoded in GSM 03.38

Returns:

  • (Boolean)


82
83
84
# File 'lib/gsm_encoder.rb', line 82

def can_encode?(str)
  !str || !!(REGEXP =~ str)
end

.decode(string, replacement = "?") ⇒ Object

Encode given GSM 03.38 string to UTF-8



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/gsm_encoder.rb', line 102

def decode(string, replacement = "?")
  return nil if string.nil?
  buffer = +""
  escaped = false
  string.each_byte do |c|
    if c == GSM_ESCAPE
      escaped = true
    elsif escaped
      buffer << GSM_EXT_TABLE[c] || replacement
      escaped = false
    else
      buffer << GSM_TABLE[c] || replacement
    end
  end
  buffer
end

.encode(string, replacement = "?") ⇒ Object

Encode given UTF-8 string to GSM 03.38



87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/gsm_encoder.rb', line 87

def encode(string, replacement = "?")
  return nil if string.nil?
  replacement = replacement == "?" ? 63 : encode(replacement)
  buffer = String.new(encoding: "binary")
  string.each_codepoint do |codepoint|
    if codepoint < UTF8_ARRAY_SIZE
      buffer << (UTF8_ARRAY[codepoint] || replacement)
    else
      buffer << (UTF8_HASH[codepoint] || replacement)
    end
  end
  buffer
end