Add various/minor changes to some TProtocols for consistency and convenience
Clients: "java"
diff --git a/lib/java/src/main/java/org/apache/thrift/protocol/TCompactProtocol.java b/lib/java/src/main/java/org/apache/thrift/protocol/TCompactProtocol.java
index 3407f62..bd36b6b 100644
--- a/lib/java/src/main/java/org/apache/thrift/protocol/TCompactProtocol.java
+++ b/lib/java/src/main/java/org/apache/thrift/protocol/TCompactProtocol.java
@@ -23,6 +23,7 @@
import java.nio.charset.StandardCharsets;
import java.util.UUID;
import org.apache.thrift.TException;
+import org.apache.thrift.partial.TFieldData;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
@@ -536,29 +537,7 @@
return TSTOP;
}
- short fieldId;
-
- // mask off the 4 MSB of the type header. it could contain a field id delta.
- short modifier = (short) ((type & 0xf0) >> 4);
- if (modifier == 0) {
- // not a delta. look ahead for the zigzag varint field id.
- fieldId = readI16();
- } else {
- // has a delta. add the delta to the last read field id.
- fieldId = (short) (lastFieldId_ + modifier);
- }
-
- TField field = new TField("", getTType((byte) (type & 0x0f)), fieldId);
-
- // if this happens to be a boolean field, the value is encoded in the type
- if (isBoolType(type)) {
- // save the boolean value in a special instance variable.
- boolValue_ = (byte) (type & 0x0f) == Types.BOOLEAN_TRUE ? Boolean.TRUE : Boolean.FALSE;
- }
-
- // push the new field onto the field stack so we can keep the deltas going.
- lastFieldId_ = field.id;
- return field;
+ return new TField("", getTType((byte) (type & 0x0f)), readFieldId(type));
}
/**
@@ -945,6 +924,43 @@
// Additional methods to improve performance.
@Override
+ public int readFieldBeginData() throws TException {
+ byte type = readByte();
+
+ // if it's a stop, then we can return immediately, as the struct is over.
+ if (type == TType.STOP) {
+ return TFieldData.encode(type);
+ }
+
+ return TFieldData.encode(getTType((byte) (type & 0x0f)), readFieldId(type));
+ }
+
+ // Only makes sense to be called by readFieldBegin and readFieldBeginData
+ private short readFieldId(byte type) throws TException {
+ short fieldId;
+
+ // mask off the 4 MSB of the type header. it could contain a field id delta.
+ short modifier = (short) ((type & 0xf0) >> 4);
+ if (modifier == 0) {
+ // not a delta. look ahead for the zigzag varint field id.
+ fieldId = readI16();
+ } else {
+ // has a delta. add the delta to the last read field id.
+ fieldId = (short) (lastFieldId_ + modifier);
+ }
+
+ // if this happens to be a boolean field, the value is encoded in the type
+ if (isBoolType(type)) {
+ // save the boolean value in a special instance variable.
+ boolValue_ = (byte) (type & 0x0f) == Types.BOOLEAN_TRUE ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ // push the new field onto the field stack so we can keep the deltas going.
+ lastFieldId_ = fieldId;
+ return fieldId;
+ }
+
+ @Override
protected void skipBinary() throws TException {
int size = intToZigZag(readI32());
this.skipBytes(size);
diff --git a/lib/java/src/main/java/org/apache/thrift/protocol/TProtocol.java b/lib/java/src/main/java/org/apache/thrift/protocol/TProtocol.java
index 22333d5..3fd27b4 100644
--- a/lib/java/src/main/java/org/apache/thrift/protocol/TProtocol.java
+++ b/lib/java/src/main/java/org/apache/thrift/protocol/TProtocol.java
@@ -223,7 +223,25 @@
* @throws TException when any sub-operation fails
*/
public final <K, V> Map<K, V> readMap(ReadMapEntryCallback<K, V> callback) throws TException {
- return readMap(callback, HashMap::new);
+ return readMap(callback::getKey, callback::getValue);
+ }
+
+ /**
+ * read a {@link Map} of elements by delegating key reading to the callback, handles {@link
+ * #readMapBegin() begin} and {@link #readMapEnd() end} automatically. Calls to keyCallback and
+ * valueCallback will be in alternating orders, i.e. k1, v1, k2, v2, .., k_n, v_n
+ *
+ * @param keyCallback callback for reading keys
+ * @param valueCallback callback for reading values
+ * @param <K> key type
+ * @param <V> value type
+ * @return the map read
+ * @throws TException when any sub-operation fails
+ */
+ public final <K, V> Map<K, V> readMap(
+ ReadCollectionCallback<K> keyCallback, ReadCollectionCallback<V> valueCallback)
+ throws TException {
+ return readMap(keyCallback, valueCallback, size -> new HashMap<>(2 * size));
}
/**
@@ -242,11 +260,33 @@
*/
public final <K, V> Map<K, V> readMap(
ReadMapEntryCallback<K, V> callback, IntFunction<Map<K, V>> mapCreator) throws TException {
+ return readMap(callback::getKey, callback::getValue, mapCreator);
+ }
+
+ /**
+ * read a {@link Map} of elements by delegating key and value reading to the callback, handles
+ * {@link #readMapBegin() begin} and {@link #readMapEnd() end} automatically, with a specialized
+ * map creator given the size hint. Calls to keyCallback and valueCallback will be in alternating
+ * orders, i.e. k1, v1, k2, v2, .., k_n, v_n
+ *
+ * @param keyCallback callback for reading keys
+ * @param valueCallback callback for reading values
+ * @param mapCreator map creator given the size hint
+ * @param <K> key type
+ * @param <V> value type
+ * @return the map read
+ * @throws TException when any sub-operation fails
+ */
+ public final <K, V> Map<K, V> readMap(
+ ReadCollectionCallback<K> keyCallback,
+ ReadCollectionCallback<V> valueCallback,
+ IntFunction<Map<K, V>> mapCreator)
+ throws TException {
return readMap(
tMap -> {
Map<K, V> map = mapCreator.apply(tMap.size);
for (int i = 0; i < tMap.size; i += 1) {
- map.put(callback.getKey(), callback.getValue());
+ map.put(keyCallback.call(), valueCallback.call());
}
return map;
});
@@ -330,7 +370,7 @@
* @throws TException when any sub-operation fails
*/
public final <T> Set<T> readSet(ReadCollectionCallback<T> callback) throws TException {
- return readSet(callback, HashSet::new);
+ return readSet(callback, size -> new HashSet<>(2 * size));
}
/**
diff --git a/lib/java/src/main/java/org/apache/thrift/protocol/TProtocolDecorator.java b/lib/java/src/main/java/org/apache/thrift/protocol/TProtocolDecorator.java
index bd9bd8e..f84ce81 100644
--- a/lib/java/src/main/java/org/apache/thrift/protocol/TProtocolDecorator.java
+++ b/lib/java/src/main/java/org/apache/thrift/protocol/TProtocolDecorator.java
@@ -262,6 +262,46 @@
return concreteProtocol.readBinary();
}
+ @Override
+ public int readFieldBeginData() throws TException {
+ return concreteProtocol.readFieldBeginData();
+ }
+
+ @Override
+ protected void skipBool() throws TException {
+ concreteProtocol.skipBool();
+ }
+
+ @Override
+ protected void skipByte() throws TException {
+ concreteProtocol.skipByte();
+ }
+
+ @Override
+ protected void skipI16() throws TException {
+ concreteProtocol.skipI16();
+ }
+
+ @Override
+ protected void skipI32() throws TException {
+ concreteProtocol.skipI32();
+ }
+
+ @Override
+ protected void skipI64() throws TException {
+ concreteProtocol.skipI64();
+ }
+
+ @Override
+ protected void skipDouble() throws TException {
+ concreteProtocol.skipDouble();
+ }
+
+ @Override
+ protected void skipBinary() throws TException {
+ concreteProtocol.skipBinary();
+ }
+
/**
* @param type Returns the minimum amount of bytes needed to store the smallest possible instance
* of TType.
@@ -272,4 +312,9 @@
public int getMinSerializedSize(byte type) throws TException {
return concreteProtocol.getMinSerializedSize(type);
}
+
+ @Override
+ public void reset() {
+ concreteProtocol.reset();
+ }
}