// line 1 "Parser.rl"
/*
* 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.RubyArray;
import org.jruby.RubyClass;
import org.jruby.RubyEncoding;
import org.jruby.RubyFloat;
import org.jruby.RubyHash;
import org.jruby.RubyInteger;
import org.jruby.RubyModule;
import org.jruby.RubyNumeric;
import org.jruby.RubyObject;
import org.jruby.RubyString;
import org.jruby.anno.JRubyMethod;
import org.jruby.exceptions.JumpException;
import org.jruby.exceptions.RaiseException;
import org.jruby.runtime.Block;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
import org.jruby.util.ConvertBytes;
import static org.jruby.util.ConvertDouble.DoubleConverter;
/**
* The <code>JSON::Ext::Parser</code> class.
*
* <p>This is the JSON parser implemented as a Java class. To use it as the
* standard parser, set
* <pre>JSON.parser = JSON::Ext::Parser</pre>
* This is performed for you when you <code>include "json/ext"</code>.
*
* <p>This class does not perform the actual parsing, just acts as an interface
* to Ruby code. When the {@link #parse()} method is invoked, a
* Parser.ParserSession object is instantiated, which handles the process.
*
* @author mernen
*/
public class Parser extends RubyObject {
private final RuntimeInfo info;
private RubyString vSource;
private RubyString createId;
private boolean createAdditions;
private int maxNesting;
private boolean allowNaN;
private boolean symbolizeNames;
private boolean quirksMode;
private RubyClass objectClass;
private RubyClass arrayClass;
private RubyHash match_string;
private static final int DEFAULT_MAX_NESTING = 19;
private static final ByteList JSON_MINUS_INFINITY = new ByteList(ByteList.plain("-Infinity"));
// constant names in the JSON module containing those values
private static final String CONST_NAN = "NaN";
private static final String CONST_INFINITY = "Infinity";
private static final String CONST_MINUS_INFINITY = "MinusInfinity";
static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
return new Parser(runtime, klazz);
}
};
/**
* Multiple-value return for internal parser methods.
*
* <p>All the <code>parse<var>Stuff</var></code> methods return instances of
* <code>ParserResult</code> when successful, or <code>null</code> when
* there's a problem with the input data.
*/
static final class ParserResult {
/**
* The result of the successful parsing. Should never be
* <code>null</code>.
*/
IRubyObject result;
/**
* The point where the parser returned.
*/
int p;
void update(IRubyObject result, int p) {
this.result = result;
this.p = p;
}
}
public Parser(Ruby runtime, RubyClass metaClass) {
super(runtime, metaClass);
info = RuntimeInfo.forRuntime(runtime);
}
/**
* <code>Parser.new(source, opts = {})</code>
*
* <p>Creates a new <code>JSON::Ext::Parser</code> instance for the string
* <code>source</code>.
* It will be configured by the <code>opts</code> Hash.
* <code>opts</code> can have the following keys:
*
* <dl>
* <dt><code>:max_nesting</code>
* <dd>The maximum depth of nesting allowed in the parsed data
* structures. Disable depth checking with <code>:max_nesting => false|nil|0</code>,
* it defaults to 19.
*
* <dt><code>:allow_nan</code>
* <dd>If set to <code>true</code>, allow <code>NaN</code>,
* <code>Infinity</code> and <code>-Infinity</code> in defiance of RFC 4627
* to be parsed by the Parser. This option defaults to <code>false</code>.
*
* <dt><code>:symbolize_names</code>
* <dd>If set to <code>true</code>, returns symbols for the names (keys) in
* a JSON object. Otherwise strings are returned, which is also the default.
*
* <dt><code>:quirks_mode?</code>
* <dd>If set to <code>true</code>, if the parse is in quirks_mode, false
* otherwise.
*
* <dt><code>:create_additions</code>
* <dd>If set to <code>false</code>, the Parser doesn't create additions
* even if a matchin class and <code>create_id</code> was found. This option
* defaults to <code>true</code>.
*
* <dt><code>:object_class</code>
* <dd>Defaults to Hash.
*
* <dt><code>:array_class</code>
* <dd>Defaults to Array.
*
* <dt><code>:quirks_mode</code>
* <dd>Enables quirks_mode for parser, that is for example parsing single
* JSON values instead of documents is possible.
* </dl>
*/
@JRubyMethod(name = "new", required = 1, optional = 1, meta = true)
public static IRubyObject newInstance(IRubyObject clazz, IRubyObject[] args, Block block) {
Parser parser = (Parser)((RubyClass)clazz).allocate();
parser.callInit(args, block);
return parser;
}
@JRubyMethod(required = 1, optional = 1, visibility = Visibility.PRIVATE)
public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {
Ruby runtime = context.getRuntime();
if (this.vSource != null) {
throw runtime.newTypeError("already initialized instance");
}
OptionsReader opts = new OptionsReader(context, args.length > 1 ? args[1] : null);
this.maxNesting = opts.getInt("max_nesting", DEFAULT_MAX_NESTING);
this.allowNaN = opts.getBool("allow_nan", false);
this.symbolizeNames = opts.getBool("symbolize_names", false);
this.quirksMode = opts.getBool("quirks_mode", false);
this.createId = opts.getString("create_id", getCreateId(context));
this.createAdditions = opts.getBool("create_additions", true);
this.objectClass = opts.getClass("object_class", runtime.getHash());
this.arrayClass = opts.getClass("array_class", runtime.getArray());
this.match_string = opts.getHash("match_string");
this.vSource = args[0].convertToString();
if (!quirksMode) this.vSource = convertEncoding(context, vSource);
return this;
}
/**
* Checks the given string's encoding. If a non-UTF-8 encoding is detected,
* a converted copy is returned.
* Returns the source string if no conversion is needed.
*/
private RubyString convertEncoding(ThreadContext context, RubyString source) {
ByteList bl = source.getByteList();
int len = bl.length();
if (len < 2) {
throw Utils.newException(context, Utils.M_PARSER_ERROR,
"A JSON text must at least contain two octets!");
}
if (info.encodingsSupported()) {
RubyEncoding encoding = (RubyEncoding)source.encoding(context);
if (encoding != info.ascii8bit.get()) {
return (RubyString)source.encode(context, info.utf8.get());
}
String sniffedEncoding = sniffByteList(bl);
if (sniffedEncoding == null) return source; // assume UTF-8
return reinterpretEncoding(context, source, sniffedEncoding);
}
String sniffedEncoding = sniffByteList(bl);
if (sniffedEncoding == null) return source; // assume UTF-8
Ruby runtime = context.getRuntime();
return (RubyString)info.jsonModule.get().
callMethod(context, "iconv",
new IRubyObject[] {
runtime.newString("utf-8"),
runtime.newString(sniffedEncoding),
没有合适的资源?快使用搜索试试~ 我知道了~
资源详情
资源评论
资源推荐
收起资源包目录
Jenkins常用插件大全jenkins-plugin-war.tar.gz (2000个子文件)
AUTHORS 3KB
bad_robots 17KB
kubernetes.bak 9.71MB
gitlab-plugin.bak 7.64MB
sonar.bak 6.65MB
subversion.bak 6.64MB
maven-plugin.bak 4.96MB
bouncycastle-api.bak 4.09MB
git-client.bak 2.48MB
pipeline-model-api.bak 2.31MB
git.bak 1.94MB
workflow-cps-global-lib.bak 1.88MB
jackson2-api.bak 1.68MB
apache-httpcomponents-client-4-api.bak 1.66MB
pipeline-model-definition.bak 1.48MB
pam-auth.bak 1.43MB
git-parameter.bak 959KB
credentials.bak 955KB
email-ext.bak 777KB
token-macro.bak 637KB
workflow-cps.bak 551KB
windows-slaves.bak 460KB
localization-zh-cn.bak 400KB
trilead-api.bak 375KB
workflow-support.bak 371KB
junit.bak 352KB
ws-cleanup.bak 318KB
branch-api.bak 300KB
jsch.bak 273KB
uno-choice.bak 242KB
scm-api.bak 212KB
cloudbees-folder.bak 211KB
pipeline-stage-view.bak 198KB
script-security.bak 166KB
workflow-api.bak 151KB
jquery.bak 144KB
pipeline-rest-api.bak 143KB
parameterized-trigger.bak 134KB
workflow-basic-steps.bak 131KB
ldap.bak 126KB
scriptler.bak 119KB
matrix-auth.bak 115KB
mailer.bak 111KB
antisamy-markup-formatter.bak 110KB
workflow-job.bak 109KB
build-timeout.bak 93KB
role-strategy.bak 89KB
workflow-durable-task-step.bak 87KB
lockable-resources.bak 83KB
timestamper.bak 81KB
docker-commons.bak 78KB
credentials-binding.bak 74KB
workflow-step-api.bak 72KB
jdk-tool.bak 68KB
ssh-credentials.bak 64KB
dynamicparameter.bak 63KB
docker-workflow.bak 55KB
durable-task.bak 53KB
structs.bak 40KB
git-server.bak 40KB
command-launcher.bak 38KB
pipeline-model-extensions.bak 32KB
pipeline-build-step.bak 32KB
pipeline-input-step.bak 28KB
display-url-api.bak 26KB
kubernetes-cli.bak 25KB
resource-disposer.bak 21KB
pipeline-graph-analysis.bak 19KB
kubernetes-credentials.bak 17KB
plain-credentials.bak 17KB
workflow-scm-step.bak 15KB
variant.bak 10KB
pipeline-stage-tags-metadata.bak 9KB
binary 26KB
hello.builder 39B
error.builder 35B
layout2.builder 33B
parser.c 47KB
generator.c 45KB
CHANGES 41KB
CHANGES 13KB
hello.coffee 13B
lighttpd.conf 953B
config 36B
content_type_and_no_filename 123B
COPYING 3KB
COPYING 1KB
COPYING 1KB
COPYING-json-jruby 3KB
hello.creole 20B
foundation4.css 161KB
foundation5.css 105KB
foundation3.css 103KB
bootstrap.min.css 97KB
style.css 41KB
jquery-ui-1.8.14.custom.css 33KB
jquery-ui.css 33KB
font-awesome3.css 28KB
font-awesome4.css 22KB
foundation-icons.css 20KB
共 2000 条
- 1
- 2
- 3
- 4
- 5
- 6
- 20
BearCoding
- 粉丝: 89
- 资源: 5
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0