Import atomix/{storage,utils}
[controller.git] / third-party / atomix / storage / src / main / java / io / atomix / storage / buffer / Buffer.java
1 /*
2  * Copyright 2015-present Open Networking Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package io.atomix.storage.buffer;
17
18 import io.atomix.utils.concurrent.ReferenceCounted;
19
20 import java.nio.ByteOrder;
21
22 /**
23  * Navigable byte buffer for input/output operations.
24  * <p>
25  * The byte buffer provides a fluent interface for reading bytes from and writing bytes to some underlying storage
26  * implementation. The {@code Buffer} type is agnostic about the specific underlying storage implementation, but different
27  * buffer implementations may be designed for specific storage layers.
28  * <p>
29  * Aside from the underlying storage implementation, this buffer works very similarly to Java's {@link java.nio.ByteBuffer}.
30  * It intentionally exposes methods that can be easily understood by any developer with experience with {@code ByteBuffer}.
31  * <p>
32  * In order to support reading and writing from buffers, {@code Buffer} implementations maintain a series of pointers to
33  * aid in navigating the buffer.
34  * <p>
35  * Most notable of these pointers is the {@code position}. When values are written to or read from the buffer, the
36  * buffer increments its internal {@code position} according to the number of bytes read. This allows users to iterate
37  * through the bytes in the buffer without maintaining external pointers.
38  * <p>
39  * <pre>
40  *   {@code
41  *      try (Buffer buffer = DirectBuffer.allocate(1024)) {
42  *        buffer.writeInt(1);
43  *        buffer.flip();
44  *        assert buffer.readInt() == 1;
45  *      }
46  *   }
47  * </pre>
48  * <p>
49  * Buffers implement {@link ReferenceCounted} in order to keep track of the number of currently
50  * held references to a given buffer. When a buffer is constructed, the buffer contains only {@code 1} reference. This
51  * reference can be released via the {@link Buffer#close()} method which can be called automatically
52  * by using a try-with-resources statement demonstrated above. Additional references to the buffer should be acquired via
53  * {@link ReferenceCounted#acquire()} and released via
54  * {@link ReferenceCounted#release}. Once all references to a buffer have been released - including
55  * the initial reference - the memory will be freed (for in-memory buffers) and writes will be automatically flushed to
56  * disk (for persistent buffers).
57  *
58  * @author <a href="http://github.com/kuujo">Jordan Halterman</a>
59  */
60 public interface Buffer extends BytesInput<Buffer>, BufferInput<Buffer>, BytesOutput<Buffer>, BufferOutput<Buffer>, ReferenceCounted<Buffer> {
61
62   /**
63    * Returns whether the buffer has an array.
64    *
65    * @return Whether the buffer has an underlying array.
66    */
67   default boolean hasArray() {
68     return false;
69   }
70
71   /**
72    * Returns the underlying byte array.
73    *
74    * @return the underlying byte array
75    * @throws UnsupportedOperationException if a heap array is not supported
76    */
77   default byte[] array() {
78     throw new UnsupportedOperationException();
79   }
80
81   /**
82    * Returns the byte order.
83    * <p>
84    * For consistency with {@link java.nio.ByteBuffer}, all buffer implementations are initially in {@link ByteOrder#BIG_ENDIAN} order.
85    *
86    * @return The byte order.
87    */
88   ByteOrder order();
89
90   /**
91    * Sets the byte order, returning a new swapped {@link Buffer} instance.
92    * <p>
93    * By default, all buffers are read and written in {@link ByteOrder#BIG_ENDIAN} order. This provides complete
94    * consistency with {@link java.nio.ByteBuffer}. To flip buffers to {@link ByteOrder#LITTLE_ENDIAN} order, this
95    * buffer's {@code Bytes} instance is decorated by a {@link SwappedBytes} instance which will reverse
96    * read and written bytes using, e.g. {@link Integer#reverseBytes(int)}.
97    *
98    * @param order The byte order.
99    * @return The updated buffer.
100    */
101   Buffer order(ByteOrder order);
102
103   /**
104    * Returns a boolean value indicating whether the buffer is a direct buffer.
105    *
106    * @return Indicates whether the buffer is a direct buffer.
107    */
108   boolean isDirect();
109
110   /**
111    * Returns a boolean value indicating whether the buffer is a read-only buffer.
112    *
113    * @return Indicates whether the buffer is a read-only buffer.
114    */
115   boolean isReadOnly();
116
117   /**
118    * Returns a boolean value indicating whether the buffer is backed by a file.
119    *
120    * @return Indicates whether the buffer is backed by a file.
121    */
122   boolean isFile();
123
124   /**
125    * Returns a read-only view of the buffer.
126    * <p>
127    * The returned buffer will share the underlying {@link Bytes} with which buffer, but the buffer's {@code limit},
128    * {@code capacity}, and {@code position} will be independent of this buffer.
129    *
130    * @return A read-only buffer.
131    */
132   Buffer asReadOnlyBuffer();
133
134   /**
135    * Returns the buffer's starting offset within the underlying {@link Bytes}.
136    * <p>
137    * The offset is used to calculate the absolute position of the buffer's relative {@link Buffer#position() position}
138    * within the underlying {@link Bytes}.
139    *
140    * @return The buffer's offset.
141    */
142   int offset();
143
144   /**
145    * Returns the buffer's capacity.
146    * <p>
147    * The capacity represents the total amount of storage space allocated to the buffer by the underlying storage
148    * implementation. As bytes are written to the buffer, the buffer's capacity may grow up to {@link Buffer#maxCapacity()}.
149    *
150    * @return The buffer's capacity.
151    */
152   int capacity();
153
154   /**
155    * Sets the buffer's capacity.
156    * <p>
157    * The given capacity must be greater than the current {@link Buffer#capacity() capacity} and less than or equal to
158    * {@link Buffer#maxCapacity()}. When the capacity is changed, the underlying {@link Bytes} will be resized via
159    * {@link Bytes#resize(int)}.
160    *
161    * @param capacity The capacity to which to resize the buffer.
162    * @return The resized buffer.
163    * @throws IllegalArgumentException If the given {@code capacity} is less than the current {@code capacity}
164    *                                  or greater than {@link Buffer#maxCapacity()}
165    */
166   Buffer capacity(int capacity);
167
168   /**
169    * Returns the maximum allowed capacity for the buffer.
170    * <p>
171    * The maximum capacity is the limit up to which this buffer's {@link Buffer#capacity() capacity} can be expanded.
172    * While the capacity grows, the maximum capacity is fixed from the moment the buffer is created and cannot change.
173    *
174    * @return The buffer's maximum capacity.
175    */
176   int maxCapacity();
177
178   /**
179    * Sets the buffer's current read/write position.
180    * <p>
181    * The position is an internal cursor that tracks where to write/read bytes in the underlying storage implementation.
182    *
183    * @param position The position to set.
184    * @return This buffer.
185    * @throws IllegalArgumentException If the given position is less than {@code 0} or more than {@link Buffer#limit()}
186    */
187   Buffer position(int position);
188
189   /**
190    * Returns the buffer's read/write limit.
191    * <p>
192    * The limit dictates the highest position to which bytes can be read from or written to the buffer. If the limit is
193    * not explicitly set then it will always equal the buffer's {@link Buffer#maxCapacity() maxCapacity}. Note that the
194    * limit may be set by related methods such as {@link Buffer#flip()}
195    *
196    * @return The buffer's limit.
197    */
198   int limit();
199
200   /**
201    * Sets the buffer's read/write limit.
202    * <p>
203    * The limit dictates the highest position to which bytes can be read from or written to the buffer. The limit must
204    * be within the bounds of the buffer, i.e. greater than {@code 0} and less than or equal to {@link Buffer#capacity()}
205    *
206    * @param limit The limit to set.
207    * @return This buffer.
208    * @throws IllegalArgumentException If the given limit is less than {@code 0} or more than {@link Buffer#capacity()}
209    */
210   Buffer limit(int limit);
211
212   /**
213    * Returns the number of bytes remaining in the buffer until the {@link Buffer#limit()} is reached.
214    * <p>
215    * The bytes remaining is calculated by {@code buffer.limit() - buffer.position()}. If no limit is set on the buffer
216    * then the {@link Buffer#maxCapacity() maxCapacity} will be used.
217    *
218    * @return The number of bytes remaining in the buffer.
219    */
220   @Override
221   int remaining();
222
223   /**
224    * Returns a boolean indicating whether the buffer has bytes remaining.
225    * <p>
226    * If {@link Buffer#remaining()} is greater than {@code 0} then this method will return {@code true}, otherwise
227    * {@code false}
228    *
229    * @return Indicates whether bytes are remaining in the buffer. {@code true} if {@link Buffer#remaining()} is
230    * greater than {@code 0}, {@code false} otherwise.
231    */
232   @Override
233   boolean hasRemaining();
234
235   /**
236    * Flips the buffer.
237    * <p>
238    * The limit is set to the current position and then the position is set to zero. If the mark is defined then it is discarded.
239    * <pre>
240    *   {@code
241    *   assert buffer.writeLong(1234).flip().readLong() == 1234;
242    *   }
243    * </pre>
244    *
245    * @return This buffer.
246    */
247   Buffer flip();
248
249   /**
250    * Sets a mark at the current position.
251    * <p>
252    * The mark is a simple internal reference to the buffer's current position. Marks can be used to reset the buffer
253    * to a specific position after some operation.
254    * <p>
255    * <pre>
256    *   {@code
257    *   buffer.mark();
258    *   buffer.writeInt(1).writeBoolean(true);
259    *   buffer.reset();
260    *   assert buffer.readInt() == 1;
261    *   }
262    * </pre>
263    *
264    * @return This buffer.
265    */
266   Buffer mark();
267
268   /**
269    * Resets the buffer's position to the previously-marked position.
270    * <p>
271    * Invoking this method neither changes nor discards the mark's value.
272    *
273    * @return This buffer.
274    * @throws java.nio.InvalidMarkException If no mark is set.
275    */
276   Buffer reset();
277
278   /**
279    * Rewinds the buffer. The position is set to zero and the mark is discarded.
280    *
281    * @return This buffer.
282    */
283   Buffer rewind();
284
285   /**
286    * Advances the buffer's {@code position} {@code length} bytes.
287    *
288    * @param length The number of bytes to advance this buffer's {@code position}.
289    * @return This buffer.
290    * @throws IndexOutOfBoundsException If {@code length} is greater than {@link Buffer#remaining()}
291    */
292   @Override
293   Buffer skip(int length);
294
295   /**
296    * Clears the buffer.
297    * <p>
298    * The position is set to zero, the limit is set to the capacity, and the mark is discarded.
299    *
300    * @return This buffer.
301    */
302   Buffer clear();
303
304   /**
305    * Compacts the buffer, moving bytes from the current position to the end of the buffer to the head of the buffer.
306    *
307    * @return This buffer.
308    */
309   Buffer compact();
310
311   /**
312    * Returns a duplicate of the buffer.
313    *
314    * @return A duplicate buffer.
315    */
316   Buffer duplicate();
317
318   /**
319    * Returns the bytes underlying the buffer.
320    * <p>
321    * The buffer is a wrapper around {@link Bytes} that handles writing sequences of bytes by tracking positions and
322    * limits. This method returns the {@link Bytes} that this buffer wraps.
323    *
324    * @return The underlying bytes.
325    */
326   Bytes bytes();
327
328   /**
329    * Returns a view of this buffer starting at the current position.
330    * <p>
331    * The returned buffer will contain the same underlying {@link Bytes} instance as this buffer, but its pointers will
332    * be offset by the current {@code position} of this buffer at the time the slice is created. Calls to
333    * {@link Buffer#rewind()} and similar methods on the resulting {@link Buffer} will result in
334    * the buffer's {@code position} being reset to the {@code position} of this buffer at the time the slice was created.
335    * <p>
336    * The returned buffer is reference counted separately from this buffer. Therefore, closing the returned buffer will
337    * release the buffer back to the internal buffer poll and will not result in this buffer being closed. Users should
338    * always call {@link Buffer#close()} once finished using the buffer slice.
339    *
340    * @return A slice of this buffer.
341    * @see Buffer#slice(int)
342    * @see Buffer#slice(int, int)
343    */
344   Buffer slice();
345
346   /**
347    * Returns a view of this buffer of the given length starting at the current position.
348    * <p>
349    * The returned buffer will contain the same underlying {@link Bytes} instance as this buffer, but its pointers will
350    * be offset by the current {@code position} of this buffer at the time the slice is created. Calls to
351    * {@link Buffer#rewind()} and similar methods on the resulting {@link Buffer} will result in
352    * the buffer's {@code position} being reset to the {@code position} of this buffer at the time the slice was created.
353    * <p>
354    * The returned buffer is reference counted separately from this buffer. Therefore, closing the returned buffer will
355    * release the buffer back to the internal buffer poll and will not result in this buffer being closed. Users should
356    * always call {@link Buffer#close()} once finished using the buffer slice.
357    *
358    * @param length The length of the slice.
359    * @return A slice of this buffer.
360    * @see Buffer#slice()
361    * @see Buffer#slice(int, int)
362    */
363   Buffer slice(int length);
364
365   /**
366    * Returns a view of this buffer starting at the given offset with the given length.
367    * <p>
368    * The returned buffer will contain the same underlying {@link Bytes} instance as this buffer, but its pointers will
369    * be offset by the given {@code offset} and its length limited by the given {@code length}. Calls to
370    * {@link Buffer#rewind()} and similar methods on the resulting {@link Buffer} will result in
371    * the buffer's {@code position} being reset to the given {@code offset}.
372    * <p>
373    * The returned buffer is reference counted separately from this buffer. Therefore, closing the returned buffer will
374    * release the buffer back to the internal buffer poll and will not result in this buffer being closed. Users should
375    * always call {@link Buffer#close()} once finished using the buffer slice.
376    *
377    * @param offset The offset at which to begin the slice.
378    * @param length The number of bytes in the slice.
379    * @return The buffer slice.
380    * @throws IndexOutOfBoundsException         If the given offset is not contained within the bounds of this buffer
381    * @throws java.nio.BufferUnderflowException If the length of the remaining bytes in the buffer is less than {@code length}
382    * @see Buffer#slice()
383    * @see Buffer#slice(int)
384    */
385   Buffer slice(int offset, int length);
386
387   /**
388    * Reads bytes into the given buffer.
389    * <p>
390    * Bytes will be read starting at the current buffer position until either {@link Buffer#limit()} has been reached.
391    * If {@link Buffer#remaining()} is less than the {@link Buffer#remaining()} of the given buffer, a
392    * {@link java.nio.BufferUnderflowException} will be thrown.
393    *
394    * @param buffer The buffer into which to read bytes.
395    * @return The buffer.
396    * @throws java.nio.BufferUnderflowException If the given {@link Buffer#remaining()} is greater than this buffer's
397    *                                           {@link Buffer#remaining()}
398    */
399   @Override
400   Buffer read(Buffer buffer);
401
402   /**
403    * Reads bytes into the given byte array.
404    * <p>
405    * Bytes will be read starting at the current buffer position until either the byte array {@code length} or the
406    * {@link Buffer#limit()} has been reached. If {@link Buffer#remaining()}
407    * is less than the {@code length} of the given byte array, a {@link java.nio.BufferUnderflowException} will be
408    * thrown.
409    *
410    * @param bytes The byte array into which to read bytes.
411    * @return The buffer.
412    * @throws java.nio.BufferUnderflowException If the given byte array's {@code length} is greater than
413    *                                           {@link Buffer#remaining()}
414    * @see Buffer#read(Bytes, int, int)
415    * @see Buffer#read(int, Bytes, int, int)
416    */
417   @Override
418   Buffer read(Bytes bytes);
419
420   /**
421    * Reads bytes into the given byte array.
422    * <p>
423    * Bytes will be read starting at the current buffer position until either the byte array {@code length} or the
424    * {@link Buffer#limit()} has been reached. If {@link Buffer#remaining()}
425    * is less than the {@code length} of the given byte array, a {@link java.nio.BufferUnderflowException} will be
426    * thrown.
427    *
428    * @param bytes The byte array into which to read bytes.
429    * @return The buffer.
430    * @throws java.nio.BufferUnderflowException If the given byte array's {@code length} is greater than
431    *                                           {@link Buffer#remaining()}
432    * @see Buffer#read(byte[], int, int)
433    * @see Buffer#read(int, byte[], int, int)
434    */
435   @Override
436   Buffer read(byte[] bytes);
437
438   /**
439    * Reads bytes into the given byte array starting at the current position.
440    * <p>
441    * Bytes will be read from the current position up to the given length. If the provided {@code length} is
442    * greater than {@link Buffer#remaining()} then a {@link java.nio.BufferUnderflowException} will
443    * be thrown. If the {@code offset} is out of bounds of the buffer then an {@link IndexOutOfBoundsException}
444    * will be thrown.
445    *
446    * @param bytes     The byte array into which to read bytes.
447    * @param dstOffset The offset at which to write bytes into the given buffer
448    * @return The buffer.
449    * @throws java.nio.BufferUnderflowException If {@code length} is greater than {@link Buffer#remaining()}
450    * @throws IndexOutOfBoundsException         If the given offset is out of the bounds of the buffer. Note that
451    *                                           bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
452    * @see Buffer#read(Bytes)
453    * @see Buffer#read(int, Bytes, int, int)
454    */
455   @Override
456   Buffer read(Bytes bytes, int dstOffset, int length);
457
458   /**
459    * Reads bytes into the given byte array starting at the given offset up to the given length.
460    * <p>
461    * Bytes will be read from the given starting offset up to the given length. If the provided {@code length} is
462    * greater than {@link Buffer#limit() - srcOffset} then a {@link java.nio.BufferUnderflowException} will
463    * be thrown. If the {@code srcOffset} is out of bounds of the buffer then an {@link IndexOutOfBoundsException}
464    * will be thrown.
465    *
466    * @param srcOffset The offset from which to start reading bytes.
467    * @param bytes     The byte array into which to read bytes.
468    * @param dstOffset The offset at which to write bytes into the given buffer
469    * @return The buffer.
470    * @throws java.nio.BufferUnderflowException If {@code length} is greater than {@link Buffer#remaining()}
471    * @throws IndexOutOfBoundsException         If the given offset is out of the bounds of the buffer. Note that
472    *                                           bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
473    * @see Buffer#read(Bytes)
474    * @see Buffer#read(Bytes, int, int)
475    */
476   @Override
477   Buffer read(int srcOffset, Bytes bytes, int dstOffset, int length);
478
479   /**
480    * Reads bytes into the given byte array starting at current position up to the given length.
481    * <p>
482    * Bytes will be read from the current position up to the given length. If the provided {@code length} is
483    * greater than {@link Buffer#remaining()} then a {@link java.nio.BufferUnderflowException} will
484    * be thrown. If the {@code offset} is out of bounds of the buffer then an {@link IndexOutOfBoundsException}
485    * will be thrown.
486    *
487    * @param bytes  The byte array into which to read bytes.
488    * @param offset The offset at which to write bytes into the given buffer
489    * @return The buffer.
490    * @throws java.nio.BufferUnderflowException If {@code length} is greater than {@link Buffer#remaining()}
491    * @throws IndexOutOfBoundsException         If the given offset is out of the bounds of the buffer. Note that
492    *                                           bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
493    * @see Buffer#read(byte[])
494    * @see Buffer#read(int, byte[], int, int)
495    */
496   @Override
497   Buffer read(byte[] bytes, int offset, int length);
498
499   /**
500    * Reads bytes into the given byte array starting at the given offset up to the given length.
501    * <p>
502    * Bytes will be read from the given starting offset up to the given length. If the provided {@code length} is
503    * greater than {@link Buffer#remaining()} then a {@link java.nio.BufferUnderflowException} will
504    * be thrown. If the {@code offset} is out of bounds of the buffer then an {@link IndexOutOfBoundsException}
505    * will be thrown.
506    *
507    * @param srcOffset The offset from which to start reading bytes.
508    * @param bytes     The byte array into which to read bytes.
509    * @param dstOffset The offset at which to write bytes into the given buffer
510    * @return The buffer.
511    * @throws java.nio.BufferUnderflowException If {@code length} is greater than {@link Buffer#remaining()}
512    * @throws IndexOutOfBoundsException         If the given offset is out of the bounds of the buffer. Note that
513    *                                           bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
514    * @see Buffer#read(byte[])
515    * @see Buffer#read(byte[], int, int)
516    */
517   @Override
518   Buffer read(int srcOffset, byte[] bytes, int dstOffset, int length);
519
520   /**
521    * Reads a byte from the buffer at the current position.
522    * <p>
523    * When the byte is read from the buffer, the buffer's {@code position} will be advanced by {@link Bytes#BYTE}. If
524    * there are no bytes remaining in the buffer then a {@link java.nio.BufferUnderflowException} will be thrown.
525    *
526    * @return The read byte.
527    * @throws java.nio.BufferUnderflowException If {@link Buffer#remaining()} is less than {@link Bytes#BYTE}
528    * @see Buffer#readByte(int)
529    */
530   @Override
531   int readByte();
532
533   /**
534    * Reads a byte from the buffer at the given offset.
535    * <p>
536    * The byte will be read from the given offset. If the given index is out of the bounds of the buffer then a
537    * {@link IndexOutOfBoundsException} will be thrown.
538    *
539    * @param offset The offset at which to read the byte.
540    * @return The read byte.
541    * @throws IndexOutOfBoundsException If the given offset is out of the bounds of the buffer. Note that
542    *                                   bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
543    * @see Buffer#readByte()
544    */
545   @Override
546   int readByte(int offset);
547
548   /**
549    * Reads an unsigned byte from the buffer at the current position.
550    * <p>
551    * When the byte is read from the buffer, the buffer's {@code position} will be advanced by {@link Bytes#BYTE}. If
552    * there are no bytes remaining in the buffer then a {@link java.nio.BufferUnderflowException} will be thrown.
553    *
554    * @return The read byte.
555    * @throws java.nio.BufferUnderflowException If {@link Buffer#remaining()} is less than {@link Bytes#BYTE}
556    * @see Buffer#readUnsignedByte(int)
557    */
558   @Override
559   int readUnsignedByte();
560
561   /**
562    * Reads an unsigned byte from the buffer at the given offset.
563    * <p>
564    * The byte will be read from the given offset. If the given index is out of the bounds of the buffer then a
565    * {@link IndexOutOfBoundsException} will be thrown.
566    *
567    * @param offset The offset at which to read the byte.
568    * @return The read byte.
569    * @throws IndexOutOfBoundsException If the given offset is out of the bounds of the buffer. Note that
570    *                                   bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
571    * @see Buffer#readUnsignedByte()
572    */
573   @Override
574   int readUnsignedByte(int offset);
575
576   /**
577    * Reads a 16-bit character from the buffer at the current position.
578    * <p>
579    * When the character is read from the buffer, the buffer's {@code position} will be advanced by {@link Bytes#CHARACTER}.
580    * If there are less than {@link Bytes#CHARACTER} bytes remaining in the buffer then a
581    * {@link java.nio.BufferUnderflowException} will be thrown.
582    *
583    * @return The read character.
584    * @throws java.nio.BufferUnderflowException If {@link Buffer#remaining()} is less than {@link Bytes#CHARACTER}
585    * @see Buffer#readChar(int)
586    */
587   @Override
588   char readChar();
589
590   /**
591    * Reads a 16-bit character from the buffer at the given offset.
592    * <p>
593    * The character will be read from the given offset. If the given index is out of the bounds of the buffer then a
594    * {@link IndexOutOfBoundsException} will be thrown.
595    *
596    * @param offset The offset at which to read the character.
597    * @return The read character.
598    * @throws IndexOutOfBoundsException If the given offset is out of the bounds of the buffer. Note that
599    *                                   bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
600    * @see Buffer#readChar()
601    */
602   @Override
603   char readChar(int offset);
604
605   /**
606    * Reads a 16-bit signed integer from the buffer at the current position.
607    * <p>
608    * When the short is read from the buffer, the buffer's {@code position} will be advanced by {@link Bytes#SHORT}.
609    * If there are less than {@link Bytes#SHORT} bytes remaining in the buffer then a
610    * {@link java.nio.BufferUnderflowException} will be thrown.
611    *
612    * @return The read short.
613    * @throws java.nio.BufferUnderflowException If {@link Buffer#remaining()} is less than {@link Bytes#SHORT}
614    * @see Buffer#readShort(int)
615    */
616   @Override
617   short readShort();
618
619   /**
620    * Reads a 16-bit signed integer from the buffer at the given offset.
621    * <p>
622    * The short will be read from the given offset. If the given index is out of the bounds of the buffer then a
623    * {@link IndexOutOfBoundsException} will be thrown.
624    *
625    * @param offset The offset at which to read the short.
626    * @return The read short.
627    * @throws IndexOutOfBoundsException If the given offset is out of the bounds of the buffer. Note that
628    *                                   bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
629    * @see Buffer#readShort()
630    */
631   @Override
632   short readShort(int offset);
633
634   /**
635    * Reads a 16-bit unsigned integer from the buffer at the current position.
636    * <p>
637    * When the short is read from the buffer, the buffer's {@code position} will be advanced by {@link Bytes#SHORT}.
638    * If there are less than {@link Bytes#SHORT} bytes remaining in the buffer then a
639    * {@link java.nio.BufferUnderflowException} will be thrown.
640    *
641    * @return The read short.
642    * @throws java.nio.BufferUnderflowException If {@link Buffer#remaining()} is less than {@link Bytes#SHORT}
643    * @see Buffer#readUnsignedShort(int)
644    */
645   @Override
646   int readUnsignedShort();
647
648   /**
649    * Reads a 16-bit unsigned integer from the buffer at the given offset.
650    * <p>
651    * The short will be read from the given offset. If the given index is out of the bounds of the buffer then a
652    * {@link IndexOutOfBoundsException} will be thrown.
653    *
654    * @param offset The offset at which to read the short.
655    * @return The read short.
656    * @throws IndexOutOfBoundsException If the given offset is out of the bounds of the buffer. Note that
657    *                                   bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
658    * @see Buffer#readUnsignedShort()
659    */
660   @Override
661   int readUnsignedShort(int offset);
662
663   /**
664    * Reads a 32-bit signed integer from the buffer at the current position.
665    * <p>
666    * When the integer is read from the buffer, the buffer's {@code position} will be advanced by {@link Bytes#INTEGER}.
667    * If there are less than {@link Bytes#INTEGER} bytes remaining in the buffer then a
668    * {@link java.nio.BufferUnderflowException} will be thrown.
669    *
670    * @return The read integer.
671    * @throws java.nio.BufferUnderflowException If {@link Buffer#remaining()} is less than {@link Bytes#INTEGER}
672    * @see Buffer#readInt(int)
673    */
674   @Override
675   int readInt();
676
677   /**
678    * Reads a 32-bit signed integer from the buffer at the given offset.
679    * <p>
680    * The integer will be read from the given offset. If the given index is out of the bounds of the buffer then a
681    * {@link IndexOutOfBoundsException} will be thrown.
682    *
683    * @param offset The offset at which to read the integer.
684    * @return The read integer.
685    * @throws IndexOutOfBoundsException If the given offset is out of the bounds of the buffer. Note that
686    *                                   bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
687    * @see Buffer#readInt()
688    */
689   @Override
690   int readInt(int offset);
691
692   /**
693    * Reads a 32-bit unsigned integer from the buffer at the current position.
694    * <p>
695    * When the integer is read from the buffer, the buffer's {@code position} will be advanced by {@link Bytes#INTEGER}.
696    * If there are less than {@link Bytes#INTEGER} bytes remaining in the buffer then a
697    * {@link java.nio.BufferUnderflowException} will be thrown.
698    *
699    * @return The read integer.
700    * @throws java.nio.BufferUnderflowException If {@link Buffer#remaining()} is less than {@link Bytes#INTEGER}
701    * @see Buffer#readUnsignedInt(int)
702    */
703   @Override
704   long readUnsignedInt();
705
706   /**
707    * Reads a 32-bit unsigned integer from the buffer at the given offset.
708    * <p>
709    * The integer will be read from the given offset. If the given index is out of the bounds of the buffer then a
710    * {@link IndexOutOfBoundsException} will be thrown.
711    *
712    * @param offset The offset at which to read the integer.
713    * @return The read integer.
714    * @throws IndexOutOfBoundsException If the given offset is out of the bounds of the buffer. Note that
715    *                                   bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
716    * @see Buffer#readUnsignedInt()
717    */
718   @Override
719   long readUnsignedInt(int offset);
720
721   /**
722    * Reads a 64-bit signed integer from the buffer at the current position.
723    * <p>
724    * When the long is read from the buffer, the buffer's {@code position} will be advanced by {@link Bytes#LONG}.
725    * If there are less than {@link Bytes#LONG} bytes remaining in the buffer then a
726    * {@link java.nio.BufferUnderflowException} will be thrown.
727    *
728    * @return The read long.
729    * @throws java.nio.BufferUnderflowException If {@link Buffer#remaining()} is less than {@link Bytes#LONG}
730    * @see Buffer#readLong(int)
731    */
732   @Override
733   long readLong();
734
735   /**
736    * Reads a 64-bit signed integer from the buffer at the given offset.
737    * <p>
738    * The long will be read from the given offset. If the given index is out of the bounds of the buffer then a
739    * {@link IndexOutOfBoundsException} will be thrown.
740    *
741    * @param offset The offset at which to read the long.
742    * @return The read long.
743    * @throws IndexOutOfBoundsException If the given offset is out of the bounds of the buffer. Note that
744    *                                   bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
745    * @see Buffer#readLong()
746    */
747   @Override
748   long readLong(int offset);
749
750   /**
751    * Reads a single-precision 32-bit floating point number from the buffer at the current position.
752    * <p>
753    * When the float is read from the buffer, the buffer's {@code position} will be advanced by {@link Bytes#FLOAT}.
754    * If there are less than {@link Bytes#FLOAT} bytes remaining in the buffer then a
755    * {@link java.nio.BufferUnderflowException} will be thrown.
756    *
757    * @return The read float.
758    * @throws java.nio.BufferUnderflowException If {@link Buffer#remaining()} is less than {@link Bytes#FLOAT}
759    * @see Buffer#readFloat(int)
760    */
761   @Override
762   float readFloat();
763
764   /**
765    * Reads a single-precision 32-bit floating point number from the buffer at the given offset.
766    * <p>
767    * The float will be read from the given offset. If the given index is out of the bounds of the buffer then a
768    * {@link IndexOutOfBoundsException} will be thrown.
769    *
770    * @param offset The offset at which to read the float.
771    * @return The read float.
772    * @throws IndexOutOfBoundsException If the given offset is out of the bounds of the buffer. Note that
773    *                                   bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
774    * @see Buffer#readFloat()
775    */
776   @Override
777   float readFloat(int offset);
778
779   /**
780    * Reads a double-precision 64-bit floating point number from the buffer at the current position.
781    * <p>
782    * When the double is read from the buffer, the buffer's {@code position} will be advanced by {@link Bytes#DOUBLE}.
783    * If there are less than {@link Bytes#DOUBLE} bytes remaining in the buffer then a
784    * {@link java.nio.BufferUnderflowException} will be thrown.
785    *
786    * @return The read double.
787    * @throws java.nio.BufferUnderflowException If {@link Buffer#remaining()} is less than {@link Bytes#DOUBLE}
788    * @see Buffer#readDouble(int)
789    */
790   @Override
791   double readDouble();
792
793   /**
794    * Reads a double-precision 64-bit floating point number from the buffer at the given offset.
795    * <p>
796    * The double will be read from the given offset. If the given index is out of the bounds of the buffer then a
797    * {@link IndexOutOfBoundsException} will be thrown.
798    *
799    * @param offset The offset at which to read the double.
800    * @return The read double.
801    * @throws IndexOutOfBoundsException If the given offset is out of the bounds of the buffer. Note that
802    *                                   bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
803    * @see Buffer#readDouble()
804    */
805   @Override
806   double readDouble(int offset);
807
808   /**
809    * Reads a 1 byte boolean from the buffer at the current position.
810    * <p>
811    * When the boolean is read from the buffer, the buffer's {@code position} will be advanced by {@code 1}.
812    * If there are no bytes remaining in the buffer then a {@link java.nio.BufferUnderflowException} will be thrown.
813    *
814    * @return The read boolean.
815    * @throws java.nio.BufferUnderflowException If {@link Buffer#remaining()} is less than {@code 1}
816    * @see Buffer#readBoolean(int)
817    */
818   @Override
819   boolean readBoolean();
820
821   /**
822    * Reads a 1 byte boolean from the buffer at the given offset.
823    * <p>
824    * The boolean will be read from the given offset. If the given index is out of the bounds of the buffer then a
825    * {@link IndexOutOfBoundsException} will be thrown.
826    *
827    * @param offset The offset at which to read the boolean.
828    * @return The read boolean.
829    * @throws IndexOutOfBoundsException If the given offset is out of the bounds of the buffer. Note that
830    *                                   bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
831    * @see Buffer#readBoolean()
832    */
833   @Override
834   boolean readBoolean(int offset);
835
836   /**
837    * Reads a UTF-8 string from the buffer at the current position.
838    * <p>
839    * When the string is read from the buffer, the buffer's {@code position} will be advanced by 2 bytes plus the byte
840    * length of the string. If there are no bytes remaining in the buffer then a {@link java.nio.BufferUnderflowException}
841    * will be thrown.
842    *
843    * @return The read string.
844    * @throws java.nio.BufferUnderflowException If {@link Buffer#remaining()} is less than {@code 1}
845    * @see Buffer#readUTF8(int)
846    */
847   @Override
848   String readUTF8();
849
850   /**
851    * Reads a UTF-8 string from the buffer at the given offset.
852    * <p>
853    * The string will be read from the given offset. If the given index is out of the bounds of the buffer then a
854    * {@link IndexOutOfBoundsException} will be thrown.
855    *
856    * @param offset The offset at which to read the boolean.
857    * @return The read string.
858    * @throws IndexOutOfBoundsException If the given offset is out of the bounds of the buffer. Note that
859    *                                   bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
860    * @see Buffer#readUTF8()
861    */
862   @Override
863   String readUTF8(int offset);
864
865   /**
866    * Writes a buffer to the buffer.
867    * <p>
868    * When the buffer is written to the buffer, the buffer's {@code position} will be advanced by the number of bytes
869    * in the provided buffer. If the provided {@link Buffer#remaining()} exceeds {@link Buffer#remaining()} then an
870    * {@link java.nio.BufferOverflowException} will be thrown.
871    *
872    * @param buffer The buffer to write.
873    * @return The written buffer.
874    * @throws java.nio.BufferOverflowException If the given buffer's {@link Buffer#remaining()} bytes exceeds this buffer's
875    *                                          remaining bytes.
876    */
877   @Override
878   Buffer write(Buffer buffer);
879
880   /**
881    * Writes an array of bytes to the buffer.
882    * <p>
883    * When the bytes are written to the buffer, the buffer's {@code position} will be advanced by the number of bytes
884    * in the provided byte array. If the number of bytes exceeds {@link Buffer#limit()} then an
885    * {@link java.nio.BufferOverflowException} will be thrown.
886    *
887    * @param bytes The array of bytes to write.
888    * @return The written buffer.
889    * @throws java.nio.BufferOverflowException If the number of bytes exceeds the buffer's remaining bytes.
890    * @see Buffer#write(Bytes, int, int)
891    * @see Buffer#write(int, Bytes, int, int)
892    */
893   @Override
894   Buffer write(Bytes bytes);
895
896   /**
897    * Writes an array of bytes to the buffer.
898    * <p>
899    * When the bytes are written to the buffer, the buffer's {@code position} will be advanced by the number of bytes
900    * in the provided byte array. If the number of bytes exceeds {@link Buffer#limit()} then an
901    * {@link java.nio.BufferOverflowException} will be thrown.
902    *
903    * @param bytes The array of bytes to write.
904    * @return The written buffer.
905    * @throws java.nio.BufferOverflowException If the number of bytes exceeds the buffer's remaining bytes.
906    * @see Buffer#write(byte[], int, int)
907    * @see Buffer#write(int, byte[], int, int)
908    */
909   @Override
910   Buffer write(byte[] bytes);
911
912   /**
913    * Writes an array of bytes to the buffer.
914    * <p>
915    * The bytes will be written starting at the current position up to the given length. If the length of the byte array
916    * is larger than the provided {@code length} then only {@code length} bytes will be read from the array. If the
917    * provided {@code length} is greater than the remaining bytes in this buffer then a {@link java.nio.BufferOverflowException}
918    * will be thrown.
919    *
920    * @param bytes  The array of bytes to write.
921    * @param offset The offset at which to start writing the bytes.
922    * @param length The number of bytes from the provided byte array to write to the buffer.
923    * @return The written buffer.
924    * @throws java.nio.BufferOverflowException If there are not enough bytes remaining in the buffer.
925    * @throws IndexOutOfBoundsException        If the given offset is out of the bounds of the buffer.
926    * @see Buffer#write(Bytes)
927    * @see Buffer#write(int, Bytes, int, int)
928    */
929   @Override
930   Buffer write(Bytes bytes, int offset, int length);
931
932   /**
933    * Writes an array of bytes to the buffer.
934    * <p>
935    * The bytes will be written starting at the given offset up to the given length. If the remaining bytes in the byte array
936    * is larger than the provided {@code length} then only {@code length} bytes will be read from the array. If the
937    * provided {@code length} is greater than {@link Buffer#limit()} minus {@code offset} then a
938    * {@link java.nio.BufferOverflowException} will be thrown.
939    *
940    * @param offset    The offset at which to start writing the bytes.
941    * @param src       The array of bytes to write.
942    * @param srcOffset The offset at which to begin reading bytes from the source.
943    * @param length    The number of bytes from the provided byte array to write to the buffer.
944    * @return The written buffer.
945    * @throws java.nio.BufferOverflowException If there are not enough bytes remaining in the buffer.
946    * @throws IndexOutOfBoundsException        If the given offset is out of the bounds of the buffer.
947    * @see Buffer#write(Bytes)
948    * @see Buffer#write(Bytes, int, int)
949    */
950   @Override
951   Buffer write(int offset, Bytes src, int srcOffset, int length);
952
953   /**
954    * Writes an array of bytes to the buffer.
955    * <p>
956    * The bytes will be written starting at the current position up to the given length. If the length of the byte array
957    * is larger than the provided {@code length} then only {@code length} bytes will be read from the array. If the
958    * provided {@code length} is greater than the remaining bytes in this buffer then a {@link java.nio.BufferOverflowException}
959    * will be thrown.
960    *
961    * @param bytes  The array of bytes to write.
962    * @param offset The offset at which to start writing the bytes.
963    * @param length The number of bytes from the provided byte array to write to the buffer.
964    * @return The written buffer.
965    * @throws java.nio.BufferOverflowException If there are not enough bytes remaining in the buffer.
966    * @throws IndexOutOfBoundsException        If the given offset is out of the bounds of the buffer.
967    * @see Buffer#write(byte[])
968    * @see Buffer#write(int, byte[], int, int)
969    */
970   @Override
971   Buffer write(byte[] bytes, int offset, int length);
972
973   /**
974    * Writes an array of bytes to the buffer.
975    * <p>
976    * The bytes will be written starting at the given offset up to the given length. If the remaining bytes in the byte array
977    * is larger than the provided {@code length} then only {@code length} bytes will be read from the array. If the
978    * provided {@code length} is greater than {@link Buffer#limit()} minus {@code offset} then a
979    * {@link java.nio.BufferOverflowException} will be thrown.
980    *
981    * @param offset    The offset at which to start writing the bytes.
982    * @param src       The array of bytes to write.
983    * @param srcOffset The offset at which to begin reading bytes from the source.
984    * @param length    The number of bytes from the provided byte array to write to the buffer.
985    * @return The written buffer.
986    * @throws java.nio.BufferOverflowException If there are not enough bytes remaining in the buffer.
987    * @throws IndexOutOfBoundsException        If the given offset is out of the bounds of the buffer.
988    * @see Buffer#write(byte[])
989    * @see Buffer#write(byte[], int, int)
990    */
991   @Override
992   Buffer write(int offset, byte[] src, int srcOffset, int length);
993
994   /**
995    * Writes a byte to the buffer at the current position.
996    * <p>
997    * When the byte is written to the buffer, the buffer's {@code position} will be advanced by {@link Bytes#BYTE}. If
998    * there are no bytes remaining in the buffer then a {@link java.nio.BufferOverflowException} will be thrown.
999    *
1000    * @param b The byte to write.
1001    * @return The written buffer.
1002    * @throws java.nio.BufferOverflowException If there are no bytes remaining in the buffer.
1003    * @see Buffer#writeByte(int, int)
1004    */
1005   @Override
1006   Buffer writeByte(int b);
1007
1008   /**
1009    * Writes a byte to the buffer at the given offset.
1010    * <p>
1011    * The byte will be written at the given offset. If there are no bytes remaining in the buffer then a
1012    * {@link java.nio.BufferOverflowException} will be thrown.
1013    *
1014    * @param offset The offset at which to write the byte.
1015    * @param b      The byte to write.
1016    * @return The written buffer.
1017    * @throws java.nio.BufferOverflowException If there are not enough bytes remaining in the buffer.
1018    * @throws IndexOutOfBoundsException        If the given offset is out of the bounds of the buffer. Note that
1019    *                                          bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
1020    * @see Buffer#writeByte(int)
1021    */
1022   @Override
1023   Buffer writeByte(int offset, int b);
1024
1025   /**
1026    * Writes an unsigned byte to the buffer at the current position.
1027    * <p>
1028    * When the byte is written to the buffer, the buffer's {@code position} will be advanced by {@link Bytes#BYTE}. If
1029    * there are no bytes remaining in the buffer then a {@link java.nio.BufferOverflowException} will be thrown.
1030    *
1031    * @param b The byte to write.
1032    * @return The written buffer.
1033    * @throws java.nio.BufferOverflowException If there are no bytes remaining in the buffer.
1034    * @see Buffer#writeUnsignedByte(int, int)
1035    */
1036   @Override
1037   Buffer writeUnsignedByte(int b);
1038
1039   /**
1040    * Writes an unsigned byte to the buffer at the given offset.
1041    * <p>
1042    * The byte will be written at the given offset. If there are no bytes remaining in the buffer then a
1043    * {@link java.nio.BufferOverflowException} will be thrown.
1044    *
1045    * @param offset The offset at which to write the byte.
1046    * @param b      The byte to write.
1047    * @return The written buffer.
1048    * @throws java.nio.BufferOverflowException If there are not enough bytes remaining in the buffer.
1049    * @throws IndexOutOfBoundsException        If the given offset is out of the bounds of the buffer. Note that
1050    *                                          bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
1051    * @see Buffer#writeUnsignedByte(int)
1052    */
1053   @Override
1054   Buffer writeUnsignedByte(int offset, int b);
1055
1056   /**
1057    * Writes a 16-bit character to the buffer at the current position.
1058    * <p>
1059    * When the character is written to the buffer, the buffer's {@code position} will be advanced by
1060    * {@link Bytes#CHARACTER}. If less than {@code 2} bytes are remaining in the buffer then a
1061    * {@link java.nio.BufferOverflowException} will be thrown.
1062    *
1063    * @param c The character to write.
1064    * @return The written buffer.
1065    * @throws java.nio.BufferOverflowException If {@link Buffer#remaining()} is less than {@link Bytes#CHARACTER}.
1066    * @see Buffer#writeChar(int, char)
1067    */
1068   @Override
1069   Buffer writeChar(char c);
1070
1071   /**
1072    * Writes a 16-bit character to the buffer at the given offset.
1073    * <p>
1074    * The character will be written at the given offset. If there are less than {@link Bytes#CHARACTER} bytes remaining
1075    * in the buffer then a {@link java.nio.BufferOverflowException} will be thrown.
1076    *
1077    * @param offset The offset at which to write the character.
1078    * @param c      The character to write.
1079    * @return The written buffer.
1080    * @throws java.nio.BufferOverflowException If {@link Buffer#remaining()} is less than {@link Bytes#CHARACTER}.
1081    * @throws IndexOutOfBoundsException        If the given offset is out of the bounds of the buffer. Note that
1082    *                                          bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
1083    * @see Buffer#writeChar(char)
1084    */
1085   @Override
1086   Buffer writeChar(int offset, char c);
1087
1088   /**
1089    * Writes a 16-bit signed integer to the buffer at the current position.
1090    * <p>
1091    * When the short is written to the buffer, the buffer's {@code position} will be advanced by {@link Bytes#SHORT}. If
1092    * less than {@link Bytes#SHORT} bytes are remaining in the buffer then a {@link java.nio.BufferOverflowException}
1093    * will be thrown.
1094    *
1095    * @param s The short to write.
1096    * @return The written buffer.
1097    * @throws java.nio.BufferOverflowException If {@link Buffer#remaining()} is less than {@link Bytes#SHORT}.
1098    * @see Buffer#writeShort(int, short)
1099    */
1100   @Override
1101   Buffer writeShort(short s);
1102
1103   /**
1104    * Writes a 16-bit signed integer to the buffer at the given offset.
1105    * <p>
1106    * The short will be written at the given offset. If there are less than {@link Bytes#SHORT} bytes remaining in the buffer
1107    * then a {@link java.nio.BufferOverflowException} will be thrown.
1108    *
1109    * @param offset The offset at which to write the short.
1110    * @param s      The short to write.
1111    * @return The written buffer.
1112    * @throws java.nio.BufferOverflowException If {@link Buffer#remaining()} is less than {@link Bytes#SHORT}.
1113    * @throws IndexOutOfBoundsException        If the given offset is out of the bounds of the buffer. Note that
1114    *                                          bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
1115    * @see Buffer#writeShort(short)
1116    */
1117   @Override
1118   Buffer writeShort(int offset, short s);
1119
1120   /**
1121    * Writes a 16-bit signed integer to the buffer at the current position.
1122    * <p>
1123    * When the short is written to the buffer, the buffer's {@code position} will be advanced by {@link Bytes#SHORT}. If
1124    * less than {@link Bytes#SHORT} bytes are remaining in the buffer then a {@link java.nio.BufferOverflowException}
1125    * will be thrown.
1126    *
1127    * @param s The short to write.
1128    * @return The written buffer.
1129    * @throws java.nio.BufferOverflowException If {@link Buffer#remaining()} is less than {@link Bytes#SHORT}.
1130    * @see Buffer#writeUnsignedShort(int, int)
1131    */
1132   @Override
1133   Buffer writeUnsignedShort(int s);
1134
1135   /**
1136    * Writes a 16-bit signed integer to the buffer at the given offset.
1137    * <p>
1138    * The short will be written at the given offset. If there are less than {@link Bytes#SHORT} bytes remaining in the buffer
1139    * then a {@link java.nio.BufferOverflowException} will be thrown.
1140    *
1141    * @param offset The offset at which to write the short.
1142    * @param s      The short to write.
1143    * @return The written buffer.
1144    * @throws java.nio.BufferOverflowException If {@link Buffer#remaining()} is less than {@link Bytes#SHORT}.
1145    * @throws IndexOutOfBoundsException        If the given offset is out of the bounds of the buffer. Note that
1146    *                                          bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
1147    * @see Buffer#writeUnsignedShort(int)
1148    */
1149   @Override
1150   Buffer writeUnsignedShort(int offset, int s);
1151
1152   /**
1153    * Writes a 32-bit signed integer to the buffer at the current position.
1154    * <p>
1155    * When the integer is written to the buffer, the buffer's {@code position} will be advanced by {@link Bytes#INTEGER}.
1156    * If less than {@link Bytes#INTEGER} bytes are remaining in the buffer then a {@link java.nio.BufferOverflowException}
1157    * will be thrown.
1158    *
1159    * @param i The integer to write.
1160    * @return The written buffer.
1161    * @throws java.nio.BufferOverflowException If {@link Buffer#remaining()} is less than {@link Bytes#INTEGER}.
1162    * @see Buffer#writeInt(int, int)
1163    */
1164   @Override
1165   Buffer writeInt(int i);
1166
1167   /**
1168    * Writes a 32-bit signed integer to the buffer at the given offset.
1169    * <p>
1170    * The integer will be written at the given offset. If there are less than {@link Bytes#INTEGER} bytes remaining
1171    * in the buffer then a {@link java.nio.BufferOverflowException} will be thrown.
1172    *
1173    * @param offset The offset at which to write the integer.
1174    * @param i      The integer to write.
1175    * @return The written buffer.
1176    * @throws java.nio.BufferOverflowException If {@link Buffer#remaining()} is less than {@link Bytes#INTEGER}.
1177    * @throws IndexOutOfBoundsException        If the given offset is out of the bounds of the buffer. Note that
1178    *                                          bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
1179    * @see Buffer#writeInt(int)
1180    */
1181   @Override
1182   Buffer writeInt(int offset, int i);
1183
1184   /**
1185    * Writes a 32-bit signed integer to the buffer at the current position.
1186    * <p>
1187    * When the integer is written to the buffer, the buffer's {@code position} will be advanced by {@link Bytes#INTEGER}.
1188    * If less than {@link Bytes#INTEGER} bytes are remaining in the buffer then a {@link java.nio.BufferOverflowException}
1189    * will be thrown.
1190    *
1191    * @param i The integer to write.
1192    * @return The written buffer.
1193    * @throws java.nio.BufferOverflowException If {@link Buffer#remaining()} is less than {@link Bytes#INTEGER}.
1194    * @see Buffer#writeUnsignedInt(int, long)
1195    */
1196   @Override
1197   Buffer writeUnsignedInt(long i);
1198
1199   /**
1200    * Writes a 32-bit signed integer to the buffer at the given offset.
1201    * <p>
1202    * The integer will be written at the given offset. If there are less than {@link Bytes#INTEGER} bytes remaining
1203    * in the buffer then a {@link java.nio.BufferOverflowException} will be thrown.
1204    *
1205    * @param offset The offset at which to write the integer.
1206    * @param i      The integer to write.
1207    * @return The written buffer.
1208    * @throws java.nio.BufferOverflowException If {@link Buffer#remaining()} is less than {@link Bytes#INTEGER}.
1209    * @throws IndexOutOfBoundsException        If the given offset is out of the bounds of the buffer. Note that
1210    *                                          bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
1211    * @see Buffer#writeUnsignedInt(long)
1212    */
1213   @Override
1214   Buffer writeUnsignedInt(int offset, long i);
1215
1216   /**
1217    * Writes a 64-bit signed integer to the buffer at the current position.
1218    * <p>
1219    * When the long is written to the buffer, the buffer's {@code position} will be advanced by {@link Bytes#LONG}.
1220    * If less than {@link Bytes#LONG} bytes are remaining in the buffer then a {@link java.nio.BufferOverflowException}
1221    * will be thrown.
1222    *
1223    * @param l The long to write.
1224    * @return The written buffer.
1225    * @throws java.nio.BufferOverflowException If {@link Buffer#remaining()} is less than {@link Bytes#LONG}.
1226    * @see Buffer#writeLong(int, long)
1227    */
1228   @Override
1229   Buffer writeLong(long l);
1230
1231   /**
1232    * Writes a 64-bit signed integer to the buffer at the given offset.
1233    * <p>
1234    * The long will be written at the given offset. If there are less than {@link Bytes#LONG} bytes remaining
1235    * in the buffer then a {@link java.nio.BufferOverflowException} will be thrown.
1236    *
1237    * @param offset The offset at which to write the long.
1238    * @param l      The long to write.
1239    * @return The written buffer.
1240    * @throws java.nio.BufferOverflowException If {@link Buffer#remaining()} is less than {@link Bytes#LONG}.
1241    * @throws IndexOutOfBoundsException        If the given offset is out of the bounds of the buffer. Note that
1242    *                                          bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
1243    * @see Buffer#writeLong(long)
1244    */
1245   @Override
1246   Buffer writeLong(int offset, long l);
1247
1248   /**
1249    * Writes a single-precision 32-bit floating point number to the buffer at the current position.
1250    * <p>
1251    * When the float is written to the buffer, the buffer's {@code position} will be advanced by {@link Bytes#FLOAT}.
1252    * If less than {@link Bytes#FLOAT} bytes are remaining in the buffer then a {@link java.nio.BufferOverflowException}
1253    * will be thrown.
1254    *
1255    * @param f The float to write.
1256    * @return The written buffer.
1257    * @throws java.nio.BufferOverflowException If {@link Buffer#remaining()} is less than {@link Bytes#FLOAT}.
1258    * @see Buffer#writeFloat(int, float)
1259    */
1260   @Override
1261   Buffer writeFloat(float f);
1262
1263   /**
1264    * Writes a single-precision 32-bit floating point number to the buffer at the given offset.
1265    * <p>
1266    * The float will be written at the given offset. If there are less than {@link Bytes#FLOAT} bytes remaining
1267    * in the buffer then a {@link java.nio.BufferOverflowException} will be thrown.
1268    *
1269    * @param offset The offset at which to write the float.
1270    * @param f      The float to write.
1271    * @return The written buffer.
1272    * @throws java.nio.BufferOverflowException If {@link Buffer#remaining()} is less than {@link Bytes#FLOAT}.
1273    * @throws IndexOutOfBoundsException        If the given offset is out of the bounds of the buffer. Note that
1274    *                                          bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
1275    * @see Buffer#writeFloat(float)
1276    */
1277   @Override
1278   Buffer writeFloat(int offset, float f);
1279
1280   /**
1281    * Writes a double-precision 64-bit floating point number to the buffer at the current position.
1282    * <p>
1283    * When the double is written to the buffer, the buffer's {@code position} will be advanced by {@link Bytes#DOUBLE}.
1284    * If less than {@link Bytes#DOUBLE} bytes are remaining in the buffer then a {@link java.nio.BufferOverflowException}
1285    * will be thrown.
1286    *
1287    * @param d The double to write.
1288    * @return The written buffer.
1289    * @throws java.nio.BufferOverflowException If {@link Buffer#remaining()} is less than {@link Bytes#DOUBLE}.
1290    * @see Buffer#writeDouble(int, double)
1291    */
1292   @Override
1293   Buffer writeDouble(double d);
1294
1295   /**
1296    * Writes a double-precision 64-bit floating point number to the buffer at the given offset.
1297    * <p>
1298    * The double will be written at the given offset. If there are less than {@link Bytes#DOUBLE} bytes remaining
1299    * in the buffer then a {@link java.nio.BufferOverflowException} will be thrown.
1300    *
1301    * @param offset The offset at which to write the double.
1302    * @param d      The double to write.
1303    * @return The written buffer.
1304    * @throws java.nio.BufferOverflowException If {@link Buffer#remaining()} is less than {@link Bytes#DOUBLE}.
1305    * @throws IndexOutOfBoundsException        If the given offset is out of the bounds of the buffer. Note that
1306    *                                          bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
1307    * @see Buffer#writeDouble(double)
1308    */
1309   @Override
1310   Buffer writeDouble(int offset, double d);
1311
1312   /**
1313    * Writes a 1 byte boolean to the buffer at the current position.
1314    * <p>
1315    * When the boolean is written to the buffer, the buffer's {@code position} will be advanced by {@code 1}.
1316    * If there are no bytes remaining in the buffer then a {@link java.nio.BufferOverflowException}
1317    * will be thrown.
1318    *
1319    * @param b The boolean to write.
1320    * @return The written buffer.
1321    * @throws java.nio.BufferOverflowException If the number of bytes exceeds the buffer's remaining bytes.
1322    * @see Buffer#writeBoolean(int, boolean)
1323    */
1324   @Override
1325   Buffer writeBoolean(boolean b);
1326
1327   /**
1328    * Writes a 1 byte boolean to the buffer at the given offset.
1329    * <p>
1330    * The boolean will be written as a single byte at the given offset. If there are no bytes remaining in the buffer
1331    * then a {@link java.nio.BufferOverflowException} will be thrown.
1332    *
1333    * @param offset The offset at which to write the boolean.
1334    * @param b      The boolean to write.
1335    * @return The written buffer.
1336    * @throws java.nio.BufferOverflowException If {@link Buffer#remaining()} is less than {@code 1}.
1337    * @throws IndexOutOfBoundsException        If the given offset is out of the bounds of the buffer. Note that
1338    *                                          bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
1339    * @see Buffer#writeBoolean(boolean)
1340    */
1341   @Override
1342   Buffer writeBoolean(int offset, boolean b);
1343
1344   /**
1345    * Writes a UTF-8 string to the buffer at the current position.
1346    * <p>
1347    * The string will be written with a two-byte unsigned byte length followed by the UTF-8 bytes. If there are not enough
1348    * bytes remaining in the buffer then a {@link java.nio.BufferOverflowException} will be thrown.
1349    *
1350    * @param s The string to write.
1351    * @return The written buffer.
1352    * @throws java.nio.BufferOverflowException If the number of bytes exceeds the buffer's remaining bytes.
1353    * @see Buffer#writeUTF8(int, String)
1354    */
1355   @Override
1356   Buffer writeUTF8(String s);
1357
1358   /**
1359    * Writes a UTF-8 string to the buffer at the given offset.
1360    * <p>
1361    * The string will be written with a two-byte unsigned byte length followed by the UTF-8 bytes. If there are not enough
1362    * bytes remaining in the buffer then a {@link java.nio.BufferOverflowException} will be thrown.
1363    *
1364    * @param offset The offset at which to write the string.
1365    * @param s      The string to write.
1366    * @return The written buffer.
1367    * @throws java.nio.BufferOverflowException If {@link Buffer#remaining()} is less than {@code 1}.
1368    * @throws IndexOutOfBoundsException        If the given offset is out of the bounds of the buffer. Note that
1369    *                                          bounds are determined by the buffer's {@link Buffer#limit()} rather than capacity.
1370    * @see Buffer#writeUTF8(String)
1371    */
1372   @Override
1373   Buffer writeUTF8(int offset, String s);
1374
1375   /**
1376    * Closes the buffer.
1377    * <p>
1378    * This method effectively acts as an alias to {@link Buffer#release()} and allows buffers to
1379    * be used as resources in try-with-resources statements. When the buffer is closed the internal reference counter
1380    * defined by {@link ReferenceCounted} will be decremented. However, if references to the
1381    * buffer still exist then those references will be allowed to continue to operate on the buffer until all references
1382    * have been released.
1383    */
1384   @Override
1385   void close();
1386
1387 }