diff options
Diffstat (limited to 'src/com/google/common/io/protocol/ProtoBufType.java')
-rw-r--r-- | src/com/google/common/io/protocol/ProtoBufType.java | 106 |
1 files changed, 63 insertions, 43 deletions
diff --git a/src/com/google/common/io/protocol/ProtoBufType.java b/src/com/google/common/io/protocol/ProtoBufType.java index 4b6408e8..728346f3 100644 --- a/src/com/google/common/io/protocol/ProtoBufType.java +++ b/src/com/google/common/io/protocol/ProtoBufType.java @@ -6,9 +6,8 @@ package com.google.common.io.protocol; import java.util.*; /** - * This class can be used to create a memory model of a .proto file. Currently, - * it is assumed that tags ids are not large. This could be improved by storing - * a start offset, relaxing the assumption to a dense number space. + * This class can be used to create a memory model of a .proto file. + * */ public class ProtoBufType { // Note: Values 0..15 are reserved for wire types! @@ -42,11 +41,46 @@ public class ProtoBufType { public static final int REQUIRED = 0x100; public static final int OPTIONAL = 0x200; public static final int REPEATED = 0x400; - - private final StringBuffer types = new StringBuffer(); - private final Vector data = new Vector(); + + private final IntMap types = new IntMap(); + + /* + * A struct to store field type and default object. + * Two TypeInfo objects are equal iff both have the + * euqal type and object. + */ + static class TypeInfo { + private int type; + private Object data; + TypeInfo(int t, Object d) { + type = t; + data = d; + } + + public int hashCode() { + return type; + } + + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || !(obj instanceof TypeInfo)) { + return false; + } + TypeInfo peerTypeInfo = (TypeInfo) obj; + return type == peerTypeInfo.type && + (data == peerTypeInfo.data || + (data != null && data.equals(peerTypeInfo.data))); + } + + public String toString() { + return "TypeInfo{type=" + type + ", data=" + data + "}"; + } + }; + private final String typeName; - + /** * Empty constructor. */ @@ -74,35 +108,36 @@ public class ProtoBufType { * @return this is returned to permit cascading */ public ProtoBufType addElement(int optionsAndType, int tag, Object data) { - while (types.length() <= tag) { - types.append((char) TYPE_UNDEFINED); - this.data.addElement(null); - } - types.setCharAt(tag, (char) optionsAndType); - this.data.setElementAt(data, tag); - + types.put(tag, new TypeInfo(optionsAndType, data)); return this; } - + + /** + * Returns a IntMap that has the same lower buffer size as types. + * This is for ProtoBuf to create IntMap with pre-allocated + * internal buffer. + */ + /* package protected */ IntMap newIntMapForProtoBuf() { + return types.newIntMapWithSameBufferSize(); + } + /** * Returns the type for the given tag id (without modifiers such as OPTIONAL, * REPEATED). For undefined tags, TYPE_UNDEFINED is returned. */ public int getType(int tag) { - return (tag < 0 || tag >= types.length()) - ? TYPE_UNDEFINED - : (types.charAt(tag) & MASK_TYPE); + TypeInfo typeInfo = (TypeInfo) types.get(tag); + return typeInfo == null ? TYPE_UNDEFINED : typeInfo.type & MASK_TYPE; } - /** + /** * Returns a bit combination of the modifiers for the given tag id * (OPTIONAL, REPEATED, REQUIRED). For undefined tags, OPTIONAL|REPEATED * is returned. - */ + */ public int getModifiers(int tag) { - return (tag < 0 || tag >= types.length()) - ? (OPTIONAL | REPEATED) - : (types.charAt(tag) & MASK_MODIFIER); + TypeInfo typeInfo = (TypeInfo) types.get(tag); + return typeInfo == null ? (OPTIONAL | REPEATED) : typeInfo.type & MASK_MODIFIER; } /** @@ -111,14 +146,15 @@ public class ProtoBufType { * tags, null is returned. */ public Object getData(int tag) { - return (tag < 0 || tag >= data.size()) ? null : data.elementAt(tag); + TypeInfo typeInfo = (TypeInfo) types.get(tag); + return typeInfo == null ? typeInfo : typeInfo.data; } /** * Returns the type name set in the constructor for debugging purposes. */ public String toString() { - return typeName; + return "ProtoBufType Name: " + typeName; } /** @@ -138,9 +174,9 @@ public class ProtoBufType { } ProtoBufType other = (ProtoBufType) object; - return stringEquals(types, other.types); + return types.equals(other.types); } - + /** * {@inheritDoc} */ @@ -151,20 +187,4 @@ public class ProtoBufType { return super.hashCode(); } } - - public static boolean stringEquals(CharSequence a, CharSequence b) { - if (a == b) return true; - int length; - if (a != null && b != null && (length = a.length()) == b.length()) { - if (a instanceof String && b instanceof String) { - return a.equals(b); - } else { - for (int i = 0; i < length; i++) { - if (a.charAt(i) != b.charAt(i)) return false; - } - return true; - } - } - return false; - } } |