first commit

This commit is contained in:
MaddoScientisto 2026-03-14 20:04:39 +01:00
commit 4d332ef662
27586 changed files with 3281783 additions and 0 deletions

View file

@ -0,0 +1,73 @@
package com.google.gson;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
final class DefaultDateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
private final DateFormat enUsFormat;
private final DateFormat localFormat;
private final DateFormat iso8601Format;
DefaultDateTypeAdapter() {
this(DateFormat.getDateTimeInstance(2, 2, Locale.US), DateFormat.getDateTimeInstance(2, 2));
}
DefaultDateTypeAdapter(String datePattern) {
this(new SimpleDateFormat(datePattern, Locale.US), new SimpleDateFormat(datePattern));
}
DefaultDateTypeAdapter(int style) {
this(DateFormat.getDateInstance(style, Locale.US), DateFormat.getDateInstance(style));
}
public DefaultDateTypeAdapter(int dateStyle, int timeStyle) {
this(DateFormat.getDateTimeInstance(dateStyle, timeStyle, Locale.US), DateFormat.getDateTimeInstance(dateStyle, timeStyle));
}
DefaultDateTypeAdapter(DateFormat enUsFormat, DateFormat localFormat) {
this.enUsFormat = enUsFormat;
this.localFormat = localFormat;
this.iso8601Format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
this.iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC"));
}
public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
synchronized (this.localFormat) {
String dateFormatAsString = this.enUsFormat.format(src);
return new JsonPrimitive(dateFormatAsString);
}
}
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (!(json instanceof JsonPrimitive))
throw new JsonParseException("The date should be a string value");
Date date = deserializeToDate(json);
if (typeOfT == Date.class)
return date;
if (typeOfT == Timestamp.class)
return new Timestamp(date.getTime());
if (typeOfT == java.sql.Date.class)
return new java.sql.Date(date.getTime());
throw new IllegalArgumentException(getClass() + " cannot deserialize to " + typeOfT);
}
private Date deserializeToDate(JsonElement json) {
synchronized (this.localFormat) {
return this.localFormat.parse(json.getAsString());
}
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(DefaultDateTypeAdapter.class.getSimpleName());
sb.append('(').append(this.localFormat.getClass().getSimpleName()).append(')');
return sb.toString();
}
}

View file

@ -0,0 +1,7 @@
package com.google.gson;
public interface ExclusionStrategy {
boolean shouldSkipField(FieldAttributes paramFieldAttributes);
boolean shouldSkipClass(Class<?> paramClass);
}

View file

@ -0,0 +1,53 @@
package com.google.gson;
import com.google.gson.internal.$Gson$Preconditions;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
public final class FieldAttributes {
private final Field field;
public FieldAttributes(Field f) {
$Gson$Preconditions.<Field>checkNotNull(f);
this.field = f;
}
public Class<?> getDeclaringClass() {
return this.field.getDeclaringClass();
}
public String getName() {
return this.field.getName();
}
public Type getDeclaredType() {
return this.field.getGenericType();
}
public Class<?> getDeclaredClass() {
return this.field.getType();
}
public <T extends Annotation> T getAnnotation(Class<T> annotation) {
return this.field.<T>getAnnotation(annotation);
}
public Collection<Annotation> getAnnotations() {
return Arrays.<Annotation>asList(this.field.getAnnotations());
}
public boolean hasModifier(int modifier) {
return ((this.field.getModifiers() & modifier) != 0);
}
Object get(Object instance) throws IllegalAccessException {
return this.field.get(instance);
}
boolean isSynthetic() {
return this.field.isSynthetic();
}
}

View file

@ -0,0 +1,64 @@
package com.google.gson;
import java.lang.reflect.Field;
public enum FieldNamingPolicy implements FieldNamingStrategy {
IDENTITY {
public String translateName(Field f) {
return f.getName();
}
},
UPPER_CAMEL_CASE {
public String translateName(Field f) {
return upperCaseFirstLetter(f.getName());
}
},
UPPER_CAMEL_CASE_WITH_SPACES {
public String translateName(Field f) {
return upperCaseFirstLetter(separateCamelCase(f.getName(), " "));
}
},
LOWER_CASE_WITH_UNDERSCORES {
public String translateName(Field f) {
return separateCamelCase(f.getName(), "_").toLowerCase();
}
},
LOWER_CASE_WITH_DASHES {
public String translateName(Field f) {
return separateCamelCase(f.getName(), "-").toLowerCase();
}
};
private static String separateCamelCase(String name, String separator) {
StringBuilder translation = new StringBuilder();
for (int i = 0; i < name.length(); i++) {
char character = name.charAt(i);
if (Character.isUpperCase(character) && translation.length() != 0)
translation.append(separator);
translation.append(character);
}
return translation.toString();
}
private static String upperCaseFirstLetter(String name) {
StringBuilder fieldNameBuilder = new StringBuilder();
int index = 0;
char firstCharacter = name.charAt(index);
while (index < name.length() - 1 &&
!Character.isLetter(firstCharacter)) {
fieldNameBuilder.append(firstCharacter);
firstCharacter = name.charAt(++index);
}
if (index == name.length())
return fieldNameBuilder.toString();
if (!Character.isUpperCase(firstCharacter)) {
String modifiedTarget = modifyString(Character.toUpperCase(firstCharacter), name, ++index);
return fieldNameBuilder.append(modifiedTarget).toString();
}
return name;
}
private static String modifyString(char firstCharacter, String srcString, int indexOfSubstring) {
return (indexOfSubstring < srcString.length()) ? (firstCharacter + srcString.substring(indexOfSubstring)) : String.valueOf(firstCharacter);
}
}

View file

@ -0,0 +1,7 @@
package com.google.gson;
import java.lang.reflect.Field;
public interface FieldNamingStrategy {
String translateName(Field paramField);
}

View file

@ -0,0 +1,452 @@
package com.google.gson;
import com.google.gson.internal.ConstructorConstructor;
import com.google.gson.internal.Excluder;
import com.google.gson.internal.Primitives;
import com.google.gson.internal.Streams;
import com.google.gson.internal.bind.ArrayTypeAdapter;
import com.google.gson.internal.bind.CollectionTypeAdapterFactory;
import com.google.gson.internal.bind.DateTypeAdapter;
import com.google.gson.internal.bind.JsonTreeReader;
import com.google.gson.internal.bind.JsonTreeWriter;
import com.google.gson.internal.bind.MapTypeAdapterFactory;
import com.google.gson.internal.bind.ObjectTypeAdapter;
import com.google.gson.internal.bind.ReflectiveTypeAdapterFactory;
import com.google.gson.internal.bind.SqlDateTypeAdapter;
import com.google.gson.internal.bind.TimeTypeAdapter;
import com.google.gson.internal.bind.TypeAdapters;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.google.gson.stream.MalformedJsonException;
import java.io.EOFException;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public final class Gson {
static final boolean DEFAULT_JSON_NON_EXECUTABLE = false;
private static final String JSON_NON_EXECUTABLE_PREFIX = ")]}'\n";
private final ThreadLocal<Map<TypeToken<?>, FutureTypeAdapter<?>>> calls = new ThreadLocal<Map<TypeToken<?>, FutureTypeAdapter<?>>>();
private final Map<TypeToken<?>, TypeAdapter<?>> typeTokenCache = Collections.<TypeToken<?>, TypeAdapter<?>>synchronizedMap(new HashMap<TypeToken<?>, TypeAdapter<?>>());
private final List<TypeAdapterFactory> factories;
private final ConstructorConstructor constructorConstructor;
private final boolean serializeNulls;
private final boolean htmlSafe;
private final boolean generateNonExecutableJson;
private final boolean prettyPrinting;
final JsonDeserializationContext deserializationContext = new JsonDeserializationContext() {
public <T> T deserialize(JsonElement json, Type typeOfT) throws JsonParseException {
return Gson.this.<T>fromJson(json, typeOfT);
}
};
final JsonSerializationContext serializationContext = new JsonSerializationContext() {
public JsonElement serialize(Object src) {
return Gson.this.toJsonTree(src);
}
public JsonElement serialize(Object src, Type typeOfSrc) {
return Gson.this.toJsonTree(src, typeOfSrc);
}
};
public Gson() {
this(Excluder.DEFAULT, FieldNamingPolicy.IDENTITY, Collections.<Type, InstanceCreator<?>>emptyMap(), false, false, false, true, false, false, LongSerializationPolicy.DEFAULT, Collections.<TypeAdapterFactory>emptyList());
}
Gson(Excluder excluder, FieldNamingStrategy fieldNamingPolicy, Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls, boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe, boolean prettyPrinting, boolean serializeSpecialFloatingPointValues, LongSerializationPolicy longSerializationPolicy, List<TypeAdapterFactory> typeAdapterFactories) {
this.constructorConstructor = new ConstructorConstructor(instanceCreators);
this.serializeNulls = serializeNulls;
this.generateNonExecutableJson = generateNonExecutableGson;
this.htmlSafe = htmlSafe;
this.prettyPrinting = prettyPrinting;
List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
factories.add(ObjectTypeAdapter.FACTORY);
factories.add(excluder);
factories.addAll(typeAdapterFactories);
factories.add(TypeAdapters.STRING_FACTORY);
factories.add(TypeAdapters.INTEGER_FACTORY);
factories.add(TypeAdapters.BOOLEAN_FACTORY);
factories.add(TypeAdapters.BYTE_FACTORY);
factories.add(TypeAdapters.SHORT_FACTORY);
factories.add(TypeAdapters.<long>newFactory(long.class, (Class)Long.class, longAdapter(longSerializationPolicy)));
factories.add(TypeAdapters.<double>newFactory(double.class, (Class)Double.class, doubleAdapter(serializeSpecialFloatingPointValues)));
factories.add(TypeAdapters.<float>newFactory(float.class, (Class)Float.class, floatAdapter(serializeSpecialFloatingPointValues)));
factories.add(TypeAdapters.NUMBER_FACTORY);
factories.add(TypeAdapters.CHARACTER_FACTORY);
factories.add(TypeAdapters.STRING_BUILDER_FACTORY);
factories.add(TypeAdapters.STRING_BUFFER_FACTORY);
factories.add(TypeAdapters.<BigDecimal>newFactory(BigDecimal.class, TypeAdapters.BIG_DECIMAL));
factories.add(TypeAdapters.<BigInteger>newFactory(BigInteger.class, TypeAdapters.BIG_INTEGER));
factories.add(TypeAdapters.URL_FACTORY);
factories.add(TypeAdapters.URI_FACTORY);
factories.add(TypeAdapters.UUID_FACTORY);
factories.add(TypeAdapters.LOCALE_FACTORY);
factories.add(TypeAdapters.INET_ADDRESS_FACTORY);
factories.add(TypeAdapters.BIT_SET_FACTORY);
factories.add(DateTypeAdapter.FACTORY);
factories.add(TypeAdapters.CALENDAR_FACTORY);
factories.add(TimeTypeAdapter.FACTORY);
factories.add(SqlDateTypeAdapter.FACTORY);
factories.add(TypeAdapters.TIMESTAMP_FACTORY);
factories.add(ArrayTypeAdapter.FACTORY);
factories.add(TypeAdapters.ENUM_FACTORY);
factories.add(TypeAdapters.CLASS_FACTORY);
factories.add(new CollectionTypeAdapterFactory(this.constructorConstructor));
factories.add(new MapTypeAdapterFactory(this.constructorConstructor, complexMapKeySerialization));
factories.add(new ReflectiveTypeAdapterFactory(this.constructorConstructor, fieldNamingPolicy, excluder));
this.factories = Collections.<TypeAdapterFactory>unmodifiableList(factories);
}
private TypeAdapter<Number> doubleAdapter(boolean serializeSpecialFloatingPointValues) {
if (serializeSpecialFloatingPointValues)
return TypeAdapters.DOUBLE;
return new TypeAdapter<Number>() {
public Double read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
return in.nextDouble();
}
public void write(JsonWriter out, Number value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
double doubleValue = value.doubleValue();
Gson.this.checkValidFloatingPoint(doubleValue);
out.value(value);
}
};
}
private TypeAdapter<Number> floatAdapter(boolean serializeSpecialFloatingPointValues) {
if (serializeSpecialFloatingPointValues)
return TypeAdapters.FLOAT;
return new TypeAdapter<Number>() {
public Float read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
return (float)in.nextDouble();
}
public void write(JsonWriter out, Number value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
float floatValue = value.floatValue();
Gson.this.checkValidFloatingPoint((double)floatValue);
out.value(value);
}
};
}
private void checkValidFloatingPoint(double value) {
if (Double.isNaN(value) || Double.isInfinite(value))
throw new IllegalArgumentException(value + " is not a valid double value as per JSON specification. To override this" + " behavior, use GsonBuilder.serializeSpecialFloatingPointValues() method.");
}
private TypeAdapter<Number> longAdapter(LongSerializationPolicy longSerializationPolicy) {
if (longSerializationPolicy == LongSerializationPolicy.DEFAULT)
return TypeAdapters.LONG;
return new TypeAdapter<Number>() {
public Number read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
return in.nextLong();
}
public void write(JsonWriter out, Number value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
out.value(value.toString());
}
};
}
public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
TypeAdapter<?> cached = this.typeTokenCache.get(type);
if (cached != null)
return (TypeAdapter<T>)cached;
Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = this.calls.get();
boolean requiresThreadLocalCleanup = false;
if (threadCalls == null) {
threadCalls = new HashMap<TypeToken<?>, FutureTypeAdapter<?>>();
this.calls.set(threadCalls);
requiresThreadLocalCleanup = true;
}
FutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>)threadCalls.get(type);
if (ongoingCall != null)
return ongoingCall;
try {
FutureTypeAdapter<T> call = new FutureTypeAdapter<T>();
threadCalls.put(type, call);
for (TypeAdapterFactory factory : this.factories) {
TypeAdapter<T> candidate = factory.<T>create(this, type);
if (candidate != null) {
call.setDelegate(candidate);
this.typeTokenCache.put(type, candidate);
return candidate;
}
}
throw new IllegalArgumentException("GSON cannot handle " + type);
} finally {
threadCalls.remove(type);
if (requiresThreadLocalCleanup)
this.calls.remove();
}
}
public <T> TypeAdapter<T> getDelegateAdapter(TypeAdapterFactory skipPast, TypeToken<T> type) {
boolean skipPastFound = false;
for (TypeAdapterFactory factory : this.factories) {
if (!skipPastFound) {
if (factory == skipPast)
skipPastFound = true;
continue;
}
TypeAdapter<T> candidate = factory.<T>create(this, type);
if (candidate != null)
return candidate;
}
throw new IllegalArgumentException("GSON cannot serialize " + type);
}
public <T> TypeAdapter<T> getAdapter(Class<T> type) {
return getAdapter(TypeToken.<T>get(type));
}
public JsonElement toJsonTree(Object src) {
if (src == null)
return JsonNull.INSTANCE;
return toJsonTree(src, src.getClass());
}
public JsonElement toJsonTree(Object src, Type typeOfSrc) {
JsonTreeWriter writer = new JsonTreeWriter();
toJson(src, typeOfSrc, writer);
return writer.get();
}
public String toJson(Object src) {
if (src == null)
return toJson((JsonElement)JsonNull.INSTANCE);
return toJson(src, src.getClass());
}
public String toJson(Object src, Type typeOfSrc) {
StringWriter writer = new StringWriter();
toJson(src, typeOfSrc, writer);
return writer.toString();
}
public void toJson(Object src, Appendable writer) throws JsonIOException {
if (src != null) {
toJson(src, src.getClass(), writer);
} else {
toJson((JsonElement)JsonNull.INSTANCE, writer);
}
}
public void toJson(Object src, Type typeOfSrc, Appendable writer) throws JsonIOException {
try {
JsonWriter jsonWriter = newJsonWriter(Streams.writerForAppendable(writer));
toJson(src, typeOfSrc, jsonWriter);
} catch (IOException e) {
throw new JsonIOException(e);
}
}
public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException {
TypeAdapter<?> adapter = getAdapter(TypeToken.get(typeOfSrc));
boolean oldLenient = writer.isLenient();
writer.setLenient(true);
boolean oldHtmlSafe = writer.isHtmlSafe();
writer.setHtmlSafe(this.htmlSafe);
boolean oldSerializeNulls = writer.getSerializeNulls();
writer.setSerializeNulls(this.serializeNulls);
try {
adapter.write(writer, src);
} catch (IOException e) {
throw new JsonIOException(e);
} finally {
writer.setLenient(oldLenient);
writer.setHtmlSafe(oldHtmlSafe);
writer.setSerializeNulls(oldSerializeNulls);
}
}
public String toJson(JsonElement jsonElement) {
StringWriter writer = new StringWriter();
toJson(jsonElement, (Appendable)writer);
return writer.toString();
}
public void toJson(JsonElement jsonElement, Appendable writer) throws JsonIOException {
try {
JsonWriter jsonWriter = newJsonWriter(Streams.writerForAppendable(writer));
toJson(jsonElement, jsonWriter);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private JsonWriter newJsonWriter(Writer writer) throws IOException {
if (this.generateNonExecutableJson)
writer.write(")]}'\n");
JsonWriter jsonWriter = new JsonWriter(writer);
if (this.prettyPrinting)
jsonWriter.setIndent(" ");
jsonWriter.setSerializeNulls(this.serializeNulls);
return jsonWriter;
}
public void toJson(JsonElement jsonElement, JsonWriter writer) throws JsonIOException {
boolean oldLenient = writer.isLenient();
writer.setLenient(true);
boolean oldHtmlSafe = writer.isHtmlSafe();
writer.setHtmlSafe(this.htmlSafe);
boolean oldSerializeNulls = writer.getSerializeNulls();
writer.setSerializeNulls(this.serializeNulls);
try {
Streams.write(jsonElement, writer);
} catch (IOException e) {
throw new JsonIOException(e);
} finally {
writer.setLenient(oldLenient);
writer.setHtmlSafe(oldHtmlSafe);
writer.setSerializeNulls(oldSerializeNulls);
}
}
public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException {
Object object = fromJson(json, (Type)classOfT);
return Primitives.<T>wrap(classOfT).cast(object);
}
public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
if (json == null)
return null;
StringReader reader = new StringReader(json);
T target = fromJson(reader, typeOfT);
return target;
}
public <T> T fromJson(Reader json, Class<T> classOfT) throws JsonSyntaxException, JsonIOException {
JsonReader jsonReader = new JsonReader(json);
Object object = fromJson(jsonReader, classOfT);
assertFullConsumption(object, jsonReader);
return Primitives.<T>wrap(classOfT).cast(object);
}
public <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {
JsonReader jsonReader = new JsonReader(json);
T object = fromJson(jsonReader, typeOfT);
assertFullConsumption(object, jsonReader);
return object;
}
private static void assertFullConsumption(Object obj, JsonReader reader) {
try {
if (obj != null && reader.peek() != JsonToken.END_DOCUMENT)
throw new JsonIOException("JSON document was not fully consumed.");
} catch (MalformedJsonException e) {
throw new JsonSyntaxException(e);
} catch (IOException e) {
throw new JsonIOException(e);
}
}
public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
boolean isEmpty = true;
boolean oldLenient = reader.isLenient();
reader.setLenient(true);
try {
reader.peek();
isEmpty = false;
TypeToken<T> typeToken = (TypeToken<T>)TypeToken.get(typeOfT);
TypeAdapter<T> typeAdapter = getAdapter(typeToken);
T object = typeAdapter.read(reader);
return object;
} catch (EOFException e) {
if (isEmpty)
return null;
throw new JsonSyntaxException(e);
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
} catch (IOException e) {
throw new JsonSyntaxException(e);
} finally {
reader.setLenient(oldLenient);
}
}
public <T> T fromJson(JsonElement json, Class<T> classOfT) throws JsonSyntaxException {
Object object = fromJson(json, (Type)classOfT);
return Primitives.<T>wrap(classOfT).cast(object);
}
public <T> T fromJson(JsonElement json, Type typeOfT) throws JsonSyntaxException {
if (json == null)
return null;
return fromJson(new JsonTreeReader(json), typeOfT);
}
static class FutureTypeAdapter<T> extends TypeAdapter<T> {
private TypeAdapter<T> delegate;
public void setDelegate(TypeAdapter<T> typeAdapter) {
if (this.delegate != null)
throw new AssertionError();
this.delegate = typeAdapter;
}
public T read(JsonReader in) throws IOException {
if (this.delegate == null)
throw new IllegalStateException();
return this.delegate.read(in);
}
public void write(JsonWriter out, T value) throws IOException {
if (this.delegate == null)
throw new IllegalStateException();
this.delegate.write(out, value);
}
}
public String toString() {
return "{serializeNulls:" + this.serializeNulls + "factories:" + this.factories + ",instanceCreators:" + this.constructorConstructor + "}";
}
}

