package com.faforever.client.remote.io;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Closeable;
import java.io.DataInput;
import java.io.IOException;
import java.io.InputStream;
import java.lang.invoke.MethodHandles;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public class QDataInputStream extends InputStream {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private final DataInput dataInput;
private final Charset charset;
public QDataInputStream(DataInput dataInput) {
this(dataInput, StandardCharsets.UTF_16BE);
}
public QDataInputStream(DataInput dataInput, Charset charset) {
this.dataInput = dataInput;
this.charset = charset;
}
public String readQString() throws IOException {
int stringSize = dataInput.readInt();
if (stringSize == -1) {
return null;
}
byte[] buffer = new byte[stringSize];
dataInput.readFully(buffer);
return new String(buffer, charset);
}
@Override
public int read() throws IOException {
return dataInput.readUnsignedByte();
}
@Override
public void close() throws IOException {
if (dataInput instanceof Closeable) {
((Closeable) dataInput).close();
}
}
public int readInt() throws IOException {
return dataInput.readInt();
}
/**
* Skip the "block size" bytes, since we just don't care.
*/
public void skipBlockSize() throws IOException {
dataInput.skipBytes(Integer.SIZE / Byte.SIZE);
}
public int readShort() throws IOException {
return dataInput.readUnsignedShort();
}
/**
* @return the number of bytes read
*/
public int readQByteArray(byte[] buffer) throws IOException {
// Skip first 4 bytes that tell us this is a QByteArray as well as the 1-byte null flag
dataInput.skipBytes(5);
int arraySize = dataInput.readInt();
logger.trace("Trying to read {} bytes", arraySize);
if (arraySize == 0xffffffff) {
// 0xffffffff means the array is null
return 0;
}
dataInput.readFully(buffer, 0, arraySize);
return arraySize;
}
}