Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (C) 2020 The zfoo Authors
* 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
*
* http://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.
*/
package com.zfoo.protocol.buffer;
import com.zfoo.protocol.collection.*;
import com.zfoo.protocol.registration.IProtocolRegistration;
import com.zfoo.protocol.util.StringUtils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.collection.IntObjectHashMap;
import io.netty.util.collection.LongObjectHashMap;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* zfoo的自定义私有协议格式,可以非常方便的对大部分数据定制序列化和反序列化实现,可以对大部分数据结构定制高性能实现方式
*
* “可变长字节码算法”的压缩数据的算法,压缩数据和减少磁盘IO。google的ProtocolBuf和Facebook的thrift底层的通信协议都是由这个算法实现
*
* @author godotg
*/
public abstract class ByteBufUtils {
//---------------------------------compatible--------------------------------------
public static final Double ZERO_DOUBLE = Double.valueOf(0D);
public static final Float ZERO_FLOAT = Float.valueOf(0F);
public static void adjustPadding(ByteBuf byteBuf, int predictionLength, int beforeWriteIndex) {
// 因为写入的是可变长的int,如果预留的位置过多,则清除多余的位置
var currentWriteIndex = byteBuf.writerIndex();
var predictionCount = writeIntCount(predictionLength);
var length = currentWriteIndex - beforeWriteIndex - predictionCount;
var lengthCount = writeIntCount(length);
var padding = lengthCount - predictionCount;
if (padding == 0) {
byteBuf.writerIndex(beforeWriteIndex);
writeInt(byteBuf, length);
byteBuf.writerIndex(currentWriteIndex);
} else if (padding < 0) {
var retainedByteBuf = byteBuf.retainedSlice(currentWriteIndex - length, length);
byteBuf.writerIndex(beforeWriteIndex);
writeInt(byteBuf, length);
byteBuf.writeBytes(retainedByteBuf);
ReferenceCountUtil.release(retainedByteBuf);
} else {
var retainedByteBuf = byteBuf.retainedSlice(currentWriteIndex - length, length);
var bytes = readAllBytes(retainedByteBuf);
byteBuf.writerIndex(beforeWriteIndex);
writeInt(byteBuf, length);
byteBuf.writeBytes(bytes);
ReferenceCountUtil.release(retainedByteBuf);
}
}
public static boolean compatibleRead(ByteBuf byteBuf, int beforeReadIndex, int length) {
return length != -1 && byteBuf.readerIndex() < length + beforeReadIndex;
}
//---------------------------------boolean--------------------------------------
public static void writeBool(ByteBuf byteBuf, boolean value) {
byteBuf.writeBoolean(value);
}
public static boolean readBool(ByteBuf byteBuf) {
return byteBuf.readBoolean();
}
public static boolean tryReadBool(ByteBuf byteBuf) {
return byteBuf.isReadable() && readBool(byteBuf);
}
public static void writeBoolBox(ByteBuf byteBuf, Boolean value) {
byteBuf.writeBoolean(value != null && value);
}
public static Boolean readBoolBox(ByteBuf byteBuf) {
return byteBuf.readBoolean();
}
//---------------------------------byte--------------------------------------
public static void writeByte(ByteBuf byteBuf, byte value) {
byteBuf.writeByte(value);
}
public static byte readByte(ByteBuf byteBuf) {
return byteBuf.readByte();
}
public static void writeByteBox(ByteBuf byteBuf, Byte value) {
byteBuf.writeByte(value == null ? 0 : value);
}
public static Byte readByteBox(ByteBuf byteBuf) {
return byteBuf.readByte();
}
public static byte[] readAllBytes(ByteBuf byteBuf) {
var readableBytes = byteBuf.readableBytes();
var bytes = new byte[readableBytes];
byteBuf.readBytes(bytes);
return bytes;
}
//---------------------------------short--------------------------------------
public static void writeShort(ByteBuf byteBuf, short value) {
byteBuf.writeShort(value);
}
public static short readShort(ByteBuf byteBuf) {
return byteBuf.readShort();
}
public static void writeShortBox(ByteBuf byteBuf, Short value) {
byteBuf.writeShort(value == null ? 0 : value);
}
public static Short readShortBox(ByteBuf byteBuf) {
return byteBuf.readShort();
}
//---------------------------------int--------------------------------------
// 用Zigzag算法压缩int和long的值,再用Varint紧凑算法表示数字的有效位
public static int writeInt(ByteBuf byteBuf, int value) {
return writeVarInt(byteBuf, (value << 1) ^ (value >> 31));
}
private static int writeVarInt(ByteBuf byteBuf, int value) {
int a = value >>> 7;
if (a == 0) {
byteBuf.writeByte(value);
return 1;
}
int writeIndex = byteBuf.writerIndex();
byteBuf.ensureWritable(5);
byteBuf.setByte(writeIndex++, value | 0x80);
int b = value >>> 14;
if (b == 0) {
byteBuf.setByte(writeIndex++, a);
byteBuf.writerIndex(writeIndex);
return 2;
}
byteBuf.setByte(writeIndex++, a | 0x80);
a = value >>> 21;
if (a == 0) {
byteBuf.setByte(writeIndex++, b);
byteBuf.writerIndex(writeIndex);
return 3;
}
byteBuf.setByte(writeIndex++, b | 0x80);
b = value >>> 28;
if (b == 0) {
byteBuf.setByte(writeIndex++, a);
byteBuf.writerIndex(writeIndex);
return 4;
}
byteBuf.setByte(writeIndex++, a | 0x80);
byteBuf.setByte(writeIndex++, b);
byteBuf.writerIndex(writeIndex);
return 5;
}
public static int readInt(ByteBuf byteBuf) {
int readIndex = byteBuf.readerIndex();
int b = byteBuf.getByte(readIndex++);
int value = b;
if (b < 0) {
b = byteBuf.getByte(readIndex++);
value = value & 0x0000007F | b << 7;
if (b < 0) {
b = byteBuf.getByte(readIndex++);
value = value & 0x00003FFF | b << 14;
if (b < 0) {
b = byteBuf.getByte(readIndex++);
value = value & 0x001FFFFF | b << 21;
if (b < 0) {
value = value & 0x0FFFFFFF | byteBuf.getByte(readIndex++) << 28;
}
}
}
}
byteBuf.readerIndex(readIndex);
return ((value >>> 1) ^ -(value & 1));
}
public static int writeIntCount(int value) {
value = (value << 1) ^ (value >> 31);
if (value >>> 7 == 0) {
return 1;
}
if (value >>> 14 == 0) {
return 2;
}
if (value >>> 21 == 0) {
return 3;
}
if (value >>> 28 == 0) {
return 4;
}
return 5;
}
public static void writeIntBox(ByteBuf byteBuf, Integer value) {
writeInt(byteBuf, value == null ? 0 : value);
}
public static Integer readIntBox(ByteBuf byteBuf) {
return readInt(byteBuf);
}
//---------------------------------long--------------------------------------
public static void writeLong(ByteBuf byteBuf, long value) {
long mask = (value << 1) ^ (value >> 63);
if (mask >>> 32 == 0) {
writeVarInt(byteBuf, (int) mask);
return;
}
byte[] bytes = new byte[9];
bytes[0] = (byte) (mask | 0x80);
bytes[1] = (byte) (mask >>> 7 | 0x80);
bytes[2] = (byte) (mask >>> 14 | 0x80);
bytes[3] = (byte) (mask >>> 21 | 0x80);
int a = (int) (mask >>> 28);
int b = (int) (mask >>> 35);
if (b == 0) {
bytes[4] = (byte) a;
byteBuf.writeBytes(bytes, 0, 5);
return;
}
bytes[4] = (byte) (a | 0x80);
a = (int) (mask >>> 42);
if (a == 0) {
bytes[5] = (byte) b;
byteBuf.writeBytes(bytes, 0, 6);
return;
}
bytes[5] = (byte) (b | 0x80);
b = (int) (mask >>> 49);
if (b == 0) {
bytes[6] = (byte) a;
byteBuf.writeBytes(bytes, 0, 7);
return;
}
bytes[6] = (byte) (a | 0x80);
a = (int) (mask >>> 56);
if (a == 0) {
bytes[7] = (byte) b;
byteBuf.writeBytes(bytes, 0, 8);
return;
}
bytes[7] = (byte) (b | 0x80);
bytes[8] = (byte) a;
byteBuf.writeBytes(bytes, 0, 9);
}
public static long readLong(ByteBuf byteBuf) {
int readIndex = byteBuf.readerIndex();
long b = byteBuf.getByte(readIndex++);
long value = b;
if (b < 0) {
b = byteBuf.getByte(readIndex++);
value = value & 0x00000000_0000007FL | b << 7;
if (b < 0) {
b = byteBuf.getByte(readIndex++);
value = value & 0x00000000_00003FFFL | b << 14;
if (b < 0) {
b = byteBuf.getByte(readIndex++);
value = value & 0x00000000_001FFFFFL | b << 21;
if (b < 0) {
b = byteBuf.getByte(readIndex++);
value = value & 0x00000000_0FFFFFFFL | b << 28;
if (b < 0) {
b = byteBuf.getByte(readIndex++);
value = value & 0x00000007_FFFFFFFFL | b << 35;
if (b < 0) {
b = byteBuf.getByte(readIndex++);
value = value & 0x000003FF_FFFFFFFFL | b << 42;
if (b < 0) {
b = byteBuf.getByte(readIndex++);
value = value & 0x0001FFFF_FFFFFFFFL | b << 49;
if (b < 0) {
b = byteBuf.getByte(readIndex++);
value = value & 0x00FFFFFF_FFFFFFFFL | b << 56;
}
}
}
}
}
}
}
}
byteBuf.readerIndex(readIndex);
return ((value >>> 1) ^ -(value & 1));
}
public static void writeLongBox(ByteBuf byteBuf, Long value) {
writeLong(byteBuf, value == null ? 0L : value);
}
public static Long readLongBox(ByteBuf byteBuf) {
return readLong(byteBuf);
}
//---------------------------------float--------------------------------------
public static void writeFloat(ByteBuf byteBuf, float value) {
byteBuf.writeFloat(value);
}
public static float readFloat(ByteBuf byteBuf) {
return byteBuf.readFloat();
}
public static void writeFloatBox(ByteBuf byteBuf, Float value) {
byteBuf.writeFloat(value == null ? 0F : value);
}
public static Float readFloatBox(ByteBuf byteBuf) {
return byteBuf.readFloat();
}
//---------------------------------double--------------------------------------
public static void writeDouble(ByteBuf byteBuf, double value) {
byteBuf.writeDouble(value);
}
public static double readDouble(ByteBuf byteBuf) {
return byteBuf.readDouble();
}
public static void writeDoubleBox(ByteBuf byteBuf, Double value) {
byteBuf.writeDouble(value == null ? 0D : value);
}
public static Double readDoubleBox(ByteBuf byteBuf) {
return byteBuf.readDouble();
}
//---------------------------------String--------------------------------------
public static void writeString(ByteBuf byteBuf, String value) {
if (StringUtils.isEmpty(value)) {
writeInt(byteBuf, 0);
return;
}
// 预估需要写入的字节数,并预留位置
var beforeWriteIndex = byteBuf.writerIndex();
var maxLength = ByteBufUtil.utf8MaxBytes(value);
var writeIntCountByte = writeInt(byteBuf, maxLength);
var length = byteBuf.writeCharSequence(value, StringUtils.DEFAULT_CHARSET);
var currentWriteIndex = byteBuf.writerIndex();
// 因为写入的是可变长的int,如果预留的位置过多,则清除多余的位置
var padding = writeIntCountByte - writeIntCount(length);
if (padding == 0) {
byteBuf.writerIndex(beforeWriteIndex);
writeInt(byteBuf, length);
byteBuf.writerIndex(currentWriteIndex);
} else {
var retainedByteBuf = byteBuf.retainedSlice(currentWriteIndex - length, length);
byteBuf.writerIndex(beforeWriteIndex);
writeInt(byteBuf, length);
byteBuf.writeBytes(retainedByteBuf);
ReferenceCountUtil.release(retainedByteBuf);
}
}
public static String readString(ByteBuf byteBuf) {
int length = readInt(byteBuf);
return length <= 0 ? StringUtils.EMPTY : (String) byteBuf.readCharSequence(length, StringUtils.DEFAULT_CHARSET);
}
//-----------------------------------------------------------------------
//---------------------------------以下方法会被字节码生成的代码调用--------------------------------------
public static void writePacketCollection(ByteBuf byteBuf, Collection> collection, IProtocolRegistration protocolRegistration) {
if (collection == null) {
byteBuf.writeByte(0);
return;
}
writeInt(byteBuf, collection.size());
for (var packet : collection) {
protocolRegistration.write(byteBuf, packet);
}
}
public static void writePacketList(ByteBuf byteBuf, List> list, IProtocolRegistration protocolRegistration) {
writePacketCollection(byteBuf, list, protocolRegistration);
}
public static List> readPacketList(ByteBuf byteBuf, IProtocolRegistration protocolRegistration) {
var length = readInt(byteBuf);
List