/** * Licensed 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 * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * 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. */ package io.journalkeeper.rpc.remoting.serialize; import io.journalkeeper.rpc.remoting.transport.codec.Decoder; import io.journalkeeper.rpc.remoting.transport.codec.Encoder; import io.netty.buffer.ByteBuf; import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; /** * @author LiYue * Date: 2019-03-28 */ public class CodecSupport { public static String decodeString(ByteBuf byteBuf) { return new String(decodeBytes(byteBuf), StandardCharsets.UTF_8); } public static void encodeString(ByteBuf byteBuf, String str) { byte[] bytes = str == null ? new byte[0] : str.getBytes(StandardCharsets.UTF_8); encodeBytes(byteBuf, bytes); } public static byte[] decodeBytes(ByteBuf byteBuf) { int length = byteBuf.readInt(); if (length > 0) { byte[] buff = new byte[length]; byteBuf.readBytes(buff); return buff; } return new byte[0]; } public static void encodeBytes(ByteBuf byteBuf, byte[] bytes) { if (null == bytes) { bytes = new byte[0]; } byteBuf.writeInt(bytes.length); if (bytes.length > 0) { byteBuf.writeBytes(bytes); } } public static void encodeLong(ByteBuf byteBuf, long l) { byteBuf.writeLong(l); } public static long decodeLong(ByteBuf byteBuf) { return byteBuf.readLong(); } public static void encodeInt(ByteBuf byteBuf, int i) { byteBuf.writeInt(i); } public static int decodeInt(ByteBuf byteBuf) { return byteBuf.readInt(); } public static void encodeShort(ByteBuf byteBuf, short s) { byteBuf.writeShort(s); } public static short decodeShort(ByteBuf byteBuf) { return byteBuf.readShort(); } public static void encodeByte(ByteBuf byteBuf, byte b) { byteBuf.writeByte(b); } public static byte decodeByte(ByteBuf byteBuf) { return byteBuf.readByte(); } public static <T> void encodeList(ByteBuf byteBuf, List<T> list, Encoder itemEncoder) { encodeCollection(byteBuf, list, itemEncoder); } public static <T> void encodeCollection(ByteBuf byteBuf, Collection<T> collection, Encoder itemEncoder) { if (null == collection) { byteBuf.writeInt(-1); } else { byteBuf.writeInt(collection.size()); collection.forEach(item -> itemEncoder.encode(item, byteBuf)); } } public static <K, V> void encodeMap(ByteBuf byteBuf, Map<K, V> map, Encoder keyEncoder, Encoder valueEncoder) { if (null == map) { byteBuf.writeInt(-1); } else { byteBuf.writeInt(map.size()); map.forEach((key, value) -> { keyEncoder.encode(key, byteBuf); valueEncoder.encode(value, byteBuf); }); } } @SuppressWarnings("unchecked") public static <T> List<T> decodeList(ByteBuf byteBuf, Decoder itemDecoder) { int size = byteBuf.readInt(); if (size < 0) { return null; } else { List<T> list = new ArrayList<>(size); for (int i = 0; i < size; i++) { list.add((T) itemDecoder.decode(byteBuf)); } return list; } } public static <T> Collection<T> decodeCollection(ByteBuf byteBuf, Decoder itemDecoder) { return decodeList(byteBuf, itemDecoder); } @SuppressWarnings("unchecked") public static <K, V> Map<K, V> decodeMap(ByteBuf byteBuf, Decoder keyDecoder, Decoder valueDecoder) { int size = byteBuf.readInt(); if (size < 0) { return null; } else { Map<K, V> map = new HashMap<>(size); for (int i = 0; i < size; i++) { map.put((K) keyDecoder.decode(byteBuf), (V) valueDecoder.decode(byteBuf)); } return map; } } public static void encodeUri(ByteBuf byteBuf, URI uri) { encodeString(byteBuf, null == uri ? null : uri.toString()); } public static URI decodeUri(ByteBuf byteBuf) { String uriString = decodeString(byteBuf); if (uriString.isEmpty()) return null; else return URI.create(uriString); } public static void encodeBoolean(ByteBuf byteBuf, boolean bool) { byteBuf.writeByte(bool ? 0X1 : 0X0); } public static boolean decodeBoolean(ByteBuf byteBuf) { return byteBuf.readByte() == 0X1; } public static void encodeUUID(ByteBuf byteBuf, UUID uuid) { long mostSigBits = 0L; long leastSigBits = 0L; if (null != uuid) { mostSigBits = uuid.getMostSignificantBits(); leastSigBits = uuid.getLeastSignificantBits(); } encodeLong(byteBuf, mostSigBits); encodeLong(byteBuf, leastSigBits); } public static UUID decodeUUID(ByteBuf byteBuf) { long mostSigBits = decodeLong(byteBuf); long leastSigBits = decodeLong(byteBuf); if (mostSigBits == 0L && leastSigBits == 0L) { return null; } else { return new UUID(mostSigBits, leastSigBits); } } }