Class LengthPrefixedFramingHandler
- All Implemented Interfaces:
FramingHandler
This implementation frames messages by prepending a 4-byte (32-bit) unsigned integer in network byte order (big-endian) that specifies the payload length. This is one of the most common framing strategies used in network protocols.
Frame Format
┌────────────────────────┬─────────────────────────────────────┐
│ Length (4 bytes, BE) │ Payload (N bytes) │
└────────────────────────┴─────────────────────────────────────┘
▲ ▲
│ │
Network byte order Variable length
(big-endian) (0 to maxPayloadSize)
Configuration
The maximum payload size is configurable at construction time. The default is 16 MB (16777216 bytes), which is suitable for most applications. For protocols with smaller messages, a lower limit reduces memory requirements and provides better protection against malformed length prefixes.
Usage Example
// Create with default max size (16 MB)
FramingHandler framing = new LengthPrefixedFramingHandler();
// Or with custom max size (1 MB)
FramingHandler framing = new LengthPrefixedFramingHandler(1024 * 1024);
// Frame a message
byte[] payload = "Hello, World!".getBytes(StandardCharsets.UTF_8);
MemorySegment source = MemorySegment.ofArray(payload);
MemorySegment frame = Arena.global().allocate(payload.length + framing.getHeaderSize());
int frameLength = framing.frameMessage(source, payload.length, frame);
// Deframe a message
MemorySegment received = ...; // from network
MemorySegment output = Arena.global().allocate(framing.getMaxPayloadSize());
int payloadLength = framing.deframeMessage(received, bytesReceived, output);
if (payloadLength >= 0) {
// Process complete message
}
Thread Safety
This class is immutable and thread-safe. The same instance can be used concurrently by multiple threads for framing and deframing operations. All configuration is fixed at construction time.
Zero-Copy Operation
This implementation uses MemorySegment.copy(MemorySegment, long, MemorySegment, long, long)
for efficient data transfer between segments. No intermediate buffers are allocated during
framing or deframing operations.
- See Also:
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intThe default maximum payload size: 16 MB.static final intThe size of the length prefix header in bytes. -
Constructor Summary
ConstructorsConstructorDescriptionCreates a new length-prefixed framing handler with the default maximum payload size.LengthPrefixedFramingHandler(int maxPayloadSize) Creates a new length-prefixed framing handler with the specified maximum payload size. -
Method Summary
Modifier and TypeMethodDescriptionintdeframeMessage(MemorySegment source, int sourceLength, MemorySegment destination) Deframes a message by extracting the payload from a framed message.intframeMessage(MemorySegment source, int sourceLength, MemorySegment destination) Frames a message by adding protocol-specific headers to the payload.intReturns the size of the framing header in bytes.intReturns the maximum payload size that can be framed.toString()Returns a string representation of this framing handler.
-
Field Details
-
HEADER_SIZE
public static final int HEADER_SIZEThe size of the length prefix header in bytes.- See Also:
-
DEFAULT_MAX_PAYLOAD_SIZE
public static final int DEFAULT_MAX_PAYLOAD_SIZEThe default maximum payload size: 16 MB.- See Also:
-
-
Constructor Details
-
LengthPrefixedFramingHandler
public LengthPrefixedFramingHandler()Creates a new length-prefixed framing handler with the default maximum payload size.The default maximum payload size is 16777216 bytes (16 MB).
-
LengthPrefixedFramingHandler
public LengthPrefixedFramingHandler(int maxPayloadSize) Creates a new length-prefixed framing handler with the specified maximum payload size.- Parameters:
maxPayloadSize- the maximum payload size in bytes- Throws:
IllegalArgumentException- if maxPayloadSize is not positive or exceedsInteger.MAX_VALUE-HEADER_SIZE
-
-
Method Details
-
frameMessage
Frames a message by adding protocol-specific headers to the payload.This method writes the framing header followed by the payload data to the destination segment. The destination must have sufficient capacity to hold the entire frame (header + payload).
Required destination capacity:
sourceLength + getHeaderSize()This implementation writes a 4-byte big-endian length prefix followed by the payload. The length prefix contains the payload size (not including the header itself).
- Specified by:
frameMessagein interfaceFramingHandler- Parameters:
source- the source segment containing the message payloadsourceLength- the number of bytes to read from the source (payload length)destination- the destination segment to write the framed message to- Returns:
- the total frame length (header + payload), which equals
sourceLength + getHeaderSize() - Throws:
FramingException- if sourceLength exceedsgetMaxPayloadSize()
-
deframeMessage
Deframes a message by extracting the payload from a framed message.This method reads the framing header to determine the payload length, validates the frame, and copies the payload to the destination segment. If the source contains an incomplete frame (fewer bytes than indicated by the header), this method returns -1.
Return Values
>= 0: The payload length; the complete payload has been written to destination-1: Incomplete frame; more data is needed to complete deframing
Note: When returning -1, the destination segment contents are undefined and should not be used.
This implementation reads the 4-byte big-endian length prefix to determine the payload size, then copies the payload to the destination. Returns -1 if the source doesn't contain enough bytes for the complete frame (header + indicated payload length).
- Specified by:
deframeMessagein interfaceFramingHandler- Parameters:
source- the source segment containing the framed message (header + payload)sourceLength- the number of bytes available in the sourcedestination- the destination segment to write the extracted payload to- Returns:
- the payload length if deframing succeeded, or -1 if the frame is incomplete
- Throws:
FramingException- if the length prefix indicates a payload larger thangetMaxPayloadSize()or is negative
-
getHeaderSize
public int getHeaderSize()Returns the size of the framing header in bytes.This is the overhead added to each message by the framing protocol. For length-prefixed framing, this is typically 4 bytes (32-bit length field).
- Specified by:
getHeaderSizein interfaceFramingHandler- Returns:
- 4 (the size of the 32-bit length prefix)
-
getMaxPayloadSize
public int getMaxPayloadSize()Returns the maximum payload size that can be framed.Attempts to frame messages larger than this size will result in a
FramingException. This limit is typically configured at construction time and may be constrained by protocol requirements or memory considerations.- Specified by:
getMaxPayloadSizein interfaceFramingHandler- Returns:
- the maximum payload size in bytes
-
toString
-