From 63946e2831011261b7c4acfa6b58fb78bdf58884 Mon Sep 17 00:00:00 2001 From: Mariotaku Lee Date: Mon, 28 Dec 2015 16:06:57 +0800 Subject: [PATCH] updated versions --- twidere.component.common/build.gradle | 4 +- twidere.wear/build.gradle | 2 +- twidere/build.gradle | 9 +- twidere/src/main/AndroidManifest.xml | 5 - .../simple/tree/JsonAbstractValue.java | 109 - .../jackson/simple/tree/JsonArray.java | 60 - .../jackson/simple/tree/JsonBoolean.java | 26 - .../jackson/simple/tree/JsonNumber.java | 74 - .../jackson/simple/tree/JsonObject.java | 65 - .../jackson/simple/tree/JsonString.java | 32 - .../jackson/simple/tree/SimpleTreeCodec.java | 184 -- .../jackson/simple/tree/TokenBuffer.java | 1746 ----------------- 12 files changed, 7 insertions(+), 2309 deletions(-) delete mode 100644 twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonAbstractValue.java delete mode 100644 twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonArray.java delete mode 100644 twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonBoolean.java delete mode 100644 twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonNumber.java delete mode 100644 twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonObject.java delete mode 100644 twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonString.java delete mode 100644 twidere/src/main/java/com/fasterxml/jackson/simple/tree/SimpleTreeCodec.java delete mode 100644 twidere/src/main/java/com/fasterxml/jackson/simple/tree/TokenBuffer.java diff --git a/twidere.component.common/build.gradle b/twidere.component.common/build.gradle index 9c140dd56..bcebb13da 100644 --- a/twidere.component.common/build.gradle +++ b/twidere.component.common/build.gradle @@ -38,7 +38,7 @@ android { dependencies { apt 'com.bluelinelabs:logansquare-compiler:1.3.4' apt 'com.hannesdorfmann.parcelableplease:processor:1.0.1' - apt 'com.github.mariotaku.ObjectCursor:processor:0.9.2' + apt 'com.github.mariotaku.ObjectCursor:processor:0.9.3' compile 'com.android.support:support-annotations:23.1.1' compile 'com.android.support:support-v4:23.1.1' compile 'com.bluelinelabs:logansquare:1.3.4' @@ -46,6 +46,6 @@ dependencies { compile 'com.github.mariotaku.RestFu:library:0.9.8' compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.1' compile 'com.github.mariotaku.SQLiteQB:library:0.9.2' - compile 'com.github.mariotaku.ObjectCursor:core:0.9.2' + compile 'com.github.mariotaku.ObjectCursor:core:0.9.3' compile fileTree(dir: 'libs', include: ['*.jar']) } diff --git a/twidere.wear/build.gradle b/twidere.wear/build.gradle index 9ab1a0237..0b2fc0bdc 100644 --- a/twidere.wear/build.gradle +++ b/twidere.wear/build.gradle @@ -39,5 +39,5 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.google.android.support:wearable:1.3.0' - compile 'com.google.android.gms:play-services-wearable:8.3.0' + compile 'com.google.android.gms:play-services-wearable:8.4.0' } diff --git a/twidere/build.gradle b/twidere/build.gradle index c2163a89a..4ec0f92c0 100644 --- a/twidere/build.gradle +++ b/twidere/build.gradle @@ -60,7 +60,7 @@ dependencies { apt 'com.bluelinelabs:logansquare-compiler:1.3.4' apt 'com.hannesdorfmann.parcelableplease:processor:1.0.1' apt 'com.google.dagger:dagger-compiler:2.0.2' - apt "com.github.mariotaku.ObjectCursor:processor:0.9.2" + apt "com.github.mariotaku.ObjectCursor:processor:0.9.3" compile 'com.android.support:multidex:1.0.1' compile 'com.android.support:support-v13:23.1.1' compile 'com.android.support:appcompat-v7:23.1.1' @@ -75,7 +75,7 @@ dependencies { compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.4.1' compile 'com.rengwuxian.materialedittext:library:2.1.4' compile 'com.pnikosis:materialish-progress:1.7' - compile 'com.squareup.okhttp:okhttp:2.6.0' + compile 'com.squareup.okhttp:okhttp:2.7.0' compile 'pl.droidsonroids.gif:android-gif-drawable:1.1.7' compile 'com.github.johnpersano:supertoasts:1.3.4.1@aar' compile 'com.github.mariotaku:MessageBubbleView:1.2' @@ -90,7 +90,7 @@ dependencies { compile 'com.bluelinelabs:logansquare:1.3.4' compile 'ch.acra:acra:4.7.0' compile 'org.jraf:android-switch-backport:2.0.1' - compile 'com.fasterxml.jackson.jr:jackson-jr-objects:2.6.3' + compile 'com.github.FasterXML:jackson-jr-trees:5baf62567e' compile 'com.makeramen:roundedimageview:2.1.1' compile 'com.soundcloud.android:android-crop:1.0.1@aar' compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.1' @@ -110,11 +110,10 @@ dependencies { debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3' compile project(':twidere.component.common') compile project(':twidere.component.nyan') - compile 'com.github.mariotaku.ObjectCursor:core:0.9.2' + compile 'com.github.mariotaku.ObjectCursor:core:0.9.3' compile fileTree(dir: 'libs/main', include: ['*.jar']) provided 'javax.annotation:jsr250-api:1.0' // googleCompile fileTree(dir: 'libs/google', include: ['*.jar']) - compile 'com.google.android.gms:play-services-appindexing:8.1.0' } task svgToDrawable(type: SvgDrawableTask) { diff --git a/twidere/src/main/AndroidManifest.xml b/twidere/src/main/AndroidManifest.xml index 518a635ac..4e5022a40 100644 --- a/twidere/src/main/AndroidManifest.xml +++ b/twidere/src/main/AndroidManifest.xml @@ -567,11 +567,6 @@ - - diff --git a/twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonAbstractValue.java b/twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonAbstractValue.java deleted file mode 100644 index c585a9b69..000000000 --- a/twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonAbstractValue.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.fasterxml.jackson.simple.tree; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonPointer; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.core.ObjectCodec; -import com.fasterxml.jackson.core.TreeNode; - -import java.util.Iterator; - -abstract class JsonAbstractValue implements TreeNode -{ - @Override - public JsonParser.NumberType numberType() { - return null; - } - - @Override - public int size() { - return 0; - } - - @Override - public boolean isValueNode() { - return false; - } - - @Override - public boolean isContainerNode() { - return false; - } - - @Override - public boolean isMissingNode() { - return false; - } - - @Override - public boolean isArray() { - return false; - } - - @Override - public boolean isObject() { - return false; - } - - @Override - public TreeNode get(String s) { - return null; - } - - @Override - public TreeNode get(int i) { - return null; - } - - @Override - public TreeNode path(String s) { - return MISSING; - } - - @Override - public TreeNode path(int i) { - return MISSING; - } - - @Override - public Iterator fieldNames() { - return null; - } - - @Override - public TreeNode at(JsonPointer jsonPointer) { - return null; - } - - @Override - public TreeNode at(String s) throws IllegalArgumentException { - return null; - } - - @Override - public JsonParser traverse() { - return null; - } - - @Override - public JsonParser traverse(ObjectCodec objectCodec) { - return null; - } - - private static class JsonMissing extends JsonAbstractValue - { - @Override - public JsonToken asToken() - { - return null; - } - - @Override - public boolean isMissingNode() - { - return true; - } - } - - protected static final TreeNode MISSING = new JsonMissing(); -} diff --git a/twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonArray.java b/twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonArray.java deleted file mode 100644 index 4770497f0..000000000 --- a/twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonArray.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.fasterxml.jackson.simple.tree; - -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.core.TreeNode; - -import java.util.Collections; -import java.util.List; - -import static com.fasterxml.jackson.core.JsonToken.START_ARRAY; - -public class JsonArray extends JsonAbstractValue -{ - private final List values; - - public JsonArray() - { - this(Collections.emptyList()); - } - - public JsonArray(List values) - { - this.values = Collections.unmodifiableList(values); - } - - @Override - public JsonToken asToken() - { - return START_ARRAY; - } - - @Override - public int size() - { - return values.size(); - } - - @Override - public boolean isContainerNode() - { - return true; - } - - @Override - public boolean isArray() - { - return true; - } - - @Override - public TreeNode get(int i) - { - return 0 <= i && i < values.size() ? values.get(i) : null; - } - - @Override - public TreeNode path(int i) - { - return 0 <= i && i < values.size() ? values.get(i) : MISSING; - } -} diff --git a/twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonBoolean.java b/twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonBoolean.java deleted file mode 100644 index ca2149fdd..000000000 --- a/twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonBoolean.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.fasterxml.jackson.simple.tree; - -import com.fasterxml.jackson.core.JsonToken; - -public class JsonBoolean extends JsonAbstractValue -{ - public static JsonBoolean TRUE = new JsonBoolean(); - public static JsonBoolean FALSE = new JsonBoolean(); - - private JsonBoolean() - { - - } - - @Override - public JsonToken asToken() - { - return this == TRUE ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE; - } - - @Override - public boolean isValueNode() - { - return true; - } -} diff --git a/twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonNumber.java b/twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonNumber.java deleted file mode 100644 index f1680d490..000000000 --- a/twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonNumber.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.fasterxml.jackson.simple.tree; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonToken; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import static com.fasterxml.jackson.core.JsonToken.VALUE_NUMBER_FLOAT; -import static com.fasterxml.jackson.core.JsonToken.VALUE_NUMBER_INT; - -public class JsonNumber extends JsonAbstractValue -{ - private static final Map, JsonParser.NumberType> NUMBER_TYPES; - static - { - final Map, JsonParser.NumberType> numberTypes = new HashMap, JsonParser.NumberType>(); - - numberTypes.put(Byte.class, JsonParser.NumberType.INT); - numberTypes.put(Short.class, JsonParser.NumberType.INT); - numberTypes.put(Integer.class, JsonParser.NumberType.INT); - numberTypes.put(Long.class, JsonParser.NumberType.LONG); - numberTypes.put(BigInteger.class, JsonParser.NumberType.BIG_INTEGER); - numberTypes.put(Float.class, JsonParser.NumberType.FLOAT); - numberTypes.put(Double.class, JsonParser.NumberType.DOUBLE); - numberTypes.put(BigDecimal.class, JsonParser.NumberType.BIG_DECIMAL); - - NUMBER_TYPES = Collections.unmodifiableMap(numberTypes); - } - - private final Number _value; - private final JsonParser.NumberType _numberType; - - public JsonNumber(Number value) - { - if (!NUMBER_TYPES.containsKey(value.getClass())) - throw new IllegalArgumentException("Unsupported Number type"); - this._value = value; - this._numberType = NUMBER_TYPES.get(value.getClass()); - } - - public Number getValue() - { - return _value; - } - - @Override - public JsonToken asToken() { - switch (numberType()) - { - case BIG_DECIMAL: - case DOUBLE: - case FLOAT: - return VALUE_NUMBER_FLOAT; - default: - return VALUE_NUMBER_INT; - } - } - - @Override - public boolean isValueNode() - { - return true; - } - - @Override - public JsonParser.NumberType numberType() - { - return _numberType; - } -} diff --git a/twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonObject.java b/twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonObject.java deleted file mode 100644 index cdad3aad0..000000000 --- a/twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonObject.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.fasterxml.jackson.simple.tree; - -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.core.TreeNode; - -import java.util.Collections; -import java.util.Iterator; -import java.util.Map; - -public class JsonObject extends JsonAbstractValue -{ - private final Map _values; - - public JsonObject() - { - this(Collections.emptyMap()); - } - - public JsonObject(Map values) - { - this._values = Collections.unmodifiableMap(values); - } - - @Override - public JsonToken asToken() - { - return JsonToken.START_OBJECT; - } - - @Override - public int size() - { - return _values.size(); - } - - @Override - public boolean isContainerNode() - { - return true; - } - - @Override - public boolean isObject() - { - return true; - } - - @Override - public Iterator fieldNames() - { - return _values.keySet().iterator(); - } - - @Override - public TreeNode get(String name) - { - return _values.containsKey(name) ? _values.get(name) : null; - } - - @Override - public TreeNode path(String name) - { - return _values.containsKey(name) ? _values.get(name) : MISSING; - } -} diff --git a/twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonString.java b/twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonString.java deleted file mode 100644 index a442ee126..000000000 --- a/twidere/src/main/java/com/fasterxml/jackson/simple/tree/JsonString.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.fasterxml.jackson.simple.tree; - -import com.fasterxml.jackson.core.JsonToken; - -import static com.fasterxml.jackson.core.JsonToken.VALUE_STRING; - -public class JsonString extends JsonAbstractValue -{ - private final String value; - - public JsonString(String value) - { - this.value = value; - } - - public String getValue() - { - return value; - } - - @Override - public JsonToken asToken() - { - return VALUE_STRING; - } - - @Override - public boolean isValueNode() - { - return true; - } -} diff --git a/twidere/src/main/java/com/fasterxml/jackson/simple/tree/SimpleTreeCodec.java b/twidere/src/main/java/com/fasterxml/jackson/simple/tree/SimpleTreeCodec.java deleted file mode 100644 index 207907695..000000000 --- a/twidere/src/main/java/com/fasterxml/jackson/simple/tree/SimpleTreeCodec.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2015 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fasterxml.jackson.simple.tree; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.TreeCodec; -import com.fasterxml.jackson.core.TreeNode; -import com.fasterxml.jackson.jr.ob.JSON; - -import java.io.IOException; -import java.util.AbstractList; -import java.util.AbstractMap; -import java.util.AbstractSet; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -public class SimpleTreeCodec extends TreeCodec { - - @Override - public T readTree(JsonParser jsonParser) throws IOException { - return nodeFrom(JSON.std.anyFrom(jsonParser)); - } - - private T nodeFrom(Object value) - { - TreeNode node = null; - - if (value instanceof Boolean) - node = ((Boolean) value ? JsonBoolean.TRUE : JsonBoolean.FALSE); - else if (value instanceof Number) - node = new JsonNumber(((Number) value)); - else if (value instanceof String) - node = new JsonString((String) value); - else if (value instanceof List) { - List values = new ArrayList<>(); - for (Object el : (List) value) { - values.add(nodeFrom(el)); - } - node = new JsonArray(values); - } - else if (value instanceof Object[]) { - List values = new ArrayList<>(); - for (Object el : (Object[]) value) { - values.add(nodeFrom(el)); - } - node = new JsonArray(values); - } - else if (value instanceof Map) { - Map values = new LinkedHashMap<>(); - for (Map.Entry entry : ((Map) value).entrySet()) { - values.put(entry.getKey().toString(), nodeFrom(entry.getValue())); - } - node = new JsonObject(values); - } - - return (T) node; - } - - @Override - public void writeTree(JsonGenerator jsonGenerator, TreeNode treeNode) throws IOException { - JSON.std.write(valueOf(treeNode), jsonGenerator); - } - - private Object valueOf(final TreeNode treeNode) - { - if (treeNode == null) - return null; - else if (treeNode instanceof JsonBoolean) - return treeNode == JsonBoolean.TRUE; - else if (treeNode instanceof JsonNumber) - return ((JsonNumber) treeNode).getValue(); - else if (treeNode instanceof JsonString) - return ((JsonString) treeNode).getValue(); - else if (treeNode instanceof JsonArray) { - return new AbstractList() { - @Override - public Object get(int index) { - return valueOf(treeNode.get(index)); - } - - @Override - public int size() { - return treeNode.size(); - } - }; - } - else if (treeNode instanceof JsonObject) { - return new AbstractMap() { - @Override - public Set> entrySet() { - return new AbstractSet>() { - @Override - public Iterator> iterator() { - return new Iterator>() { - final Iterator delegate = treeNode.fieldNames(); - - @Override - public boolean hasNext() { - return delegate.hasNext(); - } - - @Override - public Entry next() { - final String key = delegate.next(); - return new Entry() { - @Override - public String getKey() { - return key; - } - - @Override - public Object getValue() { - return valueOf(treeNode.get(key)); - } - - @Override - public Object setValue(Object value) { - throw new UnsupportedOperationException(); - } - }; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - - @Override - public int size() { - return treeNode.size(); - } - }; - } - }; - } - else return treeNode; - } - - @Override - public TreeNode createArrayNode() { - return new JsonArray(); - } - - @Override - public TreeNode createObjectNode() { - return new JsonObject(); - } - - @Override - public JsonParser treeAsTokens(TreeNode treeNode) { - final TokenBuffer buffer = new TokenBuffer(null, false); - try { - writeTree(buffer, treeNode); - } catch (IOException e) { - - } - return buffer.asParser(); - } - -} diff --git a/twidere/src/main/java/com/fasterxml/jackson/simple/tree/TokenBuffer.java b/twidere/src/main/java/com/fasterxml/jackson/simple/tree/TokenBuffer.java deleted file mode 100644 index 43f9664ae..000000000 --- a/twidere/src/main/java/com/fasterxml/jackson/simple/tree/TokenBuffer.java +++ /dev/null @@ -1,1746 +0,0 @@ -/* - * Twidere - Twitter client for Android - * - * Copyright (C) 2012-2015 Mariotaku Lee - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fasterxml.jackson.simple.tree; - -import com.fasterxml.jackson.core.Base64Variant; -import com.fasterxml.jackson.core.JsonGenerationException; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonLocation; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.JsonStreamContext; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.core.ObjectCodec; -import com.fasterxml.jackson.core.SerializableString; -import com.fasterxml.jackson.core.TreeNode; -import com.fasterxml.jackson.core.Version; -import com.fasterxml.jackson.core.base.ParserMinimalBase; -import com.fasterxml.jackson.core.json.JsonReadContext; -import com.fasterxml.jackson.core.json.JsonWriteContext; -import com.fasterxml.jackson.core.util.ByteArrayBuilder; -import com.fasterxml.jackson.jr.ob.PackageVersion; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.TreeMap; - -/** - * Utility class used for efficient storage of {@link JsonToken} - * sequences, needed for temporary buffering. - * Space efficient for different sequence lengths (especially so for smaller - * ones; but not significantly less efficient for larger), highly efficient - * for linear iteration and appending. Implemented as segmented/chunked - * linked list of tokens; only modifications are via appends. - *

- * Note that before version 2.0, this class was located in the "core" - * bundle, not data-binding; but since it was only used by data binding, - * was moved here to reduce size of core package - */ -class TokenBuffer -/* Won't use JsonGeneratorBase, to minimize overhead for validity - * checking - */ - extends JsonGenerator { - protected final static int DEFAULT_GENERATOR_FEATURES = Feature.collectDefaults(); - - /* - /********************************************************** - /* Configuration - /********************************************************** - */ - - /** - * Object codec to use for stream-based object - * conversion through parser/generator interfaces. If null, - * such methods can not be used. - */ - protected ObjectCodec _objectCodec; - - /** - * Bit flag composed of bits that indicate which - * {@link Feature}s - * are enabled. - *

- * NOTE: most features have no effect on this class - */ - protected int _generatorFeatures; - - protected boolean _closed; - - /** - * @since 2.3 - */ - protected boolean _hasNativeTypeIds; - - /** - * @since 2.3 - */ - protected boolean _hasNativeObjectIds; - - /** - * @since 2.3 - */ - protected boolean _mayHaveNativeIds; - - /* - /********************************************************** - /* Token buffering state - /********************************************************** - */ - - /** - * First segment, for contents this buffer has - */ - protected Segment _first; - - /** - * Last segment of this buffer, one that is used - * for appending more tokens - */ - protected Segment _last; - - /** - * Offset within last segment, - */ - protected int _appendOffset; - - /** - * If native type ids supported, this is the id for following - * value (or first token of one) to be written. - */ - protected Object _typeId; - - /** - * If native object ids supported, this is the id for following - * value (or first token of one) to be written. - */ - protected Object _objectId; - - /** - * Do we currnetly have a native type or object id buffered? - */ - protected boolean _hasNativeId = false; - - /* - /********************************************************** - /* Output state - /********************************************************** - */ - - protected JsonWriteContext _writeContext; - - /* - /********************************************************** - /* Life-cycle - /********************************************************** - */ - - /** - * @param codec Object codec to use for stream-based object - * conversion through parser/generator interfaces. If null, - * such methods can not be used. - * @deprecated since 2.3 preferred variant is one that takes {@link JsonParser} or additional boolean parameter. - */ - @Deprecated - public TokenBuffer(ObjectCodec codec) { - this(codec, false); - } - - /** - * @param codec Object codec to use for stream-based object - * conversion through parser/generator interfaces. If null, - * such methods can not be used. - * @param hasNativeIds Whether resulting {@link JsonParser} (if created) - * is considered to support native type and object ids - */ - public TokenBuffer(ObjectCodec codec, boolean hasNativeIds) { - _objectCodec = codec; - _generatorFeatures = DEFAULT_GENERATOR_FEATURES; - _writeContext = JsonWriteContext.createRootContext(null); - // at first we have just one segment - _first = _last = new Segment(); - _appendOffset = 0; - _hasNativeTypeIds = hasNativeIds; - _hasNativeObjectIds = hasNativeIds; - - _mayHaveNativeIds = _hasNativeTypeIds | _hasNativeObjectIds; - } - - /** - * @since 2.3 - */ - public TokenBuffer(JsonParser jp) { - _objectCodec = jp.getCodec(); - _generatorFeatures = DEFAULT_GENERATOR_FEATURES; - _writeContext = JsonWriteContext.createRootContext(null); - // at first we have just one segment - _first = _last = new Segment(); - _appendOffset = 0; - _hasNativeTypeIds = jp.canReadTypeId(); - _hasNativeObjectIds = jp.canReadObjectId(); - _mayHaveNativeIds = _hasNativeTypeIds | _hasNativeObjectIds; - } - - @Override - public Version version() { - return Version.unknownVersion(); - } - - /** - * Method used to create a {@link JsonParser} that can read contents - * stored in this buffer. Will use default _objectCodec for - * object conversions. - *

- * Note: instances are not synchronized, that is, they are not thread-safe - * if there are concurrent appends to the underlying buffer. - * - * @return Parser that can be used for reading contents stored in this buffer - */ - public JsonParser asParser() { - return asParser(_objectCodec); - } - - /** - * Method used to create a {@link JsonParser} that can read contents - * stored in this buffer. - *

- * Note: instances are not synchronized, that is, they are not thread-safe - * if there are concurrent appends to the underlying buffer. - * - * @param codec Object codec to use for stream-based object - * conversion through parser/generator interfaces. If null, - * such methods can not be used. - * @return Parser that can be used for reading contents stored in this buffer - */ - public JsonParser asParser(ObjectCodec codec) { - return new Parser(_first, codec, _hasNativeTypeIds, _hasNativeObjectIds); - } - - /** - * @param src Parser to use for accessing source information - * like location, configured codec - */ - public JsonParser asParser(JsonParser src) { - Parser p = new Parser(_first, src.getCodec(), _hasNativeTypeIds, _hasNativeObjectIds); - p.setLocation(src.getTokenLocation()); - return p; - } - - /* - /********************************************************** - /* Additional accessors - /********************************************************** - */ - - public JsonToken firstToken() { - if (_first != null) { - return _first.type(0); - } - return null; - } - - /* - /********************************************************** - /* Other custom methods not needed for implementing interfaces - /********************************************************** - */ - - /** - * Helper method that will append contents of given buffer into this - * buffer. - * Not particularly optimized; can be made faster if there is need. - * - * @return This buffer - */ - @SuppressWarnings("resource") - public TokenBuffer append(TokenBuffer other) - throws IOException, JsonGenerationException { - // Important? If source has native ids, need to store - if (!_hasNativeTypeIds) { - _hasNativeTypeIds = other.canWriteTypeId(); - } - if (!_hasNativeObjectIds) { - _hasNativeObjectIds = other.canWriteObjectId(); - } - _mayHaveNativeIds = _hasNativeTypeIds | _hasNativeObjectIds; - - JsonParser jp = other.asParser(); - while (jp.nextToken() != null) { - copyCurrentStructure(jp); - } - return this; - } - - /** - * Helper method that will write all contents of this buffer - * using given {@link JsonGenerator}. - *

- * Note: this method would be enough to implement - * JsonSerializer for TokenBuffer type; - * but we can not have upwards - * references (from core to mapper package); and as such we also - * can not take second argument. - */ - public void serialize(JsonGenerator jgen) - throws IOException, JsonGenerationException { - Segment segment = _first; - int ptr = -1; - - final boolean checkIds = _mayHaveNativeIds; - boolean hasIds = checkIds && (segment.hasIds()); - - while (true) { - if (++ptr >= Segment.TOKENS_PER_SEGMENT) { - ptr = 0; - segment = segment.next(); - if (segment == null) break; - hasIds = checkIds && (segment.hasIds()); - } - JsonToken t = segment.type(ptr); - if (t == null) break; - - if (hasIds) { - Object id = segment.findObjectId(ptr); - if (id != null) { - jgen.writeObjectId(id); - } - id = segment.findTypeId(ptr); - if (id != null) { - jgen.writeTypeId(id); - } - } - - // Note: copied from 'copyCurrentEvent'... - switch (t) { - case START_OBJECT: - jgen.writeStartObject(); - break; - case END_OBJECT: - jgen.writeEndObject(); - break; - case START_ARRAY: - jgen.writeStartArray(); - break; - case END_ARRAY: - jgen.writeEndArray(); - break; - case FIELD_NAME: { - // 13-Dec-2010, tatu: Maybe we should start using different type tokens to reduce casting? - Object ob = segment.get(ptr); - if (ob instanceof SerializableString) { - jgen.writeFieldName((SerializableString) ob); - } else { - jgen.writeFieldName((String) ob); - } - } - break; - case VALUE_STRING: { - Object ob = segment.get(ptr); - if (ob instanceof SerializableString) { - jgen.writeString((SerializableString) ob); - } else { - jgen.writeString((String) ob); - } - } - break; - case VALUE_NUMBER_INT: { - Object n = segment.get(ptr); - if (n instanceof Integer) { - jgen.writeNumber((Integer) n); - } else if (n instanceof BigInteger) { - jgen.writeNumber((BigInteger) n); - } else if (n instanceof Long) { - jgen.writeNumber((Long) n); - } else if (n instanceof Short) { - jgen.writeNumber((Short) n); - } else { - jgen.writeNumber(((Number) n).intValue()); - } - } - break; - case VALUE_NUMBER_FLOAT: { - Object n = segment.get(ptr); - if (n instanceof Double) { - jgen.writeNumber(((Double) n).doubleValue()); - } else if (n instanceof BigDecimal) { - jgen.writeNumber((BigDecimal) n); - } else if (n instanceof Float) { - jgen.writeNumber(((Float) n).floatValue()); - } else if (n == null) { - jgen.writeNull(); - } else if (n instanceof String) { - jgen.writeNumber((String) n); - } else { - throw new JsonGenerationException("Unrecognized value type for VALUE_NUMBER_FLOAT: " + n.getClass().getName() + ", can not serialize"); - } - } - break; - case VALUE_TRUE: - jgen.writeBoolean(true); - break; - case VALUE_FALSE: - jgen.writeBoolean(false); - break; - case VALUE_NULL: - jgen.writeNull(); - break; - case VALUE_EMBEDDED_OBJECT: - jgen.writeObject(segment.get(ptr)); - break; - default: - throw new RuntimeException("Internal error: should never end up through this code path"); - } - } - } - - @Override - @SuppressWarnings("resource") - public String toString() { - // Let's print up to 100 first tokens... - final int MAX_COUNT = 100; - - StringBuilder sb = new StringBuilder(); - sb.append("[TokenBuffer: "); - - /* -sb.append("NativeTypeIds=").append(_hasNativeTypeIds).append(","); -sb.append("NativeObjectIds=").append(_hasNativeObjectIds).append(","); -*/ - - JsonParser jp = asParser(); - int count = 0; - final boolean hasNativeIds = _hasNativeTypeIds || _hasNativeObjectIds; - - while (true) { - JsonToken t; - try { - t = jp.nextToken(); - if (t == null) break; - - if (hasNativeIds) { - _appendNativeIds(sb); - } - - if (count < MAX_COUNT) { - if (count > 0) { - sb.append(", "); - } - sb.append(t.toString()); - if (t == JsonToken.FIELD_NAME) { - sb.append('('); - sb.append(jp.getCurrentName()); - sb.append(')'); - } - } - } catch (IOException ioe) { // should never occur - throw new IllegalStateException(ioe); - } - ++count; - } - - if (count >= MAX_COUNT) { - sb.append(" ... (truncated ").append(count - MAX_COUNT).append(" entries)"); - } - sb.append(']'); - return sb.toString(); - } - - private final void _appendNativeIds(StringBuilder sb) { - Object objectId = _last.findObjectId(_appendOffset - 1); - if (objectId != null) { - sb.append("[objectId=").append(String.valueOf(objectId)).append(']'); - } - Object typeId = _last.findTypeId(_appendOffset - 1); - if (typeId != null) { - sb.append("[typeId=").append(String.valueOf(typeId)).append(']'); - } - } - - /* - /********************************************************** - /* JsonGenerator implementation: configuration - /********************************************************** - */ - - @Override - public JsonGenerator enable(Feature f) { - _generatorFeatures |= f.getMask(); - return this; - } - - @Override - public JsonGenerator disable(Feature f) { - _generatorFeatures &= ~f.getMask(); - return this; - } - - //public JsonGenerator configure(SerializationFeature f, boolean state) { } - - @Override - public boolean isEnabled(Feature f) { - return (_generatorFeatures & f.getMask()) != 0; - } - - @Override - public int getFeatureMask() { - return _generatorFeatures; - } - - @Override - public JsonGenerator setFeatureMask(int mask) { - _generatorFeatures = mask; - return this; - } - - @Override - public JsonGenerator useDefaultPrettyPrinter() { - // No-op: we don't indent - return this; - } - - @Override - public JsonGenerator setCodec(ObjectCodec oc) { - _objectCodec = oc; - return this; - } - - @Override - public ObjectCodec getCodec() { - return _objectCodec; - } - - @Override - public final JsonWriteContext getOutputContext() { - return _writeContext; - } - - /* - /********************************************************** - /* JsonGenerator implementation: capability introspection - /********************************************************** - */ - - /** - * Since we can efficiently store byte[], yes. - */ - @Override - public boolean canWriteBinaryNatively() { - return true; - } - - /* - /********************************************************** - /* JsonGenerator implementation: low-level output handling - /********************************************************** - */ - - @Override - public void flush() throws IOException { /* NOP */ } - - @Override - public void close() throws IOException { - _closed = true; - } - - @Override - public boolean isClosed() { - return _closed; - } - - /* - /********************************************************** - /* JsonGenerator implementation: write methods, structural - /********************************************************** - */ - - @Override - public final void writeStartArray() - throws IOException, JsonGenerationException { - _append(JsonToken.START_ARRAY); - _writeContext = _writeContext.createChildArrayContext(); - } - - @Override - public final void writeEndArray() - throws IOException, JsonGenerationException { - _append(JsonToken.END_ARRAY); - // Let's allow unbalanced tho... i.e. not run out of root level, ever - JsonWriteContext c = _writeContext.getParent(); - if (c != null) { - _writeContext = c; - } - } - - @Override - public final void writeStartObject() - throws IOException, JsonGenerationException { - _append(JsonToken.START_OBJECT); - _writeContext = _writeContext.createChildObjectContext(); - } - - @Override - public final void writeEndObject() - throws IOException, JsonGenerationException { - _append(JsonToken.END_OBJECT); - // Let's allow unbalanced tho... i.e. not run out of root level, ever - JsonWriteContext c = _writeContext.getParent(); - if (c != null) { - _writeContext = c; - } - } - - @Override - public final void writeFieldName(String name) - throws IOException, JsonGenerationException { - _append(JsonToken.FIELD_NAME, name); - _writeContext.writeFieldName(name); - } - - @Override - public void writeFieldName(SerializableString name) - throws IOException, JsonGenerationException { - _append(JsonToken.FIELD_NAME, name); - _writeContext.writeFieldName(name.getValue()); - } - - /* - /********************************************************** - /* JsonGenerator implementation: write methods, textual - /********************************************************** - */ - - @Override - public void writeString(String text) throws IOException, JsonGenerationException { - if (text == null) { - writeNull(); - } else { - _append(JsonToken.VALUE_STRING, text); - } - } - - @Override - public void writeString(char[] text, int offset, int len) throws IOException, JsonGenerationException { - writeString(new String(text, offset, len)); - } - - @Override - public void writeString(SerializableString text) throws IOException, JsonGenerationException { - if (text == null) { - writeNull(); - } else { - _append(JsonToken.VALUE_STRING, text); - } - } - - @Override - public void writeRawUTF8String(byte[] text, int offset, int length) - throws IOException, JsonGenerationException { - // could add support for buffering if we really want it... - _reportUnsupportedOperation(); - } - - @Override - public void writeUTF8String(byte[] text, int offset, int length) - throws IOException, JsonGenerationException { - // could add support for buffering if we really want it... - _reportUnsupportedOperation(); - } - - @Override - public void writeRaw(String text) throws IOException, JsonGenerationException { - _reportUnsupportedOperation(); - } - - @Override - public void writeRaw(String text, int offset, int len) throws IOException, JsonGenerationException { - _reportUnsupportedOperation(); - } - - @Override - public void writeRaw(SerializableString text) throws IOException, JsonGenerationException { - _reportUnsupportedOperation(); - } - - @Override - public void writeRaw(char[] text, int offset, int len) throws IOException, JsonGenerationException { - _reportUnsupportedOperation(); - } - - @Override - public void writeRaw(char c) throws IOException, JsonGenerationException { - _reportUnsupportedOperation(); - } - - @Override - public void writeRawValue(String text) throws IOException, JsonGenerationException { - _reportUnsupportedOperation(); - } - - @Override - public void writeRawValue(String text, int offset, int len) throws IOException, JsonGenerationException { - _reportUnsupportedOperation(); - } - - @Override - public void writeRawValue(char[] text, int offset, int len) throws IOException, JsonGenerationException { - _reportUnsupportedOperation(); - } - - /* - /********************************************************** - /* JsonGenerator implementation: write methods, primitive types - /********************************************************** - */ - - @Override - public void writeNumber(short i) throws IOException, JsonGenerationException { - _append(JsonToken.VALUE_NUMBER_INT, Short.valueOf(i)); - } - - @Override - public void writeNumber(int i) throws IOException, JsonGenerationException { - _append(JsonToken.VALUE_NUMBER_INT, Integer.valueOf(i)); - } - - @Override - public void writeNumber(long l) throws IOException, JsonGenerationException { - _append(JsonToken.VALUE_NUMBER_INT, Long.valueOf(l)); - } - - @Override - public void writeNumber(double d) throws IOException, JsonGenerationException { - _append(JsonToken.VALUE_NUMBER_FLOAT, Double.valueOf(d)); - } - - @Override - public void writeNumber(float f) throws IOException, JsonGenerationException { - _append(JsonToken.VALUE_NUMBER_FLOAT, Float.valueOf(f)); - } - - @Override - public void writeNumber(BigDecimal dec) throws IOException, JsonGenerationException { - if (dec == null) { - writeNull(); - } else { - _append(JsonToken.VALUE_NUMBER_FLOAT, dec); - } - } - - @Override - public void writeNumber(BigInteger v) throws IOException, JsonGenerationException { - if (v == null) { - writeNull(); - } else { - _append(JsonToken.VALUE_NUMBER_INT, v); - } - } - - @Override - public void writeNumber(String encodedValue) throws IOException, JsonGenerationException { - /* 03-Dec-2010, tatu: related to [JACKSON-423], should try to keep as numeric - * identity as long as possible - */ - _append(JsonToken.VALUE_NUMBER_FLOAT, encodedValue); - } - - @Override - public void writeBoolean(boolean state) throws IOException, JsonGenerationException { - _append(state ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE); - } - - @Override - public void writeNull() throws IOException, JsonGenerationException { - _append(JsonToken.VALUE_NULL); - } - - /* - /*********************************************************** - /* JsonGenerator implementation: write methods for POJOs/trees - /*********************************************************** - */ - - @Override - public void writeObject(Object value) - throws IOException, JsonProcessingException { - // embedded means that no conversions should be done... - _append(JsonToken.VALUE_EMBEDDED_OBJECT, value); - } - - @Override - public void writeTree(TreeNode rootNode) - throws IOException, JsonProcessingException { - /* 31-Dec-2009, tatu: no need to convert trees either is there? - * (note: may need to re-evaluate at some point) - */ - _append(JsonToken.VALUE_EMBEDDED_OBJECT, rootNode); - } - - /* - /*********************************************************** - /* JsonGenerator implementation; binary - /*********************************************************** - */ - - @Override - public void writeBinary(Base64Variant b64variant, byte[] data, int offset, int len) - throws IOException, JsonGenerationException { - /* 31-Dec-2009, tatu: can do this using multiple alternatives; but for - * now, let's try to limit number of conversions. - * The only (?) tricky thing is that of whether to preserve variant, - * seems pointless, so let's not worry about it unless there's some - * compelling reason to. - */ - byte[] copy = new byte[len]; - System.arraycopy(data, offset, copy, 0, len); - writeObject(copy); - } - - /** - * Although we could support this method, it does not necessarily make - * sense: we can not make good use of streaming because buffer must - * hold all the data. Because of this, currently this will simply - * throw {@link UnsupportedOperationException} - */ - @Override - public int writeBinary(Base64Variant b64variant, InputStream data, int dataLength) { - throw new UnsupportedOperationException(); - } - - /* - /*********************************************************** - /* JsonGenerator implementation: native ids - /*********************************************************** - */ - - @Override - public boolean canWriteTypeId() { - return _hasNativeTypeIds; - } - - @Override - public boolean canWriteObjectId() { - return _hasNativeObjectIds; - } - - @Override - public void writeTypeId(Object id) { - _typeId = id; - _hasNativeId = true; - } - - @Override - public void writeObjectId(Object id) { - _objectId = id; - _hasNativeId = true; - } - - /* - /********************************************************** - /* JsonGenerator implementation; pass-through copy - /********************************************************** - */ - - @Override - public void copyCurrentEvent(JsonParser jp) throws IOException, JsonProcessingException { - if (_mayHaveNativeIds) { - _checkNativeIds(jp); - } - switch (jp.getCurrentToken()) { - case START_OBJECT: - writeStartObject(); - break; - case END_OBJECT: - writeEndObject(); - break; - case START_ARRAY: - writeStartArray(); - break; - case END_ARRAY: - writeEndArray(); - break; - case FIELD_NAME: - writeFieldName(jp.getCurrentName()); - break; - case VALUE_STRING: - if (jp.hasTextCharacters()) { - writeString(jp.getTextCharacters(), jp.getTextOffset(), jp.getTextLength()); - } else { - writeString(jp.getText()); - } - break; - case VALUE_NUMBER_INT: - switch (jp.getNumberType()) { - case INT: - writeNumber(jp.getIntValue()); - break; - case BIG_INTEGER: - writeNumber(jp.getBigIntegerValue()); - break; - default: - writeNumber(jp.getLongValue()); - } - break; - case VALUE_NUMBER_FLOAT: - switch (jp.getNumberType()) { - case BIG_DECIMAL: - writeNumber(jp.getDecimalValue()); - break; - case FLOAT: - writeNumber(jp.getFloatValue()); - break; - default: - writeNumber(jp.getDoubleValue()); - } - break; - case VALUE_TRUE: - writeBoolean(true); - break; - case VALUE_FALSE: - writeBoolean(false); - break; - case VALUE_NULL: - writeNull(); - break; - case VALUE_EMBEDDED_OBJECT: - writeObject(jp.getEmbeddedObject()); - break; - default: - throw new RuntimeException("Internal error: should never end up through this code path"); - } - } - - @Override - public void copyCurrentStructure(JsonParser jp) throws IOException, JsonProcessingException { - JsonToken t = jp.getCurrentToken(); - - // Let's handle field-name separately first - if (t == JsonToken.FIELD_NAME) { - if (_mayHaveNativeIds) { - _checkNativeIds(jp); - } - writeFieldName(jp.getCurrentName()); - t = jp.nextToken(); - // fall-through to copy the associated value - } - - if (_mayHaveNativeIds) { - _checkNativeIds(jp); - } - - switch (t) { - case START_ARRAY: - writeStartArray(); - while (jp.nextToken() != JsonToken.END_ARRAY) { - copyCurrentStructure(jp); - } - writeEndArray(); - break; - case START_OBJECT: - writeStartObject(); - while (jp.nextToken() != JsonToken.END_OBJECT) { - copyCurrentStructure(jp); - } - writeEndObject(); - break; - default: // others are simple: - copyCurrentEvent(jp); - } - } - - - private final void _checkNativeIds(JsonParser jp) throws IOException, JsonProcessingException { - if ((_typeId = jp.getTypeId()) != null) { - _hasNativeId = true; - } - if ((_objectId = jp.getObjectId()) != null) { - _hasNativeId = true; - } - } - - /* - /********************************************************** - /* Internal methods - /********************************************************** - */ - - protected final void _append(JsonToken type) { - Segment next = _hasNativeId - ? _last.append(_appendOffset, type, _objectId, _typeId) - : _last.append(_appendOffset, type); - if (next == null) { - ++_appendOffset; - } else { - _last = next; - _appendOffset = 1; // since we added first at 0 - } - } - - protected final void _append(JsonToken type, Object value) { - Segment next = _hasNativeId - ? _last.append(_appendOffset, type, value, _objectId, _typeId) - : _last.append(_appendOffset, type, value); - if (next == null) { - ++_appendOffset; - } else { - _last = next; - _appendOffset = 1; - } - } - - protected final void _appendRaw(int rawType, Object value) { - Segment next = _hasNativeId - ? _last.appendRaw(_appendOffset, rawType, value, _objectId, _typeId) - : _last.appendRaw(_appendOffset, rawType, value); - if (next == null) { - ++_appendOffset; - } else { - _last = next; - _appendOffset = 1; - } - } - - protected void _reportUnsupportedOperation() { - throw new UnsupportedOperationException("Called operation not supported for TokenBuffer"); - } - - /* - /********************************************************** - /* Supporting classes - /********************************************************** - */ - - protected final static class Parser - extends ParserMinimalBase { - /* - /********************************************************** - /* Configuration - /********************************************************** - */ - - protected ObjectCodec _codec; - - /** - * @since 2.3 - */ - protected final boolean _hasNativeTypeIds; - - /** - * @since 2.3 - */ - protected final boolean _hasNativeObjectIds; - - protected final boolean _hasNativeIds; - - /* - /********************************************************** - /* Parsing state - /********************************************************** - */ - - /** - * Currently active segment - */ - protected Segment _segment; - - /** - * Pointer to current token within current segment - */ - protected int _segmentPtr; - - /** - * Information about parser context, context in which - * the next token is to be parsed (root, array, object). - */ - protected JsonReadContext _parsingContext; - - protected boolean _closed; - - protected transient ByteArrayBuilder _byteBuilder; - - protected JsonLocation _location = null; - - /* - /********************************************************** - /* Construction, init - /********************************************************** - */ - - @Deprecated // since 2.3 - protected Parser(Segment firstSeg, ObjectCodec codec) { - this(firstSeg, codec, false, false); - } - - /** - * @since 2.3 - */ - public Parser(Segment firstSeg, ObjectCodec codec, - boolean hasNativeTypeIds, - boolean hasNativeObjectIds) { - super(0); - _segment = firstSeg; - _segmentPtr = -1; // not yet read - _codec = codec; - _parsingContext = JsonReadContext.createRootContext(null); - _hasNativeTypeIds = hasNativeTypeIds; - _hasNativeObjectIds = hasNativeObjectIds; - _hasNativeIds = (hasNativeTypeIds | hasNativeObjectIds); - } - - public void setLocation(JsonLocation l) { - _location = l; - } - - @Override - public ObjectCodec getCodec() { - return _codec; - } - - @Override - public void setCodec(ObjectCodec c) { - _codec = c; - } - - @Override - public Version version() { - return new PackageVersion().version(); - } - - /* - /********************************************************** - /* Extended API beyond JsonParser - /********************************************************** - */ - - public JsonToken peekNextToken() - throws IOException, JsonParseException { - // closed? nothing more to peek, either - if (_closed) return null; - Segment seg = _segment; - int ptr = _segmentPtr + 1; - if (ptr >= Segment.TOKENS_PER_SEGMENT) { - ptr = 0; - seg = (seg == null) ? null : seg.next(); - } - return (seg == null) ? null : seg.type(ptr); - } - - /* - /********************************************************** - /* Closeable implementation - /********************************************************** - */ - - @Override - public void close() throws IOException { - if (!_closed) { - _closed = true; - } - } - - /* - /********************************************************** - /* Public API, traversal - /********************************************************** - */ - - @Override - public JsonToken nextToken() throws IOException, JsonParseException { - // If we are closed, nothing more to do - if (_closed || (_segment == null)) return null; - - // Ok, then: any more tokens? - if (++_segmentPtr >= Segment.TOKENS_PER_SEGMENT) { - _segmentPtr = 0; - _segment = _segment.next(); - if (_segment == null) { - return null; - } - } - _currToken = _segment.type(_segmentPtr); - // Field name? Need to update context - if (_currToken == JsonToken.FIELD_NAME) { - Object ob = _currentObject(); - String name = (ob instanceof String) ? ((String) ob) : ob.toString(); - _parsingContext.setCurrentName(name); - } else if (_currToken == JsonToken.START_OBJECT) { - _parsingContext = _parsingContext.createChildObjectContext(-1, -1); - } else if (_currToken == JsonToken.START_ARRAY) { - _parsingContext = _parsingContext.createChildArrayContext(-1, -1); - } else if (_currToken == JsonToken.END_OBJECT - || _currToken == JsonToken.END_ARRAY) { - // Closing JSON Object/Array? Close matching context - _parsingContext = _parsingContext.getParent(); - // but allow unbalanced cases too (more close markers) - if (_parsingContext == null) { - _parsingContext = JsonReadContext.createRootContext(null); - } - } - return _currToken; - } - - @Override - public boolean isClosed() { - return _closed; - } - - /* - /********************************************************** - /* Public API, token accessors - /********************************************************** - */ - - @Override - public JsonStreamContext getParsingContext() { - return _parsingContext; - } - - @Override - public JsonLocation getTokenLocation() { - return getCurrentLocation(); - } - - @Override - public JsonLocation getCurrentLocation() { - return (_location == null) ? JsonLocation.NA : _location; - } - - @Override - public String getCurrentName() { - return _parsingContext.getCurrentName(); - } - - @Override - public void overrideCurrentName(String name) { - // Simple, but need to look for START_OBJECT/ARRAY's "off-by-one" thing: - JsonReadContext ctxt = _parsingContext; - if (_currToken == JsonToken.START_OBJECT || _currToken == JsonToken.START_ARRAY) { - ctxt = ctxt.getParent(); - } - try { - ctxt.setCurrentName(name); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - /* - /********************************************************** - /* Public API, access to token information, text - /********************************************************** - */ - - @Override - public String getText() { - // common cases first: - if (_currToken == JsonToken.VALUE_STRING - || _currToken == JsonToken.FIELD_NAME) { - Object ob = _currentObject(); - if (ob instanceof String) { - return (String) ob; - } - return (ob == null) ? null : ob.toString(); - } - if (_currToken == null) { - return null; - } - switch (_currToken) { - case VALUE_NUMBER_INT: - case VALUE_NUMBER_FLOAT: - Object ob = _currentObject(); - return (ob == null) ? null : ob.toString(); - default: - return _currToken.asString(); - } - } - - @Override - public char[] getTextCharacters() { - String str = getText(); - return (str == null) ? null : str.toCharArray(); - } - - @Override - public int getTextLength() { - String str = getText(); - return (str == null) ? 0 : str.length(); - } - - @Override - public int getTextOffset() { - return 0; - } - - @Override - public boolean hasTextCharacters() { - // We never have raw buffer available, so: - return false; - } - - /* - /********************************************************** - /* Public API, access to token information, numeric - /********************************************************** - */ - - @Override - public BigInteger getBigIntegerValue() throws IOException, JsonParseException { - Number n = getNumberValue(); - if (n instanceof BigInteger) { - return (BigInteger) n; - } - if (getNumberType() == NumberType.BIG_DECIMAL) { - return ((BigDecimal) n).toBigInteger(); - } - // int/long is simple, but let's also just truncate float/double: - return BigInteger.valueOf(n.longValue()); - } - - @Override - public BigDecimal getDecimalValue() throws IOException, JsonParseException { - Number n = getNumberValue(); - if (n instanceof BigDecimal) { - return (BigDecimal) n; - } - switch (getNumberType()) { - case INT: - case LONG: - return BigDecimal.valueOf(n.longValue()); - case BIG_INTEGER: - return new BigDecimal((BigInteger) n); - default: - } - // float or double - return BigDecimal.valueOf(n.doubleValue()); - } - - @Override - public double getDoubleValue() throws IOException, JsonParseException { - return getNumberValue().doubleValue(); - } - - @Override - public float getFloatValue() throws IOException, JsonParseException { - return getNumberValue().floatValue(); - } - - @Override - public int getIntValue() throws IOException, JsonParseException { - // optimize common case: - if (_currToken == JsonToken.VALUE_NUMBER_INT) { - return ((Number) _currentObject()).intValue(); - } - return getNumberValue().intValue(); - } - - @Override - public long getLongValue() throws IOException, JsonParseException { - return getNumberValue().longValue(); - } - - @Override - public NumberType getNumberType() throws IOException, JsonParseException { - Number n = getNumberValue(); - if (n instanceof Integer) return NumberType.INT; - if (n instanceof Long) return NumberType.LONG; - if (n instanceof Double) return NumberType.DOUBLE; - if (n instanceof BigDecimal) return NumberType.BIG_DECIMAL; - if (n instanceof BigInteger) return NumberType.BIG_INTEGER; - if (n instanceof Float) return NumberType.FLOAT; - if (n instanceof Short) return NumberType.INT; // should be SHORT - return null; - } - - @Override - public final Number getNumberValue() throws IOException, JsonParseException { - _checkIsNumber(); - Object value = _currentObject(); - if (value instanceof Number) { - return (Number) value; - } - // Difficult to really support numbers-as-Strings; but let's try. - // NOTE: no access to DeserializationConfig, unfortunately, so can not - // try to determine Double/BigDecimal preference... - if (value instanceof String) { - String str = (String) value; - if (str.indexOf('.') >= 0) { - return Double.parseDouble(str); - } - return Long.parseLong(str); - } - if (value == null) { - return null; - } - throw new IllegalStateException("Internal error: entry should be a Number, but is of type " - + value.getClass().getName()); - } - - /* - /********************************************************** - /* Public API, access to token information, other - /********************************************************** - */ - - @Override - public Object getEmbeddedObject() { - if (_currToken == JsonToken.VALUE_EMBEDDED_OBJECT) { - return _currentObject(); - } - return null; - } - - @Override - @SuppressWarnings("resource") - public byte[] getBinaryValue(Base64Variant b64variant) throws IOException, JsonParseException { - // First: maybe we some special types? - if (_currToken == JsonToken.VALUE_EMBEDDED_OBJECT) { - // Embedded byte array would work nicely... - Object ob = _currentObject(); - if (ob instanceof byte[]) { - return (byte[]) ob; - } - // fall through to error case - } - if (_currToken != JsonToken.VALUE_STRING) { - throw _constructError("Current token (" + _currToken + ") not VALUE_STRING (or VALUE_EMBEDDED_OBJECT with byte[]), can not access as binary"); - } - final String str = getText(); - if (str == null) { - return null; - } - ByteArrayBuilder builder = _byteBuilder; - if (builder == null) { - _byteBuilder = builder = new ByteArrayBuilder(100); - } else { - _byteBuilder.reset(); - } - _decodeBase64(str, builder, b64variant); - return builder.toByteArray(); - } - - @Override - public int readBinaryValue(Base64Variant b64variant, OutputStream out) - throws IOException, JsonParseException { - byte[] data = getBinaryValue(b64variant); - if (data != null) { - out.write(data, 0, data.length); - return data.length; - } - return 0; - } - - /* - /********************************************************** - /* Public API, native ids - /********************************************************** - */ - - @Override - public boolean canReadObjectId() { - return _hasNativeObjectIds; - } - - @Override - public boolean canReadTypeId() { - return _hasNativeTypeIds; - } - - @Override - public Object getTypeId() { - return _segment.findTypeId(_segmentPtr); - } - - @Override - public Object getObjectId() { - return _segment.findObjectId(_segmentPtr); - } - - /* - /********************************************************** - /* Internal methods - /********************************************************** - */ - - protected final Object _currentObject() { - return _segment.get(_segmentPtr); - } - - protected final void _checkIsNumber() throws JsonParseException { - if (_currToken == null || !_currToken.isNumeric()) { - throw _constructError("Current token (" + _currToken + ") not numeric, can not use numeric value accessors"); - } - } - - @Override - protected void _handleEOF() throws JsonParseException { - _throwInternal(); - } - } - - /** - * Individual segment of TokenBuffer that can store up to 16 tokens - * (limited by 4 bits per token type marker requirement). - * Current implementation uses fixed length array; could alternatively - * use 16 distinct fields and switch statement (slightly more efficient - * storage, slightly slower access) - */ - protected final static class Segment { - public final static int TOKENS_PER_SEGMENT = 16; - - /** - * Static array used for fast conversion between token markers and - * matching {@link JsonToken} instances - */ - private final static JsonToken[] TOKEN_TYPES_BY_INDEX; - - static { - // ... here we know that there are <= 15 values in JsonToken enum - TOKEN_TYPES_BY_INDEX = new JsonToken[16]; - JsonToken[] t = JsonToken.values(); - // and reserve entry 0 for "not available" - System.arraycopy(t, 1, TOKEN_TYPES_BY_INDEX, 1, Math.min(15, t.length - 1)); - } - - // // // Linking - - protected Segment _next; - - // // // State - - /** - * Bit field used to store types of buffered tokens; 4 bits per token. - * Value 0 is reserved for "not in use" - */ - protected long _tokenTypes; - - - // Actual tokens - - protected final Object[] _tokens = new Object[TOKENS_PER_SEGMENT]; - - /** - * Lazily constructed Map for storing native type and object ids, if any - */ - protected TreeMap _nativeIds; - - public Segment() { - } - - // // // Accessors - - public JsonToken type(int index) { - long l = _tokenTypes; - if (index > 0) { - l >>= (index << 2); - } - int ix = ((int) l) & 0xF; - return TOKEN_TYPES_BY_INDEX[ix]; - } - - public int rawType(int index) { - long l = _tokenTypes; - if (index > 0) { - l >>= (index << 2); - } - int ix = ((int) l) & 0xF; - return ix; - } - - public Object get(int index) { - return _tokens[index]; - } - - public Segment next() { - return _next; - } - - /** - * Accessor for checking whether this segment may have native - * type or object ids. - */ - public boolean hasIds() { - return _nativeIds != null; - } - - // // // Mutators - - public Segment append(int index, JsonToken tokenType) { - if (index < TOKENS_PER_SEGMENT) { - set(index, tokenType); - return null; - } - _next = new Segment(); - _next.set(0, tokenType); - return _next; - } - - public Segment append(int index, JsonToken tokenType, - Object objectId, Object typeId) { - if (index < TOKENS_PER_SEGMENT) { - set(index, tokenType, objectId, typeId); - return null; - } - _next = new Segment(); - _next.set(0, tokenType, objectId, typeId); - return _next; - } - - public Segment append(int index, JsonToken tokenType, Object value) { - if (index < TOKENS_PER_SEGMENT) { - set(index, tokenType, value); - return null; - } - _next = new Segment(); - _next.set(0, tokenType, value); - return _next; - } - - public Segment append(int index, JsonToken tokenType, Object value, - Object objectId, Object typeId) { - if (index < TOKENS_PER_SEGMENT) { - set(index, tokenType, value, objectId, typeId); - return null; - } - _next = new Segment(); - _next.set(0, tokenType, value, objectId, typeId); - return _next; - } - - public Segment appendRaw(int index, int rawTokenType, Object value) { - if (index < TOKENS_PER_SEGMENT) { - set(index, rawTokenType, value); - return null; - } - _next = new Segment(); - _next.set(0, rawTokenType, value); - return _next; - } - - public Segment appendRaw(int index, int rawTokenType, Object value, - Object objectId, Object typeId) { - if (index < TOKENS_PER_SEGMENT) { - set(index, rawTokenType, value, objectId, typeId); - return null; - } - _next = new Segment(); - _next.set(0, rawTokenType, value, objectId, typeId); - return _next; - } - - private void set(int index, JsonToken tokenType) { - /* Assumption here is that there are no overwrites, just appends; - * and so no masking is needed (nor explicit setting of null) - */ - long typeCode = tokenType.ordinal(); - if (index > 0) { - typeCode <<= (index << 2); - } - _tokenTypes |= typeCode; - } - - private void set(int index, JsonToken tokenType, - Object objectId, Object typeId) { - long typeCode = tokenType.ordinal(); - if (index > 0) { - typeCode <<= (index << 2); - } - _tokenTypes |= typeCode; - assignNativeIds(index, objectId, typeId); - } - - private void set(int index, JsonToken tokenType, Object value) { - _tokens[index] = value; - long typeCode = tokenType.ordinal(); - if (index > 0) { - typeCode <<= (index << 2); - } - _tokenTypes |= typeCode; - } - - private void set(int index, JsonToken tokenType, Object value, - Object objectId, Object typeId) { - _tokens[index] = value; - long typeCode = tokenType.ordinal(); - if (index > 0) { - typeCode <<= (index << 2); - } - _tokenTypes |= typeCode; - assignNativeIds(index, objectId, typeId); - } - - private void set(int index, int rawTokenType, Object value) { - _tokens[index] = value; - long typeCode = (long) rawTokenType; - if (index > 0) { - typeCode <<= (index << 2); - } - _tokenTypes |= typeCode; - } - - private void set(int index, int rawTokenType, Object value, - Object objectId, Object typeId) { - _tokens[index] = value; - long typeCode = (long) rawTokenType; - if (index > 0) { - typeCode <<= (index << 2); - } - _tokenTypes |= typeCode; - assignNativeIds(index, objectId, typeId); - } - - private final void assignNativeIds(int index, - Object objectId, Object typeId) { - if (_nativeIds == null) { - _nativeIds = new TreeMap(); - } - if (objectId != null) { - _nativeIds.put(_objectIdIndex(index), objectId); - } - if (typeId != null) { - _nativeIds.put(_typeIdIndex(index), typeId); - } - } - - /** - * @since 2.3 - */ - public Object findObjectId(int index) { - return (_nativeIds == null) ? null : _nativeIds.get(_objectIdIndex(index)); - } - - /** - * @since 2.3 - */ - public Object findTypeId(int index) { - return (_nativeIds == null) ? null : _nativeIds.get(_typeIdIndex(index)); - } - - private final int _typeIdIndex(int i) { - return i + i; - } - - private final int _objectIdIndex(int i) { - return i + i + 1; - } - } -}