Top Description Fields Constructors Methods
org.glassfish.grizzly.http2.hpack

public Class Encoder

extends Object
Class Inheritance
Static Imports
java.lang.String.format, java.util.Objects.requireNonNull

Encodes headers to their binary representation.

Typical lifecycle looks like this:

new Encoder (setMaxCapacity? encode)*

Suppose headers are represented by Map<String, List<String>>. A supplier and a consumer of Buffers in forms of Supplier<ByteBuffer> and Consumer<ByteBuffer> respectively. Then to encode headers, the following approach might be used:

for (Map.Entry<String, List<String>> h : headers.entrySet()) {
        String name = h.getKey();
        for (String value : h.getValue()) {
            encoder.header(name, value);        // Set up header
            boolean encoded;
            do {
                ByteBuffer b = buffersSupplier.get();
                encoded = encoder.encode(b);    // Encode the header
                buffersConsumer.accept(b);
            } while (!encoded);
        }
    }

Though the specification does not define how an encoder is to be implemented, a default implementation is provided by the method header(CharSequence, CharSequence, boolean).

To provide a custom encoding implementation, Encoder has to be extended. A subclass then can access methods for encoding using specific representations (e.g. literal, indexed, etc.)

An Encoder provides an incremental way of encoding headers. encode(Buffer) takes a buffer a returns a boolean indicating whether, or not, the buffer was sufficiently sized to hold the remaining of the encoded representation.

This way, there's no need to provide a buffer of a specific size, or to resize (and copy) the buffer on demand, when the remaining encoded representation will not fit in the buffer's remaining space. Instead, an array of existing buffers can be used, prepended with a frame that encloses the resulting header block afterwards.

Splitting the encoding operation into header set up and header encoding, separates long lived arguments (name, value, sensitivity, etc.) from the short lived ones (e.g. buffer), simplifying each operation itself.

The default implementation does not use dynamic table. It reports to a coupled Decoder a size update with the value of 0, and never changes it afterwards.

Field Summary

Modifier and TypeField and Description
private final BulkSizeUpdateWriter
private boolean
private boolean
private int
private static final boolean
private boolean
private final HeaderTable
private final IndexedWriter
private int
private final LiteralNeverIndexedWriter
private final LiteralWithIndexingWriter
private final LiteralWriter
private int
private long
private final SizeUpdateWriter
private BinaryRepresentationWriter

Constructor Summary

AccessConstructor and Description
public
Encoder(int
a non-negative integer
maxCapacity
)

Constructs an Encoder with the specified maximum capacity of the header table.

Method Summary

Modifier and TypeMethod and Description
protected int
calculateCapacity(int maxCapacity)

protected final void
public final boolean

Returns:

true if the current header has been fully encoded, false otherwise
encode
(Buffer
the buffer to encode the header into, may be empty
headerBlock
)

Encodes the set up header into the given buffer.

protected final HeaderTable
protected final int
public void
header(CharSequence
the name
name
,
CharSequence
the value
value
)

Sets up the given header (name, value).

public void
header(CharSequence
the name
name
,
CharSequence
the value
value
,
boolean
whether or not the value is sensitive
sensitive
)

Sets up the given header (name, value) with possibly sensitive value.

protected final void
indexed(int index)

protected final void
literal(int index, CharSequence value, boolean useHuffman)

protected final void
literal(CharSequence name, boolean nameHuffman, CharSequence value, boolean valueHuffman)

protected final void
literalNeverIndexed(int index, CharSequence value, boolean valueHuffman)

protected final void
literalNeverIndexed(CharSequence name, boolean nameHuffman, CharSequence value, boolean valueHuffman)

protected final void
literalWithIndexing(int index, CharSequence value, boolean valueHuffman)

protected final void
literalWithIndexing(CharSequence name, boolean nameHuffman, CharSequence value, boolean valueHuffman)

private boolean
public void
setMaxCapacity(int
a non-negative integer
capacity
)

Sets a maximum capacity of the header table.

protected final void
sizeUpdate(int capacity)

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

bulkSizeUpdateWriterback to summary
private final BulkSizeUpdateWriter bulkSizeUpdateWriter
capacityUpdateback to summary
private boolean capacityUpdate
configuredCapacityUpdateback to summary
private boolean configuredCapacityUpdate
currCapacityback to summary
private int currCapacity
DEFAULT_HUFFMANback to summary
private static final boolean DEFAULT_HUFFMAN
encodingback to summary
private boolean encoding
headerTableback to summary
private final HeaderTable headerTable
indexedWriterback to summary
private final IndexedWriter indexedWriter
lastCapacityback to summary
private int lastCapacity
literalNeverIndexedWriterback to summary
private final LiteralNeverIndexedWriter literalNeverIndexedWriter
literalWithIndexingWriterback to summary
private final LiteralWithIndexingWriter literalWithIndexingWriter
literalWriterback to summary
private final LiteralWriter literalWriter
maxCapacityback to summary
private int maxCapacity
minCapacityback to summary
private long minCapacity
sizeUpdateWriterback to summary
private final SizeUpdateWriter sizeUpdateWriter
writerback to summary
private BinaryRepresentationWriter writer