View file

@ -0,0 +1,195 @@
package com.google.gson;
import com.google.gson.internal.$Gson$Preconditions;
import com.google.gson.internal.Excluder;
import com.google.gson.internal.bind.TypeAdapters;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public final class GsonBuilder {
private Excluder excluder = Excluder.DEFAULT;
private LongSerializationPolicy longSerializationPolicy = LongSerializationPolicy.DEFAULT;
private FieldNamingStrategy fieldNamingPolicy = FieldNamingPolicy.IDENTITY;
private final Map<Type, InstanceCreator<?>> instanceCreators = new HashMap<Type, InstanceCreator<?>>();
private final List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
private final List<TypeAdapterFactory> hierarchyFactories = new ArrayList<TypeAdapterFactory>();
private boolean serializeNulls;
private String datePattern;
private int dateStyle = 2;
private int timeStyle = 2;
private boolean complexMapKeySerialization;
private boolean serializeSpecialFloatingPointValues;
private boolean escapeHtmlChars = true;
private boolean prettyPrinting;
private boolean generateNonExecutableJson;
public GsonBuilder setVersion(double ignoreVersionsAfter) {
this.excluder = this.excluder.withVersion(ignoreVersionsAfter);
return this;
}
public GsonBuilder excludeFieldsWithModifiers(int... modifiers) {
this.excluder = this.excluder.withModifiers(modifiers);
return this;
}
public GsonBuilder generateNonExecutableJson() {
this.generateNonExecutableJson = true;
return this;
}
public GsonBuilder excludeFieldsWithoutExposeAnnotation() {
this.excluder = this.excluder.excludeFieldsWithoutExposeAnnotation();
return this;
}
public GsonBuilder serializeNulls() {
this.serializeNulls = true;
return this;
}
public GsonBuilder enableComplexMapKeySerialization() {
this.complexMapKeySerialization = true;
return this;
}
public GsonBuilder disableInnerClassSerialization() {
this.excluder = this.excluder.disableInnerClassSerialization();
return this;
}
public GsonBuilder setLongSerializationPolicy(LongSerializationPolicy serializationPolicy) {
this.longSerializationPolicy = serializationPolicy;
return this;
}
public GsonBuilder setFieldNamingPolicy(FieldNamingPolicy namingConvention) {
this.fieldNamingPolicy = namingConvention;
return this;
}
public GsonBuilder setFieldNamingStrategy(FieldNamingStrategy fieldNamingStrategy) {
this.fieldNamingPolicy = fieldNamingStrategy;
return this;
}
public GsonBuilder setExclusionStrategies(ExclusionStrategy... strategies) {
for (ExclusionStrategy strategy : strategies)
this.excluder = this.excluder.withExclusionStrategy(strategy, true, true);
return this;
}
public GsonBuilder addSerializationExclusionStrategy(ExclusionStrategy strategy) {
this.excluder = this.excluder.withExclusionStrategy(strategy, true, false);
return this;
}
public GsonBuilder addDeserializationExclusionStrategy(ExclusionStrategy strategy) {
this.excluder = this.excluder.withExclusionStrategy(strategy, false, true);
return this;
}
public GsonBuilder setPrettyPrinting() {
this.prettyPrinting = true;
return this;
}
public GsonBuilder disableHtmlEscaping() {
this.escapeHtmlChars = false;
return this;
}
public GsonBuilder setDateFormat(String pattern) {
this.datePattern = pattern;
return this;
}
public GsonBuilder setDateFormat(int style) {
this.dateStyle = style;
this.datePattern = null;
return this;
}
public GsonBuilder setDateFormat(int dateStyle, int timeStyle) {
this.dateStyle = dateStyle;
this.timeStyle = timeStyle;
this.datePattern = null;
return this;
}
public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter) {
$Gson$Preconditions.checkArgument((typeAdapter instanceof JsonSerializer || typeAdapter instanceof JsonDeserializer || typeAdapter instanceof InstanceCreator || typeAdapter instanceof TypeAdapter));
if (typeAdapter instanceof InstanceCreator)
this.instanceCreators.put(type, (InstanceCreator)typeAdapter);
if (typeAdapter instanceof JsonSerializer || typeAdapter instanceof JsonDeserializer) {
TypeToken<?> typeToken = TypeToken.get(type);
this.factories.add(TreeTypeAdapter.newFactoryWithMatchRawType(typeToken, typeAdapter));
}
if (typeAdapter instanceof TypeAdapter)
this.factories.add(TypeAdapters.newFactory(TypeToken.get(type), (TypeAdapter)typeAdapter));
return this;
}
public GsonBuilder registerTypeAdapterFactory(TypeAdapterFactory factory) {
this.factories.add(factory);
return this;
}
public GsonBuilder registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter) {
$Gson$Preconditions.checkArgument((typeAdapter instanceof JsonSerializer || typeAdapter instanceof JsonDeserializer || typeAdapter instanceof TypeAdapter));
if (typeAdapter instanceof JsonDeserializer || typeAdapter instanceof JsonSerializer)
this.hierarchyFactories.add(0, TreeTypeAdapter.newTypeHierarchyFactory(baseType, typeAdapter));
if (typeAdapter instanceof TypeAdapter)
this.factories.add(TypeAdapters.newTypeHierarchyFactory(baseType, (TypeAdapter)typeAdapter));
return this;
}
public GsonBuilder serializeSpecialFloatingPointValues() {
this.serializeSpecialFloatingPointValues = true;
return this;
}
public Gson create() {
List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
factories.addAll(this.factories);
Collections.reverse(factories);
factories.addAll(this.hierarchyFactories);
addTypeAdaptersForDate(this.datePattern, this.dateStyle, this.timeStyle, factories);
return new Gson(this.excluder, this.fieldNamingPolicy, this.instanceCreators, this.serializeNulls, this.complexMapKeySerialization, this.generateNonExecutableJson, this.escapeHtmlChars, this.prettyPrinting, this.serializeSpecialFloatingPointValues, this.longSerializationPolicy, factories);
}
private void addTypeAdaptersForDate(String datePattern, int dateStyle, int timeStyle, List<TypeAdapterFactory> factories) {
DefaultDateTypeAdapter dateTypeAdapter;
if (datePattern != null && !"".equals(datePattern.trim())) {
dateTypeAdapter = new DefaultDateTypeAdapter(datePattern);
} else if (dateStyle != 2 && timeStyle != 2) {
dateTypeAdapter = new DefaultDateTypeAdapter(dateStyle, timeStyle);
} else {
return;
}
factories.add(TreeTypeAdapter.newFactory(TypeToken.<Date>get(Date.class), dateTypeAdapter));
factories.add(TreeTypeAdapter.newFactory(TypeToken.<Timestamp>get(Timestamp.class), dateTypeAdapter));
factories.add(TreeTypeAdapter.newFactory(TypeToken.<java.sql.Date>get(java.sql.Date.class), dateTypeAdapter));
}
}

View file

@ -0,0 +1,7 @@
package com.google.gson;
import java.lang.reflect.Type;
public interface InstanceCreator<T> {
T createInstance(Type paramType);
}

View file

@ -0,0 +1,120 @@
package com.google.gson;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public final class JsonArray extends JsonElement implements Iterable<JsonElement> {
private final List<JsonElement> elements = new ArrayList<JsonElement>();
JsonArray deepCopy() {
JsonArray result = new JsonArray();
for (JsonElement element : this.elements)
result.add(element.deepCopy());
return result;
}
public void add(JsonElement element) {
if (element == null)
element = JsonNull.INSTANCE;
this.elements.add(element);
}
public void addAll(JsonArray array) {
this.elements.addAll(array.elements);
}
public int size() {
return this.elements.size();
}
public Iterator<JsonElement> iterator() {
return this.elements.iterator();
}
public JsonElement get(int i) {
return this.elements.get(i);
}
public Number getAsNumber() {
if (this.elements.size() == 1)
return this.elements.get(0).getAsNumber();
throw new IllegalStateException();
}
public String getAsString() {
if (this.elements.size() == 1)
return this.elements.get(0).getAsString();
throw new IllegalStateException();
}
public double getAsDouble() {
if (this.elements.size() == 1)
return this.elements.get(0).getAsDouble();
throw new IllegalStateException();
}
public BigDecimal getAsBigDecimal() {
if (this.elements.size() == 1)
return this.elements.get(0).getAsBigDecimal();
throw new IllegalStateException();
}
public BigInteger getAsBigInteger() {
if (this.elements.size() == 1)
return this.elements.get(0).getAsBigInteger();
throw new IllegalStateException();
}
public float getAsFloat() {
if (this.elements.size() == 1)
return this.elements.get(0).getAsFloat();
throw new IllegalStateException();
}
public long getAsLong() {
if (this.elements.size() == 1)
return this.elements.get(0).getAsLong();
throw new IllegalStateException();
}
public int getAsInt() {
if (this.elements.size() == 1)
return this.elements.get(0).getAsInt();
throw new IllegalStateException();
}
public byte getAsByte() {
if (this.elements.size() == 1)
return this.elements.get(0).getAsByte();
throw new IllegalStateException();
}
public char getAsCharacter() {
if (this.elements.size() == 1)
return this.elements.get(0).getAsCharacter();
throw new IllegalStateException();
}
public short getAsShort() {
if (this.elements.size() == 1)
return this.elements.get(0).getAsShort();
throw new IllegalStateException();
}
public boolean getAsBoolean() {
if (this.elements.size() == 1)
return this.elements.get(0).getAsBoolean();
throw new IllegalStateException();
}
public boolean equals(Object o) {
return (o == this || (o instanceof JsonArray && ((JsonArray)o).elements.equals(this.elements)));
}
public int hashCode() {
return this.elements.hashCode();
}
}

View file

@ -0,0 +1,7 @@
package com.google.gson;
import java.lang.reflect.Type;
public interface JsonDeserializationContext {
<T> T deserialize(JsonElement paramJsonElement, Type paramType) throws JsonParseException;
}

View file

@ -0,0 +1,7 @@
package com.google.gson;
import java.lang.reflect.Type;
public interface JsonDeserializer<T> {
T deserialize(JsonElement paramJsonElement, Type paramType, JsonDeserializationContext paramJsonDeserializationContext) throws JsonParseException;
}

View file

@ -0,0 +1,116 @@
package com.google.gson;
import com.google.gson.internal.Streams;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.math.BigInteger;
public abstract class JsonElement {
abstract JsonElement deepCopy();
public boolean isJsonArray() {
return this instanceof JsonArray;
}
public boolean isJsonObject() {
return this instanceof JsonObject;
}
public boolean isJsonPrimitive() {
return this instanceof JsonPrimitive;
}
public boolean isJsonNull() {
return this instanceof JsonNull;
}
public JsonObject getAsJsonObject() {
if (isJsonObject())
return (JsonObject)this;
throw new IllegalStateException("Not a JSON Object: " + this);
}
public JsonArray getAsJsonArray() {
if (isJsonArray())
return (JsonArray)this;
throw new IllegalStateException("This is not a JSON Array.");
}
public JsonPrimitive getAsJsonPrimitive() {
if (isJsonPrimitive())
return (JsonPrimitive)this;
throw new IllegalStateException("This is not a JSON Primitive.");
}
public JsonNull getAsJsonNull() {
if (isJsonNull())
return (JsonNull)this;
throw new IllegalStateException("This is not a JSON Null.");
}
public boolean getAsBoolean() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
Boolean getAsBooleanWrapper() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
public Number getAsNumber() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
public String getAsString() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
public double getAsDouble() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
public float getAsFloat() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
public long getAsLong() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
public int getAsInt() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
public byte getAsByte() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
public char getAsCharacter() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
public BigDecimal getAsBigDecimal() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
public BigInteger getAsBigInteger() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
public short getAsShort() {
throw new UnsupportedOperationException(getClass().getSimpleName());
}
public String toString() {
try {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
jsonWriter.setLenient(true);
Streams.write(this, jsonWriter);
return stringWriter.toString();
} catch (IOException e) {
throw new AssertionError(e);
}
}
}

View file

