Skip to content

Commit

Permalink
feat: replace byte array with byte buffer in array codec
Browse files Browse the repository at this point in the history
  • Loading branch information
Deng-Ran committed Jan 27, 2023
1 parent 6d29579 commit a0486d2
Show file tree
Hide file tree
Showing 14 changed files with 544 additions and 4 deletions.
41 changes: 37 additions & 4 deletions src/main/java/org/indunet/fastproto/codec/AsciiArrayCodec.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,15 @@
package org.indunet.fastproto.codec;

import lombok.val;
import org.indunet.fastproto.ByteBuffer;
import org.indunet.fastproto.annotation.Int8ArrayType;
import org.indunet.fastproto.exception.DecodingException;
import org.indunet.fastproto.exception.EncodingException;
import org.indunet.fastproto.util.CodecUtils;
import org.indunet.fastproto.util.CollectionUtils;

import java.util.Arrays;
import java.util.Collection;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
* Ascii array type codec.
Expand All @@ -46,7 +45,7 @@ public char[] decode(byte[] bytes, int offset, int length) {

return chars;
} catch (ArrayIndexOutOfBoundsException | IllegalArgumentException e) {
throw new DecodingException("Fail decoding int8 array type.", e);
throw new DecodingException("Fail decoding ascii array type.", e);
}
}

Expand All @@ -58,7 +57,7 @@ public void encode(byte[] bytes, int offset, int length, char[] values) {
IntStream.range(0, l)
.forEach(i -> CodecUtils.int8Type(bytes, o + i, values[i]));
} catch (ArrayIndexOutOfBoundsException | IllegalArgumentException e) {
throw new EncodingException("Fail encoding int8 array type.", e);
throw new EncodingException("Fail encoding ascii array type.", e);
}
}

Expand All @@ -76,6 +75,20 @@ public void encode(CodecContext context, byte[] bytes, char[] value) {
this.encode(bytes, type.offset(), type.length(), value);
}

@Override
public void encode(CodecContext context, ByteBuffer buffer, char[] values) {
val type = context.getDataTypeAnnotation(Int8ArrayType.class);

try {
val l = buffer.reverse(type.offset(), type.length());

IntStream.range(0, l)
.forEach(i -> CodecUtils.int8Type(buffer, type.offset() + i, values[i]));
} catch (ArrayIndexOutOfBoundsException | IllegalArgumentException e) {
throw new EncodingException("Fail encoding ascii array type.", e);
}
}

public class WrapperCodec implements Codec<Character[]> {
@Override
public Character[] decode(CodecContext context, byte[] bytes) {
Expand All @@ -94,6 +107,15 @@ public void encode(CodecContext context, byte[] bytes, Character[] values) {
.forEach(i -> chars[i] = values[i]);
AsciiArrayCodec.this.encode(context, bytes, chars);
}

@Override
public void encode(CodecContext context, ByteBuffer buffer, Character[] values) {
val chars = new char[values.length];

IntStream.range(0, values.length)
.forEach(i -> chars[i] = values[i]);
AsciiArrayCodec.this.encode(context, buffer, chars);
}
}

public class CollectionCodec implements Codec<Collection<Character>> {
Expand Down Expand Up @@ -124,5 +146,16 @@ public void encode(CodecContext context, byte[] bytes, Collection<Character> col
.forEach(i -> chars[i] = values[i]);
AsciiArrayCodec.this.encode(context, bytes, chars);
}

@Override
public void encode(CodecContext context, ByteBuffer buffer, Collection<Character> collection) {
val chars = new char[collection.size()];
val values = collection.stream()
.toArray(Character[]::new);

IntStream.range(0, chars.length)
.forEach(i -> chars[i] = values[i]);
AsciiArrayCodec.this.encode(context, buffer, chars);
}
}
}
61 changes: 61 additions & 0 deletions src/main/java/org/indunet/fastproto/codec/BoolArrayCodec.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import lombok.val;
import org.indunet.fastproto.BitOrder;
import org.indunet.fastproto.ByteBuffer;
import org.indunet.fastproto.annotation.BoolArrayType;
import org.indunet.fastproto.exception.DecodingException;
import org.indunet.fastproto.exception.EncodingException;
Expand Down Expand Up @@ -41,6 +42,44 @@ public void encode(CodecContext context, byte[] bytes, boolean[] values) {
}
}

@Override
public void encode(CodecContext context, ByteBuffer buffer, boolean[] values) {
try {
val type = context.getDataTypeAnnotation(BoolArrayType.class);
val bitOrder = context.getBitOrder(type::bitOrder);

int byteIndex = type.byteOffset() + type.bitOffset() / 8;
int bitIndex = type.bitOffset() % 8;

for (boolean value : values) {
if (bitOrder == BitOrder.MSB_0) {
if (value) {
buffer.orEq(byteIndex, (byte) (0x80 >>> bitIndex));
} else {
buffer.andEq(byteIndex, (byte) ~(0x80 >>> bitIndex));
}
} else if (bitOrder == BitOrder.LSB_0) {
if (value) {
buffer.orEq(byteIndex, (byte) (0x01 << bitIndex));
} else {
buffer.andEq(byteIndex, (byte) ~(0x01 << bitIndex));
}
} else {
throw new IllegalArgumentException("mode must be MSB_0 or LSB_0");
}

bitIndex++;

if (bitIndex == 8) {
bitIndex = 0;
byteIndex++;
}
}
} catch (ArrayIndexOutOfBoundsException | IllegalArgumentException e) {
throw new EncodingException("Fail encoding boolean array type.", e);
}
}

