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 write(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 write(final ByteBuf buf, final Uint16 value) {
109 buf.writeShort(value.shortValue());
113 * Write a {@link Uint32} from specified buffer.
116 * @param value A {@link Uint32}
117 * @throws NullPointerException if any argument is null
119 public static void write(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 write(final ByteBuf buf, final Uint64 value) {
131 buf.writeLong(value.longValue());
135 * Write a {@link Byte} property to specified buffer. If the {@code value} is known to be non-null, prefer
136 * {@link ByteBuf#writeByte(int)} instead of this method.
139 * @param value A {@link Byte}
140 * @param name Property name for error reporting purposes
141 * @throws NullPointerException if {@code buf} is null
142 * @throws IllegalArgumentException if {@code value} is null
144 public static void writeMandatory(final ByteBuf buf, final Byte value, final String name) {
145 buf.writeByte(nonNullArgument(value, name).byteValue());
149 * Write a {@link Short} property to specified buffer. If the {@code value} is known to be non-null, prefer
150 * {@link ByteBuf#writeShort(int)} instead of this method.
153 * @param value A {@link Short}
154 * @param name Property name for error reporting purposes
155 * @throws NullPointerException if {@code buf} is null
156 * @throws IllegalArgumentException if {@code value} is null
158 public static void writeMandatory(final ByteBuf buf, final Short value, final String name) {
159 buf.writeShort(nonNullArgument(value, name).shortValue());
163 * Write a {@link Integer} property to specified buffer. If the {@code value} is known to be non-null, prefer
164 * {@link ByteBuf#writeInt(int)} instead of this method.
167 * @param value A {@link Integer}
168 * @param name Property name for error reporting purposes
169 * @throws NullPointerException if {@code buf} is null
170 * @throws IllegalArgumentException if {@code value} is null
172 public static void writeMandatory(final ByteBuf buf, final Integer value, final String name) {
173 buf.writeInt(nonNullArgument(value, name).intValue());
177 * Write a {@link Long} property to specified buffer. If the {@code value} is known to be non-null, prefer
178 * {@link ByteBuf#writeLong(long)} instead of this method.
181 * @param value A {@link Long}
182 * @param name Property name for error reporting purposes
183 * @throws NullPointerException if {@code buf} is null
184 * @throws IllegalArgumentException if {@code value} is null
186 public static void writeMandatory(final ByteBuf buf, final Long value, final String name) {
187 buf.writeLong(nonNullArgument(value, name).longValue());
191 * Write a {@link Uint8} property to specified buffer. If the {@code value} is known to be non-null, prefer to use
192 * {@link #write(ByteBuf, Uint8)} instead of this method.
195 * @param value A {@link Uint8}
196 * @param name Property name for error reporting purposes
197 * @throws NullPointerException if {@code buf} is null
198 * @throws IllegalArgumentException if {@code value} is null
200 public static void writeMandatory(final ByteBuf buf, final Uint8 value, final String name) {
201 write(buf, nonNullArgument(value, name));
205 * Write a {@link Uint16} property to specified buffer. If the {@code value} is known to be non-null, prefer to use
206 * {@link #write(ByteBuf, Uint16)} instead of this method.
209 * @param value A {@link Uint16}
210 * @param name Property name for error reporting purposes
211 * @throws NullPointerException if {@code buf} is null
212 * @throws IllegalArgumentException if {@code value} is null
214 public static void writeMandatory(final ByteBuf buf, final Uint16 value, final String name) {
215 write(buf, nonNullArgument(value, name));
219 * Write a {@link Uint32} property to specified buffer. If the {@code value} is known to be non-null, prefer to use
220 * {@link #write(ByteBuf, Uint32)} instead of this method.
223 * @param value A {@link Uint32}
224 * @param name Property name for error reporting purposes
225 * @throws NullPointerException if {@code buf} is null
226 * @throws IllegalArgumentException if {@code value} is null
228 public static void writeMandatory(final ByteBuf buf, final Uint32 value, final String name) {
229 write(buf, nonNullArgument(value, name));
233 * Write a {@link Uint64} property to specified buffer. If the {@code value} is known to be non-null, prefer to use
234 * {@link #write(ByteBuf, Uint64)} instead of this method.
237 * @param value A {@link Uint64}
238 * @param name Property name for error reporting purposes
239 * @throws NullPointerException if {@code buf} is null
240 * @throws IllegalArgumentException if {@code value} is null
242 public static void writeMandatory(final ByteBuf buf, final Uint64 value, final String name) {
243 write(buf, nonNullArgument(value, name));
247 * Write a {@link Byte} value to specified buffer if it is not null.
250 * @param value A {@link Byte}
251 * @throws NullPointerException if {@code buf} is null
253 public static void writeOptional(final ByteBuf buf, final @Nullable Byte value) {
255 buf.writeByte(value.byteValue());
260 * Write a {@link Byte} value to specified buffer if it is not null.
263 * @param value A {@link Short}
264 * @throws NullPointerException if {@code buf} is null
266 public static void writeOptional(final ByteBuf buf, final @Nullable Short value) {
268 buf.writeShort(value.shortValue());
273 * Write a {@link Integer} value to specified buffer if it is not null.
276 * @param value A {@link Integer}
277 * @throws NullPointerException if {@code buf} is null
279 public static void writeOptional(final ByteBuf buf, final @Nullable Integer value) {
281 buf.writeInt(value.intValue());
286 * Write a {@link Long} value to specified buffer if it is not null.
289 * @param value A {@link Long}
290 * @throws NullPointerException if {@code buf} is null
292 public static void writeOptional(final ByteBuf buf, final @Nullable Long value) {
294 buf.writeLong(value.longValue());
299 * Write a {@link Uint8} value to specified buffer if it is not null.
302 * @param value A {@link Uint8}
303 * @throws NullPointerException if {@code buf} is null
305 public static void writeOptional(final ByteBuf buf, final @Nullable Uint8 value) {
312 * Write a {@link Uint16} value to specified buffer if it is not null.
315 * @param value A {@link Uint16}
316 * @throws NullPointerException if {@code buf} is null
318 public static void writeOptional(final ByteBuf buf, final @Nullable Uint16 value) {
325 * Write a {@link Uint32} value to specified buffer if it is not null.
328 * @param value A {@link Uint32}
329 * @throws NullPointerException if {@code buf} is null
331 public static void writeOptional(final ByteBuf buf, final @Nullable Uint32 value) {
338 * Write a {@link Uint64} value to specified buffer if it is not null.
341 * @param value A {@link Uint64}
342 * @throws NullPointerException if {@code buf} is null
344 public static void writeOptional(final ByteBuf buf, final @Nullable Uint64 value) {
351 * Write a {@link Byte} value to specified buffer if it is not null, otherwise write one zero byte.
354 * @param value A {@link Byte}
355 * @throws NullPointerException if {@code buf} is null
357 public static void writeOrZero(final ByteBuf buf, final @Nullable Byte value) {
358 buf.writeByte(value != null ? value.byteValue() : 0);
362 * Write a {@link Short} value to specified buffer if it is not null, otherwise write two zero bytes.
365 * @param value A {@link Short}
366 * @throws NullPointerException if {@code buf} is null
368 public static void writeOrZero(final ByteBuf buf, final @Nullable Short value) {
369 buf.writeShort(value != null ? value.shortValue() : (short) 0);
373 * Write a {@link Integer} value to specified buffer if it is not null, otherwise write four zero bytes.
376 * @param value A {@link Integer}
377 * @throws NullPointerException if {@code buf} is null
379 public static void writeOrZero(final ByteBuf buf, final @Nullable Integer value) {
380 buf.writeInt(value != null ? value.intValue() : 0);
384 * Write a {@link Byte} value to specified buffer if it is not null, otherwise write eight zero bytes.
387 * @param value A {@link Byte}
388 * @throws NullPointerException if {@code buf} is null
390 public static void writeOrZero(final ByteBuf buf, final @Nullable Long value) {
391 buf.writeLong(value != null ? value.longValue() : 0L);
395 * Write a {@link Uint8} value to specified buffer if it is not null, otherwise write one zero byte.
398 * @param value A {@link Uint8}
399 * @throws NullPointerException if {@code buf} is null
401 public static void writeOrZero(final ByteBuf buf, final @Nullable Uint8 value) {
402 buf.writeByte(value != null ? value.byteValue() : 0);
406 * Write a {@link Uint16} value to specified buffer if it is not null, otherwise write two zero bytes.
409 * @param value A {@link Uint16}
410 * @throws NullPointerException if {@code buf} is null
412 public static void writeOrZero(final ByteBuf buf, final @Nullable Uint16 value) {
413 buf.writeShort(value != null ? value.shortValue() : (short) 0);
417 * Write a {@link Uint32} value to specified buffer if it is not null, otherwise write four zero bytes.
420 * @param value A {@link Uint32}
421 * @throws NullPointerException if {@code buf} is null
423 public static void writeOrZero(final ByteBuf buf, final @Nullable Uint32 value) {
424 buf.writeInt(value != null ? value.intValue() : 0);
428 * Write a {@link Uint64} value to specified buffer if it is not null, otherwise write eight zero bytes.
431 * @param value A {@link Uint64}
432 * @throws NullPointerException if {@code buf} is null
434 public static void writeOrZero(final ByteBuf buf, final @Nullable Uint64 value) {
435 buf.writeLong(value != null ? value.longValue() : 0L);
438 private static <T> @NonNull T nonNullArgument(final @Nullable T obj, final String name) {
440 throw new IllegalArgumentException(name + " is mandatory");