1 /*
2 * Copyright 2021 The Netty Project
3 *
4 * The Netty Project licenses this file to you under the Apache License,
5 * version 2.0 (the "License"); you may not use this file except in compliance
6 * with the License. You may obtain a copy of the License at:
7 *
8 * https://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, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
14 * under the License.
15 */
16 package io.netty5.buffer.api;
17
18 import io.netty5.buffer.api.ComponentIterator.Next;
19 import io.netty5.buffer.api.internal.Statics;
20 import io.netty5.util.Resource;
21
22 import java.io.IOException;
23 import java.nio.ByteBuffer;
24 import java.nio.ByteOrder;
25 import java.nio.channels.FileChannel;
26 import java.nio.channels.GatheringByteChannel;
27 import java.nio.channels.ReadableByteChannel;
28 import java.nio.channels.ScatteringByteChannel;
29 import java.nio.channels.WritableByteChannel;
30 import java.nio.charset.Charset;
31
32 import static io.netty5.util.internal.ObjectUtil.checkPositiveOrZero;
33
34 /**
35 * A life cycled buffer of memory, with separate reader and writer offsets.
36 * <p>
37 * A buffer is a logically sequential stretch of memory with a certain capacity, an offset for writing,
38 * and an offset for reading.
39 * Buffers may be {@linkplain CompositeBuffer composed} of multiple {@linkplain #countComponents() components},
40 * where each component is a guaranteed contiguous chunk of memory.
41 *
42 * <h3>Creating a buffer</h3>
43 *
44 * Buffers are created by {@linkplain BufferAllocator allocators}, and their {@code allocate} family of methods.
45 * A number of standard allocators exist, and are available through static methods on the {@code BufferAllocator}
46 * interface.
47 *
48 * <h3>Buffer life cycle</h3>
49 *
50 * The buffer has a life cycle, where it is allocated, used, and deallocated.
51 * When the buffer is initially allocated, a pairing {@link #close()} call will deallocate it.
52 * If a buffer is {@linkplain #send() sent} elsewhere, the {@linkplain #close() close} method on the given instance
53 * will become a no-op.
54 * The buffer can be thought of as a view onto memory, and calling {@link #send()} on the buffer will effectively close
55 * that view, and recreate it upon reception at its destination.
56 *
57 * <h3>Thread-safety</h3>
58 *
59 * Buffers are <strong>not</strong> thread-safe.
60 *
61 * <h3>Accessing data</h3>
62 *
63 * Data access methods fall into two classes:
64 * <ol>
65 * <li>Access that are based on, and updates, the read or write offset positions.</li>
66 * <ul><li>These accessor methods are typically called {@code readX} or {@code writeX}.</li></ul>
67 * <li>Access that take offsets as arguments, and do not update read or write offset positions.</li>
68 * <ul><li>These accessor methods are typically called {@code getX} or {@code setX}.</li></ul>
69 * </ol>
70 *
71 * A buffer contains two mutable offset positions: one for reading and one for writing.
72 * These positions use <a href="https://en.wikipedia.org/wiki/Zero-based_numbering">zero-based indexing</a>,
73 * such that the first byte of data in the buffer is placed at offset {@code 0},
74 * and the last byte in the buffer is at offset {@link #capacity() capacity - 1}.
75 * The {@link #readerOffset()} is the offset into the buffer from which the next read will take place,
76 * and is initially zero.
77 * The reader offset must always be less than or equal to the {@link #writerOffset()}.
78 * The {@link #writerOffset()} is likewise the offset into the buffer where the next write will take place.
79 * The writer offset is also initially zero, and must be less than or equal to the {@linkplain #capacity() capacity}.
80 * <p>
81 * This carves the buffer into three regions, as demonstrated by this diagram:
82 * <pre>
83 * +-------------------+------------------+------------------+
84 * | discardable bytes | readable bytes | writable bytes |
85 * | | (CONTENT) | |
86 * +-------------------+------------------+------------------+
87 * | | | |
88 * 0 <= readerOffset <= writerOffset <= capacity
89 * </pre>
90 *
91 * <h3>Byte Order</h3>
92 *
93 * Buffers are always big endian, and this cannot be changed.
94 * Usages that need to get, set, read, or write, little-endian values will have to flip the byte order of the values
95 * they read and write.
96 *
97 * <h3 name="split">Splitting buffers</h3>
98 *
99 * The {@link #split()} method breaks a buffer into two.
100 * The two buffers will share the underlying memory, but their regions will not overlap, ensuring that the memory is
101 * safely shared between the two.
102 * <p>
103 * Splitting a buffer is useful for when you want to hand over a region of a buffer to some other,
104 * perhaps unknown, piece of code, and relinquish your ownership of that buffer region in the process.
105 * Examples include aggregating messages into an accumulator buffer, and sending messages down the pipeline for
106 * further processing, as split buffer regions, once their data has been received in its entirety.
107 *
108 * If you instead wish to temporarily share a region of a buffer, you will have to pass offset and length along with the
109 * buffer, or you will have to make a copy of the region.
110 *
111 * <h3>Buffers as constants</h3>
112 *
113 * Sometimes, the same bit of data will be processed or transmitted over and over again. In such cases, it can be
114 * tempting to allocate and fill a buffer once, and then reuse it.
115 * Such reuse must be done carefully, however, to avoid a number of bugs.
116 * The {@link BufferAllocator} has a {@link BufferAllocator#constBufferSupplier(byte[])} method that solves this, and
117 * prevents these bugs from occurring.
118 */
119 public interface Buffer extends Resource<Buffer>, BufferAccessor {
120 /**
121 * The capacity of this buffer, that is, the maximum number of bytes it can contain.
122 *
123 * @return The capacity in bytes.
124 */
125 int capacity();
126
127 /**
128 * Get the current reader offset. The next read will happen from this byte offset into the buffer.
129 *
130 * @return The current reader offset.
131 */
132 int readerOffset();
133
134 /**
135 * Move the reader offset forward by the given delta.
136 *
137 * @param delta to accumulate.
138 * @return This buffer instance.
139 * @throws IndexOutOfBoundsException if the new reader offset is greater than the current
140 * {@link #writerOffset()}.
141 * @throws IllegalArgumentException if the given delta is negative.
142 * @throws BufferClosedException if this buffer is closed.
143 */
144 default Buffer skipReadableBytes(int delta) {
145 checkPositiveOrZero(delta, "delta");
146 readerOffset(readerOffset() + delta);
147 return this;
148 }
149
150 /**
151 * Set the reader offset. Make the next read happen from the given offset into the buffer.
152 *
153 * @param offset The reader offset to set.
154 * @return This Buffer.
155 * @throws IndexOutOfBoundsException if the specified {@code offset} is less than zero or greater than the current
156 * {@link #writerOffset()}.
157 * @throws BufferClosedException if this buffer is closed.
158 */
159 Buffer readerOffset(int offset);
160
161 /**
162 * Get the current writer offset. The next write will happen at this byte offset into the buffer.
163 *
164 * @return The current writer offset.
165 */
166 int writerOffset();
167
168 /**
169 * Move the writer offset to ahead by the given delta.
170 *
171 * @param delta to accumulate.
172 * @return This buffer instance.
173 * @throws IndexOutOfBoundsException if the new writer offset is greater than {@link #capacity()}.
174 * @throws IllegalArgumentException if the given delta is negative.
175 * @throws BufferClosedException if this buffer is closed.
176 * @throws BufferReadOnlyException if this buffer is {@linkplain #readOnly() read-only}.
177 */
178 default Buffer skipWritableBytes(int delta) {
179 checkPositiveOrZero(delta, "delta");
180 writerOffset(writerOffset() + delta);
181 return this;
182 }
183
184 /**
185 * Set the writer offset. Make the next write happen at the given offset.
186 *
187 * @param offset The writer offset to set.
188 * @return This Buffer.
189 * @throws IndexOutOfBoundsException if the specified {@code offset} is less than the current
190 * {@link #readerOffset()} or greater than {@link #capacity()}.
191 * @throws BufferClosedException if this buffer is closed.
192 * @throws BufferReadOnlyException if this buffer is {@linkplain #readOnly() read-only}.
193 */
194 Buffer writerOffset(int offset);
195
196 /**
197 * Returns the number of readable bytes which is equal to {@code (writerOffset() - readerOffset())}.
198 */
199 default int readableBytes() {
200 return writerOffset() - readerOffset();
201 }
202
203 /**
204 * Returns the number of writable bytes which is equal to {@code (capacity() - writerOffset())}.
205 */
206 default int writableBytes() {
207 return capacity() - writerOffset();
208 }
209
210 /**
211 * Fills the buffer with the given byte value. This method does not respect the {@link #readerOffset()} or {@link
212 * #writerOffset()}, but copies the full capacity of the buffer. The {@link #readerOffset()} and {@link
213 * #writerOffset()} are not modified.
214 *
215 * @param value The byte value to write at every offset in the buffer.
216 * @return This Buffer.
217 * @throws BufferReadOnlyException if this buffer is {@linkplain #readOnly() read-only}.
218 */
219 Buffer fill(byte value);
220
221 /**
222 * Makes this buffer read-only. This is irreversible.
223 * This operation is also idempotent, so calling this method multiple times on the same buffer makes no difference.
224 *
225 * @return This buffer instance.
226 */
227 Buffer makeReadOnly();
228
229 /**
230 * Queries if this buffer is read-only or not.
231 *
232 * @return {@code true} if this buffer is read-only, {@code false} otherwise.
233 */
234 boolean readOnly();
235
236 /**
237 * Queries if this buffer is backed by native memory, or not.
238 *
239 * @return {@code true} if this buffer is backed by native, off-heap, memory. Otherwise, {@code false}, if this
240 * buffer is backed by on-heap memory.
241 */
242 boolean isDirect();
243
244 /**
245 * Set an upper limit to the implicit capacity growth. Buffer {@code write*} methods may implicitly grow the buffer
246 * capacity instead of throwing a bounds check exception. The implicit capacity limit restricts this growth so the
247 * buffer capacity does not automatically grow beyond the given limit. When the limit is reached, and there is no
248 * more writable space left, then the {@code write*} methods will start throwing exceptions.
249 * <p>
250 * The default limit is the maximum buffer size.
251 * <p>
252 * The limit is carried through {@link #send()} calls, but the buffer instances returned from the various
253 * {@code split} and {@code copy} methods will have the default limit set.
254 * <p>
255 * The limit is not impacted by calls to {@code split} methods on this buffer. In other words, even though
256 * {@code split} methods reduce the capacity of this buffer, the set limit, if any, remains the same.
257 *
258 * @param limit The maximum size this buffers capacity will implicitly grow to via {@code write*} methods.
259 * @return This buffer instance.
260 * @throws IndexOutOfBoundsException if the limit is negative, greater than the maximum buffer size, or if the
261 * {@linkplain #capacity() capacity} is already greater than the given limit.
262 */
263 Buffer implicitCapacityLimit(int limit);
264
265 /**
266 * Returns the implicit capacity limit of the buffer. If none was set before via {@link #implicitCapacityLimit(int)}
267 * this method will return the default value.
268 *
269 * @return the limit.
270 */
271 int implicitCapacityLimit();
272
273 /**
274 * Copies the given length of data from this buffer into the given destination array, beginning at the given source
275 * position in this buffer, and the given destination position in the destination array.
276 * <p>
277 * This method does not read or modify the {@linkplain #writerOffset() write offset} or the
278 * {@linkplain #readerOffset() read offset}.
279 *
280 * @param srcPos The byte offset into this buffer from where the copying should start; the byte at this offset in
281 * this buffer will be copied to the {@code destPos} index in the {@code dest} array.
282 * @param dest The destination byte array.
283 * @param destPos The index into the {@code dest} array from where the copying should start.
284 * @param length The number of bytes to copy.
285 * @throws NullPointerException if the destination array is null.
286 * @throws IndexOutOfBoundsException if the source or destination positions, or the length, are negative,
287 * or if the resulting end positions reaches beyond the end of either this buffer, or the destination array.
288 * @throws BufferClosedException if this buffer is closed.
289 */
290 void copyInto(int srcPos, byte[] dest, int destPos, int length);
291
292 /**
293 * Copies the given length of data from this buffer into the given destination byte buffer, beginning at the given
294 * source position in this buffer, and the given destination position in the destination byte buffer.
295 * <p>
296 * This method does not read or modify the {@linkplain #writerOffset() write offset} or the
297 * {@linkplain #readerOffset() read offset}, nor is the position of the destination buffer changed.
298 * <p>
299 * The position and limit of the destination byte buffer are also ignored, and do not influence {@code destPos}
300 * or {@code length}.
301 *
302 * @param srcPos The byte offset into this buffer from where the copying should start; the byte at this offset in
303 * this buffer will be copied to the {@code destPos} index in the {@code dest} array.
304 * @param dest The destination byte buffer.
305 * @param destPos The index into the {@code dest} array from where the copying should start.
306 * @param length The number of bytes to copy.
307 * @throws NullPointerException if the destination buffer is null.
308 * @throws IndexOutOfBoundsException if the source or destination positions, or the length, are negative,
309 * or if the resulting end positions reaches beyond the end of either this buffer, or the destination array.
310 * @throws java.nio.ReadOnlyBufferException if the destination buffer is read-only.
311 * @throws BufferClosedException if this buffer is closed.
312 */
313 void copyInto(int srcPos, ByteBuffer dest, int destPos, int length);
314
315 /**
316 * Copies the given length of data from this buffer into the given destination buffer, beginning at the given
317 * source position in this buffer, and the given destination position in the destination buffer.
318 * <p>
319 * This method does not read or modify the {@linkplain #writerOffset() write offset} or the
320 * {@linkplain #readerOffset() read offset} on this buffer, nor on the destination buffer.
321 * <p>
322 * The read and write offsets of the destination buffer are also ignored, and do not influence {@code destPos}
323 * or {@code length}.
324 *
325 * @param srcPos The byte offset into this buffer from where the copying should start; the byte at this offset in
326 * this buffer will be copied to the {@code destPos} index in the {@code dest} array.
327 * @param dest The destination buffer.
328 * @param destPos The index into the {@code dest} array from where the copying should start.
329 * @param length The number of bytes to copy.
330 * @throws NullPointerException if the destination buffer is null.
331 * @throws IndexOutOfBoundsException if the source or destination positions, or the length, are negative,
332 * or if the resulting end positions reaches beyond the end of either this buffer, or the destination array.
333 * @throws BufferReadOnlyException if the destination buffer is read-only.
334 * @throws BufferClosedException if this or the destination buffer is closed.
335 */
336 void copyInto(int srcPos, Buffer dest, int destPos, int length);
337
338 /**
339 * Read from this buffer and write to the given channel.
340 * The number of bytes actually written to the channel are returned.
341 * No more than the given {@code length} of bytes, or the number of {@linkplain #readableBytes() readable bytes},
342 * will be written to the channel, whichever is smaller.
343 * If the channel has a position, then it will be advanced by the number of bytes written.
344 * The {@linkplain #readerOffset() reader-offset} of this buffer will likewise be advanced by the number of bytes
345 * written.
346 *
347 * @implNote {@linkplain CompositeBuffer composite buffers} may offer an optimized implementation of this method,
348 * if the given channel implements {@link GatheringByteChannel}.
349 *
350 * @param channel The channel to write to.
351 * @param length The maximum number of bytes to write.
352 * @return The actual number of bytes written, possibly zero.
353 * @throws IOException If the write-operation on the channel failed for some reason.
354 */
355 int transferTo(WritableByteChannel channel, int length) throws IOException;
356
357 /**
358 * Read from the given channel starting from the given position and write to this buffer.
359 * The number of bytes actually read from the channel are returned, or -1 is returned if the channel has reached
360 * the end-of-stream.
361 * No more than the given {@code length} of bytes, or the number of {@linkplain #writableBytes() writable bytes},
362 * will be read from the channel, whichever is smaller.
363 * The channel's position is not modified.
364 * The {@linkplain #writerOffset() writer-offset} of this buffer will likewise be advanced by the number of bytes
365 * read.
366 *
367 * @param channel The channel to read from.
368 * @param position The file position.
369 * @param length The maximum number of bytes to read.
370 * @return The actual number of bytes read, possibly zero, or -1 if the end-of-stream has been reached.
371 * @throws IOException If the read-operation on the channel failed for some reason.
372 */
373 int transferFrom(FileChannel channel, long position, int length) throws IOException;
374
375 /**
376 * Read from the given channel and write to this buffer.
377 * The number of bytes actually read from the channel are returned, or -1 is returned if the channel has reached
378 * the end-of-stream.
379 * No more than the given {@code length} of bytes, or the number of {@linkplain #writableBytes() writable bytes},
380 * will be read from the channel, whichever is smaller.
381 * If the channel has a position, then it will be advanced by the number of bytes read.
382 * The {@linkplain #writerOffset() writer-offset} of this buffer will likewise be advanced by the number of bytes
383 * read.
384 *
385 * @implNote {@linkplain CompositeBuffer composite buffers} may offer an optimized implementation of this method,
386 * if the given channel implements {@link ScatteringByteChannel}.
387 *
388 * @param channel The channel to read from.
389 * @param length The maximum number of bytes to read.
390 * @return The actual number of bytes read, possibly zero, or -1 if the end-of-stream has been reached.
391 * @throws IOException If the read-operation on the channel failed for some reason.
392 */
393 int transferFrom(ReadableByteChannel channel, int length) throws IOException;
394
395 /**
396 * Writes into this buffer, all the bytes from the given {@code source} using the passed {@code charset}.
397 * This updates the {@linkplain #writerOffset() write offset} of this buffer.
398 *
399 * @param source {@link CharSequence} to read from.
400 * @param charset {@link Charset} to use for writing.
401 * @return This buffer.
402 */
403 default Buffer writeCharSequence(CharSequence source, Charset charset) {
404 Statics.writeCharSequence(source, this, charset);
405 return this;
406 }
407
408 /**
409 * Reads a {@link CharSequence} of the passed {@code length} using the passed {@link Charset}.
410 * This updates the {@linkplain #readerOffset()} reader offset} of this buffer.
411 *
412 * @param length of {@link CharSequence} to read.
413 * @param charset of the bytes to be read.
414 * @return {@link CharSequence} read from this buffer.
415 * @throws IndexOutOfBoundsException if the passed {@code length} is more than the {@linkplain #readableBytes()} of
416 * this buffer.
417 */
418 default CharSequence readCharSequence(int length, Charset charset) {
419 return Statics.readCharSequence(this, length, charset);
420 }
421
422 /**
423 * Writes into this buffer, all the readable bytes from the given buffer.
424 * This updates the {@linkplain #writerOffset() write offset} of this buffer, and the
425 * {@linkplain #readerOffset() reader offset} of the given buffer.
426 *
427 * @param source The buffer to read from.
428 * @return This buffer.
429 * @throws NullPointerException If the source buffer is {@code null}.
430 */
431 default Buffer writeBytes(Buffer source) {
432 int size = source.readableBytes();
433 if (writableBytes() < size && writerOffset() + size <= implicitCapacityLimit()) {
434 ensureWritable(size, 1, false);
435 }
436 int woff = writerOffset();
437 source.copyInto(source.readerOffset(), this, woff, size);
438 source.skipReadableBytes(size);
439 skipWritableBytes(size);
440 return this;
441 }
442
443 /**
444 * Writes into this buffer, all the bytes from the given byte array.
445 * This updates the {@linkplain #writerOffset() write offset} of this buffer by the length of the array.
446 *
447 * @param source The byte array to read from.
448 * @return This buffer.
449 */
450 default Buffer writeBytes(byte[] source) {
451 return writeBytes(source, 0, source.length);
452 }
453
454 /**
455 * Writes into this buffer, the given number of bytes from the byte array.
456 * This updates the {@linkplain #writerOffset() write offset} of this buffer by the length argument.
457 *
458 * @param source The byte array to read from.
459 * @param srcPos Position in the {@code source} from where bytes should be written to this buffer.
460 * @param length The number of bytes to copy.
461 * @return This buffer.
462 */
463 default Buffer writeBytes(byte[] source, int srcPos, int length) {
464 if (source.length < srcPos + length) {
465 throw new ArrayIndexOutOfBoundsException();
466 }
467 if (writableBytes() < length && writerOffset() + length <= implicitCapacityLimit()) {
468 ensureWritable(length, 1, false);
469 }
470 int woff = writerOffset();
471 for (int i = 0; i < length; i++) {
472 setByte(woff + i, source[srcPos + i]);
473 }
474 skipWritableBytes(length);
475 return this;
476 }
477
478 /**
479 * Writes into this buffer from the source {@link ByteBuffer}.
480 * This updates the {@linkplain #writerOffset() write offset} of this buffer and also the position of
481 * the source {@link ByteBuffer}.
482 * <p>
483 * Note: the behaviour is undefined if the given {@link ByteBuffer} is an alias for the memory in this buffer.
484 *
485 * @param source The {@link ByteBuffer} to read from.
486 * @return This buffer.
487 */
488 default Buffer writeBytes(ByteBuffer source) {
489 if (source.hasArray()) {
490 writeBytes(source.array(), source.arrayOffset() + source.position(), source.remaining());
491 source.position(source.limit());
492 } else {
493 int woff = writerOffset();
494 int length = source.remaining();
495 if (writableBytes() < length && woff + length <= implicitCapacityLimit()) {
496 ensureWritable(length, 1, false);
497 }
498 writerOffset(woff + length);
499 // Try to reduce bounds-checking by using long and int when possible.
500 boolean needReverse = source.order() != ByteOrder.BIG_ENDIAN;
501 for (; length >= Long.BYTES; length -= Long.BYTES, woff += Long.BYTES) {
502 setLong(woff, needReverse ? Long.reverseBytes(source.getLong()) : source.getLong());
503 }
504 for (; length >= Integer.BYTES; length -= Integer.BYTES, woff += Integer.BYTES) {
505 setInt(woff, needReverse ? Integer.reverseBytes(source.getInt()) : source.getInt());
506 }
507 for (; length > 0; length--, woff++) {
508 setByte(woff, source.get());
509 }
510 }
511 return this;
512 }
513
514 /**
515 * Read from this buffer, into the destination {@link ByteBuffer}
516 * This updates the {@linkplain #readerOffset() read offset} of this buffer and also the position of
517 * the destination {@link ByteBuffer}.
518 * <p>
519 * Note: the behaviour is undefined if the given {@link ByteBuffer} is an alias for the memory in this buffer.
520 *
521 * @param destination The {@link ByteBuffer} to write into.
522 * @return This buffer.
523 */
524 default Buffer readBytes(ByteBuffer destination) {
525 int byteCount = destination.remaining();
526 copyInto(readerOffset(), destination, destination.position(), byteCount);
527 skipReadableBytes(byteCount);
528 destination.position(destination.limit());
529 return this;
530 }
531
532 /**
533 * Read from this buffer, into the destination array, the given number of bytes.
534 * This updates the {@linkplain #readerOffset() read offset} of this buffer by the length argument.
535 *
536 * @param destination The byte array to write into.
537 * @param destPos Position in the {@code destination} to where bytes should be written from this buffer.
538 * @param length The number of bytes to copy.
539 * @return This buffer.
540 */
541 default Buffer readBytes(byte[] destination, int destPos, int length) {
542 int roff = readerOffset();
543 copyInto(roff, destination, destPos, length);
544 readerOffset(roff + length);
545 return this;
546 }
547
548 /**
549 * Resets the {@linkplain #readerOffset() read offset} and the {@linkplain #writerOffset() write offset} on this
550 * buffer to zero, and return this buffer.
551 *
552 * @return This buffer instance.
553 */
554 default Buffer resetOffsets() {
555 readerOffset(0);
556 if (!readOnly()) {
557 writerOffset(0);
558 }
559 return this;
560 }
561
562 /**
563 * Get the number of {@linkplain #readableBytes() readable bytes}, until the given {@code needle} is found in this
564 * buffer.
565 * If the needle is not found, {@code -1} is returned.
566 * <p>
567 * This method does not modify the {@linkplain #readerOffset() reader-offset} or the
568 * {@linkplain #writerOffset() write-offset}.
569 *
570 * @param needle The byte value to search for.
571 * @return The offset, relative to the current {@link #readerOffset()}, of the found value, or {@code -1} if none
572 * was found.
573 */
574 int bytesBefore(byte needle);
575
576 /**
577 * Get the number of {@linkplain #readableBytes() readable bytes}, until the given {@code needle} is found in this
578 * buffer.
579 * The found offset will be the offset into this buffer, relative to its {@linkplain #readerOffset() reader-offset},
580 * of the first byte of a sequence that matches all readable bytes in the given {@code needle} buffer.
581 * If the needle is not found, {@code -1} is returned.
582 * <p>
583 * This method does not modify the {@linkplain #readerOffset() reader-offset} or the
584 * {@linkplain #writerOffset() write-offset}.
585 *
586 * @param needle The buffer value to search for.
587 * @return The offset, relative to the current {@link #readerOffset()}, of the found value, or {@code -1} if none
588 * was found.
589 */
590 int bytesBefore(Buffer needle);
591
592 /**
593 * Opens a cursor to iterate the readable bytes of this buffer. The {@linkplain #readerOffset() reader offset} and
594 * {@linkplain #writerOffset() writer offset} are not modified by the cursor.
595 * <p>
596 * Care should be taken to ensure that the buffer's lifetime extends beyond the cursor and the iteration, and that
597 * the {@linkplain #readerOffset() reader offset} and {@linkplain #writerOffset() writer offset} are not modified
598 * while the iteration takes place. Otherwise, unpredictable behaviour might result.
599 *
600 * @return A {@link ByteCursor} for iterating the readable bytes of this buffer.
601 */
602 ByteCursor openCursor();
603
604 /**
605 * Opens a cursor to iterate the given number bytes of this buffer, starting at the given offset.
606 * The {@linkplain #readerOffset() reader offset} and {@linkplain #writerOffset() writer offset} are not modified by
607 * the cursor.
608 * <p>
609 * Care should be taken to ensure that the buffer's lifetime extends beyond the cursor and the iteration, and that
610 * the {@linkplain #readerOffset() reader offset} and {@linkplain #writerOffset() writer offset} are not modified
611 * while the iteration takes place. Otherwise, unpredictable behaviour might result.
612 *
613 * @param fromOffset The offset into the buffer where iteration should start.
614 * The first byte read from the iterator will be the byte at this offset.
615 * @param length The number of bytes to iterate.
616 * @return A {@link ByteCursor} for the given stretch of bytes of this buffer.
617 * @throws IllegalArgumentException if the length is negative, or if the region given by the {@code fromOffset} and
618 * the {@code length} reaches outside the bounds of this buffer.
619 */
620 ByteCursor openCursor(int fromOffset, int length);
621
622 /**
623 * Opens a cursor to iterate the readable bytes of this buffer, in reverse.
624 * The {@linkplain #readerOffset() reader offset} and {@linkplain #writerOffset() writer offset} are not modified by
625 * the cursor.
626 * <p>
627 * Care should be taken to ensure that the buffer's lifetime extends beyond the cursor and the iteration, and that
628 * the {@linkplain #readerOffset() reader offset} and {@linkplain #writerOffset() writer offset} are not modified
629 * while the iteration takes place. Otherwise, unpredictable behaviour might result.
630 *
631 * @return A {@link ByteCursor} for the readable bytes of this buffer.
632 */
633 default ByteCursor openReverseCursor() {
634 int woff = writerOffset();
635 return openReverseCursor(woff == 0? 0 : woff - 1, readableBytes());
636 }
637
638 /**
639 * Opens a cursor to iterate the given number bytes of this buffer, in reverse, starting at the given offset.
640 * The {@linkplain #readerOffset() reader offset} and {@linkplain #writerOffset() writer offset} are not modified by
641 * the cursor.
642 * <p>
643 * Care should be taken to ensure that the buffer's lifetime extends beyond the cursor and the iteration, and that
644 * the {@linkplain #readerOffset() reader offset} and {@linkplain #writerOffset() writer offset} are not modified
645 * while the iteration takes place. Otherwise, unpredictable behaviour might result.
646 *
647 * @param fromOffset The offset into the buffer where iteration should start.
648 * The first byte read from the iterator will be the byte at this offset.
649 * @param length The number of bytes to iterate.
650 * @return A {@link ByteCursor} for the given stretch of bytes of this buffer.
651 * @throws IllegalArgumentException if the length is negative, or if the region given by the {@code fromOffset} and
652 * the {@code length} reaches outside the bounds of this buffer.
653 */
654 ByteCursor openReverseCursor(int fromOffset, int length);
655
656 /**
657 * Ensures that this buffer has at least the given number of bytes of
658 * {@linkplain #writableBytes() available space for writing}.
659 * If this buffer already has the necessary space, then this method returns immediately.
660 * If this buffer does not already have the necessary space, then it will be expanded using the
661 * {@link BufferAllocator} the buffer was created with.
662 * This method is the same as calling {@link #ensureWritable(int, int, boolean)} where {@code allowCompaction} is
663 * {@code true}.
664 *
665 * @param size The requested number of bytes of space that should be available for writing.
666 * @return This buffer instance.
667 * @throws IllegalStateException if this buffer is in a bad state.
668 * @throws BufferClosedException if this buffer is closed.
669 * @throws BufferReadOnlyException if this buffer is {@linkplain #readOnly() read-only}.
670 */
671 default Buffer ensureWritable(int size) {
672 ensureWritable(size, capacity(), true);
673 return this;
674 }
675
676 /**
677 * Ensures that this buffer has at least the given number of bytes of
678 * {@linkplain #writableBytes() available space for writing}.
679 * If this buffer already has the necessary space, then this method returns immediately.
680 * If this buffer does not already have the necessary space, then space will be made available in one or all of
681 * the following available ways:
682 *
683 * <ul>
684 * <li>
685 * If {@code allowCompaction} is {@code true}, and sum of the read and writable bytes would be enough to
686 * satisfy the request, and it (depending on the buffer implementation) seems faster and easier to compact
687 * the existing buffer rather than allocation a new buffer, then the requested bytes will be made available
688 * that way. The compaction will not necessarily work the same way as the {@link #compact()} method, as the
689 * implementation may be able to make the requested bytes available with less effort than is strictly
690 * mandated by the {@link #compact()} method.
691 * </li>
692 * <li>
693 * Regardless of the value of the {@code allowCompaction}, the implementation may make more space available
694 * by just allocating more or larger buffers. This allocation would use the same {@link BufferAllocator}
695 * that this buffer was created with.
696 * </li>
697 * <li>
698 * If {@code allowCompaction} is {@code true}, then the implementation may choose to do a combination of
699 * compaction and allocation.
700 * </li>
701 * </ul>
702 *
703 * @param size The requested number of bytes of space that should be available for writing.
704 * @return This buffer instance.
705 * @param minimumGrowth The minimum number of bytes to grow by. If it is determined that memory should be allocated
706 * and copied, make sure that the new memory allocation is bigger than the old one by at least
707 * this many bytes. This way, the buffer can grow by more than what is immediately necessary,
708 * thus amortising the costs of allocating and copying.
709 * @param allowCompaction {@code true} if the method is allowed to modify the
710 * {@linkplain #readerOffset() reader offset} and
711 * {@linkplain #writerOffset() writer offset}, otherwise {@code false}.
712 * @throws BufferReadOnlyException if this buffer is {@linkplain #readOnly() read-only}.
713 * @throws IllegalArgumentException if {@code size} or {@code minimumGrowth} are negative.
714 * @throws IllegalStateException if this buffer is in a bad state.
715 */
716 Buffer ensureWritable(int size, int minimumGrowth, boolean allowCompaction);
717
718 /**
719 * Returns a copy of this buffer's readable bytes.
720 * Modifying the content of the returned buffer will not affect this buffers contents.
721 * The two buffers will maintain separate offsets. This method is identical to
722 * {@code buf.copy(buf.readerOffset(), buf.readableBytes())}.
723 * This method does not modify {@link #readerOffset()} or {@link #writerOffset()} of this buffer.
724 * <p>
725 * The copy is created with a {@linkplain #writerOffset() write offset} equal to the length of the copied data,
726 * so that the entire contents of the copy is ready to be read.
727 * <p>
728 * The returned buffer will not be read-only, regardless of the {@linkplain #readOnly() read-only state} of this
729 * buffer.
730 *
731 * @return A new buffer instance, with independent {@link #readerOffset()} and {@link #writerOffset()},
732 * that contains a copy of the readable region of this buffer.
733 * @throws BufferClosedException if this buffer is closed.
734 */
735 default Buffer copy() {
736 int offset = readerOffset();
737 int length = readableBytes();
738 return copy(offset, length);
739 }
740
741 /**
742 * Returns a copy of the given region of this buffer.
743 * Modifying the content of the returned buffer will not affect this buffers contents.
744 * The two buffers will maintain separate offsets.
745 * This method does not modify {@link #readerOffset()} or {@link #writerOffset()} of this buffer.
746 * <p>
747 * The copy is created with a {@linkplain #writerOffset() write offset} equal to the length of the copy,
748 * so that the entire contents of the copy is ready to be read.
749 * <p>
750 * The returned buffer will not be read-only, regardless of the {@linkplain #readOnly() read-only state} of this
751 * buffer.
752 * This has the same effect as calling {@link #copy(int, int, boolean)} with a {@code false} read-only argument.
753 *
754 * @param offset The offset where copying should start from. This is the offset of the first byte copied.
755 * @param length The number of bytes to copy, and the capacity of the returned buffer.
756 * @return A new buffer instance, with independent {@link #readerOffset()} and {@link #writerOffset()},
757 * that contains a copy of the given region of this buffer.
758 * @throws IllegalArgumentException if the {@code offset} or {@code length} reaches outside the bounds of the
759 * buffer.
760 * @throws BufferClosedException if this buffer is closed.
761 */
762 default Buffer copy(int offset, int length) {
763 return copy(offset, length, false);
764 }
765
766 /**
767 * Returns a copy of this buffer's readable bytes, with the given read-only setting.
768 * Modifying the content of the returned buffer will not affect this buffers contents.
769 * The two buffers will maintain separate offsets.
770 * This method does not modify {@link #readerOffset()} or {@link #writerOffset()} of this buffer.
771 * <p>
772 * The copy is created with a {@linkplain #writerOffset() write offset} equal to the length of the copy,
773 * so that the entire contents of the copy is ready to be read.
774 * <p>
775 * The returned buffer will be read-only if, and only if, the {@code readOnly} argument is {@code true}, and it
776 * will not be read-only if the argument is {@code false}.
777 * This is the case regardless of the {@linkplain #readOnly() read-only state} of this buffer.
778 * <p>
779 * If this buffer is read-only, and a read-only copy is requested, then implementations <em>may</em> use structural
780 * sharing and have both buffers backed by the same underlying memory.
781 *
782 * @param readOnly The desired {@link #readOnly()} state of the returned buffer.
783 * @return A new buffer instance, with independent {@link #readerOffset()} and {@link #writerOffset()},
784 * that contains a copy of the given region of this buffer.
785 * @throws IllegalArgumentException if the {@code offset} or {@code length} reaches outside the bounds of the
786 * buffer.
787 * @throws BufferClosedException if this buffer is closed.
788 */
789 default Buffer copy(boolean readOnly) {
790 return copy(readerOffset(), readableBytes(), readOnly);
791 }
792
793 /**
794 * Returns a copy of the given region of this buffer.
795 * Modifying the content of the returned buffer will not affect this buffers contents.
796 * The two buffers will maintain separate offsets.
797 * This method does not modify {@link #readerOffset()} or {@link #writerOffset()} of this buffer.
798 * <p>
799 * The copy is created with a {@linkplain #writerOffset() write offset} equal to the length of the copy,
800 * so that the entire contents of the copy is ready to be read.
801 * <p>
802 * The returned buffer will be read-only if, and only if, the {@code readOnly} argument is {@code true}, and it
803 * will not be read-only if the argument is {@code false}.
804 * This is the case regardless of the {@linkplain #readOnly() read-only state} of this buffer.
805 * <p>
806 * If this buffer is read-only, and a read-only copy is requested, then implementations <em>may</em> use structural
807 * sharing and have both buffers backed by the same underlying memory.
808 *
809 * @param offset The offset where copying should start from. This is the offset of the first byte copied.
810 * @param length The number of bytes to copy, and the capacity of the returned buffer.
811 * @param readOnly The desired {@link #readOnly()} state of the returned buffer.
812 * @return A new buffer instance, with independent {@link #readerOffset()} and {@link #writerOffset()},
813 * that contains a copy of the given region of this buffer.
814 * @throws IllegalArgumentException if the {@code offset} or {@code length} reaches outside the bounds of the
815 * buffer.
816 * @throws BufferClosedException if this buffer is closed.
817 */
818 Buffer copy(int offset, int length, boolean readOnly);
819
820 /**
821 * Splits the buffer into two, at {@code length} number of bytes from the current
822 * {@linkplain #readerOffset()} reader offset} position.
823 * <p>
824 * The region of this buffer that contain the previously read and readable bytes till the
825 * {@code readerOffset() + length} position, will be captured and returned in a new buffer,
826 * that will hold its own ownership of that region.
827 * This allows the returned buffer to be independently {@linkplain #send() sent} to other threads.
828 * <p>
829 * The returned buffer will change its {@link #readerOffset()} to {@code readerOffset() + length}, and have its
830 * {@link #writerOffset()} and {@link #capacity()} both set to the {@code readerOffset() + length} position.
831 * <p>
832 * The memory region in the returned buffer will become inaccessible through this buffer. This buffer will have its
833 * capacity reduced by the capacity of the returned buffer, read offset will become zero and relative position of
834 * write offset will be preserved from the provided {@code readerOffset() + length} position,
835 * even though their position in memory remain unchanged.
836 * <p>
837 * Effectively, the following transformation takes place:
838 * <pre>{@code
839 * This buffer, where offset = readerOffset() + length:
840 * +------------------------------------------+
841 * 0| |r/o offset |w/o |cap
842 * +---+---------+-----------+----------------+
843 * / / / \ \ \
844 * / / / \ \ \
845 * / / / \ \ \
846 * / / / \ \ \
847 * / / / \ \ \
848 * +---+---------+ +----------+----------------+
849 * | |r/o |w/o & cap |r/o w/o |cap
850 * +---+---------+ +---------------------------+
851 * Returned buffer. This buffer.
852 * }</pre>
853 * When the buffers are in this state, both of the split parts retain an atomic reference count on the
854 * underlying memory. This means that shared underlying memory will not be deallocated or returned to a pool, until
855 * all the split parts have been closed.
856 * <p>
857 * Composite buffers have it a little easier, in that at most only one of the constituent buffers will actually be
858 * split. If the split point lands perfectly between two constituent buffers, then a composite buffer can
859 * simply split its internal array in two.
860 * <p>
861 * Split buffers support all operations that normal buffers do, including {@link #ensureWritable(int)}.
862 * <p>
863 * See the <a href="#split">Splitting buffers</a> section for details.
864 *
865 * @return A new buffer with independent and exclusive ownership over the previously read and readable bytes from
866 * this buffer.
867 */
868 default Buffer readSplit(int length) {
869 return split(readerOffset() + length);
870 }
871
872 /**
873 * Splits the buffer into two, at {@code length} number of bytes from the current
874 * {@linkplain #writerOffset()} writer offset} position.
875 * <p>
876 * The region of this buffer that contain the previously read and readable bytes till the
877 * {@code writerOffset() + length} position, will be captured and returned in a new buffer,
878 * that will hold its own ownership of that region.
879 * This allows the returned buffer to be independently {@linkplain #send() sent} to other threads.
880 * <p>
881 * The returned buffer will change its {@link #writerOffset()} to {@code writerOffset() + length}, and have its
882 * {@link #writerOffset()} and {@link #capacity()} both set to the {@code writerOffset() + length}.
883 * <p>
884 * The memory region in the returned buffer will become inaccessible through this buffer. This buffer will have its
885 * capacity reduced by the capacity of the returned buffer, read offset will become zero and relative position of
886 * write offset will be preserved from the provided {@code writerOffset() + length} position,
887 * even though their position in memory remain unchanged.
888 * <p>
889 * Effectively, the following transformation takes place:
890 * <pre>{@code
891 * This buffer, where offset = writerOffset() + length:
892 * +------------------------------------------+
893 * 0| |r/o |w/o offset |cap
894 * +---+----+-------+-------------------------+
895 * / / / / \ \
896 * / / / / \ \
897 * / / / / \ \
898 * / / / / \ \
899 * / / / / \ \
900 * +---+----+-------+ +------------------------+
901 * | |r/o |w/o | cap |r/o & w/o |cap
902 * +---+----+-------+ +------------------------+
903 * Returned buffer. This buffer.
904 * }</pre>
905 * When the buffers are in this state, both of the split parts retain an atomic reference count on the
906 * underlying memory. This means that shared underlying memory will not be deallocated or returned to a pool, until
907 * all the split parts have been closed.
908 * <p>
909 * Composite buffers have it a little easier, in that at most only one of the constituent buffers will actually be
910 * split. If the split point lands perfectly between two constituent buffers, then a composite buffer can
911 * simply split its internal array in two.
912 * <p>
913 * Split buffers support all operations that normal buffers do, including {@link #ensureWritable(int)}.
914 * <p>
915 * See the <a href="#split">Splitting buffers</a> section for details.
916 *
917 * @return A new buffer with independent and exclusive ownership over the previously read and readable bytes from
918 * this buffer.
919 */
920 default Buffer writeSplit(int length) {
921 return split(writerOffset() + length);
922 }
923
924 /**
925 * Splits the buffer into two, at the {@linkplain #writerOffset() write offset} position.
926 * <p>
927 * The region of this buffer that contain the previously read and readable bytes, will be captured and returned in
928 * a new buffer, that will hold its own ownership of that region. This allows the returned buffer to be
929 * independently {@linkplain #send() sent} to other threads.
930 * <p>
931 * The returned buffer will adopt the {@link #readerOffset()} of this buffer, and have its {@link #writerOffset()}
932 * and {@link #capacity()} both set to the equal to the write-offset of this buffer.
933 * <p>
934 * The memory region in the returned buffer will become inaccessible through this buffer. This buffer will have its
935 * capacity reduced by the capacity of the returned buffer, and the read and write offsets of this buffer will both
936 * become zero, even though their position in memory remain unchanged.
937 * <p>
938 * Effectively, the following transformation takes place:
939 * <pre>{@code
940 * This buffer:
941 * +------------------------------------------+
942 * 0| |r/o |w/o |cap
943 * +---+---------------------+----------------+
944 * / / / \ \
945 * / / / \ \
946 * / / / \ \
947 * / / / \ \
948 * / / / \ \
949 * +---+---------------------+ +---------------+
950 * | |r/o |w/o & cap |r/o & w/o |cap
951 * +---+---------------------+ +---------------+
952 * Returned buffer. This buffer.
953 * }</pre>
954 * When the buffers are in this state, both of the split parts retain an atomic reference count on the
955 * underlying memory. This means that shared underlying memory will not be deallocated or returned to a pool, until
956 * all the split parts have been closed.
957 * <p>
958 * Composite buffers have it a little easier, in that at most only one of the constituent buffers will actually be
959 * split. If the split point lands perfectly between two constituent buffers, then a composite buffer can
960 * simply split its internal array in two.
961 * <p>
962 * Split buffers support all operations that normal buffers do, including {@link #ensureWritable(int)}.
963 * <p>
964 * See the <a href="#split">Splitting buffers</a> section for details.
965 *
966 * @return A new buffer with independent and exclusive ownership over the previously read and readable bytes from
967 * this buffer.
968 */
969 default Buffer split() {
970 return split(writerOffset());
971 }
972
973 /**
974 * Splits the buffer into two, at the given {@code splitOffset}.
975 * <p>
976 * The region of this buffer that precede the {@code splitOffset}, will be captured and returned in a new
977 * buffer, that will hold its own ownership of that region. This allows the returned buffer to be independently
978 * {@linkplain #send() sent} to other threads.
979 * <p>
980 * The returned buffer will adopt the {@link #readerOffset()} and {@link #writerOffset()} of this buffer,
981 * but truncated to fit within the capacity dictated by the {@code splitOffset}.
982 * <p>
983 * The memory region in the returned buffer will become inaccessible through this buffer. If the
984 * {@link #readerOffset()} or {@link #writerOffset()} of this buffer lie prior to the {@code splitOffset},
985 * then those offsets will be moved forward, so they land on offset 0 after the split.
986 * <p>
987 * Effectively, the following transformation takes place:
988 * <pre>{@code
989 * This buffer:
990 * +--------------------------------+
991 * 0| |splitOffset |cap
992 * +---------------+----------------+
993 * / / \ \
994 * / / \ \
995 * / / \ \
996 * / / \ \
997 * / / \ \
998 * +---------------+ +---------------+
999 * | |cap | |cap
1000 * +---------------+ +---------------+
1001 * Returned buffer. This buffer.
1002 * }</pre>
1003 * When the buffers are in this state, both of the split parts retain an atomic reference count on the
1004 * underlying memory. This means that shared underlying memory will not be deallocated or returned to a pool, until
1005 * all the split parts have been closed.
1006 * <p>
1007 * Composite buffers have it a little easier, in that at most only one of the constituent buffers will actually be
1008 * split. If the split point lands perfectly between two constituent buffers, then a composite buffer can
1009 * simply split its internal array in two.
1010 * <p>
1011 * Split buffers support all operations that normal buffers do, including {@link #ensureWritable(int)}.
1012 * <p>
1013 * See the <a href="#split">Splitting buffers</a> section for details.
1014 *
1015 * @param splitOffset The offset into this buffer where it should be split. After the split, the data at this offset
1016 * will be at offset zero in this buffer.
1017 * @return A new buffer with independent and exclusive ownership over the bytes from the beginning to the given
1018 * offset of this buffer.
1019 */
1020 Buffer split(int splitOffset);
1021
1022 /**
1023 * Discards the read bytes, and moves the buffer contents to the beginning of the buffer.
1024 *
1025 * @return This buffer instance.
1026 * @throws BufferReadOnlyException if this buffer is {@linkplain #readOnly() read-only}.
1027 * @throws IllegalStateException if this buffer is in a bad state.
1028 */
1029 Buffer compact();
1030
1031 /**
1032 * Get the number of "components" in this buffer. For composite buffers, this is the number of transitive
1033 * constituent buffers, while non-composite buffers only have one component.
1034 *
1035 * @return The number of components in this buffer.
1036 */
1037 int countComponents();
1038
1039 /**
1040 * Get the number of "components" in this buffer, that are readable. These are the components that would be
1041 * processed by {@link #forEachReadable(int, ReadableComponentProcessor)}. For composite buffers, this is the
1042 * number of transitive constituent buffers that are readable, while non-composite buffers only have at most one
1043 * readable component.
1044 * <p>
1045 * The number of readable components may be less than the {@link #countComponents() component count}, if not all of
1046 * them have readable data.
1047 *
1048 * @return The number of readable components in this buffer.
1049 */
1050 int countReadableComponents();
1051
1052 /**
1053 * Get the number of "components" in this buffer, that are writable. These are the components that would be
1054 * processed by {@link #forEachWritable(int, WritableComponentProcessor)}. For composite buffers, this is the
1055 * number of transitive constituent buffers that are writable, while non-composite buffers only have at most one
1056 * writable component.
1057 * <p>
1058 * The number of writable components may be less than the {@link #countComponents() component count}, if not all of
1059 * them have space for writing.
1060 *
1061 * @return The number of writable components in this buffer.
1062 */
1063 int countWritableComponents();
1064
1065 /**
1066 * Processes all readable components of this buffer, and return the number of components processed.
1067 * <p>
1068 * The given {@linkplain ReadableComponentProcessor processor} is called for each readable component in this buffer,
1069 * and passed a component index, for the given component in the iteration, and a {@link ReadableComponent} object
1070 * for accessing the data within the given component.
1071 * <p>
1072 * The component index is specific to the particular invocation of this method. The first call to the consumer will
1073 * be passed the given initial index, and the next call will be passed the initial index plus one, and so on.
1074 * <p>
1075 * The {@linkplain ReadableComponentProcessor component processor} may stop the iteration at any time by returning
1076 * {@code false}.
1077 * This will cause the number of components processed to be returned as a negative number (to signal early return),
1078 * and the number of components processed may then be less than the
1079 * {@linkplain #countReadableComponents() readable component count}.
1080 * <p>
1081 * <strong>Note</strong> that the {@link ReadableComponent} instance passed to the consumer could be reused for
1082 * multiple calls, so the data must be extracted from the component in the context of the iteration.
1083 * <p>
1084 * The {@link ByteBuffer} instances obtained from the component, share lifetime with that internal component.
1085 * This means they can be accessed as long as the internal memory store remain unchanged. Methods that may cause
1086 * such changes are {@link #split(int)}, {@link #split()}, {@link #readSplit(int)}, {@link #writeSplit(int)},
1087 * {@link #compact()}, {@link #ensureWritable(int)}, {@link #ensureWritable(int, int, boolean)},
1088 * and {@link #send()}.
1089 * <p>
1090 * The best way to ensure this doesn't cause any trouble, is to use the buffers directly as part of the iteration.
1091 * <p>
1092 * <strong>Note</strong> that the arrays, memory addresses, and byte buffers exposed as components by this method,
1093 * should not be used for changing the buffer contents. Doing so may cause undefined behaviour.
1094 * <p>
1095 * Changes to position and limit of the byte buffers exposed via the processed components, are not reflected back to
1096 * this buffer instance.
1097 *
1098 * @param initialIndex The initial index of the component for iteration, and the index that will be passed to the
1099 * first call to the {@linkplain ReadableComponentProcessor#process(int, ReadableComponent) processor}.
1100 * @param processor The processor that will be used to process the buffer components.
1101 * @return The number of readable components processed, as a positive number if all readable components were
1102 * processed, or as a negative number if the iteration was stopped because
1103 * {@link ReadableComponentProcessor#process(int, ReadableComponent)} returned {@code false}.
1104 * In any case, the number of components processed may be less than {@link #countComponents()}.
1105 */
1106 <E extends Exception> int forEachReadable(int initialIndex, ReadableComponentProcessor<E> processor) throws E;
1107
1108 /**
1109 * Create a {@linkplain ComponentIterator component iterator} for all readable components in this buffer.
1110 * <p>
1111 * Unlike the {@link #forEachReadable(int, ReadableComponentProcessor)} method, this API permits <em>external</em>
1112 * iteration of the components, while at the same time protecting the life-cycle of the buffer.
1113 * <p>
1114 * The typical code pattern for using this API looks like the following:
1115 * <pre>{@code
1116 * try (var iteration = buffer.forEachReadable()) {
1117 * for (var c = iteration.first(); c != null; c = c.next()) {
1118 * ByteBuffer componentBuffer = c.readableBuffer();
1119 * // ...
1120 * }
1121 * }
1122 * }</pre>
1123 * Note the use of the {@code var} keyword for local variables, which are required for correctly expressing the
1124 * generic types used in the iteration.
1125 * Following this code pattern will ensure that the components, and their parent buffer, will be correctly
1126 * life-cycled.
1127 * <p>
1128 * <strong>Note</strong> that the {@link ReadableComponent} instances exposed by the iterator could be reused for
1129 * multiple calls, so the data must be extracted from the component in the context of the iteration.
1130 * <p>
1131 * The {@link ByteBuffer} instances obtained from the component, share lifetime with that internal component.
1132 * This means they can be accessed as long as the internal memory store remain unchanged. Methods that may cause
1133 * such changes are {@link #split(int)}, {@link #split()}, {@link #readSplit(int)}, {@link #writeSplit(int)},
1134 * {@link #compact()}, {@link #ensureWritable(int)}, {@link #ensureWritable(int, int, boolean)},
1135 * and {@link #send()}.
1136 * <p>
1137 * The best way to ensure this doesn't cause any trouble, is to use the buffers directly as part of the iteration.
1138 * <p>
1139 * <strong>Note</strong> that the arrays, memory addresses, and byte buffers exposed as components by this method,
1140 * should not be used for changing the buffer contents. Doing so may cause undefined behaviour.
1141 * <p>
1142 * Changes to position and limit of the byte buffers exposed via the processed components, are not reflected back to
1143 * this buffer instance.
1144 *
1145 * @return A component iterator of {@linkplain ReadableComponent readable components}.
1146 * @param <T> An intersection type that presents both the {@link ReadableComponent} interface,
1147 * <em>and</em> the ability to progress the iteration via the {@link Next#next()} method.
1148 */
1149 <T extends ReadableComponent & ComponentIterator.Next> ComponentIterator<T> forEachReadable();
1150
1151 /**
1152 * Process all writable components of this buffer, and return the number of components processed.
1153 * <p>
1154 * The given {@linkplain WritableComponentProcessor processor} is called for each writable component in this buffer,
1155 * and passed a component index, for the given component in the iteration, and a {@link WritableComponent} object
1156 * for accessing the data within the given component.
1157 * <p>
1158 * The component index is specific to the particular invocation of this method. The first call to the consumer will
1159 * be passed the given initial index, and the next call will be passed the initial index plus one, and so on.
1160 * <p>
1161 * The {@link WritableComponentProcessor component processor} may stop the iteration at any time by returning
1162 * {@code false}.
1163 * This will cause the number of components processed to be returned as a negative number (to signal early return),
1164 * and the number of components processed may then be less than the
1165 * {@linkplain #countReadableComponents() readable component count}.
1166 * <p>
1167 * <strong>Note</strong> that the {@link WritableComponent} instance passed to the consumer could be reused for
1168 * multiple calls, so the data must be extracted from the component in the context of the iteration.
1169 * <p>
1170 * The {@link ByteBuffer} instances obtained from the component, share lifetime with that internal component.
1171 * This means they can be accessed as long as the internal memory store remain unchanged. Methods that may cause
1172 * such changes are {@link #split(int)}, {@link #split()}, {@link #readSplit(int)}, {@link #writeSplit(int)},
1173 * {@link #compact()}, {@link #ensureWritable(int)}, {@link #ensureWritable(int, int, boolean)},
1174 * and {@link #send()}.
1175 * <p>
1176 * The best way to ensure this doesn't cause any trouble, is to use the buffers directly as part of the iteration.
1177 * <p>
1178 * Changes to position and limit of the byte buffers exposed via the processed components, are not reflected back to
1179 * this buffer instance.
1180 *
1181 * @param initialIndex The initial index of the component for iteration, and the index that will be passed to the
1182 * first call to the {@linkplain WritableComponentProcessor#process(int, WritableComponent) processor}.
1183 * @param processor The processor that will be used to process the buffer components.
1184 * @return The number of writable components processed, as a positive number if all writable components were
1185 * processed, or as a negative number if the iteration was stopped because
1186 * {@link WritableComponentProcessor#process(int, WritableComponent)} returned {@code false}.
1187 * In any case, the number of components processed may be less than {@link #countComponents()}.
1188 */
1189 <E extends Exception> int forEachWritable(int initialIndex, WritableComponentProcessor<E> processor) throws E;
1190
1191 /**
1192 * Create a {@linkplain ComponentIterator component iterator} for all writable components in this buffer.
1193 * <p>
1194 * Unlike the {@link #forEachWritable(int, WritableComponentProcessor)} method, this API permits <em>external</em>
1195 * iteration of the components, while at the same time protecting the life-cycle of the buffer.
1196 * <p>
1197 * The typical code pattern for using this API looks like the following:
1198 * <pre>{@code
1199 * try (var iteration = buffer.forEachWritable()) {
1200 * for (var c = iteration.first(); c != null; c = c.next()) {
1201 * ByteBuffer componentBuffer = c.writableBuffer();
1202 * // ...
1203 * }
1204 * }
1205 * }</pre>
1206 * Note the use of the {@code var} keyword for local variables, which are required for correctly expressing the
1207 * generic types used in the iteration.
1208 * Following this code pattern will ensure that the components, and their parent buffer, will be correctly
1209 * life-cycled.
1210 * <p>
1211 * <strong>Note</strong> that the {@link WritableComponent} instances exposed by the iterator could be reused for
1212 * multiple calls, so the data must be extracted from the component in the context of the iteration.
1213 * <p>
1214 * The {@link ByteBuffer} instances obtained from the component, share lifetime with that internal component.
1215 * This means they can be accessed as long as the internal memory store remain unchanged. Methods that may cause
1216 * such changes are {@link #split(int)}, {@link #split()}, {@link #readSplit(int)}, {@link #writeSplit(int)},
1217 * {@link #compact()}, {@link #ensureWritable(int)}, {@link #ensureWritable(int, int, boolean)},
1218 * and {@link #send()}.
1219 * <p>
1220 * The best way to ensure this doesn't cause any trouble, is to use the buffers directly as part of the iteration.
1221 * <p>
1222 * <strong>Note</strong> that the arrays, memory addresses, and byte buffers exposed as components by this method,
1223 * should not be used for changing the buffer contents beyond the respective array offset and length,
1224 * or buffer position and limit. Doing so may cause undefined behaviour.
1225 * <p>
1226 * Changes to position and limit of the byte buffers exposed via the processed components, are not reflected back to
1227 * this buffer instance.
1228 *
1229 * @return A component iterator of {@linkplain ReadableComponent readable components}.
1230 * @param <T> An intersection type that presents both the {@link ReadableComponent} interface,
1231 * <em>and</em> the ability to progress the iteration via the {@link Next#next()} method.
1232 */
1233 <T extends WritableComponent & ComponentIterator.Next> ComponentIterator<T> forEachWritable();
1234
1235 /**
1236 * Decodes this buffer's readable bytes into a string with the specified {@linkplain Charset}.
1237 * <p>
1238 * This method does not modify the reader or writer offset of this buffer.
1239 *
1240 * @param charset used for decoding.
1241 * @return Buffer's readable bytes as a string.
1242 */
1243 default String toString(Charset charset) {
1244 return Statics.toString(this, charset);
1245 }
1246 }