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
# 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|
      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



44
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
# File 'lib/ffi-icu/transliteration.rb', line 44

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)
    $stderr.puts "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