下面列出了com.google.protobuf.CodedInputStream# readTag ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Parses the entry.
*
* @param <K> the key type
* @param <V> the value type
* @param input the input
* @param metadata the metadata
* @param extensionRegistry the extension registry
* @return the map. entry
* @throws IOException Signals that an I/O exception has occurred.
*/
static <K, V> Map.Entry<K, V> parseEntry(CodedInputStream input, Metadata<K, V> metadata,
ExtensionRegistryLite extensionRegistry) throws IOException {
K key = metadata.defaultKey;
V value = metadata.defaultValue;
while (true) {
int tag = input.readTag();
if (tag == 0) {
break;
}
if (tag == CodedConstant.makeTag(KEY_FIELD_NUMBER, metadata.keyType.getWireType())) {
key = parseField(input, extensionRegistry, metadata.keyType, key);
} else if (tag == CodedConstant.makeTag(VALUE_FIELD_NUMBER, metadata.valueType.getWireType())) {
value = parseField(input, extensionRegistry, metadata.valueType, value);
} else {
if (!input.skipField(tag)) {
break;
}
}
}
return new AbstractMap.SimpleImmutableEntry<K, V>(key, value);
}
/**
* Parses a serialized HyperLogLog++ {@link AggregatorStateProto} and populates this object's
* fields. If the {@code input} supports aliasing (for byte arrays and {@link ByteBuffer}, see
* {@link CodedInputStream#enableAliasing(boolean) for details}), {@link #data} and {@link
* #sparseData} will <em>alias</em> the given bytes — sharing the same memory.
*
* @throws IOException If the stream does not contain a serialized {@link AggregatorStateProto} or
* if fields are set that would typically not belong
*/
public void parse(CodedInputStream input) throws IOException {
// Reset defaults as values set to the default will not be encoded in the protocol buffer.
clear();
UnknownFieldSet.Builder ignoredFields = UnknownFieldSet.newBuilder();
while (!input.isAtEnd()) {
int tag = input.readTag();
switch (tag) {
case TYPE_TAG:
type = AggregatorType.forNumber(input.readEnum());
break;
case NUM_VALUES_TAG:
numValues = input.readInt64();
break;
case ENCODING_VERSION_TAG:
encodingVersion = input.readInt32();
break;
case VALUE_TYPE_TAG:
valueType = ValueType.forNumber(input.readEnum());
break;
case HYPERLOGLOGPLUS_UNIQUE_STATE_TAG:
parseHll(input, input.readInt32());
break;
default:
ignoredFields.mergeFieldFrom(tag, input);
}
}
}
/**
* Parses a {@link HyperLogLogPlusUniqueStateProto} message. Since the message is nested within an
* {@link AggregatorStateProto}, we limit ourselves to reading only the bytes of the specified
* message length.
*/
private void parseHll(CodedInputStream input, int size) throws IOException {
int limit = input.getTotalBytesRead() + size;
ByteBuffer buffer;
UnknownFieldSet.Builder ignoredFields = UnknownFieldSet.newBuilder();
while (input.getTotalBytesRead() < limit && !input.isAtEnd()) {
int tag = input.readTag();
switch (tag) {
case SPARSE_SIZE_TAG:
sparseSize = input.readInt32();
break;
case PRECISION_OR_NUM_BUCKETS_TAG:
precision = input.readInt32();
break;
case SPARSE_PRECISION_OR_NUM_BUCKETS_TAG:
sparsePrecision = input.readInt32();
break;
case DATA_TAG:
buffer = input.readByteBuffer();
data = ByteSlice.copyOnWrite(buffer);
break;
case SPARSE_DATA_TAG:
buffer = input.readByteBuffer();
sparseData = GrowingByteSlice.copyOnWrite(buffer);
break;
default:
ignoredFields.mergeFieldFrom(tag, input);
}
}
}
/**
* Cheap test to see if input stream is a wallet. This checks for a magic value at the beginning of the stream.
*
* @param is input stream to test
* @return true if input stream is a wallet
*/
public static boolean isWallet(InputStream is) {
try {
final CodedInputStream cis = CodedInputStream.newInstance(is);
final int tag = cis.readTag();
final int field = WireFormat.getTagFieldNumber(tag);
if (field != 1) // network_identifier
return false;
final String network = cis.readString();
return NetworkParameters.fromID(network) != null;
} catch (IOException x) {
return false;
}
}
/**
* Cheap test to see if input stream is a wallet. This checks for a magic value at the beginning of the stream.
*
* @param is
* input stream to test
* @return true if input stream is a wallet
*/
public static boolean isWallet(InputStream is) {
try {
final CodedInputStream cis = CodedInputStream.newInstance(is);
final int tag = cis.readTag();
final int field = WireFormat.getTagFieldNumber(tag);
if (field != 1) // network_identifier
return false;
final String network = cis.readString();
return NetworkParameters.fromID(network) != null;
} catch (IOException x) {
return false;
}
}
/**
* Cheap test to see if input stream is a wallet. This checks for a magic value at the beginning of the stream.
*
* @param is
* input stream to test
* @return true if input stream is a wallet
*/
public static boolean isWallet(InputStream is) {
try {
final CodedInputStream cis = CodedInputStream.newInstance(is);
final int tag = cis.readTag();
final int field = WireFormat.getTagFieldNumber(tag);
if (field != 1) // network_identifier
return false;
final String network = cis.readString();
return NetworkParameters.fromID(network) != null;
} catch (IOException x) {
return false;
}
}
/**
* Parses an entry off of the input into the map. This helper avoids allocaton of a {@link MapEntryLite} by parsing
* directly into the provided {@link MapFieldLite}.
*
* @param map the map
* @param input the input
* @param extensionRegistry the extension registry
* @throws IOException Signals that an I/O exception has occurred.
*/
public void parseInto(MapFieldLite<K, V> map, CodedInputStream input, ExtensionRegistryLite extensionRegistry)
throws IOException {
int length = input.readRawVarint32();
final int oldLimit = input.pushLimit(length);
K key = metadata.defaultKey;
V value = metadata.defaultValue;
while (true) {
int tag = input.readTag();
if (tag == 0) {
break;
}
if (tag == CodedConstant.makeTag(KEY_FIELD_NUMBER, metadata.keyType.getWireType())) {
key = parseField(input, extensionRegistry, metadata.keyType, key);
} else if (tag == CodedConstant.makeTag(VALUE_FIELD_NUMBER, metadata.valueType.getWireType())) {
value = parseField(input, extensionRegistry, metadata.valueType, value);
} else {
if (!input.skipField(tag)) {
break;
}
}
}
input.checkLastTagWas(0);
input.popLimit(oldLimit);
map.put(key, value);
}
public long extractTimestampMillis(String topic, final byte[] bytes) throws IOException {
if (timestampFieldPath != null) {
com.google.protobuf.Message decodedMessage = protobufUtil.decodeProtobufOrJsonMessage(topic,
bytes);
int i = 0;
for (; i < timestampFieldPath.length - 1; ++i) {
decodedMessage = (com.google.protobuf.Message) decodedMessage
.getField(decodedMessage.getDescriptorForType().findFieldByName(timestampFieldPath[i]));
}
Object timestampObject = decodedMessage
.getField(decodedMessage.getDescriptorForType().findFieldByName(timestampFieldPath[i]));
if (timestampObject instanceof com.google.protobuf.Timestamp){
return Timestamps.toMillis((com.google.protobuf.Timestamp) timestampObject);
}else {
return toMillis((Long) timestampObject);
}
} else {
// Assume that the timestamp field is the first field, is required,
// and is a uint64.
CodedInputStream input = CodedInputStream.newInstance(bytes);
// Don't really care about the tag, but need to read it to get, to
// the payload.
input.readTag();
return toMillis(input.readUInt64());
}
}
public static ArrayList<ByteString> extractWireFormatTxOut(Transaction tx)
throws ValidationException
{
try
{
CodedInputStream code_in = CodedInputStream.newInstance(tx.getInnerData().toByteArray());
ArrayList<ByteString> lst = new ArrayList<>();
while(true)
{
int tag = code_in.readTag();
if (tag == 0) break;
// The least signficiate 3 bits are the proto field type
// so shift to get out field number, which is 5 for TranasctionOutput
if (tag >> 3 == 5)
{
ByteArrayOutputStream b_out = new ByteArrayOutputStream();
CodedOutputStream c_out = CodedOutputStream.newInstance(b_out);
code_in.skipField(tag, c_out);
c_out.flush();
ByteString bs = ByteString.copyFrom(b_out.toByteArray());
// So funny story...when you get an inner message like this as opposed to just serializing
// the object, protobuf puts a tag and size on the coded input stream. So we need to figure
// out how many bytes that is an trim it off.
CodedInputStream read_again = CodedInputStream.newInstance(bs.toByteArray());
// Expected tag
int tag2 = read_again.readTag();
// Size of element
int size = read_again.readInt32();
// All we really care is how many bytes those two take. For shorter messages
// it will be 2, but could be higher if protobuf needs more bytes to encode the size
int offset = read_again.getTotalBytesRead();
bs = bs.substring(offset);
lst.add(bs);
}
else
{
code_in.skipField(tag);
}
}
return lst;
}
catch(java.io.IOException e)
{
throw new ValidationException(e);
}
}
@NonNull
@Override
public FileDataSource loadData(InputStream inputStream, String filePath) throws Exception {
long propertiesOffset = 0L;
Track track = new Track();
CodedInputStream input = CodedInputStream.newInstance(inputStream);
boolean done = false;
while (!done) {
long offset = input.getTotalBytesRead();
int tag = input.readTag();
int field = WireFormat.getTagFieldNumber(tag);
switch (field) {
case 0:
done = true;
break;
default: {
throw new com.google.protobuf.InvalidProtocolBufferException("Unsupported proto field: " + tag);
}
case FIELD_VERSION: {
// skip version
input.skipField(tag);
break;
}
case FIELD_POINT: {
int length = input.readRawVarint32();
int oldLimit = input.pushLimit(length);
readPoint(track, input);
input.popLimit(oldLimit);
input.checkLastTagWas(0);
break;
}
case FIELD_NAME: {
propertiesOffset = offset;
track.name = input.readBytes().toStringUtf8();
break;
}
case FIELD_COLOR: {
track.style.color = input.readUInt32();
break;
}
case FIELD_WIDTH: {
track.style.width = input.readFloat();
break;
}
}
}
inputStream.close();
track.id = 31 * filePath.hashCode() + 1;
FileDataSource dataSource = new FileDataSource();
dataSource.name = track.name;
dataSource.tracks.add(track);
track.source = dataSource;
dataSource.propertiesOffset = propertiesOffset;
return dataSource;
}
private void readPoint(Track track, CodedInputStream input) throws IOException {
int latitudeE6 = 0;
int longitudeE6 = 0;
boolean continuous = true;
float altitude = Float.NaN;
float speed = Float.NaN;
float bearing = Float.NaN;
float accuracy = Float.NaN;
long timestamp = 0L;
boolean done = false;
while (!done) {
int tag = input.readTag();
int field = WireFormat.getTagFieldNumber(tag);
switch (field) {
case 0:
done = true;
break;
default: {
throw new com.google.protobuf.InvalidProtocolBufferException("Unsupported proto field: " + tag);
}
case FIELD_POINT_LATITUDE: {
latitudeE6 = input.readInt32();
break;
}
case FIELD_POINT_LONGITUDE: {
longitudeE6 = input.readInt32();
break;
}
case FIELD_POINT_ALTITUDE: {
altitude = input.readFloat();
break;
}
case FIELD_POINT_SPEED: {
speed = input.readFloat();
break;
}
case FIELD_POINT_BEARING: {
bearing = input.readFloat();
break;
}
case FIELD_POINT_ACCURACY: {
accuracy = input.readFloat();
break;
}
case FIELD_POINT_TIMESTAMP: {
timestamp = input.readUInt64();
break;
}
case FIELD_POINT_CONTINUOUS: {
continuous = input.readBool();
break;
}
}
}
track.addPointFast(continuous, latitudeE6, longitudeE6, altitude, speed, bearing, accuracy, timestamp);
}