Files
rosetta-wss/src/main/java/io/orprotocol/Stream.java
2026-02-02 05:30:38 +02:00

180 lines
4.6 KiB
Java

package io.orprotocol;
public class Stream {
private byte[] stream;
private int readPointer = 0;
private int writePointer = 0;
public Stream() {
this.stream = new byte[0];
}
public Stream(byte[] stream) {
this.stream = stream;
}
public byte[] getStream() {
return this.stream;
}
public void setStream(byte[] stream) {
this.stream = stream;
}
public void writeInt8(int value) {
int negationBit = value < 0 ? 1 : 0;
int int8Value = Math.abs(value) & 0xFF;
ensureCapacity(writePointer >> 3);
stream[writePointer >> 3] |= (byte)(negationBit << (7 - (writePointer & 7)));
writePointer++;
for (int i = 0; i < 8; i++) {
int bit = (int8Value >> (7 - i)) & 1;
ensureCapacity(writePointer >> 3);
stream[writePointer >> 3] |= (byte)(bit << (7 - (writePointer & 7)));
writePointer++;
}
}
public int readInt8() {
int value = 0;
int negationBit = (stream[readPointer >> 3] >> (7 - (readPointer & 7))) & 1;
readPointer++;
for (int i = 0; i < 8; i++) {
int bit = (stream[readPointer >> 3] >> (7 - (readPointer & 7))) & 1;
value |= bit << (7 - i);
readPointer++;
}
return negationBit == 1 ? -value : value;
}
public void writeBit(int value) {
int bit = value & 1;
ensureCapacity(writePointer >> 3);
stream[writePointer >> 3] |= (byte)(bit << (7 - (writePointer & 7)));
writePointer++;
}
public int readBit() {
int bit = (stream[readPointer >> 3] >> (7 - (readPointer & 7))) & 1;
readPointer++;
return bit;
}
public void writeBoolean(boolean value) {
writeBit(value ? 1 : 0);
}
public boolean readBoolean() {
return readBit() == 1;
}
public void writeInt16(int value) {
writeInt8(value >> 8);
writeInt8(value & 0xFF);
}
public int readInt16() {
int value = readInt8() << 8;
return value | readInt8();
}
public void writeInt32(int value) {
writeInt16(value >> 16);
writeInt16(value & 0xFFFF);
}
public int readInt32() {
int value = readInt16() << 16;
return value | readInt16();
}
public void writeInt64(long value) {
int high = (int)(value >> 32);
int low = (int)value;
writeInt32(high);
writeInt32(low);
}
public long readInt64() {
long high = readInt32();
long low = readInt32() & 0xFFFFFFFFL;
return (high << 32) | low;
}
public void writeFloat32(float value) {
int floatValue = Float.floatToIntBits(value);
writeInt32(floatValue);
}
public float readFloat32() {
int floatValue = readInt32();
return Float.intBitsToFloat(floatValue);
}
public void writeString(String value) {
int length = value.length();
writeInt32(length);
for (int i = 0; i < value.length(); i++) {
writeInt16(value.charAt(i));
}
}
public String readString() {
int length = readInt32();
// Security fix for string length exceeding stream capacity
if (length < 0 || length > (stream.length - (readPointer >> 3))) {
System.out.println("Stream readString length invalid: " + length + ", stream length: " + stream.length + ", readPointer: " + readPointer);
return "";
}
StringBuilder value = new StringBuilder();
for (int i = 0; i < length; i++) {
value.append((char)readInt16());
}
return value.toString();
}
public void writeBytes(byte[] value) {
writeInt32(value.length);
for (int i = 0; i < value.length; i++) {
writeInt8(value[i]);
}
}
public byte[] readBytes() {
int length = readInt32();
byte[] value = new byte[length];
for (int i = 0; i < length; i++) {
value[i] = (byte)readInt8();
}
return value;
}
public boolean isEmpty() {
return this.stream.length == 0;
}
public int length() {
return this.stream.length;
}
public byte[] getBuffer() {
return this.stream;
}
private void ensureCapacity(int byteIndex) {
if (byteIndex >= stream.length) {
byte[] newStream = new byte[byteIndex + 1];
System.arraycopy(stream, 0, newStream, 0, stream.length);
stream = newStream;
}
}
}