@ -0,0 +1,17 @@
package com.google.gson;
public final class JsonIOException extends JsonParseException {
private static final long serialVersionUID = 1L;
public JsonIOException(String msg) {
super(msg);
}
public JsonIOException(String msg, Throwable cause) {
super(msg, cause);
}
public JsonIOException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,17 @@
package com.google.gson;
public final class JsonNull extends JsonElement {
public static final JsonNull INSTANCE = new JsonNull();
JsonNull deepCopy() {
return INSTANCE;
}
public int hashCode() {
return JsonNull.class.hashCode();
}
public boolean equals(Object other) {
return (this == other || other instanceof JsonNull);
}
}

View file

@ -0,0 +1,78 @@
package com.google.gson;
import com.google.gson.internal.LinkedTreeMap;
import java.util.Map;
import java.util.Set;
public final class JsonObject extends JsonElement {
private final LinkedTreeMap<String, JsonElement> members = new LinkedTreeMap<String, JsonElement>();
JsonObject deepCopy() {
JsonObject result = new JsonObject();
for (Map.Entry<String, JsonElement> entry : this.members.entrySet())
result.add(entry.getKey(), entry.getValue().deepCopy());
return result;
}
public void add(String property, JsonElement value) {
if (value == null)
value = JsonNull.INSTANCE;
this.members.put(property, value);
}
public JsonElement remove(String property) {
return this.members.remove(property);
}
public void addProperty(String property, String value) {
add(property, createJsonElement(value));
}
public void addProperty(String property, Number value) {
add(property, createJsonElement(value));
}
public void addProperty(String property, Boolean value) {
add(property, createJsonElement(value));
}
public void addProperty(String property, Character value) {
add(property, createJsonElement(value));
}
private JsonElement createJsonElement(Object value) {
return (value == null) ? JsonNull.INSTANCE : new JsonPrimitive(value);
}
public Set<Map.Entry<String, JsonElement>> entrySet() {
return this.members.entrySet();
}
public boolean has(String memberName) {
return this.members.containsKey(memberName);
}
public JsonElement get(String memberName) {
return this.members.get(memberName);
}
public JsonPrimitive getAsJsonPrimitive(String memberName) {
return (JsonPrimitive)this.members.get(memberName);
}
public JsonArray getAsJsonArray(String memberName) {
return (JsonArray)this.members.get(memberName);
}
public JsonObject getAsJsonObject(String memberName) {
return (JsonObject)this.members.get(memberName);
}
public boolean equals(Object o) {
return (o == this || (o instanceof JsonObject && ((JsonObject)o).members.equals(this.members)));
}
public int hashCode() {
return this.members.hashCode();
}
}

View file

@ -0,0 +1,17 @@
package com.google.gson;
public class JsonParseException extends RuntimeException {
static final long serialVersionUID = -4086729973971783390L;
public JsonParseException(String msg) {
super(msg);
}
public JsonParseException(String msg, Throwable cause) {
super(msg, cause);
}
public JsonParseException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,45 @@
package com.google.gson;
import com.google.gson.internal.Streams;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.MalformedJsonException;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
public final class JsonParser {
public JsonElement parse(String json) throws JsonSyntaxException {
return parse(new StringReader(json));
}
public JsonElement parse(Reader json) throws JsonIOException, JsonSyntaxException {
try {
JsonReader jsonReader = new JsonReader(json);
JsonElement element = parse(jsonReader);
if (!element.isJsonNull() && jsonReader.peek() != JsonToken.END_DOCUMENT)
throw new JsonSyntaxException("Did not consume the entire document.");
return element;
} catch (MalformedJsonException e) {
throw new JsonSyntaxException(e);
} catch (IOException e) {
throw new JsonIOException(e);
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
public JsonElement parse(JsonReader json) throws JsonIOException, JsonSyntaxException {
boolean lenient = json.isLenient();
json.setLenient(true);
try {
return Streams.parse(json);
} catch (StackOverflowError e) {
throw new JsonParseException("Failed parsing JSON source: " + json + " to Json", e);
} catch (OutOfMemoryError e) {
throw new JsonParseException("Failed parsing JSON source: " + json + " to Json", e);
} finally {
json.setLenient(lenient);
}
}
}

View file

@ -0,0 +1,169 @@
package com.google.gson;
import com.google.gson.internal.$Gson$Preconditions;
import com.google.gson.internal.LazilyParsedNumber;
import java.math.BigDecimal;
import java.math.BigInteger;
public final class JsonPrimitive extends JsonElement {
private static final Class<?>[] PRIMITIVE_TYPES = new Class<?>[] {
int.class, long.class, short.class, float.class, double.class, byte.class, boolean.class, char.class, Integer.class, Long.class,
Short.class, Float.class, Double.class, Byte.class, Boolean.class, Character.class };
private Object value;
public JsonPrimitive(Boolean bool) {
setValue(bool);
}
public JsonPrimitive(Number number) {
setValue(number);
}
public JsonPrimitive(String string) {
setValue(string);
}
public JsonPrimitive(Character c) {
setValue(c);
}
JsonPrimitive(Object primitive) {
setValue(primitive);
}
JsonPrimitive deepCopy() {
return this;
}
void setValue(Object primitive) {
if (primitive instanceof Character) {
char c = (Character)primitive;
this.value = String.valueOf(c);
} else {
$Gson$Preconditions.checkArgument((primitive instanceof Number || isPrimitiveOrString(primitive)));
this.value = primitive;
}
}
public boolean isBoolean() {
return this.value instanceof Boolean;
}
Boolean getAsBooleanWrapper() {
return (Boolean)this.value;
}
public boolean getAsBoolean() {
if (isBoolean())
return getAsBooleanWrapper();
return Boolean.parseBoolean(getAsString());
}
public boolean isNumber() {
return this.value instanceof Number;
}
public Number getAsNumber() {
return (this.value instanceof String) ? new LazilyParsedNumber((String)this.value) : (Number)this.value;
}
public boolean isString() {
return this.value instanceof String;
}
public String getAsString() {
if (isNumber())
return getAsNumber().toString();
if (isBoolean())
return getAsBooleanWrapper().toString();
return (String)this.value;
}
public double getAsDouble() {
return isNumber() ? getAsNumber().doubleValue() : Double.parseDouble(getAsString());
}
public BigDecimal getAsBigDecimal() {
return (this.value instanceof BigDecimal) ? (BigDecimal)this.value : new BigDecimal(this.value.toString());
}
public BigInteger getAsBigInteger() {
return (this.value instanceof BigInteger) ? (BigInteger)this.value : new BigInteger(this.value.toString());
}
public float getAsFloat() {
return isNumber() ? getAsNumber().floatValue() : Float.parseFloat(getAsString());
}
public long getAsLong() {
return isNumber() ? getAsNumber().longValue() : Long.parseLong(getAsString());
}
public short getAsShort() {
return isNumber() ? getAsNumber().shortValue() : Short.parseShort(getAsString());
}
public int getAsInt() {
return isNumber() ? getAsNumber().intValue() : Integer.parseInt(getAsString());
}
public byte getAsByte() {
return isNumber() ? getAsNumber().byteValue() : Byte.parseByte(getAsString());
}
public char getAsCharacter() {
return getAsString().charAt(0);
}
private static boolean isPrimitiveOrString(Object target) {
if (target instanceof String)
return true;
Class<?> classOfPrimitive = target.getClass();
for (Class<?> standardPrimitive : PRIMITIVE_TYPES) {
if (standardPrimitive.isAssignableFrom(classOfPrimitive))
return true;
}
return false;
}
public int hashCode() {
if (this.value == null)
return 31;
if (isIntegral(this)) {
long value = getAsNumber().longValue();
return (int)(value ^ value >>> 32L);
}
if (this.value instanceof Number) {
long value = Double.doubleToLongBits(getAsNumber().doubleValue());
return (int)(value ^ value >>> 32L);
}
return this.value.hashCode();
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
JsonPrimitive other = (JsonPrimitive)obj;
if (this.value == null)
return (other.value == null);
if (isIntegral(this) && isIntegral(other))
return (getAsNumber().longValue() == other.getAsNumber().longValue());
if (this.value instanceof Number && other.value instanceof Number) {
double a = getAsNumber().doubleValue();
double b = other.getAsNumber().doubleValue();
return (a == b || (Double.isNaN(a) && Double.isNaN(b)));
}
return this.value.equals(other.value);
}
private static boolean isIntegral(JsonPrimitive primitive) {
if (primitive.value instanceof Number) {
Number number = (Number)primitive.value;
return (number instanceof BigInteger || number instanceof Long || number instanceof Integer || number instanceof Short || number instanceof Byte);
}
return false;
}
}

View file

@ -0,0 +1,9 @@
package com.google.gson;
import java.lang.reflect.Type;
public interface JsonSerializationContext {
JsonElement serialize(Object paramObject);
JsonElement serialize(Object paramObject, Type paramType);
}

View file

@ -0,0 +1,7 @@
package com.google.gson;
import java.lang.reflect.Type;
public interface JsonSerializer<T> {
JsonElement serialize(T paramT, Type paramType, JsonSerializationContext paramJsonSerializationContext);
}

View file

@ -0,0 +1,49 @@
package com.google.gson;
import com.google.gson.internal.Streams;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import java.io.Reader;
import java.io.StringReader;
import java.util.Iterator;
import java.util.NoSuchElementException;
public final class JsonStreamParser implements Iterator<JsonElement> {
private final JsonReader parser;
private final Object lock;
public JsonStreamParser(String json) {
this(new StringReader(json));
}
public JsonStreamParser(Reader reader) {
this.parser = new JsonReader(reader);
this.parser.setLenient(true);
this.lock = new Object();
}
public JsonElement next() throws JsonParseException {
if (!hasNext())
throw new NoSuchElementException();
try {
return Streams.parse(this.parser);
} catch (StackOverflowError e) {
throw new JsonParseException("Failed parsing JSON source to Json", e);
} catch (OutOfMemoryError e) {
throw new JsonParseException("Failed parsing JSON source to Json", e);
} catch (JsonParseException e) {
throw (e.getCause() instanceof java.io.EOFException) ? new NoSuchElementException() : e;
}
}
public boolean hasNext() {
synchronized (this.lock) {
return (this.parser.peek() != JsonToken.END_DOCUMENT);
}
}
public void remove() {
throw new UnsupportedOperationException();
}
}

View file

@ -0,0 +1,17 @@
package com.google.gson;
public final class JsonSyntaxException extends JsonParseException {
private static final long serialVersionUID = 1L;
public JsonSyntaxException(String msg) {
super(msg);
}
public JsonSyntaxException(String msg, Throwable cause) {
super(msg, cause);
}
public JsonSyntaxException(Throwable cause) {
super(cause);
}
}

View file

@ -0,0 +1,16 @@
package com.google.gson;
public enum LongSerializationPolicy {
DEFAULT {
public JsonElement serialize(Long value) {
return new JsonPrimitive(value);
}
},
STRING {
public JsonElement serialize(Long value) {
return new JsonPrimitive(String.valueOf(value));
}
};
public abstract JsonElement serialize(Long paramLong);
}

View file

@ -0,0 +1,96 @@
package com.google.gson;
import com.google.gson.internal.$Gson$Preconditions;
import com.google.gson.internal.Streams;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
final class TreeTypeAdapter<T> extends TypeAdapter<T> {
private final JsonSerializer<T> serializer;
private final JsonDeserializer<T> deserializer;
private final Gson gson;
private final TypeToken<T> typeToken;
private final TypeAdapterFactory skipPast;
private TypeAdapter<T> delegate;
private TreeTypeAdapter(JsonSerializer<T> serializer, JsonDeserializer<T> deserializer, Gson gson, TypeToken<T> typeToken, TypeAdapterFactory skipPast) {
this.serializer = serializer;
this.deserializer = deserializer;
this.gson = gson;
this.typeToken = typeToken;
this.skipPast = skipPast;
}
public T read(JsonReader in) throws IOException {
if (this.deserializer == null)
return delegate().read(in);
JsonElement value = Streams.parse(in);
if (value.isJsonNull())
return null;
return this.deserializer.deserialize(value, this.typeToken.getType(), this.gson.deserializationContext);
}
public void write(JsonWriter out, T value) throws IOException {
if (this.serializer == null) {
delegate().write(out, value);
return;
}
if (value == null) {
out.nullValue();
return;
}
JsonElement tree = this.serializer.serialize(value, this.typeToken.getType(), this.gson.serializationContext);
Streams.write(tree, out);
}
private TypeAdapter<T> delegate() {
TypeAdapter<T> d = this.delegate;
return (d != null) ? d : (this.delegate = this.gson.<T>getDelegateAdapter(this.skipPast, this.typeToken));
}
public static TypeAdapterFactory newFactory(TypeToken<?> exactType, Object typeAdapter) {
return new SingleTypeFactory(typeAdapter, exactType, false, null);
}
public static TypeAdapterFactory newFactoryWithMatchRawType(TypeToken<?> exactType, Object typeAdapter) {
boolean matchRawType = (exactType.getType() == exactType.getRawType());
return new SingleTypeFactory(typeAdapter, exactType, matchRawType, null);
}
public static TypeAdapterFactory newTypeHierarchyFactory(Class<?> hierarchyType, Object typeAdapter) {
return new SingleTypeFactory(typeAdapter, null, false, hierarchyType);
}
private static class SingleTypeFactory implements TypeAdapterFactory {
private final TypeToken<?> exactType;
private final boolean matchRawType;
private final Class<?> hierarchyType;
private final JsonSerializer<?> serializer;
private final JsonDeserializer<?> deserializer;
private SingleTypeFactory(Object typeAdapter, TypeToken<?> exactType, boolean matchRawType, Class<?> hierarchyType) {
this.serializer = (typeAdapter instanceof JsonSerializer) ? (JsonSerializer)typeAdapter : null;
this.deserializer = (typeAdapter instanceof JsonDeserializer) ? (JsonDeserializer)typeAdapter : null;
$Gson$Preconditions.checkArgument((this.serializer != null || this.deserializer != null));
this.exactType = exactType;
this.matchRawType = matchRawType;
this.hierarchyType = hierarchyType;
}
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
boolean matches = (this.exactType != null) ? ((this.exactType.equals(type) || (this.matchRawType && this.exactType.getType() == type.getRawType()))) : this.hierarchyType.isAssignableFrom(type.getRawType());
return matches ? new TreeTypeAdapter<T>(this.serializer, this.deserializer, gson, type, this) : null;
}
}
}

View file

@ -0,0 +1,77 @@
package com.google.gson;
import com.google.gson.internal.bind.JsonTreeReader;
import com.google.gson.internal.bind.JsonTreeWriter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
public abstract class TypeAdapter<T> {
public abstract void write(JsonWriter paramJsonWriter, T paramT) throws IOException;
public final void toJson(Writer out, T value) throws IOException {
JsonWriter writer = new JsonWriter(out);
write(writer, value);
}
public final TypeAdapter<T> nullSafe() {
return new TypeAdapter<T>() {
public void write(JsonWriter out, T value) throws IOException {
if (value == null) {
out.nullValue();
} else {
TypeAdapter.this.write(out, value);
}
}
public T read(JsonReader reader) throws IOException {
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
return null;
}
return TypeAdapter.this.read(reader);
}
};
}
public final String toJson(T value) throws IOException {
StringWriter stringWriter = new StringWriter();
toJson(stringWriter, value);
return stringWriter.toString();
}
public final JsonElement toJsonTree(T value) {
try {
JsonTreeWriter jsonWriter = new JsonTreeWriter();
write(jsonWriter, value);
return jsonWriter.get();
} catch (IOException e) {
throw new JsonIOException(e);
}
}
public abstract T read(JsonReader paramJsonReader) throws IOException;
public final T fromJson(Reader in) throws IOException {
JsonReader reader = new JsonReader(in);
return read(reader);
}
public final T fromJson(String json) throws IOException {
return fromJson(new StringReader(json));
}
public final T fromJsonTree(JsonElement jsonTree) {
try {
JsonReader jsonReader = new JsonTreeReader(jsonTree);
return read(jsonReader);
} catch (IOException e) {
throw new JsonIOException(e);
}
}
}

View file

@ -0,0 +1,7 @@
package com.google.gson;
import com.google.gson.reflect.TypeToken;
public interface TypeAdapterFactory {
<T> TypeAdapter<T> create(Gson paramGson, TypeToken<T> paramTypeToken);
}

View file

@ -0,0 +1,14 @@
package com.google.gson.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Expose {
boolean serialize() default true;
boolean deserialize() default true;
}

View file

@ -0,0 +1,12 @@
package com.google.gson.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface SerializedName {
String value();
}

View file

@ -0,0 +1,12 @@
package com.google.gson.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
public @interface Since {
double value();
}

View file

@ -0,0 +1,12 @@
package com.google.gson.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
public @interface Until {
double value();
}

View file

@ -0,0 +1,163 @@
package com.google.gson.internal;
import com.google.gson.InstanceCreator;
import com.google.gson.JsonIOException;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
public final class ConstructorConstructor {
private final Map<Type, InstanceCreator<?>> instanceCreators;
public ConstructorConstructor(Map<Type, InstanceCreator<?>> instanceCreators) {
this.instanceCreators = instanceCreators;
}
public <T> ObjectConstructor<T> get(TypeToken<T> typeToken) {
final Type type = typeToken.getType();
Class<? super T> rawType = typeToken.getRawType();
final InstanceCreator<T> typeCreator = (InstanceCreator<T>)this.instanceCreators.get(type);
if (typeCreator != null)
return new ObjectConstructor<T>() {
public T construct() {
return typeCreator.createInstance(type);
}
};
final InstanceCreator<T> rawTypeCreator = (InstanceCreator<T>)this.instanceCreators.get(rawType);
if (rawTypeCreator != null)
return new ObjectConstructor<T>() {
public T construct() {
return rawTypeCreator.createInstance(type);
}
};
ObjectConstructor<T> defaultConstructor = newDefaultConstructor(rawType);
if (defaultConstructor != null)
return defaultConstructor;
ObjectConstructor<T> defaultImplementation = newDefaultImplementationConstructor(type, rawType);
if (defaultImplementation != null)
return defaultImplementation;
return newUnsafeAllocator(type, rawType);
}
private <T> ObjectConstructor<T> newDefaultConstructor(Class<? super T> rawType) {
try {
final Constructor<? super T> constructor = rawType.getDeclaredConstructor();
if (!constructor.isAccessible())
constructor.setAccessible(true);
return new ObjectConstructor<T>() {
public T construct() {
try {
Object[] args = null;
return constructor.newInstance(args);
} catch (InstantiationException e) {
throw new RuntimeException("Failed to invoke " + constructor + " with no args", e);
} catch (InvocationTargetException e) {
throw new RuntimeException("Failed to invoke " + constructor + " with no args", e.getTargetException());
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
}
};
} catch (NoSuchMethodException e) {
return null;
}
}
private <T> ObjectConstructor<T> newDefaultImplementationConstructor(final Type type, Class<? super T> rawType) {
if (Collection.class.isAssignableFrom(rawType)) {
if (SortedSet.class.isAssignableFrom(rawType))
return new ObjectConstructor<T>() {
public T construct() {
return (T)new TreeSet();
}
};
if (EnumSet.class.isAssignableFrom(rawType))
return new ObjectConstructor<T>() {
public T construct() {
if (type instanceof ParameterizedType) {
Type elementType = ((ParameterizedType)type).getActualTypeArguments()[0];
if (elementType instanceof Class)
return (T)EnumSet.noneOf((Class<Enum>)elementType);
throw new JsonIOException("Invalid EnumSet type: " + type.toString());
}
throw new JsonIOException("Invalid EnumSet type: " + type.toString());
}
};
if (Set.class.isAssignableFrom(rawType))
return new ObjectConstructor<T>() {
public T construct() {
return (T)new LinkedHashSet();
}
};
if (Queue.class.isAssignableFrom(rawType))
return new ObjectConstructor<T>() {
public T construct() {
return (T)new LinkedList();
}
};
return new ObjectConstructor<T>() {
public T construct() {
return (T)new ArrayList();
}
};
}
if (Map.class.isAssignableFrom(rawType)) {
if (SortedMap.class.isAssignableFrom(rawType))
return new ObjectConstructor<T>() {
public T construct() {
return (T)new TreeMap();
}
};
if (type instanceof ParameterizedType && !String.class.isAssignableFrom(TypeToken.get(((ParameterizedType)type).getActualTypeArguments()[0]).getRawType()))
return new ObjectConstructor<T>() {
public T construct() {
return (T)new LinkedHashMap();
}
};
return new ObjectConstructor<T>() {
public T construct() {
return (T)new LinkedTreeMap();
}
};
}
return null;
}
private <T> ObjectConstructor<T> newUnsafeAllocator(final Type type, final Class<? super T> rawType) {
return new ObjectConstructor<T>() {
private final UnsafeAllocator unsafeAllocator;
{
this.unsafeAllocator = UnsafeAllocator.create();
}
public T construct() {
try {
Object newInstance = this.unsafeAllocator.newInstance(rawType);
return (T)newInstance;
} catch (Exception e) {
throw new RuntimeException("Unable to invoke no-args constructor for " + type + ". " + "Register an InstanceCreator with Gson for this type may fix this problem.", e);
}
}
};
}
public String toString() {
return this.instanceCreators.toString();
}
}

View file

@ -0,0 +1,191 @@
package com.google.gson.internal;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.Since;
import com.google.gson.annotations.Until;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public final class Excluder implements TypeAdapterFactory, Cloneable {
private static final double IGNORE_VERSIONS = -1.0D;
public static final Excluder DEFAULT = new Excluder();
private double version = -1.0D;
private int modifiers = 136;
private boolean serializeInnerClasses = true;
private boolean requireExpose;
private List<ExclusionStrategy> serializationStrategies = Collections.<ExclusionStrategy>emptyList();
private List<ExclusionStrategy> deserializationStrategies = Collections.<ExclusionStrategy>emptyList();
protected Excluder clone() {
try {
return (Excluder)super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
public Excluder withVersion(double ignoreVersionsAfter) {
Excluder result = clone();
result.version = ignoreVersionsAfter;
return result;
}
public Excluder withModifiers(int... modifiers) {
Excluder result = clone();
result.modifiers = 0;
for (int modifier : modifiers)
result.modifiers |= modifier;
return result;
}
public Excluder disableInnerClassSerialization() {
Excluder result = clone();
result.serializeInnerClasses = false;
return result;
}
public Excluder excludeFieldsWithoutExposeAnnotation() {
Excluder result = clone();
result.requireExpose = true;
return result;
}
public Excluder withExclusionStrategy(ExclusionStrategy exclusionStrategy, boolean serialization, boolean deserialization) {
Excluder result = clone();
if (serialization) {
result.serializationStrategies = new ArrayList<ExclusionStrategy>(this.serializationStrategies);
result.serializationStrategies.add(exclusionStrategy);
}
if (deserialization) {
result.deserializationStrategies = new ArrayList<ExclusionStrategy>(this.deserializationStrategies);
result.deserializationStrategies.add(exclusionStrategy);
}
return result;
}
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {
Class<?> rawType = type.getRawType();
final boolean skipSerialize = excludeClass(rawType, true);
final boolean skipDeserialize = excludeClass(rawType, false);
if (!skipSerialize && !skipDeserialize)
return null;
return new TypeAdapter<T>() {
private TypeAdapter<T> delegate;
public T read(JsonReader in) throws IOException {
if (skipDeserialize) {
in.skipValue();
return null;
}
return delegate().read(in);
}
public void write(JsonWriter out, T value) throws IOException {
if (skipSerialize) {
out.nullValue();
return;
}
delegate().write(out, value);
}
private TypeAdapter<T> delegate() {
TypeAdapter<T> d = this.delegate;
return (d != null) ? d : (this.delegate = gson.<T>getDelegateAdapter(Excluder.this, type));
}
};
}
public boolean excludeField(Field field, boolean serialize) {
if ((this.modifiers & field.getModifiers()) != 0)
return true;
if (this.version != -1.0D && !isValidVersion(field.<Since>getAnnotation(Since.class), field.<Until>getAnnotation(Until.class)))
return true;
if (field.isSynthetic())
return true;
if (this.requireExpose) {
Expose annotation = field.<Expose>getAnnotation(Expose.class);
if (annotation == null || (serialize ? !annotation.serialize() : !annotation.deserialize()))
return true;
}
if (!this.serializeInnerClasses && isInnerClass(field.getType()))
return true;
if (isAnonymousOrLocal(field.getType()))
return true;
List<ExclusionStrategy> list = serialize ? this.serializationStrategies : this.deserializationStrategies;
if (!list.isEmpty()) {
FieldAttributes fieldAttributes = new FieldAttributes(field);
for (ExclusionStrategy exclusionStrategy : list) {
if (exclusionStrategy.shouldSkipField(fieldAttributes))
return true;
}
}
return false;
}
public boolean excludeClass(Class<?> clazz, boolean serialize) {
if (this.version != -1.0D && !isValidVersion(clazz.<Since>getAnnotation(Since.class), clazz.<Until>getAnnotation(Until.class)))
return true;
if (!this.serializeInnerClasses && isInnerClass(clazz))
return true;
if (isAnonymousOrLocal(clazz))
return true;
List<ExclusionStrategy> list = serialize ? this.serializationStrategies : this.deserializationStrategies;
for (ExclusionStrategy exclusionStrategy : list) {
if (exclusionStrategy.shouldSkipClass(clazz))
return true;
}
return false;
}
private boolean isAnonymousOrLocal(Class<?> clazz) {
return (!Enum.class.isAssignableFrom(clazz) && (clazz.isAnonymousClass() || clazz.isLocalClass()));
}
private boolean isInnerClass(Class<?> clazz) {
return (clazz.isMemberClass() && !isStatic(clazz));
}
private boolean isStatic(Class<?> clazz) {
return ((clazz.getModifiers() & 0x8) != 0);
}
private boolean isValidVersion(Since since, Until until) {
return (isValidSince(since) && isValidUntil(until));
}
private boolean isValidSince(Since annotation) {
if (annotation != null) {
double annotationVersion = annotation.value();
if (annotationVersion > this.version)
return false;
}
return true;
}
private boolean isValidUntil(Until annotation) {
if (annotation != null) {
double annotationVersion = annotation.value();
if (annotationVersion <= this.version)
return false;
}
return true;
}
}

View file

@ -0,0 +1,10 @@
package com.google.gson.internal;
import com.google.gson.stream.JsonReader;
import java.io.IOException;
public abstract class JsonReaderInternalAccess {
public static JsonReaderInternalAccess INSTANCE;
public abstract void promoteNameToValue(JsonReader paramJsonReader) throws IOException;
}

View file

@ -0,0 +1,48 @@
package com.google.gson.internal;
import java.io.ObjectStreamException;
import java.math.BigDecimal;
public final class LazilyParsedNumber extends Number {
private final String value;
public LazilyParsedNumber(String value) {
this.value = value;
}
public int intValue() {
try {
return Integer.parseInt(this.value);
} catch (NumberFormatException e) {
try {
return (int)Long.parseLong(this.value);
} catch (NumberFormatException nfe) {
return new BigDecimal(this.value).intValue();
}
}
}
public long longValue() {
try {
return Long.parseLong(this.value);
} catch (NumberFormatException e) {
return new BigDecimal(this.value).longValue();
}
}
public float floatValue() {
return Float.parseFloat(this.value);
}
public double doubleValue() {
return Double.parseDouble(this.value);
}
public String toString() {
return this.value;
}
private Object writeReplace() throws ObjectStreamException {
return new BigDecimal(this.value);
}
}

View file

@ -0,0 +1,471 @@
package com.google.gson.internal;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Comparator;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
public final class LinkedTreeMap<K, V> extends AbstractMap<K, V> implements Serializable {
private static final Comparator<Comparable> NATURAL_ORDER = new Comparator<Comparable>() {
public int compare(Comparable a, Comparable b) {
return a.compareTo(b);
}
};
Comparator<? super K> comparator;
Node<K, V> root;
int size = 0;
int modCount = 0;
final Node<K, V> header = new Node<K, V>();
private EntrySet entrySet;
private KeySet keySet;
public LinkedTreeMap() {
this(NATURAL_ORDER);
}
public LinkedTreeMap(Comparator<? super K> comparator) {
this.comparator = (comparator != null) ? comparator : NATURAL_ORDER;
}
public int size() {
return this.size;
}
public V get(Object key) {
Node<K, V> node = findByObject(key);
return (node != null) ? node.value : null;
}
public boolean containsKey(Object key) {
return (findByObject(key) != null);
}
public V put(K key, V value) {
if (key == null)
throw new NullPointerException("key == null");
Node<K, V> created = find(key, true);
V result = created.value;
created.value = value;
return result;
}
public void clear() {
this.root = null;
this.size = 0;
this.modCount++;
Node<K, V> header = this.header;
header.next = header.prev = header;
}
public V remove(Object key) {
Node<K, V> node = removeInternalByKey(key);
return (node != null) ? node.value : null;
}
Node<K, V> find(K key, boolean create) {
Node<K, V> created;
Comparator<? super K> comparator = this.comparator;
Node<K, V> nearest = this.root;
int comparison = 0;
if (nearest != null) {
Comparable<Object> comparableKey = (comparator == NATURAL_ORDER) ? (Comparable<Object>)key : null;
while (true) {
comparison = (comparableKey != null) ? comparableKey.compareTo(nearest.key) : comparator.compare(key, nearest.key);
if (comparison == 0)
return nearest;
Node<K, V> child = (comparison < 0) ? nearest.left : nearest.right;
if (child == null)
break;
nearest = child;
}
}
if (!create)
return null;
Node<K, V> header = this.header;
if (nearest == null) {
if (comparator == NATURAL_ORDER && !(key instanceof Comparable))
throw new ClassCastException(key.getClass().getName() + " is not Comparable");
created = new Node<K, V>(nearest, key, header, header.prev);
this.root = created;
} else {
created = new Node<K, V>(nearest, key, header, header.prev);
if (comparison < 0) {
nearest.left = created;
} else {
nearest.right = created;
}
rebalance(nearest, true);
}
this.size++;
this.modCount++;
return created;
}
Node<K, V> findByObject(Object key) {
try {
return (key != null) ? find((K)key, false) : null;
} catch (ClassCastException e) {
return null;
}
}
Node<K, V> findByEntry(Map.Entry<?, ?> entry) {
Node<K, V> mine = findByObject(entry.getKey());
boolean valuesEqual = (mine != null && equal(mine.value, entry.getValue()));
return valuesEqual ? mine : null;
}
private boolean equal(Object a, Object b) {
return (a == b || (a != null && a.equals(b)));
}
void removeInternal(Node<K, V> node, boolean unlink) {
if (unlink) {
node.prev.next = node.next;
node.next.prev = node.prev;
}
Node<K, V> left = node.left;
Node<K, V> right = node.right;
Node<K, V> originalParent = node.parent;
if (left != null && right != null) {
Node<K, V> adjacent = (left.height > right.height) ? left.last() : right.first();
removeInternal(adjacent, false);
int leftHeight = 0;
left = node.left;
if (left != null) {
leftHeight = left.height;
adjacent.left = left;
left.parent = adjacent;
node.left = null;
}
int rightHeight = 0;
right = node.right;
if (right != null) {
rightHeight = right.height;
adjacent.right = right;
right.parent = adjacent;
node.right = null;
}
adjacent.height = Math.max(leftHeight, rightHeight) + 1;
replaceInParent(node, adjacent);
return;
}
if (left != null) {
replaceInParent(node, left);
node.left = null;
} else if (right != null) {
replaceInParent(node, right);
node.right = null;
} else {
replaceInParent(node, null);
}
rebalance(originalParent, false);
this.size--;
this.modCount++;
}
Node<K, V> removeInternalByKey(Object key) {
Node<K, V> node = findByObject(key);
if (node != null)
removeInternal(node, true);
return node;
}
private void replaceInParent(Node<K, V> node, Node<K, V> replacement) {
Node<K, V> parent = node.parent;
node.parent = null;
if (replacement != null)
replacement.parent = parent;
if (parent != null) {
if (parent.left == node) {
parent.left = replacement;
} else {
assert parent.right == node;
parent.right = replacement;
}
} else {
this.root = replacement;
}
}
private void rebalance(Node<K, V> unbalanced, boolean insert) {
for (Node<K, V> node = unbalanced; node != null; node = node.parent) {
Node<K, V> left = node.left;
Node<K, V> right = node.right;
int leftHeight = (left != null) ? left.height : 0;
int rightHeight = (right != null) ? right.height : 0;
int delta = leftHeight - rightHeight;
if (delta == -2) {
Node<K, V> rightLeft = right.left;
Node<K, V> rightRight = right.right;
int rightRightHeight = (rightRight != null) ? rightRight.height : 0;
int rightLeftHeight = (rightLeft != null) ? rightLeft.height : 0;
int rightDelta = rightLeftHeight - rightRightHeight;
if (rightDelta == -1 || (rightDelta == 0 && !insert)) {
rotateLeft(node);
} else {
assert rightDelta == 1;
rotateRight(right);
rotateLeft(node);
}
if (insert)
break;
} else if (delta == 2) {
Node<K, V> leftLeft = left.left;
Node<K, V> leftRight = left.right;
int leftRightHeight = (leftRight != null) ? leftRight.height : 0;
int leftLeftHeight = (leftLeft != null) ? leftLeft.height : 0;
int leftDelta = leftLeftHeight - leftRightHeight;
if (leftDelta == 1 || (leftDelta == 0 && !insert)) {
rotateRight(node);
} else {
assert leftDelta == -1;
rotateLeft(left);
rotateRight(node);
}
if (insert)
break;
} else if (delta == 0) {
node.height = leftHeight + 1;
if (insert)
break;
} else {
assert delta == -1 || delta == 1;
node.height = Math.max(leftHeight, rightHeight) + 1;
if (!insert)
break;
}
}
}
private void rotateLeft(Node<K, V> root) {
Node<K, V> left = root.left;
Node<K, V> pivot = root.right;
Node<K, V> pivotLeft = pivot.left;
Node<K, V> pivotRight = pivot.right;
root.right = pivotLeft;
if (pivotLeft != null)
pivotLeft.parent = root;
replaceInParent(root, pivot);
pivot.left = root;
root.parent = pivot;
root.height = Math.max((left != null) ? left.height : 0, (pivotLeft != null) ? pivotLeft.height : 0) + 1;
pivot.height = Math.max(root.height, (pivotRight != null) ? pivotRight.height : 0) + 1;
}
private void rotateRight(Node<K, V> root) {
Node<K, V> pivot = root.left;
Node<K, V> right = root.right;
Node<K, V> pivotLeft = pivot.left;
Node<K, V> pivotRight = pivot.right;
root.left = pivotRight;
if (pivotRight != null)
pivotRight.parent = root;
replaceInParent(root, pivot);
pivot.right = root;
root.parent = pivot;
root.height = Math.max((right != null) ? right.height : 0, (pivotRight != null) ? pivotRight.height : 0) + 1;
pivot.height = Math.max(root.height, (pivotLeft != null) ? pivotLeft.height : 0) + 1;
}
public Set<Map.Entry<K, V>> entrySet() {
EntrySet result = this.entrySet;
return (result != null) ? result : (this.entrySet = new EntrySet());
}
public Set<K> keySet() {
KeySet result = this.keySet;
return (result != null) ? result : (this.keySet = new KeySet());
}
static final class Node<K, V> implements Map.Entry<K, V> {
Node<K, V> parent;
Node<K, V> left;
Node<K, V> right;
Node<K, V> next;
Node<K, V> prev;
final K key;
V value;
int height;
Node() {
this.key = null;
this.next = this.prev = this;
}
Node(Node<K, V> parent, K key, Node<K, V> next, Node<K, V> prev) {
this.parent = parent;
this.key = key;
this.height = 1;
this.next = next;
this.prev = prev;
prev.next = this;
next.prev = this;
}
public K getKey() {
return this.key;
}
public V getValue() {
return this.value;
}
public V setValue(V value) {
V oldValue = this.value;
this.value = value;
return oldValue;
}
public boolean equals(Object o) {
if (o instanceof Map.Entry) {
Map.Entry other = (Map.Entry)o;
return (((this.key == null) ? (other.getKey() == null) : this.key.equals(other.getKey())) && ((this.value == null) ? (other.getValue() == null) : this.value.equals(other.getValue())));
}
return false;
}
public int hashCode() {
return ((this.key == null) ? 0 : this.key.hashCode()) ^ ((this.value == null) ? 0 : this.value.hashCode());
}
public String toString() {
return new StringBuilder().append(this.key).append("=").append(this.value).toString();
}
public Node<K, V> first() {
Node<K, V> node = this;
Node<K, V> child = node.left;
while (child != null) {
node = child;
child = node.left;
}
return node;
}
public Node<K, V> last() {
Node<K, V> node = this;
Node<K, V> child = node.right;
while (child != null) {
node = child;
child = node.right;
}
return node;
}
}
private abstract class LinkedTreeMapIterator<T> implements Iterator<T> {
LinkedTreeMap.Node<K, V> next = LinkedTreeMap.this.header.next;
LinkedTreeMap.Node<K, V> lastReturned = null;
int expectedModCount = LinkedTreeMap.this.modCount;
public final boolean hasNext() {
return (this.next != LinkedTreeMap.this.header);
}
final LinkedTreeMap.Node<K, V> nextNode() {
LinkedTreeMap.Node<K, V> e = this.next;
if (e == LinkedTreeMap.this.header)
throw new NoSuchElementException();
if (LinkedTreeMap.this.modCount != this.expectedModCount)
throw new ConcurrentModificationException();
this.next = e.next;
return this.lastReturned = e;
}
public final void remove() {
if (this.lastReturned == null)
throw new IllegalStateException();
LinkedTreeMap.this.removeInternal(this.lastReturned, true);
this.lastReturned = null;
this.expectedModCount = LinkedTreeMap.this.modCount;
}
private LinkedTreeMapIterator() {}
}
class EntrySet extends AbstractSet<Map.Entry<K, V>> {
public int size() {
return LinkedTreeMap.this.size;
}
public Iterator<Map.Entry<K, V>> iterator() {
return new LinkedTreeMap<K, V>.LinkedTreeMapIterator<Map.Entry<K, V>>() {
public Map.Entry<K, V> next() {
return nextNode();
}
};
}
public boolean contains(Object o) {
return (o instanceof Map.Entry && LinkedTreeMap.this.findByEntry((Map.Entry<?, ?>)o) != null);
}
public boolean remove(Object o) {
if (!(o instanceof Map.Entry))
return false;
LinkedTreeMap.Node<K, V> node = LinkedTreeMap.this.findByEntry((Map.Entry<?, ?>)o);
if (node == null)
return false;
LinkedTreeMap.this.removeInternal(node, true);
return true;
}
public void clear() {
LinkedTreeMap.this.clear();
}
}
class KeySet extends AbstractSet<K> {
public int size() {
return LinkedTreeMap.this.size;
}
public Iterator<K> iterator() {
return new LinkedTreeMap<K, V>.LinkedTreeMapIterator<K>() {
public K next() {
return (nextNode()).key;
}
};
}
public boolean contains(Object o) {
return LinkedTreeMap.this.containsKey(o);
}
public boolean remove(Object key) {
return (LinkedTreeMap.this.removeInternalByKey(key) != null);
}
public void clear() {
LinkedTreeMap.this.clear();
}
}
private Object writeReplace() throws ObjectStreamException {
return new LinkedHashMap<K, V>(this);
}
}

View file

@ -0,0 +1,5 @@
package com.google.gson.internal;
public interface ObjectConstructor<T> {
T construct();
}

View file

@ -0,0 +1,51 @@
package com.google.gson.internal;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public final class Primitives {
private static final Map<Class<?>, Class<?>> PRIMITIVE_TO_WRAPPER_TYPE;
private static final Map<Class<?>, Class<?>> WRAPPER_TO_PRIMITIVE_TYPE;
static {
Map<Class<?>, Class<?>> primToWrap = new HashMap<Class<?>, Class<?>>(16);
Map<Class<?>, Class<?>> wrapToPrim = new HashMap<Class<?>, Class<?>>(16);
add(primToWrap, wrapToPrim, boolean.class, Boolean.class);
add(primToWrap, wrapToPrim, byte.class, Byte.class);
add(primToWrap, wrapToPrim, char.class, Character.class);
add(primToWrap, wrapToPrim, double.class, Double.class);
add(primToWrap, wrapToPrim, float.class, Float.class);
add(primToWrap, wrapToPrim, int.class, Integer.class);
add(primToWrap, wrapToPrim, long.class, Long.class);
add(primToWrap, wrapToPrim, short.class, Short.class);
add(primToWrap, wrapToPrim, void.class, Void.class);
PRIMITIVE_TO_WRAPPER_TYPE = Collections.<Class<?>, Class<?>>unmodifiableMap(primToWrap);
WRAPPER_TO_PRIMITIVE_TYPE = Collections.<Class<?>, Class<?>>unmodifiableMap(wrapToPrim);
}
private static void add(Map<Class<?>, Class<?>> forward, Map<Class<?>, Class<?>> backward, Class<?> key, Class<?> value) {
forward.put(key, value);
backward.put(value, key);
}
public static boolean isPrimitive(Type type) {
return PRIMITIVE_TO_WRAPPER_TYPE.containsKey(type);
}
public static boolean isWrapperType(Type type) {
return WRAPPER_TO_PRIMITIVE_TYPE.containsKey($Gson$Preconditions.<Type>checkNotNull(type));
}
public static <T> Class<T> wrap(Class<T> type) {
Class<T> wrapped = (Class<T>)PRIMITIVE_TO_WRAPPER_TYPE.get($Gson$Preconditions.<Class<T>>checkNotNull(type));
return (wrapped == null) ? type : wrapped;
}
public static <T> Class<T> unwrap(Class<T> type) {
Class<T> unwrapped = (Class<T>)WRAPPER_TO_PRIMITIVE_TYPE.get($Gson$Preconditions.<Class<T>>checkNotNull(type));
return (unwrapped == null) ? type : unwrapped;
}
}

View file

@ -0,0 +1,82 @@
package com.google.gson.internal;
import com.google.gson.JsonElement;
import com.google.gson.JsonIOException;
import com.google.gson.JsonNull;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSyntaxException;
import com.google.gson.internal.bind.TypeAdapters;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import com.google.gson.stream.MalformedJsonException;
import java.io.EOFException;
import java.io.IOException;
import java.io.Writer;
public final class Streams {
public static JsonElement parse(JsonReader reader) throws JsonParseException {
boolean isEmpty = true;
try {
reader.peek();
isEmpty = false;
return TypeAdapters.JSON_ELEMENT.read(reader);
} catch (EOFException e) {
if (isEmpty)
return JsonNull.INSTANCE;
throw new JsonSyntaxException(e);
} catch (MalformedJsonException e) {
throw new JsonSyntaxException(e);
} catch (IOException e) {
throw new JsonIOException(e);
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
public static void write(JsonElement element, JsonWriter writer) throws IOException {
TypeAdapters.JSON_ELEMENT.write(writer, element);
}
public static Writer writerForAppendable(Appendable appendable) {
return (appendable instanceof Writer) ? (Writer)appendable : new AppendableWriter(appendable);
}
private static final class AppendableWriter extends Writer {
private final Appendable appendable;
private final CurrentWrite currentWrite = new CurrentWrite();
private AppendableWriter(Appendable appendable) {
this.appendable = appendable;
}
public void write(char[] chars, int offset, int length) throws IOException {
this.currentWrite.chars = chars;
this.appendable.append(this.currentWrite, offset, offset + length);
}
public void write(int i) throws IOException {
this.appendable.append((char)i);
}
public void flush() {}
public void close() {}
static class CurrentWrite implements CharSequence {
char[] chars;
public int length() {
return this.chars.length;
}
public char charAt(int i) {
return this.chars[i];
}
public CharSequence subSequence(int start, int end) {
return new String(this.chars, start, end - start);
}
}
}
}

View file

@ -0,0 +1,54 @@
package com.google.gson.internal;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public abstract class UnsafeAllocator {
public abstract <T> T newInstance(Class<T> paramClass) throws Exception;
public static UnsafeAllocator create() {
try {
Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
Field f = unsafeClass.getDeclaredField("theUnsafe");
f.setAccessible(true);
final Object unsafe = f.get(null);
final Method allocateInstance = unsafeClass.getMethod("allocateInstance", Class.class);
return new UnsafeAllocator() {
public <T> T newInstance(Class<T> c) throws Exception {
return (T)allocateInstance.invoke(unsafe, c);
}
};
} catch (Exception ignored) {
try {
final Method newInstance = ObjectInputStream.class.getDeclaredMethod("newInstance", Class.class, Class.class);
newInstance.setAccessible(true);
return new UnsafeAllocator() {
public <T> T newInstance(Class<T> c) throws Exception {
return (T)newInstance.invoke(null, c, Object.class);
}
};
} catch (Exception exception) {
try {
Method getConstructorId = ObjectStreamClass.class.getDeclaredMethod("getConstructorId", Class.class);
getConstructorId.setAccessible(true);
final int constructorId = (Integer)getConstructorId.invoke(null, Object.class);
final Method newInstance = ObjectStreamClass.class.getDeclaredMethod("newInstance", Class.class, int.class);
newInstance.setAccessible(true);
return new UnsafeAllocator() {
public <T> T newInstance(Class<T> c) throws Exception {
return (T)newInstance.invoke(null, c, constructorId);
}
};
} catch (Exception exception1) {
return new UnsafeAllocator() {
public <T> T newInstance(Class<T> c) {
throw new UnsupportedOperationException("Cannot allocate " + c);
}
};
}
}
}
}
}

View file

@ -0,0 +1,68 @@
package com.google.gson.internal.bind;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.internal.$Gson$Types;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
public final class ArrayTypeAdapter<E> extends TypeAdapter<Object> {
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Type type = typeToken.getType();
if (!(type instanceof java.lang.reflect.GenericArrayType) && (!(type instanceof Class) || !((Class)type).isArray()))
return null;
Type componentType = $Gson$Types.getArrayComponentType(type);
TypeAdapter<?> componentTypeAdapter = gson.getAdapter(TypeToken.get(componentType));
return new ArrayTypeAdapter(gson, componentTypeAdapter, $Gson$Types.getRawType(componentType));
}
};
private final Class<E> componentType;
private final TypeAdapter<E> componentTypeAdapter;
public ArrayTypeAdapter(Gson context, TypeAdapter<E> componentTypeAdapter, Class<E> componentType) {
this.componentTypeAdapter = new TypeAdapterRuntimeTypeWrapper<E>(context, componentTypeAdapter, componentType);
this.componentType = componentType;
}
public Object read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
List<E> list = new ArrayList<E>();
in.beginArray();
while (in.hasNext()) {
E instance = this.componentTypeAdapter.read(in);
list.add(instance);
}
in.endArray();
Object array = Array.newInstance(this.componentType, list.size());
for (int i = 0; i < list.size(); i++)
Array.set(array, i, list.get(i));
return array;
}
public void write(JsonWriter out, Object array) throws IOException {
if (array == null) {
out.nullValue();
return;
}
out.beginArray();
for (int i = 0, length = Array.getLength(array); i < length; i++) {
E value = (E)Array.get(array, i);
this.componentTypeAdapter.write(out, value);
}
out.endArray();
}
}

View file

@ -0,0 +1,72 @@
package com.google.gson.internal.bind;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.internal.$Gson$Types;
import com.google.gson.internal.ConstructorConstructor;
import com.google.gson.internal.ObjectConstructor;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Collection;
public final class CollectionTypeAdapterFactory implements TypeAdapterFactory {
private final ConstructorConstructor constructorConstructor;
public CollectionTypeAdapterFactory(ConstructorConstructor constructorConstructor) {
this.constructorConstructor = constructorConstructor;
}
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Type type = typeToken.getType();
Class<? super T> rawType = typeToken.getRawType();
if (!Collection.class.isAssignableFrom(rawType))
return null;
Type elementType = $Gson$Types.getCollectionElementType(type, rawType);
TypeAdapter<?> elementTypeAdapter = gson.getAdapter(TypeToken.get(elementType));
ObjectConstructor<T> constructor = this.constructorConstructor.<T>get(typeToken);
TypeAdapter<T> result = new Adapter(gson, elementType, elementTypeAdapter, (ObjectConstructor)constructor);
return result;
}
private static final class Adapter<E> extends TypeAdapter<Collection<E>> {
private final TypeAdapter<E> elementTypeAdapter;
private final ObjectConstructor<? extends Collection<E>> constructor;
public Adapter(Gson context, Type elementType, TypeAdapter<E> elementTypeAdapter, ObjectConstructor<? extends Collection<E>> constructor) {
this.elementTypeAdapter = new TypeAdapterRuntimeTypeWrapper<E>(context, elementTypeAdapter, elementType);
this.constructor = constructor;
}
public Collection<E> read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
Collection<E> collection = this.constructor.construct();
in.beginArray();
while (in.hasNext()) {
E instance = this.elementTypeAdapter.read(in);
collection.add(instance);
}
in.endArray();
return collection;
}
public void write(JsonWriter out, Collection<E> collection) throws IOException {
if (collection == null) {
out.nullValue();
return;
}
out.beginArray();
for (E element : (Iterable<E>)collection)
this.elementTypeAdapter.write(out, element);
out.endArray();
}
}
}

View file

@ -0,0 +1,70 @@
package com.google.gson.internal.bind;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public final class DateTypeAdapter extends TypeAdapter<Date> {
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
return (typeToken.getRawType() == Date.class) ? new DateTypeAdapter() : null;
}
};
private final DateFormat enUsFormat = DateFormat.getDateTimeInstance(2, 2, Locale.US);
private final DateFormat localFormat = DateFormat.getDateTimeInstance(2, 2);
private final DateFormat iso8601Format = buildIso8601Format();
private static DateFormat buildIso8601Format() {
DateFormat iso8601Format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC"));
return iso8601Format;
}
public Date read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
return deserializeToDate(in.nextString());
}
private synchronized Date deserializeToDate(String json) {
try {
return this.localFormat.parse(json);
} catch (ParseException ignored) {
try {
return this.enUsFormat.parse(json);
} catch (ParseException parseException) {
try {
return this.iso8601Format.parse(json);
} catch (ParseException e) {
throw new JsonSyntaxException(json, e);
}
}
}
}
public synchronized void write(JsonWriter out, Date value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
String dateFormatAsString = this.enUsFormat.format(value);
out.value(dateFormatAsString);
}
}

