Core gRPC library containing transport implementation, channel abstraction, load balancing, name resolution, and other fundamental gRPC functionalities for Java
—
gRPC Core provides memory-efficient buffer abstractions for handling data in gRPC streams. These interfaces allow different transport implementations to optimize memory usage while providing a consistent API for reading and writing data.
Interface for reading data from buffers in a streaming fashion.
/**
* Interface for readable byte buffers
* Located: io.grpc.internal.ReadableBuffer
*/
interface ReadableBuffer {
/**
* Gets the number of readable bytes remaining in this buffer
* @return Number of bytes that can be read
*/
int readableBytes();
/**
* Reads a single byte as an unsigned integer (0-255)
* @return Unsigned byte value
* @throws IndexOutOfBoundsException if no bytes are readable
*/
int readUnsignedByte();
/**
* Reads bytes into the destination array
* @param dest Destination byte array
* @param destOffset Starting offset in destination array
* @param length Number of bytes to read
* @throws IndexOutOfBoundsException if not enough bytes are readable
*/
void readBytes(byte[] dest, int destOffset, int length);
/**
* Reads bytes into a newly allocated byte array
* @param length Number of bytes to read
* @return Byte array containing the read data
* @throws IndexOutOfBoundsException if not enough bytes are readable
*/
void readBytes(byte[] dest);
/**
* Reads bytes into a new readable buffer
* @param length Number of bytes to read
* @return New ReadableBuffer containing the read data
* @throws IndexOutOfBoundsException if not enough bytes are readable
*/
ReadableBuffer readBytes(int length);
/**
* Skips the specified number of bytes
* @param length Number of bytes to skip
* @throws IndexOutOfBoundsException if not enough bytes are readable
*/
void skipBytes(int length);
/**
* Checks if this buffer has a backing byte array
* @return true if hasArray() and array() are supported
*/
boolean hasArray();
/**
* Gets the backing byte array (if available)
* @return Backing byte array
* @throws UnsupportedOperationException if hasArray() returns false
*/
byte[] array();
/**
* Gets the offset in the backing array where readable data starts
* @return Array offset
* @throws UnsupportedOperationException if hasArray() returns false
*/
int arrayOffset();
/**
* Closes the buffer and releases any associated resources
*/
void close();
}Interface for writing data to buffers.
/**
* Interface for writable byte buffers
* Located: io.grpc.internal.WritableBuffer
*/
interface WritableBuffer {
/**
* Writes bytes from the source array to this buffer
* @param src Source byte array
* @param srcOffset Starting offset in source array
* @param length Number of bytes to write
* @throws IndexOutOfBoundsException if buffer doesn't have enough space
*/
void write(byte[] src, int srcOffset, int length);
/**
* Writes all bytes from the source array to this buffer
* @param src Source byte array
* @throws IndexOutOfBoundsException if buffer doesn't have enough space
*/
void write(byte[] src);
/**
* Writes a single byte to this buffer
* @param b Byte value to write
* @throws IndexOutOfBoundsException if buffer doesn't have enough space
*/
void write(int b);
/**
* Gets the number of bytes that can still be written to this buffer
* @return Number of writable bytes remaining
*/
int writableBytes();
/**
* Gets the number of bytes that have been written and can be read
* @return Number of readable bytes
*/
int readableBytes();
/**
* Releases the buffer and returns it as a ReadableBuffer
* After calling this method, the WritableBuffer should not be used
* @return ReadableBuffer containing the written data
*/
ReadableBuffer readableBuffer();
}Interface for allocating writable buffers.
/**
* Interface for allocating writable buffers
* Located: io.grpc.internal.WritableBufferAllocator
*/
interface WritableBufferAllocator {
/**
* Allocates a new writable buffer with the specified capacity hint
* @param capacityHint Hint for the desired buffer capacity
* @return New WritableBuffer instance
*/
WritableBuffer allocate(int capacityHint);
}Implementation that combines multiple readable buffers into a single logical buffer.
/**
* Composite readable buffer implementation
* Located: io.grpc.internal.CompositeReadableBuffer
*/
class CompositeReadableBuffer implements ReadableBuffer {
/**
* Creates a new composite buffer
*/
public CompositeReadableBuffer();
/**
* Adds a buffer to the end of this composite buffer
* @param buffer Buffer to add
* @throws IllegalArgumentException if buffer is null
*/
public void addBuffer(ReadableBuffer buffer);
@Override
public int readableBytes();
@Override
public int readUnsignedByte();
@Override
public void readBytes(byte[] dest, int destOffset, int length);
@Override
public void readBytes(byte[] dest);
@Override
public ReadableBuffer readBytes(int length);
@Override
public void skipBytes(int length);
@Override
public boolean hasArray();
@Override
public byte[] array();
@Override
public int arrayOffset();
@Override
public void close();
}Simple implementations using byte arrays as backing storage.
/**
* ReadableBuffer implementation backed by a byte array
* Located: io.grpc.internal.ReadableBuffers
*/
class ReadableBuffers {
/**
* Creates a readable buffer wrapping the entire byte array
* @param bytes Byte array to wrap
* @return ReadableBuffer wrapping the array
*/
public static ReadableBuffer wrap(byte[] bytes);
/**
* Creates a readable buffer wrapping part of a byte array
* @param bytes Byte array to wrap
* @param offset Starting offset in the array
* @param length Number of bytes to include
* @return ReadableBuffer wrapping the specified array section
*/
public static ReadableBuffer wrap(byte[] bytes, int offset, int length);
/**
* Creates an empty readable buffer
* @return Empty ReadableBuffer
*/
public static ReadableBuffer empty();
}
/**
* WritableBuffer implementation backed by a byte array
* Located: io.grpc.internal.WritableBuffers
*/
class WritableBuffers {
/**
* Creates a writable buffer with the specified initial capacity
* @param capacity Initial capacity in bytes
* @return WritableBuffer with the specified capacity
*/
public static WritableBuffer allocate(int capacity);
}import io.grpc.internal.ReadableBuffer;
import io.grpc.internal.CompositeReadableBuffer;
// Reading from a single buffer
ReadableBuffer buffer = getMessageBuffer();
byte[] messageData = new byte[buffer.readableBytes()];
buffer.readBytes(messageData);
buffer.close();
// Reading from composite buffer (multiple chunks)
CompositeReadableBuffer composite = new CompositeReadableBuffer();
composite.addBuffer(chunk1);
composite.addBuffer(chunk2);
composite.addBuffer(chunk3);
// Read the entire composite as one logical buffer
byte[] fullMessage = new byte[composite.readableBytes()];
composite.readBytes(fullMessage);
composite.close();import io.grpc.internal.WritableBuffer;
import io.grpc.internal.WritableBufferAllocator;
// Allocate buffer for writing
WritableBufferAllocator allocator = getBufferAllocator();
WritableBuffer buffer = allocator.allocate(1024);
// Write data to buffer
byte[] messageData = serializeMessage(message);
buffer.write(messageData);
// Convert to readable buffer for transmission
ReadableBuffer readable = buffer.readableBuffer();
sendBuffer(readable);import io.grpc.internal.WritableBufferAllocator;
import io.grpc.internal.WritableBuffer;
// Custom allocator implementation
public class PooledBufferAllocator implements WritableBufferAllocator {
private final BufferPool pool;
public PooledBufferAllocator(BufferPool pool) {
this.pool = pool;
}
@Override
public WritableBuffer allocate(int capacityHint) {
// Get buffer from pool based on capacity hint
return pool.borrowBuffer(capacityHint);
}
}// Always close buffers to prevent memory leaks
ReadableBuffer buffer = null;
try {
buffer = receiveBuffer();
processBuffer(buffer);
} finally {
if (buffer != null) {
buffer.close();
}
}
// Or use try-with-resources if buffer implements AutoCloseable
try (ReadableBuffer buffer = receiveBuffer()) {
processBuffer(buffer);
}hasArray() to access backing arrays directly when possibleBuffer operations handle errors through:
array() when hasArray() is false)close() methodsInstall with Tessl CLI
npx tessl i tessl/maven-io-grpc--grpc-core