Constructor Detail

Encoderback to summary
public Encoder(int maxCapacity)

Constructs an Encoder with the specified maximum capacity of the header table.

The value has to be agreed between decoder and encoder out-of-band, e.g. by a protocol that uses HPACK (see 4.2. Maximum Table Size).

Parameters
maxCapacity:int

a non-negative integer

Exceptions
IllegalArgumentException:
if maxCapacity is negative

Method Detail

calculateCapacityback to summary
protected int calculateCapacity(int maxCapacity)
Annotations
@SuppressWarnings:UnusedParameters
checkEncodingback to summary
protected final void checkEncoding()
encodeback to summary
public final boolean encode(Buffer headerBlock)

Encodes the set up header into the given buffer.

The encoder writes as much as possible of the header's binary representation into the given buffer, starting at the buffer's position, and increments its position to reflect the bytes written. The buffer's mark and limit will not be modified.

Once the method has returned true, the current header is deemed encoded. A new header may be set up.

Parameters
headerBlock:Buffer

the buffer to encode the header into, may be empty

Returns:boolean

true if the current header has been fully encoded, false otherwise

Exceptions
NullPointerException:
if the buffer is null
ReadOnlyBufferException:
if this buffer is read-only
IllegalStateException:
if there is no set up header
getHeaderTableback to summary
protected final HeaderTable getHeaderTable()
getMaxCapacityback to summary
protected final int getMaxCapacity()
Annotations
@SuppressWarnings:unused
headerback to summary
public void header(CharSequence name, CharSequence value) throws IllegalStateException

Sets up the given header (name, value).

Fixates name and value for the duration of encoding.

Parameters
name:CharSequence

the name

value:CharSequence

the value

Exceptions
IllegalStateException:
if the encoder hasn't fully encoded the previous header, or hasn't yet started to encode it
NullPointerException:
if any of the arguments are null
See Also
header(CharSequence, CharSequence, boolean)
headerback to summary
public void header(CharSequence name, CharSequence value, boolean sensitive) throws IllegalStateException

Sets up the given header (name, value) with possibly sensitive value.

Fixates name and value for the duration of encoding.

Parameters
name:CharSequence

the name

value:CharSequence

the value

sensitive:boolean

whether or not the value is sensitive

Exceptions
IllegalStateException:
if the encoder hasn't fully encoded the previous header, or hasn't yet started to encode it
NullPointerException:
if any of the arguments are null
See Also
header(CharSequence, CharSequence), DecodingCallback#onDecoded(CharSequence, CharSequence, boolean)
indexedback to summary
protected final void indexed(int index) throws IndexOutOfBoundsException
literalback to summary
protected final void literal(int index, CharSequence value, boolean useHuffman) throws IndexOutOfBoundsException
literalback to summary
protected final void literal(CharSequence name, boolean nameHuffman, CharSequence value, boolean valueHuffman)
literalNeverIndexedback to summary
protected final void literalNeverIndexed(int index, CharSequence value, boolean valueHuffman) throws IndexOutOfBoundsException
literalNeverIndexedback to summary
protected final void literalNeverIndexed(CharSequence name, boolean nameHuffman, CharSequence value, boolean valueHuffman)
literalWithIndexingback to summary
protected final void literalWithIndexing(int index, CharSequence value, boolean valueHuffman) throws IndexOutOfBoundsException
Annotations
@SuppressWarnings:unused
literalWithIndexingback to summary
protected final void literalWithIndexing(CharSequence name, boolean nameHuffman, CharSequence value, boolean valueHuffman)
Annotations
@SuppressWarnings:unused
prependWithCapacityUpdateback to summary
private boolean prependWithCapacityUpdate(Buffer headerBlock)
setMaxCapacityback to summary
public void setMaxCapacity(int capacity)

Sets a maximum capacity of the header table.

The value has to be agreed between decoder and encoder out-of-band, e.g. by a protocol that uses HPACK (see 4.2. Maximum Table Size).

May be called any number of times after or before a complete header has been encoded.

If the encoder decides to change the actual capacity, an update will be encoded before a new encoding operation starts.

Parameters
capacity:int

a non-negative integer

Exceptions
IllegalArgumentException:
if capacity is negative
IllegalStateException:
if the encoder hasn't fully encoded the previous header, or hasn't yet started to encode it
sizeUpdateback to summary
protected final void sizeUpdate(int capacity) throws IllegalArgumentException
Annotations
@SuppressWarnings:unused