diff options
Diffstat (limited to 'java/src/main/java/com/google/protobuf/Internal.java')
-rw-r--r-- | java/src/main/java/com/google/protobuf/Internal.java | 223 |
1 files changed, 163 insertions, 60 deletions
diff --git a/java/src/main/java/com/google/protobuf/Internal.java b/java/src/main/java/com/google/protobuf/Internal.java index 5a0de6d1..20054b79 100644 --- a/java/src/main/java/com/google/protobuf/Internal.java +++ b/java/src/main/java/com/google/protobuf/Internal.java @@ -31,8 +31,8 @@ package com.google.protobuf; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; +import java.nio.charset.Charset; import java.util.AbstractList; import java.util.AbstractMap; import java.util.AbstractSet; @@ -51,6 +51,10 @@ import java.util.Set; * @author kenton@google.com (Kenton Varda) */ public class Internal { + + protected static final Charset UTF_8 = Charset.forName("UTF-8"); + protected static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); + /** * Helper called by generated code to construct default values for string * fields. @@ -80,14 +84,7 @@ public class Internal { * generated code calls this automatically. */ public static String stringDefaultValue(String bytes) { - try { - return new String(bytes.getBytes("ISO-8859-1"), "UTF-8"); - } catch (UnsupportedEncodingException e) { - // This should never happen since all JVMs are required to implement - // both of the above character sets. - throw new IllegalStateException( - "Java VM does not support a standard character set.", e); - } + return new String(bytes.getBytes(ISO_8859_1), UTF_8); } /** @@ -99,37 +96,23 @@ public class Internal { * embed raw bytes as a string literal with ISO-8859-1 encoding. */ public static ByteString bytesDefaultValue(String bytes) { - try { - return ByteString.copyFrom(bytes.getBytes("ISO-8859-1")); - } catch (UnsupportedEncodingException e) { - // This should never happen since all JVMs are required to implement - // ISO-8859-1. - throw new IllegalStateException( - "Java VM does not support a standard character set.", e); - } + return ByteString.copyFrom(bytes.getBytes(ISO_8859_1)); } /** * Helper called by generated code to construct default values for bytes * fields. * <p> - * This is like {@link #bytesDefaultValue}, but returns a byte array. + * This is like {@link #bytesDefaultValue}, but returns a byte array. */ public static byte[] byteArrayDefaultValue(String bytes) { - try { - return bytes.getBytes("ISO-8859-1"); - } catch (UnsupportedEncodingException e) { - // This should never happen since all JVMs are required to implement - // ISO-8859-1. - throw new IllegalStateException( - "Java VM does not support a standard character set.", e); - } + return bytes.getBytes(ISO_8859_1); } /** * Helper called by generated code to construct default values for bytes * fields. * <p> - * This is like {@link #bytesDefaultValue}, but returns a ByteBuffer. + * This is like {@link #bytesDefaultValue}, but returns a ByteBuffer. */ public static ByteBuffer byteBufferDefaultValue(String bytes) { return ByteBuffer.wrap(byteArrayDefaultValue(bytes)); @@ -185,7 +168,7 @@ public class Internal { public static boolean isValidUtf8(ByteString byteString) { return byteString.isValidUtf8(); } - + /** * Like {@link #isValidUtf8(ByteString)} but for byte arrays. */ @@ -197,22 +180,14 @@ public class Internal { * Helper method to get the UTF-8 bytes of a string. */ public static byte[] toByteArray(String value) { - try { - return value.getBytes("UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException("UTF-8 not supported?", e); - } + return value.getBytes(UTF_8); } - + /** * Helper method to convert a byte array to a string using UTF-8 encoding. */ public static String toStringUtf8(byte[] bytes) { - try { - return new String(bytes, "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException("UTF-8 not supported?", e); - } + return new String(bytes, UTF_8); } /** @@ -274,7 +249,7 @@ public class Internal { } return hash; } - + /** * Helper method for implementing {@link Message#equals(Object)} for bytes field. */ @@ -298,7 +273,7 @@ public class Internal { } return hash; } - + /** * Helper method for implementing {@link Message#hashCode()} for bytes field. */ @@ -309,7 +284,7 @@ public class Internal { // based hashCode() method. return LiteralByteString.hashCode(bytes); } - + /** * Helper method for implementing {@link Message#equals(Object)} for bytes * field. @@ -322,7 +297,7 @@ public class Internal { // compare all the content. return a.duplicate().clear().equals(b.duplicate().clear()); } - + /** * Helper method for implementing {@link Message#equals(Object)} for bytes * field. @@ -351,9 +326,9 @@ public class Internal { } return hash; } - + private static final int DEFAULT_BUFFER_SIZE = 4096; - + /** * Helper method for implementing {@link Message#hashCode()} for bytes * field. @@ -382,18 +357,18 @@ public class Internal { return h == 0 ? 1 : h; } } - + /** * An empty byte array constant used in generated code. */ public static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; - + /** * An empty byte array constant used in generated code. */ public static final ByteBuffer EMPTY_BYTE_BUFFER = ByteBuffer.wrap(EMPTY_BYTE_ARRAY); - + /** An empty coded input stream constant used in generated code. */ public static final CodedInputStream EMPTY_CODED_INPUT_STREAM = CodedInputStream.newInstance(EMPTY_BYTE_ARRAY); @@ -458,13 +433,13 @@ public class Internal { private final Map<K, RealValue> realMap; private final Converter<RealValue, V> valueConverter; - + public MapAdapter(Map<K, RealValue> realMap, Converter<RealValue, V> valueConverter) { this.realMap = realMap; this.valueConverter = valueConverter; } - + @SuppressWarnings("unchecked") @Override public V get(Object key) { @@ -474,7 +449,7 @@ public class Internal { } return valueConverter.doForward(result); } - + @Override public V put(K key, V value) { RealValue oldValue = realMap.put(key, valueConverter.doBackward(value)); @@ -488,13 +463,13 @@ public class Internal { public Set<java.util.Map.Entry<K, V>> entrySet() { return new SetAdapter(realMap.entrySet()); } - + private class SetAdapter extends AbstractSet<Map.Entry<K, V>> { private final Set<Map.Entry<K, RealValue>> realSet; public SetAdapter(Set<Map.Entry<K, RealValue>> realSet) { this.realSet = realSet; } - + @Override public Iterator<java.util.Map.Entry<K, V>> iterator() { return new IteratorAdapter(realSet.iterator()); @@ -503,17 +478,17 @@ public class Internal { @Override public int size() { return realSet.size(); - } + } } - + private class IteratorAdapter implements Iterator<Map.Entry<K, V>> { private final Iterator<Map.Entry<K, RealValue>> realIterator; - + public IteratorAdapter( Iterator<Map.Entry<K, RealValue>> realIterator) { this.realIterator = realIterator; } - + @Override public boolean hasNext() { return realIterator.hasNext(); @@ -529,14 +504,14 @@ public class Internal { realIterator.remove(); } } - + private class EntryAdapter implements Map.Entry<K, V> { private final Map.Entry<K, RealValue> realEntry; - + public EntryAdapter(Map.Entry<K, RealValue> realEntry) { this.realEntry = realEntry; } - + @Override public K getKey() { return realEntry.getKey(); @@ -558,4 +533,132 @@ public class Internal { } } } + + /** + * Extends {@link List} to add the capability to make the list immutable and inspect if it is + * modifiable. + */ + public static interface ProtobufList<E> extends List<E> { + + /** + * Makes this list immutable. All subsequent modifications will throw an + * {@link UnsupportedOperationException}. + */ + void makeImmutable(); + + /** + * Returns whether this list can be modified via the publicly accessible {@link List} methods. + */ + boolean isModifiable(); + } + + /** + * A {@link java.util.List} implementation that avoids boxing the elements into Integers if + * possible. Does not support null elements. + */ + public static interface IntList extends ProtobufList<Integer> { + + /** + * Like {@link #get(int)} but more efficient in that it doesn't box the returned value. + */ + int getInt(int index); + + /** + * Like {@link #add(Integer)} but more efficient in that it doesn't box the element. + */ + void addInt(int element); + + /** + * Like {@link #set(int, Integer)} but more efficient in that it doesn't box the element. + */ + int setInt(int index, int element); + } + + /** + * A {@link java.util.List} implementation that avoids boxing the elements into Booleans if + * possible. Does not support null elements. + */ + public static interface BooleanList extends ProtobufList<Boolean> { + + /** + * Like {@link #get(int)} but more efficient in that it doesn't box the returned value. + */ + boolean getBoolean(int index); + + /** + * Like {@link #add(Boolean)} but more efficient in that it doesn't box the element. + */ + void addBoolean(boolean element); + + /** + * Like {@link #set(int, Boolean)} but more efficient in that it doesn't box the element. + */ + boolean setBoolean(int index, boolean element); + } + + /** + * A {@link java.util.List} implementation that avoids boxing the elements into Longs if + * possible. Does not support null elements. + */ + public static interface LongList extends ProtobufList<Long> { + + /** + * Like {@link #get(int)} but more efficient in that it doesn't box the returned value. + */ + long getLong(int index); + + /** + * Like {@link #add(Long)} but more efficient in that it doesn't box the element. + */ + void addLong(long element); + + /** + * Like {@link #set(int, Long)} but more efficient in that it doesn't box the element. + */ + long setLong(int index, long element); + } + + /** + * A {@link java.util.List} implementation that avoids boxing the elements into Doubles if + * possible. Does not support null elements. + */ + public static interface DoubleList extends ProtobufList<Double> { + + /** + * Like {@link #get(int)} but more efficient in that it doesn't box the returned value. + */ + double getDouble(int index); + + /** + * Like {@link #add(Double)} but more efficient in that it doesn't box the element. + */ + void addDouble(double element); + + /** + * Like {@link #set(int, Double)} but more efficient in that it doesn't box the element. + */ + double setDouble(int index, double element); + } + + /** + * A {@link java.util.List} implementation that avoids boxing the elements into Floats if + * possible. Does not support null elements. + */ + public static interface FloatList extends ProtobufList<Float> { + + /** + * Like {@link #get(int)} but more efficient in that it doesn't box the returned value. + */ + float getFloat(int index); + + /** + * Like {@link #add(Float)} but more efficient in that it doesn't box the element. + */ + void addFloat(float element); + + /** + * Like {@link #set(int, Float)} but more efficient in that it doesn't box the element. + */ + float setFloat(int index, float element); + } } |