2 * Copyright (c) 2019 PANTHEON.tech, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.common.netty;
10 import com.google.common.annotations.Beta;
11 import io.netty.buffer.ByteBuf;
12 import org.eclipse.jdt.annotation.NonNull;
13 import org.eclipse.jdt.annotation.Nullable;
14 import org.opendaylight.yangtools.yang.common.Uint16;
15 import org.opendaylight.yangtools.yang.common.Uint32;
16 import org.opendaylight.yangtools.yang.common.Uint64;
17 import org.opendaylight.yangtools.yang.common.Uint8;
20 * Utility methods for interacting with {@link ByteBuf}s. These add a number of methods for reading and writing various
21 * data types from/to ByteBufs. Methods fall into these categories:
23 * <li>{@code readUint*}, which extract the corresponding amount of data from a buffer and return an Uint type. These
24 * are more efficient than going the {@code Uint8.valueOf(buf.readUnsignedByte())} route.</li>
25 * <li>{@code writeUint*}, which write specified value into a buffer.</li>
26 * <li>{@code writeMandatory*}, which write a property not statically known to be non-null. These methods throw
27 * an {@link IllegalArgumentException} if the supplied value is null. Otherwise they will write it to provided
29 * <li>{@code writeOptional*}, which write a value which can legally be null. In case the value is not null, it is
30 * written to the provided buffer. If the value null, the method does nothing.</li>
31 * <li>{@code writeOrZero*}, which write a value which can legally be null. In case the value is not null, it is
32 * written to the provided buffer. If the value is null, a {code zero} value of corresponding width is written
37 public final class ByteBufUtils {
38 private ByteBufUtils() {
43 * Read an {@link Uint8} from specified buffer.
46 * @return A {@link Uint8}
47 * @throws NullPointerException if {@code buf} is null
48 * @throws IndexOutOfBoundsException if {@code buf} does not have enough data
50 public static @NonNull Uint8 readUint8(final ByteBuf buf) {
51 return Uint8.fromByteBits(buf.readByte());
55 * Read a {@link Uint16} from specified buffer.
58 * @return A {@link Uint16}
59 * @throws NullPointerException if {@code buf} is null
60 * @throws IndexOutOfBoundsException if {@code buf} does not have enough data
62 public static @NonNull Uint16 readUint16(final ByteBuf buf) {
63 return Uint16.fromShortBits(buf.readShort());
67 * Read a {@link Uint32} from specified buffer.
70 * @return A {@link Uint32}
71 * @throws NullPointerException if {@code buf} is null
72 * @throws IndexOutOfBoundsException if {@code buf} does not have enough data
74 public static @NonNull Uint32 readUint32(final ByteBuf buf) {
75 return Uint32.fromIntBits(buf.readInt());
79 * Read a {@link Uint64} from specified buffer.
82 * @return A {@link Uint64}
83 * @throws NullPointerException if {@code buf} is null
84 * @throws IndexOutOfBoundsException if {@code buf} does not have enough data
86 public static @NonNull Uint64 readUint64(final ByteBuf buf) {
87 return Uint64.fromLongBits(buf.readLong());
91 * Write a {@link Uint8} to specified buffer.
94 * @param value A {@link Uint8}
95 * @throws NullPointerException if any argument is null
97 public static void writeUint8(final ByteBuf buf, final Uint8 value) {
98 buf.writeByte(value.byteValue());
102 * Write a {@link Uint16} to specified buffer.
105 * @param value A {@link Uint16}
106 * @throws NullPointerException if any argument is null
108 public static void writeUint16(final ByteBuf buf, final Uint16 value) {
109 buf.writeShort(value.shortValue());
113 * Write a {@link Uint32} to specified buffer.
116 * @param value A {@link Uint32}
117 * @throws NullPointerException if any argument is null
119 public static void writeUint32(final ByteBuf buf, final Uint32 value) {
120 buf.writeInt(value.intValue());
124 * Write a {@link Uint64} to specified buffer.
127 * @param value A {@link Uint64}
128 * @throws NullPointerException if any argument is null
130 public static void writeUint64(final ByteBuf buf, final Uint64 value) {
131 buf.writeLong(value.longValue());
135 * Write a {@link Uint8} to specified buffer. This method is provided for convenience, you may want to use
136 * {@link #writeUint8(ByteBuf, Uint8)} as it is more explicit.
139 * @param value A {@link Uint8}
140 * @throws NullPointerException if any argument is null
142 public static void write(final ByteBuf buf, final Uint8 value) {
143 writeUint8(buf, value);
147 * Write a {@link Uint16} to specified buffer. This method is provided for convenience, you may want to use
148 * {@link #writeUint16(ByteBuf, Uint16)} as it is more explicit.
151 * @param value A {@link Uint16}
152 * @throws NullPointerException if any argument is null
154 public static void write(final ByteBuf buf, final Uint16 value) {
155 writeUint16(buf, value);
159 * Write a {@link Uint32} to specified buffer. This method is provided for convenience, you may want to use
160 * {@link #writeUint32(ByteBuf, Uint32)} as it is more explicit.
163 * @param value A {@link Uint32}
164 * @throws NullPointerException if any argument is null
166 public static void write(final ByteBuf buf, final Uint32 value) {
167 writeUint32(buf, value);
171 * Write a {@link Uint64} to specified buffer. This method is provided for convenience, you may want to use
172 * {@link #writeUint64(ByteBuf, Uint64)} as it is more explicit.
175 * @param value A {@link Uint64}
176 * @throws NullPointerException if any argument is null
178 public static void write(final ByteBuf buf, final Uint64 value) {
179 writeUint64(buf, value);
183 * Write a {@link Byte} property to specified buffer. If the {@code value} is known to be non-null, prefer
184 * {@link ByteBuf#writeByte(int)} instead of this method.
187 * @param value A {@link Byte}
188 * @param name Property name for error reporting purposes
189 * @throws NullPointerException if {@code buf} is null
190 * @throws IllegalArgumentException if {@code value} is null
192 public static void writeMandatory(final ByteBuf buf, final Byte value, final String name) {
193 buf.writeByte(nonNullArgument(value, name).byteValue());
197 * Write a {@link Short} property to specified buffer. If the {@code value} is known to be non-null, prefer
198 * {@link ByteBuf#writeShort(int)} instead of this method.
201 * @param value A {@link Short}
202 * @param name Property name for error reporting purposes
203 * @throws NullPointerException if {@code buf} is null
204 * @throws IllegalArgumentException if {@code value} is null
206 public static void writeMandatory(final ByteBuf buf, final Short value, final String name) {
207 buf.writeShort(nonNullArgument(value, name).shortValue());
211 * Write a {@link Integer} property to specified buffer. If the {@code value} is known to be non-null, prefer
212 * {@link ByteBuf#writeInt(int)} instead of this method.
215 * @param value A {@link Integer}
216 * @param name Property name for error reporting purposes
217 * @throws NullPointerException if {@code buf} is null
218 * @throws IllegalArgumentException if {@code value} is null
220 public static void writeMandatory(final ByteBuf buf, final Integer value, final String name) {
221 buf.writeInt(nonNullArgument(value, name));
225 * Write a {@link Long} property to specified buffer. If the {@code value} is known to be non-null, prefer
226 * {@link ByteBuf#writeLong(long)} instead of this method.
229 * @param value A {@link Long}
230 * @param name Property name for error reporting purposes
231 * @throws NullPointerException if {@code buf} is null
232 * @throws IllegalArgumentException if {@code value} is null
234 public static void writeMandatory(final ByteBuf buf, final Long value, final String name) {
235 buf.writeLong(nonNullArgument(value, name));
239 * Write a {@link Uint8} property to specified buffer. If the {@code value} is known to be non-null, prefer to use
240 * {@link #write(ByteBuf, Uint8)} instead of this method.
243 * @param value A {@link Uint8}
244 * @param name Property name for error reporting purposes
245 * @throws NullPointerException if {@code buf} is null
246 * @throws IllegalArgumentException if {@code value} is null
248 public static void writeMandatory(final ByteBuf buf, final Uint8 value, final String name) {
249 write(buf, nonNullArgument(value, name));
253 * Write a {@link Uint16} property to specified buffer. If the {@code value} is known to be non-null, prefer to use
254 * {@link #write(ByteBuf, Uint16)} instead of this method.
257 * @param value A {@link Uint16}
258 * @param name Property name for error reporting purposes
259 * @throws NullPointerException if {@code buf} is null
260 * @throws IllegalArgumentException if {@code value} is null
262 public static void writeMandatory(final ByteBuf buf, final Uint16 value, final String name) {
263 write(buf, nonNullArgument(value, name));
267 * Write a {@link Uint32} property to specified buffer. If the {@code value} is known to be non-null, prefer to use
268 * {@link #write(ByteBuf, Uint32)} instead of this method.
271 * @param value A {@link Uint32}
272 * @param name Property name for error reporting purposes
273 * @throws NullPointerException if {@code buf} is null
274 * @throws IllegalArgumentException if {@code value} is null
276 public static void writeMandatory(final ByteBuf buf, final Uint32 value, final String name) {
277 write(buf, nonNullArgument(value, name));
281 * Write a {@link Uint64} property to specified buffer. If the {@code value} is known to be non-null, prefer to use
282 * {@link #write(ByteBuf, Uint64)} instead of this method.
285 * @param value A {@link Uint64}
286 * @param name Property name for error reporting purposes
287 * @throws NullPointerException if {@code buf} is null
288 * @throws IllegalArgumentException if {@code value} is null
290 public static void writeMandatory(final ByteBuf buf, final Uint64 value, final String name) {
291 write(buf, nonNullArgument(value, name));
295 * Write a {@link Byte} value to specified buffer if it is not null.
298 * @param value A {@link Byte}
299 * @throws NullPointerException if {@code buf} is null
301 public static void writeOptional(final ByteBuf buf, final @Nullable Byte value) {
303 buf.writeByte(value.byteValue());
308 * Write a {@link Byte} value to specified buffer if it is not null.
311 * @param value A {@link Short}
312 * @throws NullPointerException if {@code buf} is null
314 public static void writeOptional(final ByteBuf buf, final @Nullable Short value) {
316 buf.writeShort(value.shortValue());
321 * Write a {@link Integer} value to specified buffer if it is not null.
324 * @param value A {@link Integer}
325 * @throws NullPointerException if {@code buf} is null
327 public static void writeOptional(final ByteBuf buf, final @Nullable Integer value) {
334 * Write a {@link Long} value to specified buffer if it is not null.
337 * @param value A {@link Long}
338 * @throws NullPointerException if {@code buf} is null
340 public static void writeOptional(final ByteBuf buf, final @Nullable Long value) {
342 buf.writeLong(value);
347 * Write a {@link Uint8} value to specified buffer if it is not null.
350 * @param value A {@link Uint8}
351 * @throws NullPointerException if {@code buf} is null
353 public static void writeOptional(final ByteBuf buf, final @Nullable Uint8 value) {
360 * Write a {@link Uint16} value to specified buffer if it is not null.
363 * @param value A {@link Uint16}
364 * @throws NullPointerException if {@code buf} is null
366 public static void writeOptional(final ByteBuf buf, final @Nullable Uint16 value) {
373 * Write a {@link Uint32} value to specified buffer if it is not null.
376 * @param value A {@link Uint32}
377 * @throws NullPointerException if {@code buf} is null
379 public static void writeOptional(final ByteBuf buf, final @Nullable Uint32 value) {
386 * Write a {@link Uint64} value to specified buffer if it is not null.
389 * @param value A {@link Uint64}
390 * @throws NullPointerException if {@code buf} is null
392 public static void writeOptional(final ByteBuf buf, final @Nullable Uint64 value) {
399 * Write a {@link Byte} value to specified buffer if it is not null, otherwise write one zero byte.
402 * @param value A {@link Byte}
403 * @throws NullPointerException if {@code buf} is null
405 public static void writeOrZero(final ByteBuf buf, final @Nullable Byte value) {
406 buf.writeByte(value != null ? value.byteValue() : 0);
410 * Write a {@link Short} value to specified buffer if it is not null, otherwise write two zero bytes.
413 * @param value A {@link Short}
414 * @throws NullPointerException if {@code buf} is null
416 public static void writeOrZero(final ByteBuf buf, final @Nullable Short value) {
417 buf.writeShort(value != null ? value.shortValue() : (short) 0);
421 * Write a {@link Integer} value to specified buffer if it is not null, otherwise write four zero bytes.
424 * @param value A {@link Integer}
425 * @throws NullPointerException if {@code buf} is null
427 public static void writeOrZero(final ByteBuf buf, final @Nullable Integer value) {
428 buf.writeInt(value != null ? value : 0);
432 * Write a {@link Byte} value to specified buffer if it is not null, otherwise write eight zero bytes.
435 * @param value A {@link Byte}
436 * @throws NullPointerException if {@code buf} is null
438 public static void writeOrZero(final ByteBuf buf, final @Nullable Long value) {
439 buf.writeLong(value != null ? value : 0L);
443 * Write a {@link Uint8} value to specified buffer if it is not null, otherwise write one zero byte.
446 * @param value A {@link Uint8}
447 * @throws NullPointerException if {@code buf} is null
449 public static void writeOrZero(final ByteBuf buf, final @Nullable Uint8 value) {
450 buf.writeByte(value != null ? value.byteValue() : 0);
454 * Write a {@link Uint16} value to specified buffer if it is not null, otherwise write two zero bytes.
457 * @param value A {@link Uint16}
458 * @throws NullPointerException if {@code buf} is null
460 public static void writeOrZero(final ByteBuf buf, final @Nullable Uint16 value) {
461 buf.writeShort(value != null ? value.shortValue() : (short) 0);
465 * Write a {@link Uint32} value to specified buffer if it is not null, otherwise write four zero bytes.
468 * @param value A {@link Uint32}
469 * @throws NullPointerException if {@code buf} is null
471 public static void writeOrZero(final ByteBuf buf, final @Nullable Uint32 value) {
472 buf.writeInt(value != null ? value.intValue() : 0);
476 * Write a {@link Uint64} value to specified buffer if it is not null, otherwise write eight zero bytes.
479 * @param value A {@link Uint64}
480 * @throws NullPointerException if {@code buf} is null
482 public static void writeOrZero(final ByteBuf buf, final @Nullable Uint64 value) {
483 buf.writeLong(value != null ? value.longValue() : 0L);
486 private static <T> @NonNull T nonNullArgument(final @Nullable T obj, final String name) {
488 throw new IllegalArgumentException(name + " is mandatory");