View file

@ -0,0 +1,192 @@
package com.google.gson.internal.bind;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public final class JsonTreeReader extends JsonReader {
private static final Reader UNREADABLE_READER = new Reader() {
public int read(char[] buffer, int offset, int count) throws IOException {
throw new AssertionError();
}
public void close() throws IOException {
throw new AssertionError();
}
};
private static final Object SENTINEL_CLOSED = new Object();
private final List<Object> stack = new ArrayList();
public JsonTreeReader(JsonElement element) {
super(UNREADABLE_READER);
this.stack.add(element);
}
public void beginArray() throws IOException {
expect(JsonToken.BEGIN_ARRAY);
JsonArray array = (JsonArray)peekStack();
this.stack.add(array.iterator());
}
public void endArray() throws IOException {
expect(JsonToken.END_ARRAY);
popStack();
popStack();
}
public void beginObject() throws IOException {
expect(JsonToken.BEGIN_OBJECT);
JsonObject object = (JsonObject)peekStack();
this.stack.add(object.entrySet().iterator());
}
public void endObject() throws IOException {
expect(JsonToken.END_OBJECT);
popStack();
popStack();
}
public boolean hasNext() throws IOException {
JsonToken token = peek();
return (token != JsonToken.END_OBJECT && token != JsonToken.END_ARRAY);
}
public JsonToken peek() throws IOException {
if (this.stack.isEmpty())
return JsonToken.END_DOCUMENT;
Object o = peekStack();
if (o instanceof Iterator) {
boolean isObject = this.stack.get(this.stack.size() - 2) instanceof JsonObject;
Iterator<?> iterator = (Iterator)o;
if (iterator.hasNext()) {
if (isObject)
return JsonToken.NAME;
this.stack.add(iterator.next());
return peek();
}
return isObject ? JsonToken.END_OBJECT : JsonToken.END_ARRAY;
}
if (o instanceof JsonObject)
return JsonToken.BEGIN_OBJECT;
if (o instanceof JsonArray)
return JsonToken.BEGIN_ARRAY;
if (o instanceof JsonPrimitive) {
JsonPrimitive primitive = (JsonPrimitive)o;
if (primitive.isString())
return JsonToken.STRING;
if (primitive.isBoolean())
return JsonToken.BOOLEAN;
if (primitive.isNumber())
return JsonToken.NUMBER;
throw new AssertionError();
}
if (o instanceof com.google.gson.JsonNull)
return JsonToken.NULL;
if (o == SENTINEL_CLOSED)
throw new IllegalStateException("JsonReader is closed");
throw new AssertionError();
}
private Object peekStack() {
return this.stack.get(this.stack.size() - 1);
}
private Object popStack() {
return this.stack.remove(this.stack.size() - 1);
}
private void expect(JsonToken expected) throws IOException {
if (peek() != expected)
throw new IllegalStateException("Expected " + expected + " but was " + peek());
}
public String nextName() throws IOException {
expect(JsonToken.NAME);
Iterator<?> i = (Iterator)peekStack();
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)i.next();
this.stack.add(entry.getValue());
return (String)entry.getKey();
}
public String nextString() throws IOException {
JsonToken token = peek();
if (token != JsonToken.STRING && token != JsonToken.NUMBER)
throw new IllegalStateException("Expected " + JsonToken.STRING + " but was " + token);
return ((JsonPrimitive)popStack()).getAsString();
}
public boolean nextBoolean() throws IOException {
expect(JsonToken.BOOLEAN);
return ((JsonPrimitive)popStack()).getAsBoolean();
}
public void nextNull() throws IOException {
expect(JsonToken.NULL);
popStack();
}
public double nextDouble() throws IOException {
JsonToken token = peek();
if (token != JsonToken.NUMBER && token != JsonToken.STRING)
throw new IllegalStateException("Expected " + JsonToken.NUMBER + " but was " + token);
double result = ((JsonPrimitive)peekStack()).getAsDouble();
if (!isLenient() && (Double.isNaN(result) || Double.isInfinite(result)))
throw new NumberFormatException("JSON forbids NaN and infinities: " + result);
popStack();
return result;
}
public long nextLong() throws IOException {
JsonToken token = peek();
if (token != JsonToken.NUMBER && token != JsonToken.STRING)
throw new IllegalStateException("Expected " + JsonToken.NUMBER + " but was " + token);
long result = ((JsonPrimitive)peekStack()).getAsLong();
popStack();
return result;
}
public int nextInt() throws IOException {
JsonToken token = peek();
if (token != JsonToken.NUMBER && token != JsonToken.STRING)
throw new IllegalStateException("Expected " + JsonToken.NUMBER + " but was " + token);
int result = ((JsonPrimitive)peekStack()).getAsInt();
popStack();
return result;
}
public void close() throws IOException {
this.stack.clear();
this.stack.add(SENTINEL_CLOSED);
}
public void skipValue() throws IOException {
if (peek() == JsonToken.NAME) {
nextName();
} else {
popStack();
}
}
public String toString() {
return getClass().getSimpleName();
}
public void promoteNameToValue() throws IOException {
expect(JsonToken.NAME);
Iterator<?> i = (Iterator)peekStack();
Map.Entry<?, ?> entry = (Map.Entry<?, ?>)i.next();
this.stack.add(entry.getValue());
this.stack.add(new JsonPrimitive((String)entry.getKey()));
}
}

