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.size + 1
    rules = UCharPointer.from_string(rules)
  end

  parse_error = Lib::UParseError.new
  begin
    Lib.check_error do |status|
      ptr = Lib.utrans_openU(UCharPointer.from_string(id), id.size, direction, rules, rules_length,
                             @parse_error, status)
      @tr = FFI::AutoPointer.new(ptr, Lib.method(:utrans_close))
    end
  rescue ICU::Error => e
    raise(e, "#{e.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
80
81
82
83
# File 'lib/ffi-icu/transliteration.rb', line 45

def transliterate(from)
  # this is a bit unpleasant

  unicode_size = from.unpack('U*').size
  capacity     = unicode_size + 1
  buf          = UCharPointer.from_string(from, capacity)
  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)
    warn("BufferOverflowError, needs: #{new_size}") if $DEBUG

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

    capacity = new_size + 1

    # create a new buffer with more capacity instead of resizing,
    # since the old buffer now has result data
    buf.free
    buf = UCharPointer.from_string(from, capacity)

    retried = true
    retry
  end

  buf.string(text_length.get_int32(0))
end