Please wait. This can take some minutes ...
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.
com.hazelcast.internal.serialization.impl.DefaultPortableReader Maven / Gradle / Ivy
/*
* Copyright (c) 2008-2018, Hazelcast, Inc. All Rights Reserved.
*
* 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.hazelcast.internal.serialization.impl;
import com.hazelcast.nio.Bits;
import com.hazelcast.nio.BufferObjectDataInput;
import com.hazelcast.nio.ObjectDataInput;
import com.hazelcast.nio.serialization.ClassDefinition;
import com.hazelcast.nio.serialization.FieldType;
import com.hazelcast.nio.serialization.HazelcastSerializationException;
import com.hazelcast.nio.serialization.Portable;
import com.hazelcast.nio.serialization.PortableReader;
import com.hazelcast.query.extractor.ValueCallback;
import com.hazelcast.query.extractor.ValueCollector;
import com.hazelcast.query.extractor.ValueReader;
import com.hazelcast.query.extractor.ValueReadingException;
import com.hazelcast.query.impl.getters.ImmutableMultiResult;
import com.hazelcast.query.impl.getters.MultiResult;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import static com.hazelcast.internal.serialization.impl.PortableUtils.getPortableArrayCellPosition;
/**
* Can't be accessed concurrently.
*/
public class DefaultPortableReader extends ValueReader implements PortableReader {
private static final MultiResult NULL_EMPTY_TARGET_MULTIRESULT;
static {
MultiResult result = new MultiResult();
result.addNullOrEmptyTarget();
NULL_EMPTY_TARGET_MULTIRESULT = new ImmutableMultiResult(result);
}
protected final ClassDefinition cd;
protected final PortableSerializer serializer;
private final BufferObjectDataInput in;
private final int finalPosition;
private final int offset;
private final PortableNavigatorContext ctx;
private final PortablePathCursor pathCursor;
private boolean raw;
DefaultPortableReader(PortableSerializer serializer, BufferObjectDataInput in, ClassDefinition cd) {
this.in = in;
this.serializer = serializer;
this.cd = cd;
this.ctx = new PortableNavigatorContext(in, cd, serializer);
this.pathCursor = new PortablePathCursor();
this.finalPosition = ctx.getCurrentFinalPosition();
this.offset = ctx.getCurrentOffset();
}
@Override
public int getVersion() {
return cd.getVersion();
}
@Override
public boolean hasField(String fieldName) {
return cd.hasField(fieldName);
}
@Override
public Set getFieldNames() {
return cd.getFieldNames();
}
@Override
public FieldType getFieldType(String fieldName) {
return cd.getFieldType(fieldName);
}
@Override
public int getFieldClassId(String fieldName) {
return cd.getFieldClassId(fieldName);
}
@Override
public ObjectDataInput getRawDataInput() throws IOException {
if (!raw) {
int pos = in.readInt(offset + cd.getFieldCount() * Bits.INT_SIZE_IN_BYTES);
in.position(pos);
}
raw = true;
return in;
}
final void end() {
in.position(finalPosition);
}
@Override
public byte readByte(String path) throws IOException {
PortablePosition pos = findPositionForReading(path);
validatePrimitive(pos, FieldType.BYTE);
return in.readByte(pos.getStreamPosition());
}
@Override
public short readShort(String path) throws IOException {
PortablePosition pos = findPositionForReading(path);
validatePrimitive(pos, FieldType.SHORT);
return in.readShort(pos.getStreamPosition());
}
@Override
public int readInt(String path) throws IOException {
PortablePosition pos = findPositionForReading(path);
validatePrimitive(pos, FieldType.INT);
return in.readInt(pos.getStreamPosition());
}
@Override
public long readLong(String path) throws IOException {
PortablePosition pos = findPositionForReading(path);
validatePrimitive(pos, FieldType.LONG);
return in.readLong(pos.getStreamPosition());
}
@Override
public float readFloat(String path) throws IOException {
PortablePosition pos = findPositionForReading(path);
validatePrimitive(pos, FieldType.FLOAT);
return in.readFloat(pos.getStreamPosition());
}
@Override
public double readDouble(String path) throws IOException {
PortablePosition pos = findPositionForReading(path);
validatePrimitive(pos, FieldType.DOUBLE);
return in.readDouble(pos.getStreamPosition());
}
@Override
public boolean readBoolean(String path) throws IOException {
PortablePosition pos = findPositionForReading(path);
validatePrimitive(pos, FieldType.BOOLEAN);
return in.readBoolean(pos.getStreamPosition());
}
@Override
public char readChar(String path) throws IOException {
PortablePosition pos = findPositionForReading(path);
validatePrimitive(pos, FieldType.CHAR);
return in.readChar(pos.getStreamPosition());
}
@Override
public String readUTF(String path) throws IOException {
final int currentPos = in.position();
try {
PortablePosition position = findPositionForReading(path);
if (position.isNullOrEmpty()) {
return null;
}
validateNotMultiPosition(position);
validateType(position, FieldType.UTF);
in.position(position.getStreamPosition());
return in.readUTF();
} finally {
in.position(currentPos);
}
}
@Override
@SuppressWarnings("unchecked")
public Portable readPortable(String path) throws IOException {
final int currentPos = in.position();
try {
PortablePosition position = findPositionForReading(path);
if (position.isNullOrEmpty()) {
return null;
}
validateNotMultiPosition(position);
validateType(position, FieldType.PORTABLE);
in.position(position.getStreamPosition());
return serializer.readAndInitialize(in, position.getFactoryId(), position.getClassId());
} finally {
in.position(currentPos);
}
}
@Override
public byte[] readByteArray(String path) throws IOException {
final int currentPos = in.position();
try {
PortablePosition position = findPositionForReading(path);
if (position.isNullOrEmpty()) {
return null;
} else if (position.isMultiPosition()) {
return readMultiByteArray(position.asMultiPosition());
} else {
return readSingleByteArray(position);
}
} finally {
in.position(currentPos);
}
}
private byte[] readMultiByteArray(List positions) throws IOException {
byte[] result = new byte[positions.size()];
for (int i = 0; i < result.length; i++) {
PortablePosition position = positions.get(i);
validateNonNullOrEmptyPosition(position);
validateType(position, FieldType.BYTE);
result[i] = in.readByte(position.getStreamPosition());
}
return result;
}
private byte[] readSingleByteArray(PortablePosition position) throws IOException {
validateType(position, FieldType.BYTE_ARRAY);
in.position(position.getStreamPosition());
return in.readByteArray();
}
@Override
public boolean[] readBooleanArray(String path) throws IOException {
final int currentPos = in.position();
try {
PortablePosition position = findPositionForReading(path);
if (position.isNullOrEmpty()) {
return null;
} else if (position.isMultiPosition()) {
return readMultiBooleanArray(position.asMultiPosition());
} else {
return readSingleBooleanArray(position);
}
} finally {
in.position(currentPos);
}
}
private boolean[] readMultiBooleanArray(List positions) throws IOException {
boolean[] result = new boolean[positions.size()];
for (int i = 0; i < result.length; i++) {
PortablePosition position = positions.get(i);
validateNonNullOrEmptyPosition(position);
validateType(position, FieldType.BOOLEAN);
result[i] = in.readBoolean(position.getStreamPosition());
}
return result;
}
private boolean[] readSingleBooleanArray(PortablePosition position) throws IOException {
validateType(position, FieldType.BOOLEAN_ARRAY);
in.position(position.getStreamPosition());
return in.readBooleanArray();
}
@Override
public char[] readCharArray(String path) throws IOException {
final int currentPos = in.position();
try {
PortablePosition position = findPositionForReading(path);
if (position.isNullOrEmpty()) {
return null;
} else if (position.isMultiPosition()) {
return readMultiCharArray(position.asMultiPosition());
} else {
return readSingleCharArray(position);
}
} finally {
in.position(currentPos);
}
}
private char[] readMultiCharArray(List positions) throws IOException {
char[] result = new char[positions.size()];
for (int i = 0; i < result.length; i++) {
PortablePosition position = positions.get(i);
validateNonNullOrEmptyPosition(position);
validateType(position, FieldType.CHAR);
result[i] = in.readChar(position.getStreamPosition());
}
return result;
}
private char[] readSingleCharArray(PortablePosition position) throws IOException {
validateType(position, FieldType.CHAR_ARRAY);
in.position(position.getStreamPosition());
return in.readCharArray();
}
@Override
public int[] readIntArray(String path) throws IOException {
final int currentPos = in.position();
try {
PortablePosition position = findPositionForReading(path);
if (position.isNullOrEmpty()) {
return null;
} else if (position.isMultiPosition()) {
return readMultiIntArray(position.asMultiPosition());
} else {
return readSingleIntArray(position);
}
} finally {
in.position(currentPos);
}
}
private int[] readMultiIntArray(List positions) throws IOException {
int[] result = new int[positions.size()];
for (int i = 0; i < result.length; i++) {
PortablePosition position = positions.get(i);
validateNonNullOrEmptyPosition(position);
validateType(position, FieldType.INT);
result[i] = in.readInt(position.getStreamPosition());
}
return result;
}
private int[] readSingleIntArray(PortablePosition position) throws IOException {
validateType(position, FieldType.INT_ARRAY);
in.position(position.getStreamPosition());
return in.readIntArray();
}
@Override
public long[] readLongArray(String path) throws IOException {
final int currentPos = in.position();
try {
PortablePosition position = findPositionForReading(path);
if (position.isNullOrEmpty()) {
return null;
} else if (position.isMultiPosition()) {
return readMultiLongArray(position.asMultiPosition());
} else {
return readSingleLongArray(position);
}
} finally {
in.position(currentPos);
}
}
private long[] readMultiLongArray(List positions) throws IOException {
long[] result = new long[positions.size()];
for (int i = 0; i < result.length; i++) {
PortablePosition position = positions.get(i);
validateNonNullOrEmptyPosition(position);
validateType(position, FieldType.LONG);
result[i] = in.readLong(position.getStreamPosition());
}
return result;
}
private long[] readSingleLongArray(PortablePosition position) throws IOException {
validateType(position, FieldType.LONG_ARRAY);
in.position(position.getStreamPosition());
return in.readLongArray();
}
@Override
public double[] readDoubleArray(String path) throws IOException {
final int currentPos = in.position();
try {
PortablePosition position = findPositionForReading(path);
if (position.isNullOrEmpty()) {
return null;
} else if (position.isMultiPosition()) {
return readMultiDoubleArray(position.asMultiPosition());
} else {
return readSingleDoubleArray(position);
}
} finally {
in.position(currentPos);
}
}
private double[] readMultiDoubleArray(List positions) throws IOException {
double[] result = new double[positions.size()];
for (int i = 0; i < result.length; i++) {
PortablePosition position = positions.get(i);
validateNonNullOrEmptyPosition(position);
validateType(position, FieldType.DOUBLE);
result[i] = in.readDouble(position.getStreamPosition());
}
return result;
}
private double[] readSingleDoubleArray(PortablePosition position) throws IOException {
validateType(position, FieldType.DOUBLE_ARRAY);
in.position(position.getStreamPosition());
return in.readDoubleArray();
}
@Override
public float[] readFloatArray(String path) throws IOException {
final int currentPos = in.position();
try {
PortablePosition position = findPositionForReading(path);
if (position.isNullOrEmpty()) {
return null;
} else if (position.isMultiPosition()) {
return readMultiFloatArray(position.asMultiPosition());
} else {
return readSingleFloatArray(position);
}
} finally {
in.position(currentPos);
}
}
private float[] readMultiFloatArray(List positions) throws IOException {
float[] result = new float[positions.size()];
for (int i = 0; i < result.length; i++) {
PortablePosition position = positions.get(i);
validateNonNullOrEmptyPosition(position);
validateType(position, FieldType.FLOAT);
result[i] = in.readFloat(position.getStreamPosition());
}
return result;
}
private float[] readSingleFloatArray(PortablePosition position) throws IOException {
validateType(position, FieldType.FLOAT_ARRAY);
in.position(position.getStreamPosition());
return in.readFloatArray();
}
@Override
public short[] readShortArray(String path) throws IOException {
final int currentPos = in.position();
try {
PortablePosition position = findPositionForReading(path);
if (position.isNullOrEmpty()) {
return null;
} else if (position.isMultiPosition()) {
return readMultiShortArray(position.asMultiPosition());
} else {
return readSingleShortArray(position);
}
} finally {
in.position(currentPos);
}
}
private short[] readMultiShortArray(List positions) throws IOException {
short[] result = new short[positions.size()];
for (int i = 0; i < result.length; i++) {
PortablePosition position = positions.get(i);
validateNonNullOrEmptyPosition(position);
validateType(position, FieldType.SHORT);
result[i] = in.readShort(position.getStreamPosition());
}
return result;
}
private short[] readSingleShortArray(PortablePosition position) throws IOException {
validateType(position, FieldType.SHORT_ARRAY);
in.position(position.getStreamPosition());
return in.readShortArray();
}
@Override
public String[] readUTFArray(String path) throws IOException {
final int currentPos = in.position();
try {
PortablePosition position = findPositionForReading(path);
if (position.isNullOrEmpty()) {
return null;
} else if (position.isMultiPosition()) {
return readMultiUTFArray(position.asMultiPosition());
} else {
return readSingleUTFArray(position);
}
} finally {
in.position(currentPos);
}
}
private String[] readMultiUTFArray(List positions) throws IOException {
String[] result = new String[positions.size()];
for (int i = 0; i < result.length; i++) {
PortablePosition position = positions.get(i);
if (!position.isNullOrEmpty()) {
validateType(position, FieldType.UTF);
in.position(position.getStreamPosition());
result[i] = in.readUTF();
}
}
return result;
}
private String[] readSingleUTFArray(PortablePosition position) throws IOException {
validateType(position, FieldType.UTF_ARRAY);
in.position(position.getStreamPosition());
return in.readUTFArray();
}
@Override
public Portable[] readPortableArray(String fieldName) throws IOException {
final int currentPos = in.position();
try {
PortablePosition position = findPositionForReading(fieldName);
if (position.isMultiPosition()) {
return readMultiPortableArray(position.asMultiPosition());
} else if (position.isNull()) {
return null;
} else if (position.isEmpty() && position.isAny()) {
return null;
} else {
return readSinglePortableArray(position);
}
} finally {
in.position(currentPos);
}
}
private Portable[] readSinglePortableArray(PortablePosition position) throws IOException {
in.position(position.getStreamPosition());
if (position.getLen() == Bits.NULL_ARRAY_LENGTH) {
return null;
}
validateType(position, FieldType.PORTABLE_ARRAY);
final Portable[] portables = new Portable[position.getLen()];
for (int index = 0; index < position.getLen(); index++) {
in.position(getPortableArrayCellPosition(in, position.getStreamPosition(), index));
portables[index] = serializer.readAndInitialize(in, position.getFactoryId(), position.getClassId());
}
return portables;
}
private Portable[] readMultiPortableArray(List positions) throws IOException {
final Portable[] portables = new Portable[positions.size()];
for (int i = 0; i < portables.length; i++) {
PortablePosition position = positions.get(i);
if (!position.isNullOrEmpty()) {
validateType(position, FieldType.PORTABLE);
in.position(position.getStreamPosition());
portables[i] = serializer.readAndInitialize(in, position.getFactoryId(), position.getClassId());
}
}
return portables;
}
@Override
@SuppressWarnings("unchecked")
public void read(String path, ValueCallback callback) {
try {
Object result = read(path);
if (result instanceof MultiResult) {
MultiResult multiResult = (MultiResult) result;
for (Object singleResult : multiResult.getResults()) {
callback.onResult(singleResult);
}
} else {
callback.onResult(result);
}
} catch (IOException e) {
throw new ValueReadingException(e.getMessage(), e);
} catch (RuntimeException e) {
throw new ValueReadingException(e.getMessage(), e);
}
}
@Override
@SuppressWarnings("unchecked")
public void read(String path, ValueCollector collector) {
try {
Object result = read(path);
if (result instanceof MultiResult) {
MultiResult multiResult = (MultiResult) result;
for (Object singleResult : multiResult.getResults()) {
collector.addObject(singleResult);
}
} else {
collector.addObject(result);
}
} catch (IOException e) {
throw new ValueReadingException(e.getMessage(), e);
} catch (RuntimeException e) {
throw new ValueReadingException(e.getMessage(), e);
}
}
public Object read(String path) throws IOException {
final int currentPos = in.position();
try {
PortablePosition position = findPositionForReading(path);
if (position.isMultiPosition()) {
return readMultiPosition(position.asMultiPosition());
} else if (position.isNull()) {
if (position.isAny()) {
return NULL_EMPTY_TARGET_MULTIRESULT;
}
return null;
} else if (position.isEmpty()) {
if (position.isLeaf() && position.getType() != null) {
return readSinglePosition(position);
} else {
if (position.isAny()) {
return NULL_EMPTY_TARGET_MULTIRESULT;
}
return null;
}
} else {
return readSinglePosition(position);
}
} finally {
in.position(currentPos);
}
}
private MultiResult readMultiPosition(List positions) throws IOException {
MultiResult result = new MultiResult();
for (PortablePosition position : positions) {
if (!position.isNullOrEmpty()) {
T read = readSinglePosition(position);
result.add(read);
} else {
result.addNullOrEmptyTarget();
}
}
return result;
}
@SuppressWarnings("unchecked")
private T readSinglePosition(PortablePosition position) throws IOException {
if (position.getIndex() >= 0) {
return readSinglePositionFromArray(position);
}
return readSinglePositionFromNonArray(position);
}
private PortablePosition findPositionForReading(String path) throws IOException {
if (raw) {
throw new HazelcastSerializationException("Cannot read Portable fields after getRawDataInput() is called!");
}
try {
return PortablePositionNavigator.findPositionForReading(ctx, path, pathCursor);
} finally {
// The context is reset each time to enable its reuse in consecutive calls and avoid allocation
ctx.reset();
}
}
@SuppressWarnings({"checkstyle:cyclomaticcomplexity", "checkstyle:returncount", "unchecked"})
private T readSinglePositionFromArray(PortablePosition position) throws IOException {
assert position.getType() != null : "Unsupported type read: null";
switch (position.getType()) {
case BYTE:
case BYTE_ARRAY:
return (T) Byte.valueOf(in.readByte(position.getStreamPosition()));
case SHORT:
case SHORT_ARRAY:
return (T) Short.valueOf(in.readShort(position.getStreamPosition()));
case INT:
case INT_ARRAY:
return (T) Integer.valueOf(in.readInt(position.getStreamPosition()));
case LONG:
case LONG_ARRAY:
return (T) Long.valueOf(in.readLong(position.getStreamPosition()));
case FLOAT:
case FLOAT_ARRAY:
return (T) Float.valueOf(in.readFloat(position.getStreamPosition()));
case DOUBLE:
case DOUBLE_ARRAY:
return (T) Double.valueOf(in.readDouble(position.getStreamPosition()));
case BOOLEAN:
case BOOLEAN_ARRAY:
return (T) Boolean.valueOf(in.readBoolean(position.getStreamPosition()));
case CHAR:
case CHAR_ARRAY:
return (T) Character.valueOf(in.readChar(position.getStreamPosition()));
case UTF:
case UTF_ARRAY:
in.position(position.getStreamPosition());
return (T) in.readUTF();
case PORTABLE:
case PORTABLE_ARRAY:
in.position(position.getStreamPosition());
return (T) serializer.readAndInitialize(in, position.getFactoryId(), position.getClassId());
default:
throw new IllegalArgumentException("Unsupported type: " + position.getType());
}
}
@SuppressWarnings({"checkstyle:cyclomaticcomplexity", "checkstyle:returncount", "unchecked"})
private T readSinglePositionFromNonArray(PortablePosition position) throws IOException {
assert position.getType() != null : "Unsupported type read: null";
switch (position.getType()) {
case BYTE:
return (T) Byte.valueOf(in.readByte(position.getStreamPosition()));
case BYTE_ARRAY:
return (T) readSingleByteArray(position);
case SHORT:
return (T) Short.valueOf(in.readShort(position.getStreamPosition()));
case SHORT_ARRAY:
return (T) readSingleShortArray(position);
case INT:
return (T) Integer.valueOf(in.readInt(position.getStreamPosition()));
case INT_ARRAY:
return (T) readSingleIntArray(position);
case LONG:
return (T) Long.valueOf(in.readLong(position.getStreamPosition()));
case LONG_ARRAY:
return (T) readSingleLongArray(position);
case FLOAT:
return (T) Float.valueOf(in.readFloat(position.getStreamPosition()));
case FLOAT_ARRAY:
return (T) readSingleFloatArray(position);
case DOUBLE:
return (T) Double.valueOf(in.readDouble(position.getStreamPosition()));
case DOUBLE_ARRAY:
return (T) readSingleDoubleArray(position);
case BOOLEAN:
return (T) Boolean.valueOf(in.readBoolean(position.getStreamPosition()));
case BOOLEAN_ARRAY:
return (T) readSingleBooleanArray(position);
case CHAR:
return (T) Character.valueOf(in.readChar(position.getStreamPosition()));
case CHAR_ARRAY:
return (T) readSingleCharArray(position);
case UTF:
in.position(position.getStreamPosition());
return (T) in.readUTF();
case UTF_ARRAY:
return (T) readSingleUTFArray(position);
case PORTABLE:
in.position(position.getStreamPosition());
return (T) serializer.readAndInitialize(in, position.getFactoryId(), position.getClassId());
case PORTABLE_ARRAY:
return (T) readSinglePortableArray(position);
default:
throw new IllegalArgumentException("Unsupported type " + position.getType());
}
}
private void validatePrimitive(PortablePosition position, FieldType expectedType) {
validateNonNullOrEmptyPosition(position);
validateNotMultiPosition(position);
validateType(position, expectedType);
}
private void validateNonNullOrEmptyPosition(PortablePosition position) {
if (position.isNullOrEmpty()) {
throw new IllegalArgumentException("Primitive type cannot be returned since the result is/contains null.");
}
}
private void validateNotMultiPosition(PortablePosition position) {
if (position.isMultiPosition()) {
throw new IllegalArgumentException("The method expected a single result but multiple results have been returned."
+ " Did you use the [any] quantifier? If so, use the readArray method family.");
}
}
private void validateType(PortablePosition position, FieldType expectedType) {
FieldType returnedType = position.getType();
if (position.getIndex() >= 0) {
returnedType = returnedType != null ? returnedType.getSingleType() : null;
}
if (expectedType != returnedType) {
String name = returnedType != null ? returnedType.name() : null;
throw new IllegalArgumentException("Wrong type read! Actual: " + name + " Expected: " + expectedType.name()
+ ". Did you use a correct read method? E.g. readInt() for int.");
}
}
}