diff --git a/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java b/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java index 7223f851..299cb6e7 100644 --- a/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java +++ b/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java @@ -16,21 +16,20 @@ package com.google.gson; -import com.google.gson.internal.ParameterizedTypeHandlerMap; - import java.lang.reflect.Type; import java.sql.Time; import java.sql.Timestamp; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.BitSet; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.Locale; import java.util.TimeZone; +import com.google.gson.internal.ParameterizedTypeHandlerMap; + /** * List of all the default type adapters ({@link JsonSerializer}s, {@link JsonDeserializer}s, * and {@link InstanceCreator}s. @@ -50,7 +49,6 @@ final class DefaultTypeAdapters { @SuppressWarnings("unchecked") private static final EnumTypeAdapter ENUM_TYPE_ADAPTER = new EnumTypeAdapter(); - private static final BitSetTypeAdapter BIT_SET_ADAPTER = new BitSetTypeAdapter(); private static final CharacterTypeAdapter CHARACTER_TYPE_ADAPTER = new CharacterTypeAdapter(); private static final NumberTypeAdapter NUMBER_TYPE_ADAPTER = new NumberTypeAdapter(); @@ -82,7 +80,6 @@ final class DefaultTypeAdapters { map.register(Time.class, TIME_TYPE_ADAPTER, true); map.register(Calendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER, true); map.register(GregorianCalendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER, true); - map.register(BitSet.class, BIT_SET_ADAPTER, true); // Add primitive serializers map.register(Character.class, CHARACTER_TYPE_ADAPTER, true); @@ -109,7 +106,6 @@ final class DefaultTypeAdapters { map.register(Time.class, wrapDeserializer(TIME_TYPE_ADAPTER), true); map.register(Calendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER, true); map.register(GregorianCalendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER, true); - map.register(BitSet.class, BIT_SET_ADAPTER, true); // Add primitive deserializers map.register(Character.class, wrapDeserializer(CHARACTER_TYPE_ADAPTER), true); @@ -377,38 +373,6 @@ final class DefaultTypeAdapters { } } - private static final class BitSetTypeAdapter implements JsonSerializer, JsonDeserializer { - public JsonElement serialize(BitSet src, Type typeOfSrc, JsonSerializationContext context) { - JsonArray array = new JsonArray(); - for (int i = 0; i < src.length(); i++) { - int value = (src.get(i)) ? 1 : 0; - array.add(new JsonPrimitive(value)); - } - return array; - } - - public BitSet deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { - if (!json.isJsonArray()) { - throw new JsonParseException("Expected an array of bits."); - } - BitSet result = new BitSet(); - JsonArray array = json.getAsJsonArray(); - for (int i = 0; i < array.size(); i++) { - JsonElement element = array.get(i); - if (element.getAsBoolean()) { - result.set(i); - } - } - return result; - } - - @Override - public String toString() { - return BitSetTypeAdapter.class.getSimpleName(); - } - } - private static final class NumberTypeAdapter implements JsonSerializer, JsonDeserializer { public JsonElement serialize(Number src, Type typeOfSrc, JsonSerializationContext context) { diff --git a/gson/src/main/java/com/google/gson/Gson.java b/gson/src/main/java/com/google/gson/Gson.java index 34300cb2..ffabf73b 100644 --- a/gson/src/main/java/com/google/gson/Gson.java +++ b/gson/src/main/java/com/google/gson/Gson.java @@ -244,6 +244,7 @@ public final class Gson { .factory(TypeAdapters.UUID_FACTORY) .factory(TypeAdapters.LOCALE_FACTORY) .factory(TypeAdapters.INET_ADDRESS_FACTORY) + .factory(TypeAdapters.BIT_SET_FACTORY) .typeAdapter(BigDecimal.class, new BigDecimalTypeAdapter()) .typeAdapter(BigInteger.class, new BigIntegerTypeAdapter()) .factory(new CollectionTypeAdapterFactory(constructorConstructor)) diff --git a/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java b/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java index 63267a51..36418a1a 100644 --- a/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java +++ b/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java @@ -16,6 +16,16 @@ package com.google.gson.internal.bind; +import java.io.IOException; +import java.net.InetAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.BitSet; +import java.util.Locale; +import java.util.StringTokenizer; +import java.util.UUID; + import com.google.gson.JsonIOException; import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; @@ -23,21 +33,61 @@ import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.net.InetAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.Locale; -import java.util.StringTokenizer; -import java.util.UUID; - /** * Type adapters for basic types. */ public final class TypeAdapters { private TypeAdapters() {} + public static final TypeAdapter BIT_SET = new TypeAdapter() { + public BitSet read(JsonReader reader) throws IOException { + BitSet bitset = new BitSet(); + reader.beginArray(); + int i = 0; + JsonToken tokenType = reader.peek(); + while (tokenType != JsonToken.END_ARRAY) { + boolean set = false; + switch (tokenType) { + case NUMBER: + set = reader.nextInt() != 0; + break; + case BOOLEAN: + set = reader.nextBoolean(); + break; + case STRING: + String stringValue = reader.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 = reader.peek(); + } + reader.endArray(); + return bitset; + } + + public void write(JsonWriter writer, BitSet src) throws IOException { + writer.beginArray(); + for (int i = 0; i < src.length(); i++) { + int value = (src.get(i)) ? 1 : 0; + writer.value(value); + } + writer.endArray(); + } + }; + + public static final TypeAdapter.Factory BIT_SET_FACTORY = newFactory(BitSet.class, BIT_SET); + public static final TypeAdapter BOOLEAN = new TypeAdapter() { @Override public Boolean read(JsonReader reader) throws IOException {