Class: ICU::NumberFormatting::NumberFormatter

Inherits:
BaseFormatter show all
Defined in:
lib/ffi-icu/number_formatting.rb

Instance Method Summary collapse

Methods inherited from BaseFormatter

#set_attributes

Constructor Details

#initialize(locale, type = :decimal) ⇒ NumberFormatter

Returns a new instance of NumberFormatter.



56
57
58
# File 'lib/ffi-icu/number_formatting.rb', line 56

def initialize(locale, type = :decimal)
  @f = make_formatter(type, locale)
end

Instance Method Details

#format(number) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/ffi-icu/number_formatting.rb', line 60

def format(number)
  needed_length = 0
  out_ptr = UCharPointer.new(needed_length)

  retried = false

  begin
    Lib.check_error do |error|
      case number
      when Float
        needed_length = Lib.unum_format_double(@f, number, out_ptr, needed_length, nil, error)
      when Integer
        begin
          # Try doing it fast, for integers that can be marshaled into an int64_t
          needed_length = Lib.unum_format_int64(@f, number, out_ptr, needed_length, nil, error)
        rescue RangeError
          # Fall back to stringifying in Ruby and passing that to ICU
          unless defined? Lib.unum_format_decimal
            raise RangeError,"Number #{number} is too big to fit in int64_t and your "\
                              "ICU version is too old to have unum_format_decimal"
          end
          string_version = number.to_s
          needed_length = Lib.unum_format_decimal(@f, string_version, string_version.bytesize, out_ptr, needed_length, nil, error)
        end
      when BigDecimal
        string_version = number.to_s('F')
        if Lib.respond_to? :unum_format_decimal
          needed_length = Lib.unum_format_decimal(@f, string_version, string_version.bytesize, out_ptr, needed_length, nil, error)
        else
          needed_length = Lib.unum_format_double(@f, number.to_f, out_ptr, needed_length, nil, error)
        end
      end
    end
    out_ptr.string needed_length
  rescue BufferOverflowError
    raise BufferOverflowError, "needed: #{needed_length}" if retried
    out_ptr = out_ptr.resized_to needed_length
    retried = true
    retry
  end
end