View file

@ -0,0 +1,165 @@
package com.google.gson.internal.bind;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
public final class JsonTreeWriter extends JsonWriter {
private static final Writer UNWRITABLE_WRITER = new Writer() {
public void write(char[] buffer, int offset, int counter) {
throw new AssertionError();
}
public void flush() throws IOException {
throw new AssertionError();
}
public void close() throws IOException {
throw new AssertionError();
}
};
private static final JsonPrimitive SENTINEL_CLOSED = new JsonPrimitive("closed");
private final List<JsonElement> stack = new ArrayList<JsonElement>();
private String pendingName;
private JsonElement product = JsonNull.INSTANCE;
public JsonTreeWriter() {
super(UNWRITABLE_WRITER);
}
public JsonElement get() {
if (!this.stack.isEmpty())
throw new IllegalStateException("Expected one JSON element but was " + this.stack);
return this.product;
}
private JsonElement peek() {
return this.stack.get(this.stack.size() - 1);
}
private void put(JsonElement value) {
if (this.pendingName != null) {
if (!value.isJsonNull() || getSerializeNulls()) {
JsonObject object = (JsonObject)peek();
object.add(this.pendingName, value);
}
this.pendingName = null;
} else if (this.stack.isEmpty()) {
this.product = value;
} else {
JsonElement element = peek();
if (element instanceof JsonArray) {
((JsonArray)element).add(value);
} else {
throw new IllegalStateException();
}
}
}
public JsonWriter beginArray() throws IOException {
JsonArray array = new JsonArray();
put(array);
this.stack.add(array);
return this;
}
public JsonWriter endArray() throws IOException {
if (this.stack.isEmpty() || this.pendingName != null)
throw new IllegalStateException();
JsonElement element = peek();
if (element instanceof JsonArray) {
this.stack.remove(this.stack.size() - 1);
return this;
}
throw new IllegalStateException();
}
public JsonWriter beginObject() throws IOException {
JsonObject object = new JsonObject();
put(object);
this.stack.add(object);
return this;
}
public JsonWriter endObject() throws IOException {
if (this.stack.isEmpty() || this.pendingName != null)
throw new IllegalStateException();
JsonElement element = peek();
if (element instanceof JsonObject) {
this.stack.remove(this.stack.size() - 1);
return this;
}
throw new IllegalStateException();
}
public JsonWriter name(String name) throws IOException {
if (this.stack.isEmpty() || this.pendingName != null)
throw new IllegalStateException();
JsonElement element = peek();
if (element instanceof JsonObject) {
this.pendingName = name;
return this;
}
throw new IllegalStateException();
}
public JsonWriter value(String value) throws IOException {
if (value == null)
return nullValue();
put(new JsonPrimitive(value));
return this;
}
public JsonWriter nullValue() throws IOException {
put(JsonNull.INSTANCE);
return this;
}
public JsonWriter value(boolean value) throws IOException {
put(new JsonPrimitive(value));
return this;
}
public JsonWriter value(double value) throws IOException {
if (!isLenient() && (Double.isNaN(value) || Double.isInfinite(value)))
throw new IllegalArgumentException("JSON forbids NaN and infinities: " + value);
put(new JsonPrimitive((Number)value));
return this;
}
public JsonWriter value(long value) throws IOException {
put(new JsonPrimitive((Number)value));
return this;
}
public JsonWriter value(Number value) throws IOException {
if (value == null)
return nullValue();
if (!isLenient()) {
double d = value.doubleValue();
if (Double.isNaN(d) || Double.isInfinite(d))
throw new IllegalArgumentException("JSON forbids NaN and infinities: " + value);
}
put(new JsonPrimitive(value));
return this;
}
public void flush() throws IOException {}
public void close() throws IOException {
if (!this.stack.isEmpty())
throw new IOException("Incomplete document");
this.stack.add(SENTINEL_CLOSED);
}
}

View file

@ -0,0 +1,158 @@
package com.google.gson.internal.bind;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSyntaxException;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.internal.$Gson$Types;
import com.google.gson.internal.ConstructorConstructor;
import com.google.gson.internal.JsonReaderInternalAccess;
import com.google.gson.internal.ObjectConstructor;
import com.google.gson.internal.Streams;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public final class MapTypeAdapterFactory implements TypeAdapterFactory {
private final ConstructorConstructor constructorConstructor;
private final boolean complexMapKeySerialization;
public MapTypeAdapterFactory(ConstructorConstructor constructorConstructor, boolean complexMapKeySerialization) {
this.constructorConstructor = constructorConstructor;
this.complexMapKeySerialization = complexMapKeySerialization;
}
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Type type = typeToken.getType();
Class<? super T> rawType = typeToken.getRawType();
if (!Map.class.isAssignableFrom(rawType))
return null;
Class<?> rawTypeOfSrc = $Gson$Types.getRawType(type);
Type[] keyAndValueTypes = $Gson$Types.getMapKeyAndValueTypes(type, rawTypeOfSrc);
TypeAdapter<?> keyAdapter = getKeyAdapter(gson, keyAndValueTypes[0]);
TypeAdapter<?> valueAdapter = gson.getAdapter(TypeToken.get(keyAndValueTypes[1]));
ObjectConstructor<T> constructor = this.constructorConstructor.<T>get(typeToken);
TypeAdapter<T> result = new Adapter(gson, keyAndValueTypes[0], keyAdapter, keyAndValueTypes[1], valueAdapter, (ObjectConstructor)constructor);
return result;
}
private TypeAdapter<?> getKeyAdapter(Gson context, Type keyType) {
return (keyType == boolean.class || keyType == Boolean.class) ? TypeAdapters.BOOLEAN_AS_STRING : context.getAdapter(TypeToken.get(keyType));
}
private final class Adapter<K, V> extends TypeAdapter<Map<K, V>> {
private final TypeAdapter<K> keyTypeAdapter;
private final TypeAdapter<V> valueTypeAdapter;
private final ObjectConstructor<? extends Map<K, V>> constructor;
public Adapter(Gson context, Type keyType, TypeAdapter<K> keyTypeAdapter, Type valueType, TypeAdapter<V> valueTypeAdapter, ObjectConstructor<? extends Map<K, V>> constructor) {
this.keyTypeAdapter = new TypeAdapterRuntimeTypeWrapper<K>(context, keyTypeAdapter, keyType);
this.valueTypeAdapter = new TypeAdapterRuntimeTypeWrapper<V>(context, valueTypeAdapter, valueType);
this.constructor = constructor;
}
public Map<K, V> read(JsonReader in) throws IOException {
JsonToken peek = in.peek();
if (peek == JsonToken.NULL) {
in.nextNull();
return null;
}
Map<K, V> map = this.constructor.construct();
if (peek == JsonToken.BEGIN_ARRAY) {
in.beginArray();
while (in.hasNext()) {
in.beginArray();
K key = this.keyTypeAdapter.read(in);
V value = this.valueTypeAdapter.read(in);
V replaced = map.put(key, value);
if (replaced != null)
throw new JsonSyntaxException("duplicate key: " + key);
in.endArray();
}
in.endArray();
} else {
in.beginObject();
while (in.hasNext()) {
JsonReaderInternalAccess.INSTANCE.promoteNameToValue(in);
K key = this.keyTypeAdapter.read(in);
V value = this.valueTypeAdapter.read(in);
V replaced = map.put(key, value);
if (replaced != null)
throw new JsonSyntaxException("duplicate key: " + key);
}
in.endObject();
}
return map;
}
public void write(JsonWriter out, Map<K, V> map) throws IOException {
if (map == null) {
out.nullValue();
return;
}
if (!MapTypeAdapterFactory.this.complexMapKeySerialization) {
out.beginObject();
for (Map.Entry<K, V> entry : map.entrySet()) {
out.name(String.valueOf(entry.getKey()));
this.valueTypeAdapter.write(out, entry.getValue());
}
out.endObject();
return;
}
boolean hasComplexKeys = false;
List<JsonElement> keys = new ArrayList<JsonElement>(map.size());
List<V> values = new ArrayList<V>(map.size());
for (Map.Entry<K, V> entry : map.entrySet()) {
JsonElement keyElement = this.keyTypeAdapter.toJsonTree(entry.getKey());
keys.add(keyElement);
values.add(entry.getValue());
hasComplexKeys |= (keyElement.isJsonArray() || keyElement.isJsonObject()) ? true : false;
}
if (hasComplexKeys) {
out.beginArray();
for (int i = 0; i < keys.size(); i++) {
out.beginArray();
Streams.write(keys.get(i), out);
this.valueTypeAdapter.write(out, values.get(i));
out.endArray();
}
out.endArray();
} else {
out.beginObject();
for (int i = 0; i < keys.size(); i++) {
JsonElement keyElement = keys.get(i);
out.name(keyToString(keyElement));
this.valueTypeAdapter.write(out, values.get(i));
}
out.endObject();
}
}
private String keyToString(JsonElement keyElement) {
if (keyElement.isJsonPrimitive()) {
JsonPrimitive primitive = keyElement.getAsJsonPrimitive();
if (primitive.isNumber())
return String.valueOf(primitive.getAsNumber());
if (primitive.isBoolean())
return Boolean.toString(primitive.getAsBoolean());
if (primitive.isString())
return primitive.getAsString();
throw new AssertionError();
}
if (keyElement.isJsonNull())
return "null";
throw new AssertionError();
}
}
}

View file

@ -0,0 +1,76 @@
package com.google.gson.internal.bind;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.internal.LinkedTreeMap;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public final class ObjectTypeAdapter extends TypeAdapter<Object> {
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if (type.getRawType() == Object.class)
return new ObjectTypeAdapter(gson);
return null;
}
};
private final Gson gson;
private ObjectTypeAdapter(Gson gson) {
this.gson = gson;
}
public Object read(JsonReader in) throws IOException {
List<Object> list;
Map<String, Object> map;
JsonToken token = in.peek();
switch (token) {
case BEGIN_ARRAY:
list = new ArrayList();
in.beginArray();
while (in.hasNext())
list.add(read(in));
in.endArray();
return list;
case BEGIN_OBJECT:
map = new LinkedTreeMap<String, Object>();
in.beginObject();
while (in.hasNext())
map.put(in.nextName(), read(in));
in.endObject();
return map;
case STRING:
return in.nextString();
case NUMBER:
return in.nextDouble();
case BOOLEAN:
return in.nextBoolean();
case NULL:
in.nextNull();
return null;
}
throw new IllegalStateException();
}
public void write(JsonWriter out, Object value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
TypeAdapter<Object> typeAdapter = this.gson.getAdapter(value.getClass());
if (typeAdapter instanceof ObjectTypeAdapter) {
out.beginObject();
out.endObject();
return;
}
typeAdapter.write(out, value);
}
}

View file

@ -0,0 +1,175 @@
package com.google.gson.internal.bind;
import com.google.gson.FieldNamingStrategy;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.annotations.SerializedName;
import com.google.gson.internal.$Gson$Types;
import com.google.gson.internal.ConstructorConstructor;
import com.google.gson.internal.Excluder;
import com.google.gson.internal.ObjectConstructor;
import com.google.gson.internal.Primitives;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.LinkedHashMap;
import java.util.Map;
public final class ReflectiveTypeAdapterFactory implements TypeAdapterFactory {
private final ConstructorConstructor constructorConstructor;
private final FieldNamingStrategy fieldNamingPolicy;
private final Excluder excluder;
public ReflectiveTypeAdapterFactory(ConstructorConstructor constructorConstructor, FieldNamingStrategy fieldNamingPolicy, Excluder excluder) {
this.constructorConstructor = constructorConstructor;
this.fieldNamingPolicy = fieldNamingPolicy;
this.excluder = excluder;
}
public boolean excludeField(Field f, boolean serialize) {
return (!this.excluder.excludeClass(f.getType(), serialize) && !this.excluder.excludeField(f, serialize));
}
private String getFieldName(Field f) {
SerializedName serializedName = f.<SerializedName>getAnnotation(SerializedName.class);
return (serializedName == null) ? this.fieldNamingPolicy.translateName(f) : serializedName.value();
}
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
Class<? super T> raw = type.getRawType();
if (!Object.class.isAssignableFrom(raw))
return null;
ObjectConstructor<T> constructor = this.constructorConstructor.<T>get(type);
return new Adapter<T>(constructor, getBoundFields(gson, type, raw));
}
private BoundField createBoundField(final Gson context, final Field field, String name, final TypeToken<?> fieldType, boolean serialize, boolean deserialize) {
final boolean isPrimitive = Primitives.isPrimitive(fieldType.getRawType());
return new BoundField(name, serialize, deserialize) {
final TypeAdapter<?> typeAdapter;
{
this.typeAdapter = context.getAdapter(fieldType);
}
void write(JsonWriter writer, Object value) throws IOException, IllegalAccessException {
Object fieldValue = field.get(value);
TypeAdapter t = new TypeAdapterRuntimeTypeWrapper(context, this.typeAdapter, fieldType.getType());
t.write(writer, fieldValue);
}
void read(JsonReader reader, Object value) throws IOException, IllegalAccessException {
Object fieldValue = this.typeAdapter.read(reader);
if (fieldValue != null || !isPrimitive)
field.set(value, fieldValue);
}
};
}
private Map<String, BoundField> getBoundFields(Gson context, TypeToken<?> type, Class<?> raw) {
Map<String, BoundField> result = new LinkedHashMap<String, BoundField>();
if (raw.isInterface())
return result;
Type declaredType = type.getType();
while (raw != Object.class) {
Field[] fields = raw.getDeclaredFields();
for (Field field : fields) {
boolean serialize = excludeField(field, true);
boolean deserialize = excludeField(field, false);
if (serialize || deserialize) {
field.setAccessible(true);
Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType());
BoundField boundField = createBoundField(context, field, getFieldName(field), TypeToken.get(fieldType), serialize, deserialize);
BoundField previous = result.put(boundField.name, boundField);
if (previous != null)
throw new IllegalArgumentException(declaredType + " declares multiple JSON fields named " + previous.name);
}
}
type = TypeToken.get($Gson$Types.resolve(type.getType(), raw, raw.getGenericSuperclass()));
raw = type.getRawType();
}
return result;
}
static abstract class BoundField {
final String name;
final boolean serialized;
final boolean deserialized;
protected BoundField(String name, boolean serialized, boolean deserialized) {
this.name = name;
this.serialized = serialized;
this.deserialized = deserialized;
}
abstract void write(JsonWriter param1JsonWriter, Object param1Object) throws IOException, IllegalAccessException;
abstract void read(JsonReader param1JsonReader, Object param1Object) throws IOException, IllegalAccessException;
}
public static final class Adapter<T> extends TypeAdapter<T> {
private final ObjectConstructor<T> constructor;
private final Map<String, ReflectiveTypeAdapterFactory.BoundField> boundFields;
private Adapter(ObjectConstructor<T> constructor, Map<String, ReflectiveTypeAdapterFactory.BoundField> boundFields) {
this.constructor = constructor;
this.boundFields = boundFields;
}
public T read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
T instance = this.constructor.construct();
try {
in.beginObject();
while (in.hasNext()) {
String name = in.nextName();
ReflectiveTypeAdapterFactory.BoundField field = this.boundFields.get(name);
if (field == null || !field.deserialized) {
in.skipValue();
continue;
}
field.read(in, instance);
}
} catch (IllegalStateException e) {
throw new JsonSyntaxException(e);
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
in.endObject();
return instance;
}
public void write(JsonWriter out, T value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
out.beginObject();
try {
for (ReflectiveTypeAdapterFactory.BoundField boundField : this.boundFields.values()) {
if (boundField.serialized) {
out.name(boundField.name);
boundField.write(out, value);
}
}
} catch (IllegalAccessException e) {
throw new AssertionError();
}
out.endObject();
}
}
}

View file

