serde-generate/runtime/java/com/novi/serde/BinarySerializer.java (114 lines of code) (raw):
// Copyright (c) Facebook, Inc. and its affiliates
// SPDX-License-Identifier: MIT OR Apache-2.0
package com.novi.serde;
import java.math.BigInteger;
public abstract class BinarySerializer implements Serializer {
protected MyByteArrayOutputStream output;
private long containerDepthBudget;
public BinarySerializer(long maxContainerDepth) {
output = new BinarySerializer.MyByteArrayOutputStream();
containerDepthBudget = maxContainerDepth;
}
public void increase_container_depth() throws SerializationError {
if (containerDepthBudget == 0) {
throw new SerializationError("Exceeded maximum container depth");
}
containerDepthBudget -= 1;
}
public void decrease_container_depth() {
containerDepthBudget += 1;
}
public void serialize_str(String value) throws SerializationError {
serialize_bytes(new Bytes(value.getBytes()));
}
public void serialize_bytes(Bytes value) throws SerializationError {
byte[] content = value.content();
serialize_len(content.length);
output.write(content, 0, content.length);
}
public void serialize_bool(Boolean value) throws SerializationError {
output.write((value.booleanValue() ? 1 : 0));
}
public void serialize_unit(Unit value) throws SerializationError {
}
public void serialize_char(Character value) throws SerializationError {
throw new SerializationError("Not implemented: serialize_char");
}
public void serialize_u8(@Unsigned Byte value) throws SerializationError {
output.write(value.byteValue());
}
public void serialize_u16(@Unsigned Short value) throws SerializationError {
short val = value.shortValue();
output.write((byte) (val >>> 0));
output.write((byte) (val >>> 8));
}
public void serialize_u32(@Unsigned Integer value) throws SerializationError {
int val = value.intValue();
output.write((byte) (val >>> 0));
output.write((byte) (val >>> 8));
output.write((byte) (val >>> 16));
output.write((byte) (val >>> 24));
}
public void serialize_u64(@Unsigned Long value) throws SerializationError {
long val = value.longValue();
output.write((byte) (val >>> 0));
output.write((byte) (val >>> 8));
output.write((byte) (val >>> 16));
output.write((byte) (val >>> 24));
output.write((byte) (val >>> 32));
output.write((byte) (val >>> 40));
output.write((byte) (val >>> 48));
output.write((byte) (val >>> 56));
}
public void serialize_u128(@Unsigned @Int128 BigInteger value) throws SerializationError {
if (value.compareTo(BigInteger.ZERO) < 0 || !value.shiftRight(128).equals(BigInteger.ZERO)) {
throw new java.lang.IllegalArgumentException("Invalid value for an unsigned int128");
}
byte[] content = value.toByteArray();
// BigInteger.toByteArray() may add a most-significant zero
// byte for signing purpose: ignore it.
assert content.length <= 16 || content[0] == 0;
int len = Math.min(content.length, 16);
// Write content in little-endian order.
for (int i = 0; i < len; i++) {
output.write(content[content.length - 1 - i]);
}
// Complete with zeros if needed.
for (int i = len; i < 16; i++) {
output.write(0);
}
}
public void serialize_i8(Byte value) throws SerializationError {
serialize_u8(value);
}
public void serialize_i16(Short value) throws SerializationError {
serialize_u16(value);
}
public void serialize_i32(Integer value) throws SerializationError {
serialize_u32(value);
}
public void serialize_i64(Long value) throws SerializationError {
serialize_u64(value);
}
public void serialize_i128(@Int128 BigInteger value) throws SerializationError {
if (value.compareTo(BigInteger.ZERO) >= 0) {
if (!value.shiftRight(127).equals(BigInteger.ZERO)) {
throw new java.lang.IllegalArgumentException("Invalid value for a signed int128");
}
serialize_u128(value);
} else {
if (!value.add(BigInteger.ONE).negate().shiftRight(127).equals(BigInteger.ZERO)) {
throw new java.lang.IllegalArgumentException("Invalid value for a signed int128");
}
serialize_u128(value.add(BigInteger.ONE.shiftLeft(128)));
}
}
public void serialize_option_tag(boolean value) throws SerializationError {
output.write((value ? (byte) 1 : (byte) 0));
}
public int get_buffer_offset() {
return output.size();
}
public byte[] get_bytes() {
return output.toByteArray();
}
// Local extension to provide access to the underlying buffer.
static public class MyByteArrayOutputStream extends java.io.ByteArrayOutputStream {
public byte[] getBuffer() {
return buf;
}
}
}