Class: ICU::Transliteration::Transliterator

Inherits:
Object
  • Object
show all
Defined in:
lib/ffi-icu/transliteration.rb

Instance Method Summary collapse

Constructor Details

#initialize(id, rules = nil, direction = :forward) ⇒ Transliterator

Returns a new instance of Transliterator.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/ffi-icu/transliteration.rb', line 25

def initialize(id, rules = nil, direction = :forward)
  rules_length = 0

  if rules
    rules_length = rules.jlength + 1
    rules = UCharPointer.from_string(rules)
  end

  parse_error = Lib::UParseError.new
  begin
    Lib.check_error do |status|
      # couldn't get utrans_openU to work properly, so using deprecated utrans_open for now
      ptr = Lib.utrans_openU(UCharPointer.from_string(id), id.jlength, direction, rules, rules_length, @parse_error, status)
      @tr = FFI::AutoPointer.new(ptr, Lib.method(:utrans_close))
    end
  rescue ICU::Error => ex
    raise ex, "#{ex.message} (#{parse_error})"
  end
end

Instance Method Details

#transliterate(from) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/ffi-icu/transliteration.rb', line 45

def transliterate(from)
  # this is a bit unpleasant

  unicode_size = from.unpack("U*").size
  capacity     = from.bytesize + 1
  buf          = UCharPointer.from_string(from)
  limit        = FFI::MemoryPointer.new :int32
  text_length  = FFI::MemoryPointer.new :int32

  retried = false

  begin
    # resets to original size on retry
    [limit, text_length].each do |ptr|
      ptr.put_int32(0, unicode_size)
    end

    Lib.check_error do |error|
      Lib.utrans_transUChars(@tr, buf, text_length, capacity, 0, limit, error)
    end
  rescue BufferOverflowError
    new_size = text_length.get_int32(0)
    $stderr.puts "BufferOverflowError, needs: #{new_size}" if $DEBUG

    raise BufferOverflowError, "needed #{new_size}" if retried

    capacity = new_size + 1
    buf      = buf.resized_to capacity
    retried  = true

    retry
  end

  buf.string text_length.get_int32(0)
end