Skip to content

Instantly share code, notes, and snippets.

@jeffyip
Created November 16, 2012 21:47
Show Gist options
  • Save jeffyip/4091200 to your computer and use it in GitHub Desktop.
Save jeffyip/4091200 to your computer and use it in GitHub Desktop.
# encoding: utf-8
# code from: http://techtime.getharvest.com/blog/harvest-is-now-on-ruby-1-dot-9-3
# and also: https://gist.github.com/1976864
# Serialized columns in AR don't support UTF-8 well, so set the encoding on those
class ActiveRecord::Base
def unserialize_attribute_with_utf8(attr_name)
traverse = lambda do |object, block|
if object.kind_of?(Hash)
object.each_value { |o| traverse.call(o, block) }
elsif object.kind_of?(Array)
object.each { |o| traverse.call(o, block) }
else
block.call(object)
end
object
end
force_encoding = lambda do |o|
RubyBridge.force_utf8_encoding(o)
end
value = unserialize_attribute_without_utf8(attr_name)
traverse.call(value, force_encoding)
end
alias_method_chain :unserialize_attribute, :utf8
end
if RUBY_VERSION >= '1.9'
# from http://www.zendesk.com/blog/upgrade-the-road-to-1-9
module Marshal
class << self
def load_with_utf8_enforcement(object, other_proc=nil)
@utf8_proc ||= Proc.new do |o|
o.force_encoding("UTF-8") if (o.is_a?(String) && o.respond_to?(:force_encoding))
other_proc.call(o) if other_proc
o
end
load_without_utf8_enforcement(object, @utf8_proc)
end
alias_method_chain :load, :utf8_enforcement
end
end
end
if RUBY_VERSION >= '1.9'
# from http://www.deploymentzone.com/2012/01/19/ruby-1-9-3-and-thrift-0-5-0-0-8-0
module Thrift
BINARY_ENCODING = "ASCII-8BIT"
class BinaryProtocol
def write_string(str)
write_i32(str.bytesize)
trans.write(str)
end
end
class HTTPClientTransport < BaseTransport
def write(buf)
buf.force_encoding(BINARY_ENCODING) if buf.respond_to?(:force_encoding)
@outbuf << buf
end
end
class FramedTransport < BaseTransport
def write(buf,sz=nil)
buf.force_encoding(BINARY_ENCODING) if buf.respond_to?(:force_encoding) && !buf.frozen?
return @transport.write(buf) unless @write
@wbuf << (sz ? buf[0...sz] : buf)
end
def flush
return @transport.flush unless @write
out = [@wbuf.length].pack('N')
out.force_encoding(BINARY_ENCODING) if out.respond_to?(:force_encoding)
out << @wbuf
@transport.write(out)
@transport.flush
@wbuf = ''
end
end
class BufferedTransport < BaseTransport
def write(buf)
buf.force_encoding(BINARY_ENCODING) if buf.respond_to?(:force_encoding)
@wbuf << buf
end
def flush
if @wbuf != ''
@wbuf.force_encoding(BINARY_ENCODING) if @wbuf.respond_to?(:force_encoding)
@transport.write(@wbuf)
@wbuf = ''
end
@transport.flush
end
end
end
end
# This file is for methods meant to bridge Ruby 1.8 and Ruby 1.9 code
class RubyBridge
# This is an attempt to fix issues with strings that are SafeBuffers breaking URI.escape and RightAws::AwsUtils.URLencode
def self.regular_string(s)
if RUBY_VERSION >= '1.9'
(s.nil? || s.class.to_s == 'String') ? s : s.to_s.to_str
# do not check is_a?(String) here since ActiveSupport::SafeBuffer and ActiveSupport::OutputBuffer return true
else
s.to_s
end
end
# for reference, see http://www.zendesk.com/blog/upgrade-the-road-to-1-9
def self.force_utf8_encoding(str)
if str.is_a?(String) && str.respond_to?(:force_encoding)
str = str.dup if str.frozen?
str.force_encoding(Encoding::UTF_8)
if !str.valid_encoding?
#logger.warn("encoding: forcing invalid UTF-8 string; text is #{str}")
str.encode!(Encoding::UTF_8, Encoding::ISO_8859_1)
end
end
str
end
# for reference, see http://www.zendesk.com/blog/upgrade-the-road-to-1-9
def self.force_binary_encoding(str)
if str.is_a?(String) && str.respond_to?(:force_encoding)
str = str.dup if str.frozen?
str.force_encoding(Encoding::BINARY)
end
str
end
# Encodes a string from encoding "from" to encoding "to" in
# a way that works for both ruby 1.8 and 1.9
def self.convert_string_encoding(to, from, str)
if "1.9".respond_to?(:force_encoding)
str = str.dup if str.frozen?
str.encode(to, from, :undef => :replace)
else
require 'iconv'
Iconv.conv(to, from, str)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment