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.



59
60
61
62
63
# File 'lib/ffi-icu/number_formatting.rb', line 59

def initialize(locale, type = :decimal)
  super()

  @f = make_formatter(type, locale)
end

Instance Method Details

#format(number) ⇒ Object



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
101
102
103
104
105
106
107
108
# File 'lib/ffi-icu/number_formatting.rb', line 65

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.size, out_ptr,
                                                  needed_length, nil, error)
        end
      when BigDecimal
        string_version = number.to_s('F')
        needed_length = if Lib.respond_to?(:unum_format_decimal)
                          Lib.unum_format_decimal(@f, string_version, string_version.size, out_ptr,
                                                  needed_length, nil, error)
                        else
                          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