public boolean[] decode(byte[] bytes, int byteOffset, int bitOffset, int length, BitOrder bitOrder) {
boolean[] result = new boolean[length];
int byteIndex = byteOffset + bitOffset / 8;
Expand Down Expand Up @@ -119,6 +158,16 @@ public void encode(CodecContext context, byte[] bytes, Boolean[] values) {

BoolArrayCodec.this.encode(context, bytes, bools);
}

@Override
public void encode(CodecContext context, ByteBuffer buffer, Boolean[] values) {
boolean[] bools = new boolean[values.length];

IntStream.range(0, values.length)
.forEach(i -> bools[i] = values[i]);

BoolArrayCodec.this.encode(context, buffer, bools);
}
}

public class CollectionCodec implements Codec<Collection<Boolean>> {
Expand Down Expand Up @@ -150,5 +199,17 @@ public void encode(CodecContext context, byte[] bytes, Collection<Boolean> colle

BoolArrayCodec.this.encode(context, bytes, bools);
}

@Override
public void encode(CodecContext context, ByteBuffer buffer, Collection<Boolean> collection) {
val bools = new boolean[collection.size()];
val values = collection.stream()
.toArray(Boolean[]::new);

IntStream.range(0, values.length)
.forEach(i -> bools[i] = values[i]);

BoolArrayCodec.this.encode(context, buffer, bools);
}
}
}
41 changes: 41 additions & 0 deletions src/main/java/org/indunet/fastproto/codec/CharArrayCodec.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import lombok.val;
import lombok.var;
import org.indunet.fastproto.ByteBuffer;
import org.indunet.fastproto.ByteOrder;
import org.indunet.fastproto.annotation.CharType;
import org.indunet.fastproto.annotation.UInt16ArrayType;
Expand Down Expand Up @@ -89,6 +90,26 @@ public void encode(CodecContext context, byte[] bytes, char[] value) {
this.encode(bytes, type.offset(), type.length(), order, value);
}

@Override
public void encode(CodecContext context, ByteBuffer buffer, char[] values) {
val type = context.getDataTypeAnnotation(UInt16ArrayType.class);
val order = context.getByteOrder(type::byteOrder);

try {
var l = type.length();

if (l < 0) {
l = buffer.reverse(type.offset(), type.length() * UInt16Type.SIZE) / UInt16Type.SIZE + 1;
}

IntStream.range(0, l)
.forEach(i ->
CodecUtils.uint16Type(buffer, type.offset() + i * UInt16Type.SIZE, order, values[i]));
} catch (ArrayIndexOutOfBoundsException | IllegalArgumentException e) {
throw new EncodingException("Fail encoding char array type.", e);
}
}

public class WrapperCodec implements Codec<Character[]> {
@Override
public Character[] decode(CodecContext context, byte[] bytes) {
Expand All @@ -107,6 +128,15 @@ public void encode(CodecContext context, byte[] bytes, Character[] values) {
.forEach(i -> chars[i] = values[i]);
CharArrayCodec.this.encode(context, bytes, chars);
}

@Override
public void encode(CodecContext context, ByteBuffer buffer, Character[] values) {
val chars = new char[values.length];

IntStream.range(0, values.length)
.forEach(i -> chars[i] = values[i]);
CharArrayCodec.this.encode(context, buffer, chars);
}
}

public class CollectionCodec implements Codec<Collection<Character>> {
Expand Down Expand Up @@ -137,5 +167,16 @@ public void encode(CodecContext context, byte[] bytes, Collection<Character> col
.forEach(i -> chars[i] = values[i]);
CharArrayCodec.this.encode(context, bytes, chars);
}

@Override
public void encode(CodecContext context, ByteBuffer buffer, Collection<Character> collection) {
val chars = new char[collection.size()];
val values = collection.stream()
.toArray(Character[]::new);

IntStream.range(0, chars.length)
.forEach(i -> chars[i] = values[i]);
CharArrayCodec.this.encode(context, buffer, chars);
}
}
}
43 changes: 43 additions & 0 deletions src/main/java/org/indunet/fastproto/codec/DoubleArrayCodec.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import lombok.val;
import lombok.var;
import org.indunet.fastproto.ByteBuffer;
import org.indunet.fastproto.ByteOrder;
import org.indunet.fastproto.annotation.DoubleArrayType;
import org.indunet.fastproto.annotation.DoubleType;
Expand Down Expand Up @@ -91,6 +92,30 @@ public void encode(CodecContext context, byte[] bytes, double[] value) {
this.encode(bytes, type.offset(), type.length(), order, value);
}

