All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.pulsar.common.api.proto.LightProtoCodec Maven / Gradle / Ivy

/**
 * Copyright 2020 Splunk Inc.
 *
 * 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 org.apache.pulsar.common.api.proto;

import org.apache.pulsar.shade.io.netty.buffer.ByteBuf;
import org.apache.pulsar.shade.io.netty.buffer.ByteBufUtil;

import java.nio.charset.StandardCharsets;

class LightProtoCodec {
	static final int TAG_TYPE_MASK = 7;
	static final int TAG_TYPE_BITS = 3;
	static final int WIRETYPE_VARINT = 0;
	static final int WIRETYPE_FIXED64 = 1;
	static final int WIRETYPE_LENGTH_DELIMITED = 2;
	static final int WIRETYPE_START_GROUP = 3;
	static final int WIRETYPE_END_GROUP = 4;
	static final int WIRETYPE_FIXED32 = 5;
	private LightProtoCodec() {
	}

	private static int getTagType(int tag) {
		return tag & TAG_TYPE_MASK;
	}

	static int getFieldId(int tag) {
		return tag >>> TAG_TYPE_BITS;
	}

	static void writeVarInt(ByteBuf b, int n) {
		if (n >= 0) {
			_writeVarInt(b, n);
		} else {
			writeVarInt64(b, n);
		}
	}

	static void writeSignedVarInt(ByteBuf b, int n) {
		writeVarInt(b, encodeZigZag32(n));
	}

	static int readSignedVarInt(ByteBuf b) {
		return decodeZigZag32(readVarInt(b));
	}

	static long readSignedVarInt64(ByteBuf b) {
		return decodeZigZag64(readVarInt64(b));
	}

	static void writeFloat(ByteBuf b, float n) {
		writeFixedInt32(b, Float.floatToRawIntBits(n));
	}

	static void writeDouble(ByteBuf b, double n) {
		writeFixedInt64(b, Double.doubleToRawLongBits(n));
	}

	static float readFloat(ByteBuf b) {
		return Float.intBitsToFloat(readFixedInt32(b));
	}

	static double readDouble(ByteBuf b) {
		return Double.longBitsToDouble(readFixedInt64(b));
	}

	private static void _writeVarInt(ByteBuf b, int n) {
		while (true) {
			if ((n & ~0x7F) == 0) {
				b.writeByte(n);
				return;
			} else {
				b.writeByte((n & 0x7F) | 0x80);
				n >>>= 7;
			}
		}
	}

	static void writeVarInt64(ByteBuf b, long value) {
		while (true) {
			if ((value & ~0x7FL) == 0) {
				b.writeByte((int) value);
				return;
			} else {
				b.writeByte(((int) value & 0x7F) | 0x80);
				value >>>= 7;
			}
		}
	}

	static void writeFixedInt32(ByteBuf b, int n) {
		b.writeIntLE(n);
	}

	static void writeFixedInt64(ByteBuf b, long n) {
		b.writeLongLE(n);
	}

	static int readFixedInt32(ByteBuf b) {
		return b.readIntLE();
	}

	static long readFixedInt64(ByteBuf b) {
		return b.readLongLE();
	}

	static void writeSignedVarInt64(ByteBuf b, long n) {
		writeVarInt64(b, encodeZigZag64(n));
	}

	private static int encodeZigZag32(final int n) {
		return (n << 1) ^ (n >> 31);
	}

	private static long encodeZigZag64(final long n) {
		return (n << 1) ^ (n >> 63);
	}

	private static int decodeZigZag32(int n) {
		return n >>> 1 ^ -(n & 1);
	}

	private static long decodeZigZag64(long n) {
		return n >>> 1 ^ -(n & 1L);
	}

	static int readVarInt(ByteBuf buf) {
		byte tmp = buf.readByte();
		if (tmp >= 0) {
			return tmp;
		}
		int result = tmp & 0x7f;
		if ((tmp = buf.readByte()) >= 0) {
			result |= tmp << 7;
		} else {
			result |= (tmp & 0x7f) << 7;
			if ((tmp = buf.readByte()) >= 0) {
				result |= tmp << 14;
			} else {
				result |= (tmp & 0x7f) << 14;
				if ((tmp = buf.readByte()) >= 0) {
					result |= tmp << 21;
				} else {
					result |= (tmp & 0x7f) << 21;
					result |= (tmp = buf.readByte()) << 28;
					if (tmp < 0) {
						// Discard upper 32 bits.
						for (int i = 0; i < 5; i++) {
							if (buf.readByte() >= 0) {
								return result;
							}
						}
						throw new IllegalArgumentException("Encountered a malformed varint.");
					}
				}
			}
		}
		return result;
	}

	static long readVarInt64(ByteBuf buf) {
		int shift = 0;
		long result = 0;
		while (shift < 64) {
			final byte b = buf.readByte();
			result |= (long) (b & 0x7F) << shift;
			if ((b & 0x80) == 0) {
				return result;
			}
			shift += 7;
		}
		throw new IllegalArgumentException("Encountered a malformed varint.");
	}

	static int computeSignedVarIntSize(final int value) {
		return computeVarUIntSize(encodeZigZag32(value));
	}

	static int computeSignedVarInt64Size(final long value) {
		return computeVarInt64Size(encodeZigZag64(value));
	}

	static int computeVarIntSize(final int value) {
		if (value < 0) {
			return 10;
		} else {
			return computeVarUIntSize(value);
		}
	}

	static int computeVarUIntSize(final int value) {
		if ((value & (0xffffffff << 7)) == 0) {
			return 1;
		} else if ((value & (0xffffffff << 14)) == 0) {
			return 2;
		} else if ((value & (0xffffffff << 21)) == 0) {
			return 3;
		} else if ((value & (0xffffffff << 28)) == 0) {
			return 4;
		} else {
			return 5;
		}
	}

	static int computeVarInt64Size(final long value) {
		if ((value & (0xffffffffffffffffL << 7)) == 0) {
			return 1;
		} else if ((value & (0xffffffffffffffffL << 14)) == 0) {
			return 2;
		} else if ((value & (0xffffffffffffffffL << 21)) == 0) {
			return 3;
		} else if ((value & (0xffffffffffffffffL << 28)) == 0) {
			return 4;
		} else if ((value & (0xffffffffffffffffL << 35)) == 0) {
			return 5;
		} else if ((value & (0xffffffffffffffffL << 42)) == 0) {
			return 6;
		} else if ((value & (0xffffffffffffffffL << 49)) == 0) {
			return 7;
		} else if ((value & (0xffffffffffffffffL << 56)) == 0) {
			return 8;
		} else if ((value & (0xffffffffffffffffL << 63)) == 0) {
			return 9;
		} else {
			return 10;
		}
	}

	static int computeStringUTF8Size(String s) {
		return ByteBufUtil.utf8Bytes(s);
	}

	static void writeString(ByteBuf b, String s, int bytesCount) {
		ByteBufUtil.reserveAndWriteUtf8(b, s, bytesCount);
	}

	static String readString(ByteBuf b, int index, int len) {
		return b.toString(index, len, StandardCharsets.UTF_8);
	}

	static void skipUnknownField(int tag, ByteBuf buffer) {
		int tagType = getTagType(tag);
		switch (tagType) {
			case WIRETYPE_VARINT :
				readVarInt(buffer);
				break;
			case WIRETYPE_FIXED64 :
				buffer.skipBytes(8);
				break;
			case WIRETYPE_LENGTH_DELIMITED :
				int len = readVarInt(buffer);
				buffer.skipBytes(len);
				break;
			case WIRETYPE_FIXED32 :
				buffer.skipBytes(4);
				break;
			default :
				throw new IllegalArgumentException("Invalid unknonwn tag type: " + tagType);
		}
	}

	static final class StringHolder {
		String s;
		int idx;
		int len;
	}

	static final class BytesHolder {
		ByteBuf b;
		int idx;
		int len;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy