/*
* Copyright (C) 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.gson.stream;
import com.google.gson.internal.JsonReaderInternalAccess;
import com.google.gson.internal.bind.JsonTreeReader;
import java.io.Closeable;
import java.io.EOFException;
import java.io.IOException;
import java.io.Reader;
/**
* Reads a JSON (<a href="http://www.ietf.org/rfc/rfc7159.txt">RFC 7159</a>)
* encoded value as a stream of tokens. This stream includes both literal
* values (strings, numbers, booleans, and nulls) as well as the begin and
* end delimiters of objects and arrays. The tokens are traversed in
* depth-first order, the same order that they appear in the JSON document.
* Within JSON objects, name/value pairs are represented by a single token.
*
* <h3>Parsing JSON</h3>
* To create a recursive descent parser for your own JSON streams, first create
* an entry point method that creates a {@code JsonReader}.
*
* <p>Next, create handler methods for each structure in your JSON text. You'll
* need a method for each object type and for each array type.
* <ul>
* <li>Within <strong>array handling</strong> methods, first call {@link
* #beginArray} to consume the array's opening bracket. Then create a
* while loop that accumulates values, terminating when {@link #hasNext}
* is false. Finally, read the array's closing bracket by calling {@link
* #endArray}.
* <li>Within <strong>object handling</strong> methods, first call {@link
* #beginObject} to consume the object's opening brace. Then create a
* while loop that assigns values to local variables based on their name.
* This loop should terminate when {@link #hasNext} is false. Finally,
* read the object's closing brace by calling {@link #endObject}.
* </ul>
* <p>When a nested object or array is encountered, delegate to the
* corresponding handler method.
*
* <p>When an unknown name is encountered, strict parsers should fail with an
* exception. Lenient parsers should call {@link #skipValue()} to recursively
* skip the value's nested tokens, which may otherwise conflict.
*
* <p>If a value may be null, you should first check using {@link #peek()}.
* Null literals can be consumed using either {@link #nextNull()} or {@link
* #skipValue()}.
*
* <h3>Example</h3>
* Suppose we'd like to parse a stream of messages such as the following: <pre> {@code
* [
* {
* "id": 912345678901,
* "text": "How do I read a JSON stream in Java?",
* "geo": null,
* "user": {
* "name": "json_newb",
* "followers_count": 41
* }
* },
* {
* "id": 912345678902,
* "text": "@json_newb just use JsonReader!",
* "geo": [50.454722, -104.606667],
* "user": {
* "name": "jesse",
* "followers_count": 2
* }
* }
* ]}</pre>
* This code implements the parser for the above structure: <pre> {@code
*
* public List<Message> readJsonStream(InputStream in) throws IOException {
* JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
* try {
* return readMessagesArray(reader);
* } finally {
* reader.close();
* }
* }
*
* public List<Message> readMessagesArray(JsonReader reader) throws IOException {
* List<Message> messages = new ArrayList<Message>();
*
* reader.beginArray();
* while (reader.hasNext()) {
* messages.add(readMessage(reader));
* }
* reader.endArray();
* return messages;
* }
*
* public Message readMessage(JsonReader reader) throws IOException {
* long id = -1;
* String text = null;
* User user = null;
* List<Double> geo = null;
*
* reader.beginObject();
* while (reader.hasNext()) {
* String name = reader.nextName();
* if (name.equals("id")) {
* id = reader.nextLong();
* } else if (name.equals("text")) {
* text = reader.nextString();
* } else if (name.equals("geo") && reader.peek() != JsonToken.NULL) {
* geo = readDoublesArray(reader);
* } else if (name.equals("user")) {
* user = readUser(reader);
* } else {
* reader.skipValue();
* }
* }
* reader.endObject();
* return new Message(id, text, user, geo);
* }
*
* public List<Double> readDoublesArray(JsonReader reader) throws IOException {
* List<Double> doubles = new ArrayList<Double>();
*
* reader.beginArray();
* while (reader.hasNext()) {
* doubles.add(reader.nextDouble());
* }
* reader.endArray();
* return doubles;
* }
*
* public User readUser(JsonReader reader) throws IOException {
* String username = null;
* int followersCount = -1;
*
* reader.beginObject();
* while (reader.hasNext()) {
* String name = reader.nextName();
* if (name.equals("name")) {
* username = reader.nextString();
* } else if (name.equals("followers_count")) {
* followersCount = reader.nextInt();
* } else {
* reader.skipValue();
* }
* }
* reader.endObject();
* return new User(username, followersCount);
* }}</pre>
*
* <h3>Number Handling</h3>
* This reader permits numeric values to be read as strings and string values to
* be read as numbers. For example, both elements of the JSON array {@code
* [1, "1"]} may be read using either {@link #nextInt} or {@link #nextString}.
* This behavior is intended to prevent lossy numeric conversions: double is
* JavaScript's only numeric type and very large values like {@code
* 9007199254740993} cannot be represented exactly on that platform. To minimize
* precision loss, extremely large values should be written and read as strings
* in JSON.
*
* <a name="nonexecuteprefix"/><h3>Non-Execute Prefix</h3>
* Web servers that serve private data using JSON may be vulnerable to <a
* href="http://en.wikipedia.org/wiki/JSON#Cross-site_request_forgery">Cross-site
* request forgery</a> attacks. In such an attack, a malicious site gains access
* to a private JSON file by executing it with an HTML {@code <script>} tag.
*
* <p>Prefixing JSON files with <code>")]}'\n"</code> makes them non-executable
* by {@code <script>} tags, disarming the attack. Since the prefix is malformed
* JSON, strict parsing fails when it is encountered. This class permits the
* non-execute prefix when {@link #setLenient(boolean) lenient parsing} is
* enabled.
*
* <p>Each {@code JsonReader} may be used to read a single JSON stream. Instances
* of this class are not thread safe.
*
* @author Jesse Wilson
* @since 1.6
*/
public class JsonReader implements Closeable {
/** The only non-execute prefix this parser permits */
private static final char[] NON_EXECUTE_PREFIX = ")]}'\n".toCharArray();
private static final long MIN_INCOMPLETE_INTEGER = Long.MIN_VALUE / 10;
private static final int PEEKED_NONE = 0;
private static final int PEEKED_BEGIN_OBJECT = 1;
private static final int PEEKED_END_OBJECT = 2;
private static final int PEEKED_BEGIN_ARRAY = 3;
private static final int PEEKED_END_ARRAY = 4;
private static final int PEEKED_TRUE = 5;
private static final int PEEKED_FALSE = 6;
private static final int PEEKED_NULL = 7;
private static final int PEEKED_SINGLE_QUOTED = 8;
private static final int PEEKED_DOUBLE_QUOTED = 9;
private static final int PEEKED_UNQUOTED = 10;
/** When this i
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
gson源码与文档,集成多枚举类型统一序列化/反序列化处理 (350个子文件)
Gson.class 21KB
JsonReader.class 19KB
LinkedHashTreeMap.class 14KB
LinkedTreeMap.class 11KB
$Gson$Types.class 10KB
TypeAdapters.class 10KB
ReflectiveTypeAdapterFactory.class 8KB
GsonBuilder.class 8KB
JsonWriter.class 8KB
TypeToken.class 8KB
JsonTreeReader.class 8KB
MapTypeAdapterFactory$Adapter.class 7KB
ISO8601Utils.class 7KB
Excluder.class 7KB
JsonPrimitive.class 6KB
ConstructorConstructor.class 6KB
TypeAdapters$29.class 5KB
JsonArray.class 5KB
TreeTypeAdapter.class 5KB
JsonTreeWriter.class 5KB
DefaultDateTypeAdapter.class 5KB
JsonObject.class 4KB
ReflectiveTypeAdapterFactory$Adapter.class 4KB
ObjectTypeAdapter.class 4KB
TypeAdapters$2.class 4KB
JsonAdapterAnnotationTypeAdapterFactory.class 4KB
JsonElement.class 4KB
CollectionTypeAdapterFactory$Adapter.class 4KB
TypeAdapters$EnumTypeAdapter.class 4KB
TypeAdapter.class 3KB
LinkedHashTreeMap$Node.class 3KB
MapTypeAdapterFactory.class 3KB
LinkedTreeMap$Node.class 3KB
FieldNamingPolicy.class 3KB
ArrayTypeAdapter.class 3KB
ReflectiveTypeAdapterFactory$1.class 3KB
UnsafeAllocator.class 3KB
$Gson$Types$ParameterizedTypeImpl.class 3KB
DateTypeAdapter.class 3KB
TypeAdapters$27.class 3KB
TypeAdapters$14.class 3KB
Primitives.class 3KB
JsonParser.class 3KB
TypeAdapterRuntimeTypeWrapper.class 3KB
JsonStreamParser.class 3KB
TreeTypeAdapter$SingleTypeFactory.class 3KB
TypeAdapters$10.class 3KB
CollectionTypeAdapterFactory.class 3KB
Gson$6.class 3KB
SqlDateTypeAdapter.class 2KB
TimeTypeAdapter.class 2KB
LinkedHashTreeMap$AvlBuilder.class 2KB
TypeAdapters$28.class 2KB
Streams.class 2KB
$Gson$Types$WildcardTypeImpl.class 2KB
Excluder$1.class 2KB
TypeAdapters$15.class 2KB
FieldAttributes.class 2KB
TypeAdapters$35$1.class 2KB
ConstructorConstructor$3.class 2KB
TypeAdapters$35.class 2KB
TypeAdapters$1.class 2KB
TypeAdapters$22.class 2KB
LinkedHashTreeMap$LinkedTreeMapIterator.class 2KB
ConstructorConstructor$14.class 2KB
TypeAdapters$34.class 2KB
LinkedTreeMap$LinkedTreeMapIterator.class 2KB
TypeAdapters$33.class 2KB
Gson$3.class 2KB
Gson$2.class 2KB
LinkedHashTreeMap$EntrySet.class 2KB
ArrayTypeAdapter$1.class 2KB
TypeAdapters$5.class 2KB
LazilyParsedNumber.class 2KB
TypeAdapters$18.class 2KB
TypeAdapters$17.class 2KB
TypeAdapters$7.class 2KB
TypeAdapters$6.class 2KB
TypeAdapters$11.class 2KB
LinkedTreeMap$EntrySet.class 2KB
TypeAdapters$21.class 2KB
Gson$4.class 2KB
TypeAdapters$23.class 2KB
TypeAdapters$3.class 2KB
TypeAdapters$4.class 2KB
TypeAdapters$19.class 2KB
TypeAdapters$16.class 2KB
TypeAdapters$20.class 2KB
TypeAdapters$26$1.class 2KB
TypeAdapters$24.class 2KB
TypeAdapters$32.class 2KB
TreeTypeAdapter$GsonContextImpl.class 2KB
TypeAdapters$8.class 2KB
TypeAdapters$13.class 2KB
TypeAdapters$12.class 2KB
Gson$5.class 2KB
ConstructorConstructor$5.class 2KB
Gson$FutureTypeAdapter.class 2KB
LinkedHashTreeMap$AvlIterator.class 2KB
$Gson$Types$GenericArrayTypeImpl.class 2KB
共 350 条
- 1
- 2
- 3
- 4
资源评论
atm008
- 粉丝: 4
- 资源: 2
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功