@Override
public void encode(CodecContext context, ByteBuffer buffer, double[] values) {
val type = context.getDataTypeAnnotation(DoubleArrayType.class);
val order = context.getByteOrder(type::byteOrder);

try {
var l = type.length();

if (l < 0) {
l = buffer.reverse(type.offset(), type.length() * DoubleType.SIZE) / DoubleType.SIZE + 1;
}

if (l >= values.length) {
IntStream.range(0, values.length)
.forEach(i -> CodecUtils.doubleType(buffer, type.offset() + i * DoubleType.SIZE, order, values[i]));
} else {
IntStream.range(0, l)
.forEach(i -> CodecUtils.doubleType(buffer, type.offset() + i * DoubleType.SIZE, order, values[i]));
}
} catch (ArrayIndexOutOfBoundsException | IllegalArgumentException e) {
throw new EncodingException("Fail encoding double array type.", e);
}
}

public class WrapperCodec implements Codec<Double[]> {
@Override
public Double[] decode(CodecContext context, byte[] bytes) {
Expand All @@ -107,6 +132,15 @@ public void encode(CodecContext context, byte[] bytes, Double[] values) {

DoubleArrayCodec.this.encode(context, bytes, doubles);
}

@Override
public void encode(CodecContext context, ByteBuffer buffer, Double[] values) {
val doubles = Stream.of(values)
.mapToDouble(i -> i.doubleValue())
.toArray();

DoubleArrayCodec.this.encode(context, buffer, doubles);
}
}

public class CollectionCodec implements Codec<Collection<Double>> {
Expand Down Expand Up @@ -134,5 +168,14 @@ public void encode(CodecContext context, byte[] bytes, Collection<Double> collec

DoubleArrayCodec.this.encode(context, bytes, doubles);
}

@Override
public void encode(CodecContext context, ByteBuffer buffer, Collection<Double> collection) {
val doubles = collection.stream()
.mapToDouble(Double::doubleValue)
.toArray();

DoubleArrayCodec.this.encode(context, buffer, doubles);
}
}
}
47 changes: 47 additions & 0 deletions src/main/java/org/indunet/fastproto/codec/FloatArrayCodec.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import lombok.val;
import lombok.var;
import org.indunet.fastproto.ByteBuffer;
import org.indunet.fastproto.ByteOrder;
import org.indunet.fastproto.annotation.FloatArrayType;
import org.indunet.fastproto.annotation.FloatType;
Expand Down Expand Up @@ -92,6 +93,30 @@ public void encode(CodecContext context, byte[] bytes, float[] value) {
this.encode(bytes, type.offset(), type.length(), order, value);
}

@Override
public void encode(CodecContext context, ByteBuffer buffer, float[] values) {
val type = context.getDataTypeAnnotation(FloatArrayType.class);
val order = context.getByteOrder(type::byteOrder);

try {
var l = type.length();

if (l < 0) {
l = buffer.reverse(type.offset(), type.length() * FloatType.SIZE) / FloatType.SIZE + 1;
}

if (l >= values.length) {
IntStream.range(0, values.length)
.forEach(i -> CodecUtils.floatType(buffer, type.offset() + i * FloatType.SIZE, order, values[i]));
} else {
IntStream.range(0, l)
.forEach(i -> CodecUtils.floatType(buffer, type.offset() + i * FloatType.SIZE, order, values[i]));
}
} catch (ArrayIndexOutOfBoundsException | IllegalArgumentException e) {
throw new EncodingException("Fail encoding float array type.", e);
}
}

public class WrapperCodec implements Codec<Float[]> {
@Override
public Float[] decode(CodecContext context, byte[] bytes) {
Expand All @@ -113,6 +138,16 @@ public void encode(CodecContext context, byte[] bytes, Float[] values) {

FloatArrayCodec.this.encode(context, bytes, floats);
}

@Override
public void encode(CodecContext context, ByteBuffer buffer, Float[] values) {
val floats = new float[values.length];

IntStream.range(0, floats.length)
.forEach(i -> floats[i] = values[i]);

FloatArrayCodec.this.encode(context, buffer, floats);
}
}

public class CollectionCodec implements Codec<Collection<Float>> {
Expand Down Expand Up @@ -144,5 +179,17 @@ public void encode(CodecContext context, byte[] bytes, Collection<Float> collect

FloatArrayCodec.this.encode(context, bytes, bs);
}

@Override
public void encode(CodecContext context, ByteBuffer buffer, Collection<Float> collection) {
val bs = new float[collection.size()];
val values = collection.stream()
.toArray(Float[]::new);

IntStream.range(0, bs.length)
.forEach(i -> bs[i] = values[i]);

FloatArrayCodec.this.encode(context, buffer, bs);
}
}
}
Loading

0 comments on commit a0486d2

Please sign in to comment.