diff options
author | Florian Frank <flori@ping.de> | 2010-09-22 22:21:02 +0200 |
---|---|---|
committer | Florian Frank <flori@ping.de> | 2010-09-23 01:16:01 +0200 |
commit | e3fe104e7d5ec184aac36128aed2d217cb655dfc (patch) | |
tree | 3a63dc0152effdb990defcd5c935e38209649a8f /java/src/json/ext/OptionsReader.java | |
parent | 2c0f8d2c9b15a33b8d10ffcb1959aef54d320b57 (diff) | |
download | json-e3fe104e7d5ec184aac36128aed2d217cb655dfc.tar.gz |
started to build jruby extension with Rakefile
Diffstat (limited to 'java/src/json/ext/OptionsReader.java')
-rw-r--r-- | java/src/json/ext/OptionsReader.java | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/java/src/json/ext/OptionsReader.java b/java/src/json/ext/OptionsReader.java new file mode 100644 index 0000000..3bc8d5f --- /dev/null +++ b/java/src/json/ext/OptionsReader.java @@ -0,0 +1,108 @@ +/* + * This code is copyrighted work by Daniel Luz <dev at mernen dot com>. + * + * Distributed under the Ruby and GPLv2 licenses; see COPYING and GPL files + * for details. + */ +package json.ext; + +import org.jruby.Ruby; +import org.jruby.RubyClass; +import org.jruby.RubyHash; +import org.jruby.RubyNumeric; +import org.jruby.RubyString; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.util.ByteList; + +final class OptionsReader { + private final ThreadContext context; + private final Ruby runtime; + private final RubyHash opts; + private RuntimeInfo info; + + OptionsReader(ThreadContext context, IRubyObject vOpts) { + this.context = context; + this.runtime = context.getRuntime(); + + if (vOpts == null || vOpts.isNil()) { + opts = null; + } else if (vOpts.respondsTo("to_hash")) { + opts = vOpts.convertToHash(); + } else { + opts = vOpts.callMethod(context, "to_h").convertToHash(); + } + } + + private RuntimeInfo getRuntimeInfo() { + if (info != null) return info; + info = RuntimeInfo.forRuntime(runtime); + return info; + } + + /** + * Efficiently looks up items with a {@link RubySymbol Symbol} key + * @param key The Symbol name to look up for + * @return The item in the {@link RubyHash Hash}, or <code>null</code> + * if not found + */ + IRubyObject get(String key) { + return opts == null ? null : opts.fastARef(runtime.newSymbol(key)); + } + + boolean getBool(String key, boolean defaultValue) { + IRubyObject value = get(key); + return value == null ? defaultValue : value.isTrue(); + } + + int getInt(String key, int defaultValue) { + IRubyObject value = get(key); + if (value == null) return defaultValue; + if (!value.isTrue()) return 0; + return RubyNumeric.fix2int(value); + } + + /** + * Reads the setting from the options hash. If no entry is set for this + * key or if it evaluates to <code>false</code>, returns null; attempts to + * coerce the value to {@link RubyString String} otherwise. + * @param key The Symbol name to look up for + * @return <code>null</code> if the key is not in the Hash or if + * its value evaluates to <code>false</code> + * @throws RaiseException <code>TypeError</code> if the value does not + * evaluate to <code>false</code> and can't be + * converted to string + */ + ByteList getString(String key) { + IRubyObject value = get(key); + if (value == null || !value.isTrue()) return null; + + RubyString str = value.convertToString(); + RuntimeInfo info = getRuntimeInfo(); + if (info.encodingsSupported() && str.encoding(context) != info.utf8) { + str = (RubyString)str.encode(context, info.utf8); + } + return str.getByteList().dup(); + } + + /** + * Reads the setting from the options hash. If it is <code>nil</code> or + * undefined, returns the default value given. + * If not, ensures it is a RubyClass instance and shares the same + * allocator as the default value (i.e. for the basic types which have + * their specific allocators, this ensures the passed value is + * a subclass of them). + */ + RubyClass getClass(String key, RubyClass defaultValue) { + IRubyObject value = get(key); + + if (value == null || value.isNil()) return defaultValue; + + if (value instanceof RubyClass && + ((RubyClass)value).getAllocator() == defaultValue.getAllocator()) { + return (RubyClass)value; + } + throw runtime.newTypeError(key + " option must be a subclass of " + + defaultValue); + } +} |