/* * Copyright 2012 The Netty Project * * The Netty Project licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ /** * Abstraction of a byte buffer - the fundamental data structure * to represent a low-level binary and text message. * * Netty uses its own buffer API instead of NIO {@link java.nio.ByteBuffer} to * represent a sequence of bytes. This approach has significant advantage over * using {@link java.nio.ByteBuffer}. Netty's new buffer type, * {@link io.netty5.buffer.ByteBuf}, has been designed from ground * up to address the problems of {@link java.nio.ByteBuffer} and to meet the * daily needs of network application developers. To list a few cool features: *
* +--------+----------+ * | header | body | * +--------+----------+ ** If {@link java.nio.ByteBuffer} were used, you would have to create a new big * buffer and copy the two parts into the new buffer. Alternatively, you can * perform a gathering write operation in NIO, but it restricts you to represent * the composite of buffers as an array of {@link java.nio.ByteBuffer}s rather * than a single buffer, breaking the abstraction and introducing complicated * state management. Moreover, it's of no use if you are not going to read or * write from an NIO channel. *
* // The composite type is incompatible with the component type. * ByteBuffer[] message = new ByteBuffer[] { header, body }; ** By contrast, {@link io.netty5.buffer.ByteBuf} does not have such * caveats because it is fully extensible and has a built-in composite buffer * type. *
* // The composite type is compatible with the component type. * {@link io.netty5.buffer.ByteBuf} message * = {@link io.netty5.buffer.Unpooled}.wrappedBuffer(header, body); * * // Therefore, you can even create a composite by mixing a composite and an * // ordinary buffer. * {@link io.netty5.buffer.ByteBuf} messageWithFooter * = {@link io.netty5.buffer.Unpooled}.wrappedBuffer(message, footer); * * // Because the composite is still * a {@link io.netty5.buffer.ByteBuf}, you can access its content * // easily, and the accessor method will behave just like it's a single buffer * // even if the region you want to access spans over multiple components. The * // unsigned integer being read here is located across body and footer. * messageWithFooter.getUnsignedInt( * messageWithFooter.readableBytes() - footer.readableBytes() - 1); ** *
* // A new dynamic buffer is created. Internally, the actual buffer is created * // lazily to avoid potentially wasted memory space. * {@link io.netty5.buffer.ByteBuf} b = {@link io.netty5.buffer.Unpooled}.buffer(4); * * // When the first write attempt is made, the internal buffer is created with * // the specified initial capacity (4). * b.writeByte('1'); * * b.writeByte('2'); * b.writeByte('3'); * b.writeByte('4'); * * // When the number of written bytes exceeds the initial capacity (4), the * // internal buffer is reallocated automatically with a larger capacity. * b.writeByte('5'); ** *