1 /* 2 * Copyright 2022 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.util.SafeCloseable; 20 21 /** 22 * A facade for iterating the readable or writable components of a {@link Buffer}. 23 * 24 * <strong>Note:</strong> the {@linkplain ComponentIterator iterator object} must be 25 * {@linkplain ComponentIterator#close() closed} after use. 26 * The easiest way to ensure this, is to use a try-with-resources clause. 27 * <p> 28 * The typical code pattern for using this API looks like the following: 29 * <pre>{@code 30 * try (var iteration = buffer.forEachReadable()) { 31 * for (var c = iteration.first(); c != null; c = c.next()) { 32 * ByteBuffer componentBuffer = c.readableBuffer(); 33 * // ... 34 * } 35 * } 36 * }</pre> 37 * Note the use of the {@code var} keyword for local variables, which are required for correctly expressing the 38 * generic types used in the iteration. 39 * Following this code pattern will ensure that the components, and their parent buffer, will be correctly 40 * life-cycled. 41 * 42 * @param <T> A type that implements {@link Next}, and either {@link ReadableComponent} or {@link WritableComponent}. 43 * @see Buffer#forEachReadable() 44 * @see Buffer#forEachWritable() 45 */ 46 public interface ComponentIterator<T extends Next> extends SafeCloseable { 47 /** 48 * Get the first component of the iteration, or {@code null} if there are no components. 49 * <p> 50 * The object returned will implement both {@link Next}, and one of the {@link ReadableComponent} or 51 * {@link WritableComponent} interfaces. 52 * 53 * @return The first component of the iteration, or {@code null} if there are no components. 54 */ 55 T first(); 56 57 /** 58 * This interface exposes external iteration on components. 59 */ 60 interface Next { 61 /** 62 * Get the next component of the iteration, or {@code null} if there are no more components. 63 * <p> 64 * The returned object, if any, will be of the same type as this object, and would typically be assigned to the 65 * same variable. 66 * <p> 67 * Iteration is only valid while the {@link ComponentIterator} is open. 68 * Calling this method after the associated component iterator has been 69 * {@linkplain ComponentIterator#close() closed} may result in undefined behaviour. 70 * 71 * @return The next component in the iteration, or {@code null} if there are no more components. 72 * @param <N> A type that implements {@link Next}, and one of the {@link ReadableComponent} or 73 * {@link WritableComponent} interfaces. 74 */ 75 <N extends Next> N next(); 76 } 77 }