jruby-memcached-thoughtworks 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +31 -0
- data/.travis.yml +5 -0
- data/CHANGELOG.md +89 -0
- data/Gemfile +6 -0
- data/MIT-LICENSE +20 -0
- data/README.md +75 -0
- data/Rakefile +16 -0
- data/benchmark.rb +104 -0
- data/jruby_memcached.gemspec +21 -0
- data/lib/memcached.rb +12 -0
- data/lib/memcached/version.rb +3 -0
- data/pom.xml +69 -0
- data/spec/memcached_spec.rb +247 -0
- data/spec/rails_spec.rb +181 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/timeout_spec.rb +103 -0
- data/src/main/java/com/openfeint/memcached/Memcached.java +511 -0
- data/src/main/java/com/openfeint/memcached/MemcachedService.java +35 -0
- data/src/main/java/com/openfeint/memcached/Rails.java +237 -0
- data/src/main/java/com/openfeint/memcached/error/ATimeoutOccurred.java +7 -0
- data/src/main/java/com/openfeint/memcached/error/Error.java +31 -0
- data/src/main/java/com/openfeint/memcached/error/NotFound.java +7 -0
- data/src/main/java/com/openfeint/memcached/error/NotStored.java +7 -0
- data/src/main/java/com/openfeint/memcached/error/NotSupport.java +7 -0
- data/src/main/java/com/openfeint/memcached/transcoder/MarshalTranscoder.java +91 -0
- data/src/main/java/com/openfeint/memcached/transcoder/MarshalZlibTranscoder.java +103 -0
- data/src/main/java/net/spy/memcached/KetamaNodeLocator.java +165 -0
- data/src/main/java/net/spy/memcached/util/DefaultKetamaNodeLocatorConfiguration.java +104 -0
- data/target/spymemcached-ext-0.0.2.jar +0 -0
- metadata +104 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
package com.openfeint.memcached;
|
2
|
+
|
3
|
+
import org.jruby.Ruby;
|
4
|
+
import org.jruby.RubyClass;
|
5
|
+
import org.jruby.runtime.ObjectAllocator;
|
6
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
7
|
+
import org.jruby.runtime.load.BasicLibraryService;
|
8
|
+
|
9
|
+
import java.io.IOException;
|
10
|
+
|
11
|
+
public class MemcachedService implements BasicLibraryService {
|
12
|
+
public boolean basicLoad(final Ruby ruby) throws IOException {
|
13
|
+
RubyClass memcached = ruby.defineClass("Memcached", ruby.getObject(), new ObjectAllocator() {
|
14
|
+
public IRubyObject allocate(Ruby ruby, RubyClass klazz) {
|
15
|
+
return new Memcached(ruby, klazz);
|
16
|
+
}
|
17
|
+
});
|
18
|
+
memcached.defineAnnotatedMethods(Memcached.class);
|
19
|
+
|
20
|
+
RubyClass rails = memcached.defineClassUnder("Rails", memcached, new ObjectAllocator() {
|
21
|
+
public IRubyObject allocate(Ruby ruby, RubyClass klazz) {
|
22
|
+
return new Rails(ruby, klazz);
|
23
|
+
}
|
24
|
+
});
|
25
|
+
rails.defineAnnotatedMethods(Rails.class);
|
26
|
+
|
27
|
+
RubyClass runtimeError = ruby.getRuntimeError();
|
28
|
+
RubyClass memcachedError = memcached.defineClassUnder("Error", runtimeError, runtimeError.getAllocator());
|
29
|
+
memcached.defineClassUnder("NotFound", memcachedError, memcachedError.getAllocator());
|
30
|
+
memcached.defineClassUnder("NotStored", memcachedError, memcachedError.getAllocator());
|
31
|
+
memcached.defineClassUnder("NotSupport", memcachedError, memcachedError.getAllocator());
|
32
|
+
memcached.defineClassUnder("ATimeoutOccurred", memcachedError, memcachedError.getAllocator());
|
33
|
+
return true;
|
34
|
+
}
|
35
|
+
}
|
@@ -0,0 +1,237 @@
|
|
1
|
+
package com.openfeint.memcached;
|
2
|
+
|
3
|
+
import org.jruby.Ruby;
|
4
|
+
import org.jruby.RubyArray;
|
5
|
+
import org.jruby.RubyBoolean;
|
6
|
+
import org.jruby.RubyClass;
|
7
|
+
import org.jruby.RubyHash;
|
8
|
+
import org.jruby.RubyFixnum;
|
9
|
+
import org.jruby.RubyString;
|
10
|
+
import org.jruby.anno.JRubyClass;
|
11
|
+
import org.jruby.anno.JRubyMethod;
|
12
|
+
import org.jruby.exceptions.RaiseException;
|
13
|
+
import org.jruby.runtime.Block;
|
14
|
+
import org.jruby.runtime.ThreadContext;
|
15
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
16
|
+
|
17
|
+
import java.util.ArrayList;
|
18
|
+
import java.util.List;
|
19
|
+
import java.util.HashMap;
|
20
|
+
import java.util.Map;
|
21
|
+
|
22
|
+
@JRubyClass(name = "Memcached::Rails", parent = "Memcached")
|
23
|
+
public class Rails extends Memcached {
|
24
|
+
private boolean stringReturnTypes;
|
25
|
+
|
26
|
+
public Rails(final Ruby ruby, RubyClass rubyClass) {
|
27
|
+
super(ruby, rubyClass);
|
28
|
+
|
29
|
+
stringReturnTypes = false;
|
30
|
+
}
|
31
|
+
|
32
|
+
@JRubyMethod(name = "initialize", rest = true)
|
33
|
+
public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {
|
34
|
+
Ruby ruby = context.getRuntime();
|
35
|
+
|
36
|
+
List<String> servers = new ArrayList<String>();
|
37
|
+
for (IRubyObject arg : args) {
|
38
|
+
if (arg instanceof RubyString) {
|
39
|
+
servers.add(arg.toString());
|
40
|
+
} else if (arg instanceof RubyArray) {
|
41
|
+
servers.addAll((List<String>) arg.convertToArray());
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
Map<String, String> options = new HashMap<String, String>();
|
46
|
+
if (args[args.length - 1] instanceof RubyHash) {
|
47
|
+
RubyHash arguments = args[args.length - 1].convertToHash();
|
48
|
+
for (Object key : arguments.keySet()) {
|
49
|
+
if (!"servers".equals(key.toString())) {
|
50
|
+
options.put(key.toString(), arguments.get(key).toString());
|
51
|
+
}
|
52
|
+
}
|
53
|
+
if (servers.isEmpty()) {
|
54
|
+
IRubyObject serverNames = (IRubyObject) arguments.get(ruby.newSymbol("servers"));
|
55
|
+
servers.addAll((List<String>) serverNames.convertToArray());
|
56
|
+
}
|
57
|
+
}
|
58
|
+
if (options.containsKey("namespace")) {
|
59
|
+
options.put("prefix_key", options.get("namespace"));
|
60
|
+
}
|
61
|
+
if (options.containsKey("namespace_separator")) {
|
62
|
+
options.put("prefix_delimiter", options.get("namespace_separator"));
|
63
|
+
}
|
64
|
+
if (options.containsKey("string_return_types")) {
|
65
|
+
stringReturnTypes = true;
|
66
|
+
}
|
67
|
+
return super.init(context, servers, options);
|
68
|
+
}
|
69
|
+
|
70
|
+
@JRubyMethod(name = "active?")
|
71
|
+
public IRubyObject active_p(ThreadContext context) {
|
72
|
+
Ruby ruby = context.getRuntime();
|
73
|
+
if (((RubyArray) super.servers(context)).isEmpty()) {
|
74
|
+
return ruby.getFalse();
|
75
|
+
}
|
76
|
+
return ruby.getTrue();
|
77
|
+
}
|
78
|
+
|
79
|
+
@JRubyMethod(name = { "get", "[]" }, required = 1, optional = 1)
|
80
|
+
public IRubyObject get(ThreadContext context, IRubyObject[] args) {
|
81
|
+
IRubyObject key = args[0];
|
82
|
+
RubyBoolean notRaw = notRaw(context, args, 1);
|
83
|
+
try {
|
84
|
+
return super.get(context, new IRubyObject[] { key, notRaw });
|
85
|
+
} catch (RaiseException e) {
|
86
|
+
return context.nil;
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
@JRubyMethod(name = "read", required = 1, optional = 1)
|
91
|
+
public IRubyObject read(ThreadContext context, IRubyObject[] args) {
|
92
|
+
IRubyObject key = args[0];
|
93
|
+
RubyBoolean notRaw = notRaw(context, args, 1);
|
94
|
+
return get(context, new IRubyObject[] { key, notRaw });
|
95
|
+
}
|
96
|
+
|
97
|
+
@JRubyMethod(name = "exist?", required = 1, optional = 1)
|
98
|
+
public IRubyObject exist_p(ThreadContext context, IRubyObject[] args) {
|
99
|
+
Ruby ruby = context.getRuntime();
|
100
|
+
try {
|
101
|
+
super.get(context, args);
|
102
|
+
return ruby.getTrue();
|
103
|
+
} catch (RaiseException e) {
|
104
|
+
return ruby.getFalse();
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
@JRubyMethod(name = "get_multi", required = 1, optional = 1)
|
109
|
+
public IRubyObject getMulti(ThreadContext context, IRubyObject[] args) {
|
110
|
+
IRubyObject keys = args[0];
|
111
|
+
RubyBoolean notRaw = notRaw(context, args, 1);
|
112
|
+
return super.get(context, new IRubyObject[] { keys, notRaw });
|
113
|
+
}
|
114
|
+
|
115
|
+
@JRubyMethod(name = { "set", "[]=" }, required = 2, optional = 2)
|
116
|
+
public IRubyObject set(ThreadContext context, IRubyObject[] args) {
|
117
|
+
Ruby ruby = context.getRuntime();
|
118
|
+
IRubyObject key = args[0];
|
119
|
+
IRubyObject value = args[1];
|
120
|
+
RubyFixnum ttl = getTTL(context, args, 2);
|
121
|
+
RubyBoolean notRaw = notRaw(context, args, 3);
|
122
|
+
try {
|
123
|
+
super.set(context, new IRubyObject[] { key, value, ttl, notRaw });
|
124
|
+
return ruby.getTrue();
|
125
|
+
} catch (RaiseException e) {
|
126
|
+
return ruby.getFalse();
|
127
|
+
}
|
128
|
+
}
|
129
|
+
|
130
|
+
@JRubyMethod(name = "write", required = 2, optional = 1)
|
131
|
+
public IRubyObject write(ThreadContext context, IRubyObject[] args) {
|
132
|
+
IRubyObject key = args[0];
|
133
|
+
IRubyObject value = args[1];
|
134
|
+
RubyFixnum ttl = getTTL(context, args, 2);
|
135
|
+
RubyBoolean notRaw = notRaw(context, args, 2);
|
136
|
+
return set(context, new IRubyObject[] { key, value, ttl, notRaw });
|
137
|
+
}
|
138
|
+
|
139
|
+
@JRubyMethod(name = "fetch", required = 1, optional = 1)
|
140
|
+
public IRubyObject fetch(ThreadContext context, IRubyObject[] args, Block block) {
|
141
|
+
Ruby ruby = context.getRuntime();
|
142
|
+
IRubyObject key = args[0];
|
143
|
+
RubyHash options;
|
144
|
+
if (args.length > 1) {
|
145
|
+
options = (RubyHash) args[1];
|
146
|
+
} else {
|
147
|
+
options = new RubyHash(ruby);
|
148
|
+
}
|
149
|
+
IRubyObject value = read(context, args);
|
150
|
+
if (value.isNil()) {
|
151
|
+
value = block.call(context);
|
152
|
+
write(context, new IRubyObject[] { key, value, options });
|
153
|
+
}
|
154
|
+
return value;
|
155
|
+
}
|
156
|
+
|
157
|
+
@JRubyMethod(name = "add", required = 2, optional = 2)
|
158
|
+
public IRubyObject add(ThreadContext context, IRubyObject[] args) {
|
159
|
+
Ruby ruby = context.getRuntime();
|
160
|
+
if (args.length > 3) {
|
161
|
+
if (ruby.getTrue() == args[3]) {
|
162
|
+
args[3] = ruby.getFalse();
|
163
|
+
} else {
|
164
|
+
args[3] = ruby.getTrue();
|
165
|
+
}
|
166
|
+
}
|
167
|
+
try {
|
168
|
+
super.add(context, args);
|
169
|
+
if (stringReturnTypes) {
|
170
|
+
return ruby.newString("STORED\r\n");
|
171
|
+
} else {
|
172
|
+
return ruby.getTrue();
|
173
|
+
}
|
174
|
+
} catch (RaiseException e) {
|
175
|
+
if (stringReturnTypes) {
|
176
|
+
return ruby.newString("NOT STORED\r\n");
|
177
|
+
} else {
|
178
|
+
return ruby.getFalse();
|
179
|
+
}
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
@JRubyMethod(name = "delete", required = 1, optional = 1)
|
184
|
+
public IRubyObject delete(ThreadContext context, IRubyObject[] args) {
|
185
|
+
try {
|
186
|
+
super.delete(context, args[0]);
|
187
|
+
} catch(RaiseException e) { }
|
188
|
+
|
189
|
+
return context.nil;
|
190
|
+
}
|
191
|
+
|
192
|
+
@JRubyMethod(name = { "flush", "flush_all", "clear" })
|
193
|
+
public IRubyObject flush(ThreadContext context) {
|
194
|
+
return super.flush(context);
|
195
|
+
}
|
196
|
+
|
197
|
+
@JRubyMethod(name = "read_multi", rest = true)
|
198
|
+
public IRubyObject readMulti(ThreadContext context, IRubyObject[] args) {
|
199
|
+
Ruby ruby = context.getRuntime();
|
200
|
+
if (args.length == 0) {
|
201
|
+
return new RubyHash(ruby);
|
202
|
+
} else {
|
203
|
+
return getMulti(context, args);
|
204
|
+
}
|
205
|
+
}
|
206
|
+
|
207
|
+
private RubyFixnum getTTL(ThreadContext context, IRubyObject[] args, int index) {
|
208
|
+
Ruby ruby = context.getRuntime();
|
209
|
+
if (args.length > index) {
|
210
|
+
if (args[index] instanceof RubyFixnum) {
|
211
|
+
return (RubyFixnum) args[index];
|
212
|
+
} else if (args[index] instanceof RubyHash) {
|
213
|
+
RubyHash options = (RubyHash) args[index];
|
214
|
+
if (options.containsKey(ruby.newSymbol("ttl"))) {
|
215
|
+
Long ttl = (Long) options.get(ruby.newSymbol("ttl"));
|
216
|
+
return ruby.newFixnum(ttl);
|
217
|
+
} else if (options.containsKey(ruby.newSymbol("expires_in"))) {
|
218
|
+
Long expiresIn = (Long) options.get(ruby.newSymbol("expires_in"));
|
219
|
+
return ruby.newFixnum(expiresIn);
|
220
|
+
}
|
221
|
+
}
|
222
|
+
}
|
223
|
+
return ruby.newFixnum(super.getDefaultTTL());
|
224
|
+
}
|
225
|
+
|
226
|
+
private RubyBoolean notRaw(ThreadContext context, IRubyObject[] args, int index) {
|
227
|
+
Ruby ruby = context.getRuntime();
|
228
|
+
RubyBoolean notRaw = ruby.getTrue();
|
229
|
+
if (args.length > index) {
|
230
|
+
if ((args[index] instanceof RubyBoolean && ruby.getTrue() == args[index]) ||
|
231
|
+
(args[index] instanceof RubyHash && ruby.getTrue() == ((RubyHash) args[index]).get(ruby.newSymbol("raw")))) {
|
232
|
+
notRaw = ruby.getFalse();
|
233
|
+
}
|
234
|
+
}
|
235
|
+
return notRaw;
|
236
|
+
}
|
237
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
package com.openfeint.memcached.error;
|
2
|
+
|
3
|
+
import org.jruby.Ruby;
|
4
|
+
import org.jruby.RubyClass;
|
5
|
+
import org.jruby.RubyException;
|
6
|
+
import org.jruby.anno.JRubyClass;
|
7
|
+
import org.jruby.exceptions.RaiseException;
|
8
|
+
|
9
|
+
@JRubyClass(name = "Memcached::Error", parent = "RuntimeError")
|
10
|
+
public class Error {
|
11
|
+
public static RaiseException newNotFound(Ruby ruby, String message) {
|
12
|
+
return newMemcachedError(ruby, "NotFound", message);
|
13
|
+
}
|
14
|
+
|
15
|
+
public static RaiseException newNotStored(Ruby ruby, String message) {
|
16
|
+
return newMemcachedError(ruby, "NotStored", message);
|
17
|
+
}
|
18
|
+
|
19
|
+
public static RaiseException newNotSupport(Ruby ruby, String message) {
|
20
|
+
return newMemcachedError(ruby, "NotSupport", message);
|
21
|
+
}
|
22
|
+
|
23
|
+
public static RaiseException newATimeoutOccurred(Ruby ruby, String message) {
|
24
|
+
return newMemcachedError(ruby, "ATimeoutOccurred", message);
|
25
|
+
}
|
26
|
+
|
27
|
+
private static RaiseException newMemcachedError(Ruby ruby, String klass, String message) {
|
28
|
+
RubyClass errorClass = ruby.getModule("Memcached").getClass(klass);
|
29
|
+
return new RaiseException(RubyException.newException(ruby, errorClass, message), true);
|
30
|
+
}
|
31
|
+
}
|
@@ -0,0 +1,91 @@
|
|
1
|
+
package com.openfeint.memcached.transcoder;
|
2
|
+
|
3
|
+
import net.spy.memcached.CachedData;
|
4
|
+
import net.spy.memcached.transcoders.Transcoder;
|
5
|
+
import org.jruby.Ruby;
|
6
|
+
import org.jruby.exceptions.RaiseException;
|
7
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
8
|
+
import org.jruby.runtime.marshal.MarshalStream;
|
9
|
+
import org.jruby.runtime.marshal.UnmarshalStream;
|
10
|
+
|
11
|
+
import java.io.ByteArrayInputStream;
|
12
|
+
import java.io.ByteArrayOutputStream;
|
13
|
+
import java.io.IOException;
|
14
|
+
|
15
|
+
/**
|
16
|
+
*
|
17
|
+
* MarshalTranscoder does marshaling and unmarshaling.
|
18
|
+
*
|
19
|
+
*/
|
20
|
+
public class MarshalTranscoder implements Transcoder {
|
21
|
+
protected Ruby ruby;
|
22
|
+
private int flags;
|
23
|
+
|
24
|
+
public MarshalTranscoder(Ruby ruby) {
|
25
|
+
this(ruby, 0);
|
26
|
+
}
|
27
|
+
|
28
|
+
public MarshalTranscoder(Ruby ruby, int flags) {
|
29
|
+
this.ruby = ruby;
|
30
|
+
this.flags = flags;
|
31
|
+
}
|
32
|
+
|
33
|
+
public boolean asyncDecode(CachedData d) {
|
34
|
+
return false;
|
35
|
+
}
|
36
|
+
|
37
|
+
public CachedData encode(Object o) {
|
38
|
+
if (o instanceof IRubyObject) {
|
39
|
+
try {
|
40
|
+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
41
|
+
MarshalStream marshal = new MarshalStream(ruby, baos, Integer.MAX_VALUE);
|
42
|
+
marshal.dumpObject((IRubyObject) o);
|
43
|
+
byte[] bytes = baos.toByteArray();
|
44
|
+
return new CachedData(getFlags(), bytes, bytes.length);
|
45
|
+
} catch (IOException e) {
|
46
|
+
throw ruby.newIOErrorFromException(e);
|
47
|
+
}
|
48
|
+
} else {
|
49
|
+
return encodeNumber(o);
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
public Object decode(CachedData d) {
|
54
|
+
try {
|
55
|
+
return new UnmarshalStream(ruby, new ByteArrayInputStream(d.getData()), null, false, false).unmarshalObject();
|
56
|
+
} catch (RaiseException e) {
|
57
|
+
return decodeNumber(d, e);
|
58
|
+
} catch (IOException e) {
|
59
|
+
return decodeNumber(d, e);
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
public int getMaxSize() {
|
64
|
+
return CachedData.MAX_SIZE;
|
65
|
+
}
|
66
|
+
|
67
|
+
public int getFlags() {
|
68
|
+
return flags;
|
69
|
+
}
|
70
|
+
|
71
|
+
protected CachedData encodeNumber(Object o) {
|
72
|
+
byte[] bytes = o.toString().getBytes();
|
73
|
+
return new CachedData(getFlags(), bytes, bytes.length);
|
74
|
+
}
|
75
|
+
|
76
|
+
protected Long decodeNumber(CachedData d, RaiseException originalException) {
|
77
|
+
try {
|
78
|
+
return Long.valueOf(new String(d.getData()).trim());
|
79
|
+
} catch (NumberFormatException e) {
|
80
|
+
throw ruby.newRuntimeError(originalException.getLocalizedMessage());
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
protected Long decodeNumber(CachedData d, IOException originalException) {
|
85
|
+
try {
|
86
|
+
return Long.valueOf(new String(d.getData()).trim());
|
87
|
+
} catch (NumberFormatException e) {
|
88
|
+
throw ruby.newIOErrorFromException(originalException);
|
89
|
+
}
|
90
|
+
}
|
91
|
+
}
|
@@ -0,0 +1,103 @@
|
|
1
|
+
package com.openfeint.memcached.transcoder;
|
2
|
+
|
3
|
+
import com.jcraft.jzlib.JZlib;
|
4
|
+
import com.jcraft.jzlib.ZInputStream;
|
5
|
+
import com.jcraft.jzlib.ZOutputStream;
|
6
|
+
import net.spy.memcached.CachedData;
|
7
|
+
import org.jruby.Ruby;
|
8
|
+
import org.jruby.exceptions.RaiseException;
|
9
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
10
|
+
import org.jruby.runtime.marshal.MarshalStream;
|
11
|
+
import org.jruby.runtime.marshal.UnmarshalStream;
|
12
|
+
|
13
|
+
import java.io.ByteArrayInputStream;
|
14
|
+
import java.io.ByteArrayOutputStream;
|
15
|
+
import java.io.IOException;
|
16
|
+
|
17
|
+
/**
|
18
|
+
*
|
19
|
+
* MarshalZlibTranscoder do marshaling/unmarshaling and compressing/decompressing with zlib.
|
20
|
+
*
|
21
|
+
*/
|
22
|
+
public class MarshalZlibTranscoder extends MarshalTranscoder {
|
23
|
+
static final int COMPRESS_FLAG = 1;
|
24
|
+
|
25
|
+
public MarshalZlibTranscoder(Ruby ruby) {
|
26
|
+
super(ruby, COMPRESS_FLAG);
|
27
|
+
}
|
28
|
+
|
29
|
+
public MarshalZlibTranscoder(Ruby ruby, int flags) {
|
30
|
+
super(ruby, flags);
|
31
|
+
}
|
32
|
+
|
33
|
+
public CachedData encode(Object o) {
|
34
|
+
if (o instanceof IRubyObject) {
|
35
|
+
ZOutputStream zout = null;
|
36
|
+
try {
|
37
|
+
ByteArrayOutputStream out1 = new ByteArrayOutputStream();
|
38
|
+
MarshalStream marshal = new MarshalStream(ruby, out1, Integer.MAX_VALUE);
|
39
|
+
marshal.dumpObject((IRubyObject) o);
|
40
|
+
|
41
|
+
byte[] bytes;
|
42
|
+
if (getFlags() == COMPRESS_FLAG) {
|
43
|
+
ByteArrayOutputStream out2 = new ByteArrayOutputStream();
|
44
|
+
zout = new ZOutputStream(out2, JZlib.Z_DEFAULT_COMPRESSION);
|
45
|
+
zout.write(out1.toByteArray());
|
46
|
+
zout.flush();
|
47
|
+
zout.end();
|
48
|
+
bytes = out2.toByteArray();
|
49
|
+
} else {
|
50
|
+
bytes = out1.toByteArray();
|
51
|
+
}
|
52
|
+
|
53
|
+
return new CachedData(super.getFlags(), bytes, bytes.length);
|
54
|
+
} catch (IOException e) {
|
55
|
+
throw ruby.newIOErrorFromException(e);
|
56
|
+
} finally {
|
57
|
+
if (zout != null) {
|
58
|
+
try {
|
59
|
+
zout.close();
|
60
|
+
} catch (IOException e) {}
|
61
|
+
zout = null;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
} else {
|
65
|
+
return super.encodeNumber(o);
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
public Object decode(CachedData d) {
|
70
|
+
ZInputStream zin = null;
|
71
|
+
try {
|
72
|
+
byte[] bytes;
|
73
|
+
if (d.getFlags() == COMPRESS_FLAG) {
|
74
|
+
ByteArrayInputStream in = new ByteArrayInputStream(d.getData());
|
75
|
+
zin = new ZInputStream(in);
|
76
|
+
|
77
|
+
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
78
|
+
int nRead;
|
79
|
+
byte[] data = new byte[1024];
|
80
|
+
while ((nRead = zin.read(data, 0, data.length)) != -1) {
|
81
|
+
buffer.write(data, 0, nRead);
|
82
|
+
}
|
83
|
+
buffer.flush();
|
84
|
+
bytes = buffer.toByteArray();
|
85
|
+
} else {
|
86
|
+
bytes = d.getData();
|
87
|
+
}
|
88
|
+
|
89
|
+
return new UnmarshalStream(ruby, new ByteArrayInputStream(bytes), null, false, false).unmarshalObject();
|
90
|
+
} catch (RaiseException e) {
|
91
|
+
return super.decodeNumber(d, e);
|
92
|
+
} catch (IOException e) {
|
93
|
+
return super.decodeNumber(d, e);
|
94
|
+
} finally {
|
95
|
+
if (zin != null) {
|
96
|
+
try {
|
97
|
+
zin.close();
|
98
|
+
} catch (IOException e) {}
|
99
|
+
zin = null;
|
100
|
+
}
|
101
|
+
}
|
102
|
+
}
|
103
|
+
}
|