module GSMTexting

Constants

BASIC_CHARACTER_SET
BASIC_CHARACTER_SET_EXTENSION
CHARACTER_EXTENSION_REGEX
CHARACTER_SET_REGEX
DEFAULT_REPLACE_CHAR
GSM_NOT_EXTENDED_REGEX
GSM_REGEX
GSM_SEGMENT_LENGTH

Public Instance Methods

can_encode?(str) click to toggle source

Verifies if string can be encoded in GSM-7 without loosing information

# File lib/gsm_texting.rb, line 56
def can_encode?(str)
  str.nil? || !(GSM_REGEX =~ str).nil?
end
encode(str, transliterate: false, replace_char: nil, truncate: false) click to toggle source

Convert unicode chars to GSM-7 compatible equivalents if possible

# File lib/gsm_texting.rb, line 61
def encode(str, transliterate: false, replace_char: nil, truncate: false)
  return if str.nil?

  replace_char = canonicalize_replace_char(replace_char)

  processed_str = str.unpack('U*').map do |char|
    utf8_char = char.chr(Encoding::UTF_8)

    compatible_char = compatible_char_for(char)
    transformed_char = transformed_char_for(char) if transliterate
    gsm_char_for(compatible_char || transformed_char || utf8_char, replace_char)
  end.join

  truncate ? truncate_into_single_segment(processed_str) : processed_str
end
single_segment?(str) click to toggle source

Check if string fits into a single gsm sms segment (1120 bits)

# File lib/gsm_texting.rb, line 48
def single_segment?(str)
  raise InvalidGSMString unless can_encode?(str)

  extended_chars = str.gsub(GSM_NOT_EXTENDED_REGEX, '').length
  (str.length + extended_chars) <= GSM_SEGMENT_LENGTH
end

Private Instance Methods

canonicalize_replace_char(char) click to toggle source
# File lib/gsm_texting.rb, line 79
def canonicalize_replace_char(char)
  char && can_encode?(char) ? char : DEFAULT_REPLACE_CHAR
end
compatible_char_for(char) click to toggle source
# File lib/gsm_texting.rb, line 83
def compatible_char_for(char)
  COMPATIBILITY_TABLE[char]
end
gsm_char_for(char, replace_char) click to toggle source
# File lib/gsm_texting.rb, line 91
def gsm_char_for(char, replace_char)
  can_encode?(char) ? char : replace_char
end
transformed_char_for(char) click to toggle source
# File lib/gsm_texting.rb, line 87
def transformed_char_for(char)
  CONVERSION_TABLE[char]
end
truncate_into_single_segment(str) click to toggle source

Truncates string to fit into a single SMS Segment of 1120 bits Each basic character takes a septet and extended characters take two.

# File lib/gsm_texting.rb, line 97
def truncate_into_single_segment(str)
  return str if single_segment?(str)

  extended_chars = str.gsub(GSM_NOT_EXTENDED_REGEX, '').length
  final_length = GSM_SEGMENT_LENGTH - extended_chars - 3
  str[0..final_length].concat('...')
end