2 * This code is copyrighted work by Daniel Luz <dev at mernen dot com>.
4 * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files
10 import org.jruby.RubyClass;
11 import org.jruby.RubyHash;
12 import org.jruby.RubyNumeric;
13 import org.jruby.RubyString;
14 import org.jruby.runtime.ThreadContext;
15 import org.jruby.runtime.builtin.IRubyObject;
16 import org.jruby.util.ByteList;
18 final class OptionsReader {
19 private final ThreadContext context;
20 private final Ruby runtime;
21 private final RubyHash opts;
22 private RuntimeInfo info;
24 OptionsReader(ThreadContext context, IRubyObject vOpts) {
25 this.context = context;
26 this.runtime = context.getRuntime();
28 if (vOpts == null || vOpts.isNil()) {
30 } else if (vOpts.respondsTo("to_hash")) {
31 opts = vOpts.convertToHash();
33 opts = vOpts.callMethod(context, "to_h").convertToHash();
37 private RuntimeInfo getRuntimeInfo() {
38 if (info != null) return info;
39 info = RuntimeInfo.forRuntime(runtime);
44 * Efficiently looks up items with a {@link RubySymbol Symbol} key
45 * @param key The Symbol name to look up for
46 * @return The item in the {@link RubyHash Hash}, or <code>null</code>
49 IRubyObject get(String key) {
50 return opts == null ? null : opts.fastARef(runtime.newSymbol(key));
53 boolean getBool(String key, boolean defaultValue) {
54 IRubyObject value = get(key);
55 return value == null ? defaultValue : value.isTrue();
58 int getInt(String key, int defaultValue) {
59 IRubyObject value = get(key);
60 if (value == null) return defaultValue;
61 if (!value.isTrue()) return 0;
62 return RubyNumeric.fix2int(value);
66 * Reads the setting from the options hash. If no entry is set for this
67 * key or if it evaluates to <code>false</code>, returns null; attempts to
68 * coerce the value to {@link RubyString String} otherwise.
69 * @param key The Symbol name to look up for
70 * @return <code>null</code> if the key is not in the Hash or if
71 * its value evaluates to <code>false</code>
72 * @throws RaiseException <code>TypeError</code> if the value does not
73 * evaluate to <code>false</code> and can't be
76 ByteList getString(String key) {
77 RubyString str = getString(key, null);
78 return str == null ? null : str.getByteList().dup();
81 RubyString getString(String key, RubyString defaultValue) {
82 IRubyObject value = get(key);
83 if (value == null || !value.isTrue()) return defaultValue;
85 RubyString str = value.convertToString();
86 RuntimeInfo info = getRuntimeInfo();
87 if (info.encodingsSupported() && str.encoding(context) != info.utf8.get()) {
88 str = (RubyString)str.encode(context, info.utf8.get());
94 * Reads the setting from the options hash. If it is <code>nil</code> or
95 * undefined, returns the default value given.
96 * If not, ensures it is a RubyClass instance and shares the same
97 * allocator as the default value (i.e. for the basic types which have
98 * their specific allocators, this ensures the passed value is
99 * a subclass of them).
101 RubyClass getClass(String key, RubyClass defaultValue) {
102 IRubyObject value = get(key);
104 if (value == null || value.isNil()) return defaultValue;
106 if (value instanceof RubyClass &&
107 ((RubyClass)value).getAllocator() == defaultValue.getAllocator()) {
108 return (RubyClass)value;
110 throw runtime.newTypeError(key + " option must be a subclass of "
114 public RubyHash getHash(String key) {
115 IRubyObject value = get(key);
116 if (value == null || value.isNil()) return new RubyHash(runtime);
117 return (RubyHash) value;