Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

More work on encoding. Force values from socket to default_external.

  • Loading branch information...
commit f6001ffdd7115c80f39cce741f92519e32651e70 1 parent 6ba8289
Mike Perham authored
Showing with 36 additions and 4 deletions.
  1. +14 −4 lib/memcache.rb
  2. +22 −0 test/test_mem_cache.rb
18 lib/memcache.rb
View
@@ -371,10 +371,10 @@ def set(key, value, expiry = 0, raw = false)
raise MemCacheError, "Value too large, memcached can only store 1MB of data per key"
end
- command = "set #{cache_key} 0 #{expiry} #{value.to_s.bytesize}#{noreply}\r\n#{value}\r\n"
-
with_socket_management(server) do |socket|
- socket.write command
+ socket.write "set #{cache_key} 0 #{expiry} #{value.to_s.bytesize}#{noreply}\r\n"
+ socket.write value.to_s
+ socket.write "\r\n"
break nil if @no_reply
result = socket.gets
raise_on_error_response! result
@@ -1152,7 +1152,17 @@ def setsockopt(*args)
end
def gets
- readuntil("\n")
+ encode(readuntil("\n"))
+ end
+
+ if defined?(Encoding)
+ def encode(str)
+ str.force_encoding(Encoding.default_external)

I was under the impression that default_internal is what you want to use for string coming back into ruby. Could totally be wrong, but then again there are basically no docs for any of it... You know for sure either way?

Mike Perham Owner
mperham added a note

I think what I did was superfluous. Read this and let me know what you think:

http://blog.grayproductions.net/articles/ruby_19s_three_default_encodings

Mike Perham Owner
mperham added a note

That is, Ruby should be forcing all data read from a socket into the Encoding.default_external encoding already so no need for me to force it. I was just cargo culting what the redis client recently did.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ end
+ else
+ def encode(str)
+ str
+ end
end
end
22 test/test_mem_cache.rb
View
@@ -1259,6 +1259,8 @@ def test_crazy_multithreaded_access
cache.set('d', 'a', 100, true)
cache.set('e', 'x', 100, true)
cache.set('f', 'zzz')
+ cache.set('g', '1ብbሲg')
+ cache.set('Ẽ뷽cc벼g', 'batman')
assert_not_nil(cache.cas('f') do |value|
value << 'z'
end)
@@ -1271,6 +1273,8 @@ def test_crazy_multithreaded_access
assert inc > 14
assert cache.decr('c', 5) > 14
assert_equal 11, cache.get('b')
+ assert_equal '1ብbሲg', cache.get('g')
+ assert_equal 'batman', cache.get('Ẽ뷽cc벼g')
d = cache.get('d', true)
assert_match(/\Aab*\Z/, d)
e = cache.get('e', true)
@@ -1284,5 +1288,23 @@ def test_crazy_multithreaded_access
end
end
+ def test_custom_encoding
+ requirement(memcached_running?, 'A memcached server must be running for live testing') do
+ key = "£"
+ array = [180,250,184,213]
+ value = array.pack('c*')
+ value.force_encoding('big5')
+ assert_equal array, value.bytes.to_a
+
+ m = MemCache.new 'localhost'
+ m.set(key, value)
+ result = m.get(key)
+ assert_equal(value, result)
+ assert_equal(value.encoding.name, result.encoding.name)
+ # m.set(key, value, true)
+ # assert_equal(value, m.get(key))
+ end
+ end
+
end
Brian Lopez

I was under the impression that default_internal is what you want to use for string coming back into ruby. Could totally be wrong, but then again there are basically no docs for any of it... You know for sure either way?

Mike Perham

I think what I did was superfluous. Read this and let me know what you think:

http://blog.grayproductions.net/articles/ruby_19s_three_default_encodings

Mike Perham

That is, Ruby should be forcing all data read from a socket into the Encoding.default_external encoding already so no need for me to force it. I was just cargo culting what the redis client recently did.

Please sign in to comment.
Something went wrong with that request. Please try again.