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

io.activej.codec.binary.BinaryStructuredInput Maven / Gradle / Ivy

There is a newer version: 4.4-rc1
Show newest version
/*
 * Copyright (C) 2020 ActiveJ LLC.
 *
 * 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 io.activej.codec.binary;

import io.activej.bytebuf.ByteBuf;
import io.activej.codec.StructuredDecoder;
import io.activej.codec.StructuredInput;
import io.activej.common.exception.MalformedDataException;
import io.activej.common.exception.UncheckedException;
import org.jetbrains.annotations.Nullable;

import java.lang.reflect.Type;
import java.util.*;

import static java.nio.charset.StandardCharsets.UTF_8;

@SuppressWarnings("RedundantThrows")
public final class BinaryStructuredInput implements StructuredInput {
	private final ByteBuf buf;

	public BinaryStructuredInput(ByteBuf buf) {
		this.buf = buf;
	}

	@Override
	public boolean readBoolean() throws MalformedDataException {
		try {
			return buf.readBoolean();
		} catch (ArrayIndexOutOfBoundsException e) {
			throw new MalformedDataException(e);
		}
	}

	@Override
	public byte readByte() throws MalformedDataException {
		try {
			return buf.readByte();
		} catch (ArrayIndexOutOfBoundsException e) {
			throw new MalformedDataException(e);
		}
	}

	@Override
	public int readInt() throws MalformedDataException {
		try {
			return buf.readVarInt();
		} catch (ArrayIndexOutOfBoundsException | IllegalStateException e) {
			throw new MalformedDataException(e);
		}
	}

	@Override
	public long readLong() throws MalformedDataException {
		try {
			return buf.readVarLong();
		} catch (ArrayIndexOutOfBoundsException | IllegalStateException e) {
			throw new MalformedDataException(e);
		}
	}

	@Override
	public int readInt32() throws MalformedDataException {
		try {
			return buf.readInt();
		} catch (ArrayIndexOutOfBoundsException e) {
			throw new MalformedDataException(e);
		}
	}

	@Override
	public long readLong64() throws MalformedDataException {
		try {
			return buf.readLong();
		} catch (ArrayIndexOutOfBoundsException e) {
			throw new MalformedDataException(e);
		}
	}

	@Override
	public float readFloat() throws MalformedDataException {
		try {
			return buf.readFloat();
		} catch (ArrayIndexOutOfBoundsException e) {
			throw new MalformedDataException(e);
		}
	}

	@Override
	public double readDouble() throws MalformedDataException {
		try {
			return buf.readDouble();
		} catch (ArrayIndexOutOfBoundsException e) {
			throw new MalformedDataException(e);
		}
	}

	@Override
	public byte[] readBytes() throws MalformedDataException {
		int length = readInt();
		if (length < 0 || length > buf.readRemaining()) {
			throw new MalformedDataException("Invalid length: " + length + ", remaining: " + buf.readRemaining() + ", buf: " + buf);
		}
		byte[] result = new byte[length];
		buf.read(result);
		return result;
	}

	@Override
	public String readString() throws MalformedDataException {
		int length = readInt();
		if (length == 0)
			return "";
		if (length > buf.readRemaining())
			throw new MalformedDataException("Read string length is greater than the remaining data");
		String result = new String(buf.array(), buf.head(), length, UTF_8);
		buf.moveHead(length);
		return result;
	}

	@Override
	public void readNull() throws MalformedDataException {
		if (readBoolean()) {
			throw new MalformedDataException("Expected NULL value");
		}
	}

	@Nullable
	@Override
	public  T readNullable(StructuredDecoder decoder) throws MalformedDataException {
		try {
			return readBoolean() ? decoder.decode(this) : null;
		} catch (UncheckedException e) {
			throw e.propagate(MalformedDataException.class);
		}
	}

	@Override
	public  List readList(StructuredDecoder decoder) throws MalformedDataException {
		int size = readInt();
		List list = new ArrayList<>(size);
		try {
			for (int i = 0; i < size; i++) {
				list.add(decoder.decode(this));
			}
		} catch (UncheckedException e) {
			throw e.propagate(MalformedDataException.class);
		}
		return list;
	}

	@Override
	public  Map readMap(StructuredDecoder keyDecoder, StructuredDecoder valueDecoder) throws MalformedDataException {
		int size = readInt();
		Map map = new LinkedHashMap<>();
		try {
			for (int i = 0; i < size; i++) {
				map.put(keyDecoder.decode(this), valueDecoder.decode(this));
			}
		} catch (UncheckedException e) {
			throw e.propagate(MalformedDataException.class);
		}
		return map;
	}

	@Override
	public  T readTuple(StructuredDecoder decoder) throws MalformedDataException {
		try {
			return decoder.decode(this);
		} catch (UncheckedException e) {
			throw e.propagate(MalformedDataException.class);
		}
	}

	@Override
	public  T readObject(StructuredDecoder decoder) throws MalformedDataException {
		try {
			return decoder.decode(this);
		} catch (UncheckedException e) {
			throw e.propagate(MalformedDataException.class);
		}
	}

	@Override
	public boolean hasNext() throws MalformedDataException {
		throw new UnsupportedOperationException("hasNext() is not supported for binary data");
	}

	@Override
	public String readKey() throws MalformedDataException {
		return readString();
	}

	@Override
	public  T readCustom(Type type) throws MalformedDataException {
		throw new UnsupportedOperationException("No custom type readers");
	}

	@Override
	public EnumSet getNext() throws MalformedDataException {
		throw new UnsupportedOperationException("getNext() is not supported for binary data");
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy