summaryrefslogtreecommitdiffstats
path: root/src/com/google/common/io/protocol/ProtoBufType.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/google/common/io/protocol/ProtoBufType.java')
-rw-r--r--src/com/google/common/io/protocol/ProtoBufType.java106
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 4b6408e..728346f 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;
- }
}