@ -0,0 +1,42 @@
package com.google.gson.internal.bind;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.sql.Date;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public final class SqlDateTypeAdapter extends TypeAdapter<Date> {
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
return (typeToken.getRawType() == Date.class) ? new SqlDateTypeAdapter() : null;
}
};
private final DateFormat format = new SimpleDateFormat("MMM d, yyyy");
public synchronized Date read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
try {
long utilDate = this.format.parse(in.nextString()).getTime();
return new Date(utilDate);
} catch (ParseException e) {
throw new JsonSyntaxException(e);
}
}
public synchronized void write(JsonWriter out, Date value) throws IOException {
out.value((value == null) ? null : this.format.format((java.util.Date)value));
}
}

View file

@ -0,0 +1,43 @@
package com.google.gson.internal.bind;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.sql.Time;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public final class TimeTypeAdapter extends TypeAdapter<Time> {
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
return (typeToken.getRawType() == Time.class) ? new TimeTypeAdapter() : null;
}
};
private final DateFormat format = new SimpleDateFormat("hh:mm:ss a");
public synchronized Time read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
try {
Date date = this.format.parse(in.nextString());
return new Time(date.getTime());
} catch (ParseException e) {
throw new JsonSyntaxException(e);
}
}
public synchronized void write(JsonWriter out, Time value) throws IOException {
out.value((value == null) ? null : this.format.format((Date)value));
}
}

View file

@ -0,0 +1,49 @@
package com.google.gson.internal.bind;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.lang.reflect.Type;
final class TypeAdapterRuntimeTypeWrapper<T> extends TypeAdapter<T> {
private final Gson context;
private final TypeAdapter<T> delegate;
private final Type type;
TypeAdapterRuntimeTypeWrapper(Gson context, TypeAdapter<T> delegate, Type type) {
this.context = context;
this.delegate = delegate;
this.type = type;
}
public T read(JsonReader in) throws IOException {
return this.delegate.read(in);
}
public void write(JsonWriter out, T value) throws IOException {
TypeAdapter<T> chosen = this.delegate;
Type runtimeType = getRuntimeTypeIfMoreSpecific(this.type, value);
if (runtimeType != this.type) {
TypeAdapter<?> runtimeTypeAdapter = this.context.getAdapter(TypeToken.get(runtimeType));
if (!(runtimeTypeAdapter instanceof ReflectiveTypeAdapterFactory.Adapter)) {
chosen = (TypeAdapter<T>)runtimeTypeAdapter;
} else if (!(this.delegate instanceof ReflectiveTypeAdapterFactory.Adapter)) {
chosen = this.delegate;
} else {
chosen = (TypeAdapter<T>)runtimeTypeAdapter;
}
}
chosen.write(out, value);
}
private Type getRuntimeTypeIfMoreSpecific(Type<?> type, Object value) {
if (value != null && (type == Object.class || type instanceof java.lang.reflect.TypeVariable || type instanceof Class))
type = value.getClass();
return type;
}
}

View file

@ -0,0 +1,752 @@
package com.google.gson.internal.bind;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonIOException;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSyntaxException;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.annotations.SerializedName;
import com.google.gson.internal.LazilyParsedNumber;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.sql.Timestamp;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.UUID;
public final class TypeAdapters {
public static final TypeAdapter<Class> CLASS = new TypeAdapter<Class>() {
public void write(JsonWriter out, Class value) throws IOException {
if (value == null) {
out.nullValue();
} else {
throw new UnsupportedOperationException("Attempted to serialize java.lang.Class: " + value.getName() + ". Forgot to register a type adapter?");
}
}
public Class read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
throw new UnsupportedOperationException("Attempted to deserialize a java.lang.Class. Forgot to register a type adapter?");
}
};
public static final TypeAdapterFactory CLASS_FACTORY = TypeAdapters.<Class<?>>newFactory(Class.class, CLASS);
public static final TypeAdapter<BitSet> BIT_SET = new TypeAdapter<BitSet>() {
public BitSet read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
BitSet bitset = new BitSet();
in.beginArray();
int i = 0;
JsonToken tokenType = in.peek();
while (tokenType != JsonToken.END_ARRAY) {
boolean set;
String stringValue;
switch (tokenType) {
case NUMBER:
set = (in.nextInt() != 0);
break;
case BOOLEAN:
set = in.nextBoolean();
break;
case STRING:
stringValue = in.nextString();
try {
set = (Integer.parseInt(stringValue) != 0);
} catch (NumberFormatException e) {
throw new JsonSyntaxException("Error: Expecting: bitset number value (1, 0), Found: " + stringValue);
}
break;
default:
throw new JsonSyntaxException("Invalid bitset value type: " + tokenType);
}
if (set)
bitset.set(i);
i++;
tokenType = in.peek();
}
in.endArray();
return bitset;
}
public void write(JsonWriter out, BitSet src) throws IOException {
if (src == null) {
out.nullValue();
return;
}
out.beginArray();
for (int i = 0; i < src.length(); i++) {
int value = src.get(i) ? 1 : 0;
out.value((long)value);
}
out.endArray();
}
};
public static final TypeAdapterFactory BIT_SET_FACTORY = TypeAdapters.<BitSet>newFactory(BitSet.class, BIT_SET);
public static final TypeAdapter<Boolean> BOOLEAN = new TypeAdapter<Boolean>() {
public Boolean read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
if (in.peek() == JsonToken.STRING)
return Boolean.parseBoolean(in.nextString());
return in.nextBoolean();
}
public void write(JsonWriter out, Boolean value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
out.value(value.booleanValue());
}
};
public static final TypeAdapter<Boolean> BOOLEAN_AS_STRING = new TypeAdapter<Boolean>() {
public Boolean read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
return Boolean.valueOf(in.nextString());
}
public void write(JsonWriter out, Boolean value) throws IOException {
out.value((value == null) ? "null" : value.toString());
}
};
public static final TypeAdapterFactory BOOLEAN_FACTORY = TypeAdapters.<boolean>newFactory(boolean.class, (Class)Boolean.class, BOOLEAN);
public static final TypeAdapter<Number> BYTE = new TypeAdapter<Number>() {
public Number read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
try {
int intValue = in.nextInt();
return (byte)intValue;
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
public void write(JsonWriter out, Number value) throws IOException {
out.value(value);
}
};
public static final TypeAdapterFactory BYTE_FACTORY = TypeAdapters.<byte>newFactory(byte.class, (Class)Byte.class, BYTE);
public static final TypeAdapter<Number> SHORT = new TypeAdapter<Number>() {
public Number read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
try {
return (short)in.nextInt();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
public void write(JsonWriter out, Number value) throws IOException {
out.value(value);
}
};
public static final TypeAdapterFactory SHORT_FACTORY = TypeAdapters.<short>newFactory(short.class, (Class)Short.class, SHORT);
public static final TypeAdapter<Number> INTEGER = new TypeAdapter<Number>() {
public Number read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
try {
return in.nextInt();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
public void write(JsonWriter out, Number value) throws IOException {
out.value(value);
}
};
public static final TypeAdapterFactory INTEGER_FACTORY = TypeAdapters.<int>newFactory(int.class, (Class)Integer.class, INTEGER);
public static final TypeAdapter<Number> LONG = new TypeAdapter<Number>() {
public Number read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
try {
return in.nextLong();
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
public void write(JsonWriter out, Number value) throws IOException {
out.value(value);
}
};
public static final TypeAdapter<Number> FLOAT = new TypeAdapter<Number>() {
public Number read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
return (float)in.nextDouble();
}
public void write(JsonWriter out, Number value) throws IOException {
out.value(value);
}
};
public static final TypeAdapter<Number> DOUBLE = new TypeAdapter<Number>() {
public Number read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
return in.nextDouble();
}
public void write(JsonWriter out, Number value) throws IOException {
out.value(value);
}
};
public static final TypeAdapter<Number> NUMBER = new TypeAdapter<Number>() {
public Number read(JsonReader in) throws IOException {
JsonToken jsonToken = in.peek();
switch (jsonToken) {
case NULL:
in.nextNull();
return null;
case NUMBER:
return new LazilyParsedNumber(in.nextString());
}
throw new JsonSyntaxException("Expecting number, got: " + jsonToken);
}
public void write(JsonWriter out, Number value) throws IOException {
out.value(value);
}
};
public static final TypeAdapterFactory NUMBER_FACTORY = TypeAdapters.<Number>newFactory(Number.class, NUMBER);
public static final TypeAdapter<Character> CHARACTER = new TypeAdapter<Character>() {
public Character read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
String str = in.nextString();
if (str.length() != 1)
throw new JsonSyntaxException("Expecting character, got: " + str);
return str.charAt(0);
}
public void write(JsonWriter out, Character value) throws IOException {
out.value((value == null) ? null : String.valueOf(value));
}
};
public static final TypeAdapterFactory CHARACTER_FACTORY = TypeAdapters.<char>newFactory(char.class, (Class)Character.class, CHARACTER);
public static final TypeAdapter<String> STRING = new TypeAdapter<String>() {
public String read(JsonReader in) throws IOException {
JsonToken peek = in.peek();
if (peek == JsonToken.NULL) {
in.nextNull();
return null;
}
if (peek == JsonToken.BOOLEAN)
return Boolean.toString(in.nextBoolean());
return in.nextString();
}
public void write(JsonWriter out, String value) throws IOException {
out.value(value);
}
};
public static final TypeAdapter<BigDecimal> BIG_DECIMAL = new TypeAdapter<BigDecimal>() {
public BigDecimal read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
try {
return new BigDecimal(in.nextString());
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
public void write(JsonWriter out, BigDecimal value) throws IOException {
out.value(value);
}
};
public static final TypeAdapter<BigInteger> BIG_INTEGER = new TypeAdapter<BigInteger>() {
public BigInteger read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
try {
return new BigInteger(in.nextString());
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
public void write(JsonWriter out, BigInteger value) throws IOException {
out.value(value);
}
};
public static final TypeAdapterFactory STRING_FACTORY = TypeAdapters.<String>newFactory(String.class, STRING);
public static final TypeAdapter<StringBuilder> STRING_BUILDER = new TypeAdapter<StringBuilder>() {
public StringBuilder read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
return new StringBuilder(in.nextString());
}
public void write(JsonWriter out, StringBuilder value) throws IOException {
out.value((value == null) ? null : value.toString());
}
};
public static final TypeAdapterFactory STRING_BUILDER_FACTORY = TypeAdapters.<StringBuilder>newFactory(StringBuilder.class, STRING_BUILDER);
public static final TypeAdapter<StringBuffer> STRING_BUFFER = new TypeAdapter<StringBuffer>() {
public StringBuffer read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
return new StringBuffer(in.nextString());
}
public void write(JsonWriter out, StringBuffer value) throws IOException {
out.value((value == null) ? null : value.toString());
}
};
public static final TypeAdapterFactory STRING_BUFFER_FACTORY = TypeAdapters.<StringBuffer>newFactory(StringBuffer.class, STRING_BUFFER);
public static final TypeAdapter<URL> URL = new TypeAdapter<URL>() {
public URL read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
String nextString = in.nextString();
return "null".equals(nextString) ? null : new URL(nextString);
}
public void write(JsonWriter out, URL value) throws IOException {
out.value((value == null) ? null : value.toExternalForm());
}
};
public static final TypeAdapterFactory URL_FACTORY = TypeAdapters.<URL>newFactory(URL.class, URL);
public static final TypeAdapter<URI> URI = new TypeAdapter<URI>() {
public URI read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
try {
String nextString = in.nextString();
return "null".equals(nextString) ? null : new URI(nextString);
} catch (URISyntaxException e) {
throw new JsonIOException(e);
}
}
public void write(JsonWriter out, URI value) throws IOException {
out.value((value == null) ? null : value.toASCIIString());
}
};
public static final TypeAdapterFactory URI_FACTORY = TypeAdapters.<URI>newFactory(URI.class, URI);
public static final TypeAdapter<InetAddress> INET_ADDRESS = new TypeAdapter<InetAddress>() {
public InetAddress read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
return InetAddress.getByName(in.nextString());
}
public void write(JsonWriter out, InetAddress value) throws IOException {
out.value((value == null) ? null : value.getHostAddress());
}
};
public static final TypeAdapterFactory INET_ADDRESS_FACTORY = TypeAdapters.<InetAddress>newTypeHierarchyFactory(InetAddress.class, INET_ADDRESS);
public static final TypeAdapter<UUID> UUID = new TypeAdapter<UUID>() {
public UUID read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
return UUID.fromString(in.nextString());
}
public void write(JsonWriter out, UUID value) throws IOException {
out.value((value == null) ? null : value.toString());
}
};
public static final TypeAdapterFactory UUID_FACTORY = TypeAdapters.<UUID>newFactory(UUID.class, UUID);
public static final TypeAdapterFactory TIMESTAMP_FACTORY = new TypeAdapterFactory() {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
if (typeToken.getRawType() != Timestamp.class)
return null;
final TypeAdapter<Date> dateTypeAdapter = gson.<Date>getAdapter(Date.class);
return new TypeAdapter<Timestamp>() {
public Timestamp read(JsonReader in) throws IOException {
Date date = dateTypeAdapter.read(in);
return (date != null) ? new Timestamp(date.getTime()) : null;
}
public void write(JsonWriter out, Timestamp value) throws IOException {
dateTypeAdapter.write(out, value);
}
};
}
};
public static final TypeAdapter<Calendar> CALENDAR = new TypeAdapter<Calendar>() {
private static final String YEAR = "year";
private static final String MONTH = "month";
private static final String DAY_OF_MONTH = "dayOfMonth";
private static final String HOUR_OF_DAY = "hourOfDay";
private static final String MINUTE = "minute";
private static final String SECOND = "second";
public Calendar read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
in.beginObject();
int year = 0;
int month = 0;
int dayOfMonth = 0;
int hourOfDay = 0;
int minute = 0;
int second = 0;
while (in.peek() != JsonToken.END_OBJECT) {
String name = in.nextName();
int value = in.nextInt();
if ("year".equals(name)) {
year = value;
continue;
}
if ("month".equals(name)) {
month = value;
continue;
}
if ("dayOfMonth".equals(name)) {
dayOfMonth = value;
continue;
}
if ("hourOfDay".equals(name)) {
hourOfDay = value;
continue;
}
if ("minute".equals(name)) {
minute = value;
continue;
}
if ("second".equals(name))
second = value;
}
in.endObject();
return new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute, second);
}
public void write(JsonWriter out, Calendar value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
out.beginObject();
out.name("year");
out.value((long)value.get(1));
out.name("month");
out.value((long)value.get(2));
out.name("dayOfMonth");
out.value((long)value.get(5));
out.name("hourOfDay");
out.value((long)value.get(11));
out.name("minute");
out.value((long)value.get(12));
out.name("second");
out.value((long)value.get(13));
out.endObject();
}
};
public static final TypeAdapterFactory CALENDAR_FACTORY = TypeAdapters.<Calendar>newFactoryForMultipleTypes(Calendar.class, GregorianCalendar.class, CALENDAR);
public static final TypeAdapter<Locale> LOCALE = new TypeAdapter<Locale>() {
public Locale read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
String locale = in.nextString();
StringTokenizer tokenizer = new StringTokenizer(locale, "_");
String language = null;
String country = null;
String variant = null;
if (tokenizer.hasMoreElements())
language = tokenizer.nextToken();
if (tokenizer.hasMoreElements())
country = tokenizer.nextToken();
if (tokenizer.hasMoreElements())
variant = tokenizer.nextToken();
if (country == null && variant == null)
return new Locale(language);
if (variant == null)
return new Locale(language, country);
return new Locale(language, country, variant);
}
public void write(JsonWriter out, Locale value) throws IOException {
out.value((value == null) ? null : value.toString());
}
};
public static final TypeAdapterFactory LOCALE_FACTORY = TypeAdapters.<Locale>newFactory(Locale.class, LOCALE);
public static final TypeAdapter<JsonElement> JSON_ELEMENT = new TypeAdapter<JsonElement>() {
public JsonElement read(JsonReader in) throws IOException {
String number;
JsonArray array;
JsonObject object;
switch (in.peek()) {
case STRING:
return new JsonPrimitive(in.nextString());
case NUMBER:
number = in.nextString();
return new JsonPrimitive((Number)new LazilyParsedNumber(number));
case BOOLEAN:
return new JsonPrimitive(in.nextBoolean());
case NULL:
in.nextNull();
return JsonNull.INSTANCE;
case BEGIN_ARRAY:
array = new JsonArray();
in.beginArray();
while (in.hasNext())
array.add(read(in));
in.endArray();
return array;
case BEGIN_OBJECT:
object = new JsonObject();
in.beginObject();
while (in.hasNext())
object.add(in.nextName(), read(in));
in.endObject();
return object;
}
throw new IllegalArgumentException();
}
public void write(JsonWriter out, JsonElement value) throws IOException {
if (value == null || value.isJsonNull()) {
out.nullValue();
} else if (value.isJsonPrimitive()) {
JsonPrimitive primitive = value.getAsJsonPrimitive();
if (primitive.isNumber()) {
out.value(primitive.getAsNumber());
} else if (primitive.isBoolean()) {
out.value(primitive.getAsBoolean());
} else {
out.value(primitive.getAsString());
}
} else if (value.isJsonArray()) {
out.beginArray();
for (JsonElement e : (Iterable<JsonElement>)value.getAsJsonArray())
write(out, e);
out.endArray();
} else if (value.isJsonObject()) {
out.beginObject();
for (Map.Entry<String, JsonElement> e : value.getAsJsonObject().entrySet()) {
out.name(e.getKey());
write(out, e.getValue());
}
out.endObject();
} else {
throw new IllegalArgumentException("Couldn't write " + value.getClass());
}
}
};
public static final TypeAdapterFactory JSON_ELEMENT_FACTORY = TypeAdapters.<JsonElement>newTypeHierarchyFactory(JsonElement.class, JSON_ELEMENT);
private static final class EnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> {
private final Map<String, T> nameToConstant = new HashMap<String, T>();
private final Map<T, String> constantToName = new HashMap<T, String>();
public EnumTypeAdapter(Class<T> classOfT) {
try {
for (T constant : classOfT.getEnumConstants()) {
String name = constant.name();
SerializedName annotation = classOfT.getField(name).<SerializedName>getAnnotation(SerializedName.class);
if (annotation != null)
name = annotation.value();
this.nameToConstant.put(name, constant);
this.constantToName.put(constant, name);
}
} catch (NoSuchFieldException e) {
throw new AssertionError();
}
}
public T read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
return this.nameToConstant.get(in.nextString());
}
public void write(JsonWriter out, T value) throws IOException {
out.value((value == null) ? null : this.constantToName.get(value));
}
}
public static final TypeAdapterFactory ENUM_FACTORY = newEnumTypeHierarchyFactory();
public static TypeAdapterFactory newEnumTypeHierarchyFactory() {
return new TypeAdapterFactory() {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Class<? super T> rawType = typeToken.getRawType();
if (!Enum.class.isAssignableFrom(rawType) || rawType == Enum.class)
return null;
if (!rawType.isEnum())
rawType = rawType.getSuperclass();
return new TypeAdapters.EnumTypeAdapter<T>(rawType);
}
};
}
public static <TT> TypeAdapterFactory newFactory(final TypeToken<TT> type, final TypeAdapter<TT> typeAdapter) {
return new TypeAdapterFactory() {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
return typeToken.equals(type) ? typeAdapter : null;
}
};
}
public static <TT> TypeAdapterFactory newFactory(final Class<TT> type, final TypeAdapter<TT> typeAdapter) {
return new TypeAdapterFactory() {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
return (typeToken.getRawType() == type) ? typeAdapter : null;
}
public String toString() {
return "Factory[type=" + type.getName() + ",adapter=" + typeAdapter + "]";
}
};
}
public static <TT> TypeAdapterFactory newFactory(final Class<TT> unboxed, final Class<TT> boxed, final TypeAdapter<? super TT> typeAdapter) {
return new TypeAdapterFactory() {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Class<? super T> rawType = typeToken.getRawType();
return (rawType == unboxed || rawType == boxed) ? typeAdapter : null;
}
public String toString() {
return "Factory[type=" + boxed.getName() + "+" + unboxed.getName() + ",adapter=" + typeAdapter + "]";
}
};
}
public static <TT> TypeAdapterFactory newFactoryForMultipleTypes(final Class<TT> base, final Class<? extends TT> sub, final TypeAdapter<? super TT> typeAdapter) {
return new TypeAdapterFactory() {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Class<? super T> rawType = typeToken.getRawType();
return (rawType == base || rawType == sub) ? typeAdapter : null;
}
public String toString() {
return "Factory[type=" + base.getName() + "+" + sub.getName() + ",adapter=" + typeAdapter + "]";
}
};
}
public static <TT> TypeAdapterFactory newTypeHierarchyFactory(final Class<TT> clazz, final TypeAdapter<TT> typeAdapter) {
return new TypeAdapterFactory() {
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
return clazz.isAssignableFrom(typeToken.getRawType()) ? typeAdapter : null;
}
public String toString() {
return "Factory[typeHierarchy=" + clazz.getName() + ",adapter=" + typeAdapter + "]";
}
};
}
}

