aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/multibyte
diff options
context:
space:
mode:
authorManfred Stienstra <manfred@fngtps.com>2009-11-01 17:18:27 +0100
committerManfred Stienstra <manfred@fngtps.com>2009-11-04 10:12:03 +0100
commit935bd0fef8e26f4ec65fe411a1d29942493f8d46 (patch)
tree209d11fac03a7917a23d9c1816817cd35018ab98 /activesupport/lib/active_support/multibyte
parenta3d5274e67c841a6fdc9f9acb9e1b6bbc351dd28 (diff)
downloadrails-935bd0fef8e26f4ec65fe411a1d29942493f8d46.tar.gz
rails-935bd0fef8e26f4ec65fe411a1d29942493f8d46.tar.bz2
rails-935bd0fef8e26f4ec65fe411a1d29942493f8d46.zip
Add ActiveSupport::Multibyte::Chars#limit.
The limit method limits the number of bytes in a string. Useful when the storage space of the string is limited, for instance in a database column definition. Sharpen up the implementation of translate offset. [#3192 state:committed]
Diffstat (limited to 'activesupport/lib/active_support/multibyte')
-rw-r--r--activesupport/lib/active_support/multibyte/chars.rb29
1 files changed, 15 insertions, 14 deletions
diff --git a/activesupport/lib/active_support/multibyte/chars.rb b/activesupport/lib/active_support/multibyte/chars.rb
index c9bcfbd313..51b870de8c 100644
--- a/activesupport/lib/active_support/multibyte/chars.rb
+++ b/activesupport/lib/active_support/multibyte/chars.rb
@@ -363,6 +363,16 @@ module ActiveSupport #:nodoc:
slice
end
+ # Limit the byte size of the string to a number of bytes without breaking characters. Usable
+ # when the storage for a string is limited for some reason.
+ #
+ # Example:
+ # s = 'こんにちは'
+ # s.mb_chars.limit(7) #=> "こに"
+ def limit(limit)
+ slice(0...translate_offset(limit))
+ end
+
# Returns the codepoint of the first character in the string.
#
# Example:
@@ -651,24 +661,15 @@ module ActiveSupport #:nodoc:
end
protected
-
+
def translate_offset(byte_offset) #:nodoc:
return nil if byte_offset.nil?
return 0 if @wrapped_string == ''
- chunk = @wrapped_string[0..byte_offset]
begin
- begin
- chunk.unpack('U*').length - 1
- rescue ArgumentError => e
- chunk = @wrapped_string[0..(byte_offset+=1)]
- # Stop retrying at the end of the string
- raise e unless byte_offset < chunk.length
- # We damaged a character, retry
- retry
- end
- # Catch the ArgumentError so we can throw our own
- rescue ArgumentError
- raise EncodingError, 'malformed UTF-8 character'
+ @wrapped_string[0...byte_offset].unpack('U*').length
+ rescue ArgumentError => e
+ byte_offset -= 1
+ retry
end
end