[wpimath] Add remaining struct and protobuf implementations (#5953)

This commit is contained in:
Joseph Eng
2024-07-29 07:55:44 -07:00
committed by GitHub
parent 3e1e3fb4ca
commit 073192d513
112 changed files with 3989 additions and 45 deletions

View File

@@ -4,11 +4,14 @@
package edu.wpi.first.util.protobuf;
import java.lang.reflect.Array;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
import us.hebi.quickbuf.Descriptors.Descriptor;
import us.hebi.quickbuf.Descriptors.FileDescriptor;
import us.hebi.quickbuf.ProtoMessage;
import us.hebi.quickbuf.RepeatedDouble;
import us.hebi.quickbuf.RepeatedMessage;
/**
* Interface for Protobuf serialization.
@@ -18,7 +21,8 @@ import us.hebi.quickbuf.ProtoMessage;
* code is auto-generated from .proto interface descriptions (the MessageType generic parameter).
*
* <p>Idiomatically, classes that support protobuf serialization should provide a static final
* member named "proto" that provides an instance of an implementation of this interface.
* member named "proto" that provides an instance of an implementation of this interface, or a
* static final method named "getProto" if the class is generic.
*
* @param <T> object type
* @param <MessageType> protobuf message type
@@ -142,4 +146,67 @@ public interface Protobuf<T, MessageType extends ProtoMessage<?>> {
}
fn.accept(name, desc.toProtoBytes());
}
/**
* Unpack a serialized protobuf array message.
*
* @param <T> object type
* @param <MessageType> element type of the protobuf array
* @param msg protobuf array message
* @param proto protobuf implementation
* @return Deserialized array
*/
static <T, MessageType extends ProtoMessage<MessageType>> T[] unpackArray(
RepeatedMessage<MessageType> msg, Protobuf<T, MessageType> proto) {
@SuppressWarnings("unchecked")
T[] result = (T[]) Array.newInstance(proto.getTypeClass(), msg.length());
for (int i = 0; i < result.length; i++) {
result[i] = proto.unpack(msg.get(i));
}
return result;
}
/**
* Unpack a serialized protobuf double array message.
*
* @param msg protobuf double array message
* @return Deserialized array
*/
static double[] unpackArray(RepeatedDouble msg) {
double[] result = new double[msg.length()];
for (int i = 0; i < result.length; i++) {
result[i] = msg.get(i);
}
return result;
}
/**
* Pack a serialized protobuf array message.
*
* @param <T> object type
* @param <MessageType> element type of the protobuf array
* @param msg protobuf array message
* @param arr array of objects
* @param proto protobuf implementation
*/
static <T, MessageType extends ProtoMessage<MessageType>> void packArray(
RepeatedMessage<MessageType> msg, T[] arr, Protobuf<T, MessageType> proto) {
msg.clear();
msg.reserve(arr.length);
for (var obj : arr) {
proto.pack(msg.next(), obj);
}
}
/**
* Pack a serialized protobuf double array message.
*
* @param msg protobuf double array message
* @param arr array of objects
*/
static void packArray(RepeatedDouble msg, double[] arr) {
msg.clear();
msg.reserve(arr.length);
msg.addAll(arr);
}
}

View File

@@ -10,6 +10,7 @@ import edu.wpi.first.util.WPISerializable;
* Marker interface to indicate a class is serializable using Protobuf serialization.
*
* <p>While this cannot be enforced by the interface, any class implementing this interface should
* provide a public final static `proto` member variable.
* provide a public final static `proto` member variable, or a static final `getProto()` method if
* the class is generic.
*/
public interface ProtobufSerializable extends WPISerializable {}

View File

@@ -4,6 +4,7 @@
package edu.wpi.first.util.struct;
import java.lang.reflect.Array;
import java.nio.ByteBuffer;
/**
@@ -124,6 +125,73 @@ public interface Struct<T> {
throw new UnsupportedOperationException("object does not support unpackInto");
}
/**
* Deserializes an array from a raw struct serialized ByteBuffer starting at the current position.
* Will increment the ByteBuffer position by size * struct.size() bytes. Will not otherwise modify
* the ByteBuffer (e.g. byte order will not be changed).
*
* @param <T> Object type
* @param bb ByteBuffer
* @param size Size of the array
* @param struct Struct implementation
* @return Deserialized array
*/
static <T> T[] unpackArray(ByteBuffer bb, int size, Struct<T> struct) {
@SuppressWarnings("unchecked")
T[] arr = (T[]) Array.newInstance(struct.getTypeClass(), size);
for (int i = 0; i < arr.length; i++) {
arr[i] = struct.unpack(bb);
}
return arr;
}
/**
* Deserializes a double array from a raw struct serialized ByteBuffer starting at the current
* position. Will increment the ByteBuffer position by size * kSizeDouble bytes. Will not
* otherwise modify the ByteBuffer (e.g. byte order will not be changed).
*
* @param bb ByteBuffer
* @param size Size of the array
* @return Double array
*/
static double[] unpackDoubleArray(ByteBuffer bb, int size) {
double[] arr = new double[size];
for (int i = 0; i < size; i++) {
arr[i] = bb.getDouble();
}
return arr;
}
/**
* Puts array contents to a ByteBuffer starting at the current position. Will increment the
* ByteBuffer position by size * struct.size() bytes. Will not otherwise modify the ByteBuffer
* (e.g. byte order will not be changed).
*
* @param <T> Object type
* @param bb ByteBuffer
* @param arr Array to serialize
* @param struct Struct implementation
*/
static <T> void packArray(ByteBuffer bb, T[] arr, Struct<T> struct) {
for (T obj : arr) {
struct.pack(bb, obj);
}
}
/**
* Puts array contents to a ByteBuffer starting at the current position. Will increment the
* ByteBuffer position by size * kSizeDouble bytes. Will not otherwise modify the ByteBuffer (e.g.
* byte order will not be changed).
*
* @param bb ByteBuffer
* @param arr Array to serialize
*/
static void packArray(ByteBuffer bb, double[] arr) {
for (double obj : arr) {
bb.putDouble(obj);
}
}
/**
* Returns whether or not objects are immutable. Immutable objects must also be comparable using
* the equals() method. Default implementation returns false.