View file

@ -0,0 +1,165 @@
package com.google.gson.reflect;
import com.google.gson.internal.$Gson$Preconditions;
import com.google.gson.internal.$Gson$Types;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.HashMap;
import java.util.Map;
public class TypeToken<T> {
final Class<? super T> rawType;
final Type type;
final int hashCode;
protected TypeToken() {
this.type = getSuperclassTypeParameter(getClass());
this.rawType = $Gson$Types.getRawType(this.type);
this.hashCode = this.type.hashCode();
}
TypeToken(Type type) {
this.type = $Gson$Types.canonicalize($Gson$Preconditions.<Type>checkNotNull(type));
this.rawType = $Gson$Types.getRawType(this.type);
this.hashCode = this.type.hashCode();
}
static Type getSuperclassTypeParameter(Class<?> subclass) {
Type superclass = subclass.getGenericSuperclass();
if (superclass instanceof Class)
throw new RuntimeException("Missing type parameter.");
ParameterizedType parameterized = (ParameterizedType)superclass;
return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
}
public final Class<? super T> getRawType() {
return this.rawType;
}
public final Type getType() {
return this.type;
}
@Deprecated
public boolean isAssignableFrom(Class<?> cls) {
return isAssignableFrom((Type)cls);
}
@Deprecated
public boolean isAssignableFrom(Type from) {
if (from == null)
return false;
if (this.type.equals(from))
return true;
if (this.type instanceof Class)
return this.rawType.isAssignableFrom($Gson$Types.getRawType(from));
if (this.type instanceof ParameterizedType)
return isAssignableFrom(from, (ParameterizedType)this.type, new HashMap<String, Type>());
if (this.type instanceof GenericArrayType)
return (this.rawType.isAssignableFrom($Gson$Types.getRawType(from)) && isAssignableFrom(from, (GenericArrayType)this.type));
throw buildUnexpectedTypeError(this.type, new Class<?>[] { Class.class, ParameterizedType.class, GenericArrayType.class });
}
@Deprecated
public boolean isAssignableFrom(TypeToken<?> token) {
return isAssignableFrom(token.getType());
}
private static boolean isAssignableFrom(Type<?> from, GenericArrayType to) {
Type toGenericComponentType = to.getGenericComponentType();
if (toGenericComponentType instanceof ParameterizedType) {
Type<?> t = from;
if (from instanceof GenericArrayType) {
t = ((GenericArrayType)from).getGenericComponentType();
} else if (from instanceof Class) {
Class<?> classType = (Class)from;
while (classType.isArray())
classType = classType.getComponentType();
t = classType;
}
return isAssignableFrom(t, (ParameterizedType)toGenericComponentType, new HashMap<String, Type>());
}
return true;
}
private static boolean isAssignableFrom(Type from, ParameterizedType to, Map<String, Type> typeVarMap) {
if (from == null)
return false;
if (to.equals(from))
return true;
Class<?> clazz = $Gson$Types.getRawType(from);
ParameterizedType ptype = null;
if (from instanceof ParameterizedType)
ptype = (ParameterizedType)from;
if (ptype != null) {
Type[] tArgs = ptype.getActualTypeArguments();
TypeVariable<?>[] tParams = clazz.getTypeParameters();
for (int i = 0; i < tArgs.length; i++) {
Type arg = tArgs[i];
TypeVariable<?> var = tParams[i];
while (arg instanceof TypeVariable) {
TypeVariable<?> v = (TypeVariable)arg;
arg = typeVarMap.get(v.getName());
}
typeVarMap.put(var.getName(), arg);
}
if (typeEquals(ptype, to, typeVarMap))
return true;
}
for (Type itype : clazz.getGenericInterfaces()) {
if (isAssignableFrom(itype, to, new HashMap<String, Type>(typeVarMap)))
return true;
}
Type sType = clazz.getGenericSuperclass();
return isAssignableFrom(sType, to, new HashMap<String, Type>(typeVarMap));
}
private static boolean typeEquals(ParameterizedType from, ParameterizedType to, Map<String, Type> typeVarMap) {
if (from.getRawType().equals(to.getRawType())) {
Type[] fromArgs = from.getActualTypeArguments();
Type[] toArgs = to.getActualTypeArguments();
for (int i = 0; i < fromArgs.length; i++) {
if (!matches(fromArgs[i], toArgs[i], typeVarMap))
return false;
}
return true;
}
return false;
}
private static AssertionError buildUnexpectedTypeError(Type token, Class<?>... expected) {
StringBuilder exceptionMessage = new StringBuilder("Unexpected type. Expected one of: ");
for (Class<?> clazz : expected)
exceptionMessage.append(clazz.getName()).append(", ");
exceptionMessage.append("but got: ").append(token.getClass().getName()).append(", for type token: ").append(token.toString()).append('.');
return new AssertionError((Object)exceptionMessage.toString());
}
private static boolean matches(Type from, Type to, Map<String, Type> typeMap) {
return (to.equals(from) || (from instanceof TypeVariable && to.equals(typeMap.get(((TypeVariable)from).getName()))));
}
public final int hashCode() {
return this.hashCode;
}
public final boolean equals(Object o) {
return (o instanceof TypeToken && $Gson$Types.equals(this.type, ((TypeToken)o).type));
}
public final String toString() {
return $Gson$Types.typeToString(this.type);
}
public static TypeToken<?> get(Type type) {
return new TypeToken(type);
}
public static <T> TypeToken<T> get(Class<T> type) {
return new TypeToken<T>(type);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,19 @@
package com.google.gson.stream;
final class JsonScope {
static final int EMPTY_ARRAY = 1;
static final int NONEMPTY_ARRAY = 2;
static final int EMPTY_OBJECT = 3;
static final int DANGLING_NAME = 4;
static final int NONEMPTY_OBJECT = 5;
static final int EMPTY_DOCUMENT = 6;
static final int NONEMPTY_DOCUMENT = 7;
static final int CLOSED = 8;
}

View file

@ -0,0 +1,5 @@
package com.google.gson.stream;
public enum JsonToken {
BEGIN_ARRAY, END_ARRAY, BEGIN_OBJECT, END_OBJECT, NAME, STRING, NUMBER, BOOLEAN, NULL, END_DOCUMENT;
}

View file

@ -0,0 +1,315 @@
package com.google.gson.stream;
import java.io.Closeable;
import java.io.Flushable;
import java.io.IOException;
import java.io.Writer;
public class JsonWriter implements Closeable, Flushable {
private static final String[] REPLACEMENT_CHARS = new String[128];
static {
for (int i = 0; i <= 31; i++)
REPLACEMENT_CHARS[i] = String.format("\\u%04x", i);
REPLACEMENT_CHARS[34] = "\\\"";
REPLACEMENT_CHARS[92] = "\\\\";
REPLACEMENT_CHARS[9] = "\\t";
REPLACEMENT_CHARS[8] = "\\b";
REPLACEMENT_CHARS[10] = "\\n";
REPLACEMENT_CHARS[13] = "\\r";
REPLACEMENT_CHARS[12] = "\\f";
}
private static final String[] HTML_SAFE_REPLACEMENT_CHARS = (String[])REPLACEMENT_CHARS.clone();
private final Writer out;
static {
HTML_SAFE_REPLACEMENT_CHARS[60] = "\\u003c";
HTML_SAFE_REPLACEMENT_CHARS[62] = "\\u003e";
HTML_SAFE_REPLACEMENT_CHARS[38] = "\\u0026";
HTML_SAFE_REPLACEMENT_CHARS[61] = "\\u003d";
HTML_SAFE_REPLACEMENT_CHARS[39] = "\\u0027";
}
private int[] stack = new int[32];
private int stackSize = 0;
private String indent;
private String separator;
private boolean lenient;
private boolean htmlSafe;
private String deferredName;
private boolean serializeNulls;
public JsonWriter(Writer out) {
push(6);
this.separator = ":";
this.serializeNulls = true;
if (out == null)
throw new NullPointerException("out == null");
this.out = out;
}
public final void setIndent(String indent) {
if (indent.length() == 0) {
this.indent = null;
this.separator = ":";
} else {
this.indent = indent;
this.separator = ": ";
}
}
public final void setLenient(boolean lenient) {
this.lenient = lenient;
}
public boolean isLenient() {
return this.lenient;
}
public final void setHtmlSafe(boolean htmlSafe) {
this.htmlSafe = htmlSafe;
}
public final boolean isHtmlSafe() {
return this.htmlSafe;
}
public final void setSerializeNulls(boolean serializeNulls) {
this.serializeNulls = serializeNulls;
}
public final boolean getSerializeNulls() {
return this.serializeNulls;
}
public JsonWriter beginArray() throws IOException {
writeDeferredName();
return open(1, "[");
}
public JsonWriter endArray() throws IOException {
return close(1, 2, "]");
}
public JsonWriter beginObject() throws IOException {
writeDeferredName();
return open(3, "{");
}
public JsonWriter endObject() throws IOException {
return close(3, 5, "}");
}
private JsonWriter open(int empty, String openBracket) throws IOException {
beforeValue(true);
push(empty);
this.out.write(openBracket);
return this;
}
private JsonWriter close(int empty, int nonempty, String closeBracket) throws IOException {
int context = peek();
if (context != nonempty && context != empty)
throw new IllegalStateException("Nesting problem.");
if (this.deferredName != null)
throw new IllegalStateException("Dangling name: " + this.deferredName);
this.stackSize--;
if (context == nonempty)
newline();
this.out.write(closeBracket);
return this;
}
private void push(int newTop) {
if (this.stackSize == this.stack.length) {
int[] newStack = new int[this.stackSize * 2];
System.arraycopy(this.stack, 0, newStack, 0, this.stackSize);
this.stack = newStack;
}
this.stack[this.stackSize++] = newTop;
}
private int peek() {
if (this.stackSize == 0)
throw new IllegalStateException("JsonWriter is closed.");
return this.stack[this.stackSize - 1];
}
private void replaceTop(int topOfStack) {
this.stack[this.stackSize - 1] = topOfStack;
}
public JsonWriter name(String name) throws IOException {
if (name == null)
throw new NullPointerException("name == null");
if (this.deferredName != null)
throw new IllegalStateException();
if (this.stackSize == 0)
throw new IllegalStateException("JsonWriter is closed.");
this.deferredName = name;
return this;
}
private void writeDeferredName() throws IOException {
if (this.deferredName != null) {
beforeName();
string(this.deferredName);
this.deferredName = null;
}
}
public JsonWriter value(String value) throws IOException {
if (value == null)
return nullValue();
writeDeferredName();
beforeValue(false);
string(value);
return this;
}
public JsonWriter nullValue() throws IOException {
if (this.deferredName != null)
if (this.serializeNulls) {
writeDeferredName();
} else {
this.deferredName = null;
return this;
}
beforeValue(false);
this.out.write("null");
return this;
}
public JsonWriter value(boolean value) throws IOException {
writeDeferredName();
beforeValue(false);
this.out.write(value ? "true" : "false");
return this;
}
public JsonWriter value(double value) throws IOException {
if (Double.isNaN(value) || Double.isInfinite(value))
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
writeDeferredName();
beforeValue(false);
this.out.append(Double.toString(value));
return this;
}
public JsonWriter value(long value) throws IOException {
writeDeferredName();
beforeValue(false);
this.out.write(Long.toString(value));
return this;
}
public JsonWriter value(Number value) throws IOException {
if (value == null)
return nullValue();
writeDeferredName();
String string = value.toString();
if (!this.lenient && (string.equals("-Infinity") || string.equals("Infinity") || string.equals("NaN")))
throw new IllegalArgumentException("Numeric values must be finite, but was " + value);
beforeValue(false);
this.out.append(string);
return this;
}
public void flush() throws IOException {
if (this.stackSize == 0)
throw new IllegalStateException("JsonWriter is closed.");
this.out.flush();
}
public void close() throws IOException {
this.out.close();
int size = this.stackSize;
if (size > 1 || (size == 1 && this.stack[size - 1] != 7))
throw new IOException("Incomplete document");
this.stackSize = 0;
}
private void string(String value) throws IOException {
String[] replacements = this.htmlSafe ? HTML_SAFE_REPLACEMENT_CHARS : REPLACEMENT_CHARS;
this.out.write("\"");
int last = 0;
int length = value.length();
for (int i = 0; i < length; i++) {
String replacement;
char c = value.charAt(i);
if (c < '\u0080') {
replacement = replacements[c];
if (replacement == null)
continue;
} else if (c == '') {
replacement = "\\u2028";
} else if (c == '') {
replacement = "\\u2029";
} else {
continue;
}
if (last < i)
this.out.write(value, last, i - last);
this.out.write(replacement);
last = i + 1;
}
if (last < length)
this.out.write(value, last, length - last);
this.out.write("\"");
}
private void newline() throws IOException {
if (this.indent == null)
return;
this.out.write("\n");
for (int i = 1, size = this.stackSize; i < size; i++)
this.out.write(this.indent);
}
private void beforeName() throws IOException {
int context = peek();
if (context == 5) {
this.out.write(44);
} else if (context != 3) {
throw new IllegalStateException("Nesting problem.");
}
newline();
replaceTop(4);
}
private void beforeValue(boolean root) throws IOException {
switch (peek()) {
case 7:
if (!this.lenient)
throw new IllegalStateException("JSON must have only one top-level value.");
case 6:
if (!this.lenient && !root)
throw new IllegalStateException("JSON must start with an array or an object.");
replaceTop(7);
break;
case 1:
replaceTop(2);
newline();
break;
case 2:
this.out.append(',');
newline();
break;
case 4:
this.out.append(this.separator);
replaceTop(5);
break;
default:
throw new IllegalStateException("Nesting problem.");
}
}
}

View file

@ -0,0 +1,20 @@
package com.google.gson.stream;
import java.io.IOException;
public final class MalformedJsonException extends IOException {
private static final long serialVersionUID = 1L;
public MalformedJsonException(String msg) {
super(msg);
}
public MalformedJsonException(String msg, Throwable throwable) {
super(msg);
initCause(throwable);
}
public MalformedJsonException(Throwable throwable) {
initCause(throwable);
}
}