Variable-length fields are common in binary protocols. FastProto supports them via the lengthRef attribute on many annotations, allowing a field to reference a length/count defined elsewhere in the same class. This works for strings, byte arrays, numeric arrays, boolean arrays, and struct arrays.
StringType, BinaryType, AsciiArrayType, CharArrayType, BoolArrayType, Int8ArrayType, Int16ArrayType, Int32ArrayType, Int64ArrayType, UInt8ArrayType, UInt16ArrayType, UInt32ArrayType, UInt64ArrayType, FloatArrayType, DoubleArrayType, StructArrayType.@AutoType also supports lengthRef so you can write @AutoType(offset=..., lengthRef="$count") for arrays/strings/collections.length: a fixed number of elements/bytes.lengthRef: the name of a field in the same class that holds the length/count; it must be prefixed with $ (e.g. $count).lengthRef takes precedence for the effective length.import org.indunet.fastproto.annotation.StringType;
public class Packet {
@UInt16Type(offset = 0)
int nameLen;
// Read nameLen bytes at offset 2 as UTF-8 string
@StringType(offset = 2, lengthRef = "$nameLen", charset = "UTF-8")
String name;
}import org.indunet.fastproto.annotation.Int32ArrayType;
public class Packet {
@UInt16Type(offset = 0)
int count;
// Read count int32 elements starting at offset 2 (little endian by default unless overridden)
@Int32ArrayType(offset = 2, lengthRef = "$count")
int[] values;
}You can also use wrapper arrays, collections (e.g. List<Integer>) or @AutoType:
public class Packet {
@UInt16Type(offset = 0)
int count;
@AutoType(offset = 2, lengthRef = "$count")
List<Integer> values; // inferred as Int32ArrayType
}For arrays of structured items, use @StructArrayType. Each element is a POJO annotated with FastProto data type annotations.
@DefaultByteOrder(ByteOrder.LITTLE)
public class Item { // 6 bytes per item: UInt16 + Int32
@UInt16Type(offset = 0) int id;
@Int32Type(offset = 2) int value;
}
public class PacketFixed {
@StructArrayType(offset = 0, length = 2, element = Item.class)
Item[] items;
}@DefaultByteOrder(ByteOrder.LITTLE)
public class Item {
@UInt16Type(offset = 0) int id;
@Int32Type(offset = 2) int value;
}
public class PacketVar {
@UInt16Type(offset = 0)
int count;
// Read count items starting at offset 2
@StructArrayType(offset = 2, element = Item.class, lengthRef = "$count")
List<Item> items;
}lengthRef is case-sensitive and must start with $ followed by the field name.charset.BoolArrayType (byte-aligned). Per-bit packed variable-length booleans are not supported.@AutoType, you must still supply offset and lengthRef for arrays/strings; FastProto infers only the data type, not the layout.docs/arrays-and-strings.mddocs/annotation-mapping.mddocs/byte-and-bit-order.mddocs/dynamic-offset.md