/*
This file is part of jpcsp.
Jpcsp is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Jpcsp is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Jpcsp. If not, see <http://www.gnu.org/licenses/>.
*/
package jpcsp.util;
import java.io.EOFException;
public class BytesPacket {
private byte[] buffer;
private int offset;
private int length;
private boolean littleEndian;
private int bufferBits;
private int bit;
public BytesPacket(int length) {
buffer = new byte[length];
this.length = length;
}
public BytesPacket(byte[] buffer) {
this.buffer = buffer;
length = buffer.length;
}
public BytesPacket(byte[] buffer, int length) {
this.buffer = buffer;
this.length = length;
}
public BytesPacket(byte[] buffer, int offset, int length) {
this.buffer = buffer;
this.offset = offset;
this.length = length;
}
public void setLittleEndian() {
littleEndian = true;
}
public void setBigEndian() {
littleEndian = false;
}
public byte[] getBuffer() {
return buffer;
}
public int getOffset() {
return offset;
}
public int getLength() {
return length;
}
public byte readByte() throws EOFException {
if (length <= 0) {
throw new EOFException();
}
length--;
return buffer[offset++];
}
public int read8() throws EOFException {
return readByte() & 0xFF;
}
public int read16() throws EOFException {
if (littleEndian) {
return read8() | (read8() << 8);
}
return (read8() << 8) | read8();
}
public int read32() throws EOFException {
if (littleEndian) {
return read8() | (read8() << 8) | (read8() << 16) | (read8() << 24);
}
return (read8() << 24) | (read8() << 16) | (read8() << 8) | read8();
}
public int read1() throws EOFException {
if (bit <= 0) {
bufferBits = read8();
bit = 8;
}
bit--;
return (bufferBits >> bit) & 1;
}
public int readBits(int n) throws EOFException {
if (n <= bit) {
bit -= n;
return (bufferBits >> bit) & ((1 << n) - 1);
}
int value = 0;
for (int i = 0; i < n; i++) {
value = (value << 1) | read1();
}
return value;
}
public boolean readBoolean() throws EOFException {
return read1() != 0;
}
public byte[] readBytes(byte[] dataBuffer) throws EOFException {
return readBytes(dataBuffer, 0, dataBuffer.length);
}
public byte[] readBytes(int dataLength) throws EOFException {
return readBytes(new byte[dataLength], 0, dataLength);
}
public byte[] readBytes(byte[] dataBuffer, int dataOffset, int dataLength) throws EOFException {
for (int i = 0; i < dataLength; i++) {
dataBuffer[dataOffset + i] = readByte();
}
return dataBuffer;
}
public char readAsciiChar() throws EOFException {
return (char) read8();
}
public void skip8() throws EOFException {
skip8(1);
}
public void skip8(int n) throws EOFException {
if (n > 0) {
if (length < n) {
offset += length;
length = 0;
throw new EOFException();
}
offset += n;
length -= n;
}
}
public String readStringNZ(int n) throws EOFException {
StringBuilder s = new StringBuilder();
while (n > 0) {
n--;
int c = read8();
if (c == 0) {
break;
}
s.append((char) c);
}
skip8(n);
return s.toString();
}
public void writeByte(byte b) throws EOFException {
if (length <= 0) {
throw new EOFException();
}
length--;
buffer[offset++] = b;
}
public void writeBytesZero(int n) throws EOFException {
for (; n > 0; n--) {
writeByte((byte) 0);
}
}
public void write8(int n) throws EOFException {
writeByte((byte) (n & 0xFF));
}
public void write16(int n) throws EOFException {
if (littleEndian) {
write8(n);
write8(n >> 8);
} else {
write8(n >> 8);
write8(n);
}
}
public void write32(int n) throws EOFException {
if (littleEndian) {
write8(n);
write8(n >> 8);
write8(n >> 16);
write8(n >> 24);
} else {
write8(n >> 24);
write8(n >> 16);
write8(n >> 8);
write8(n);
}
}
public void writeBytes(byte[] dataBuffer) throws EOFException {
if (dataBuffer != null) {
writeBytes(dataBuffer, 0, dataBuffer.length);
}
}
public void writeBytes(byte[] dataBuffer, int dataOffset, int dataLength) throws EOFException {
if (dataBuffer != null) {
int copyLength = Math.min(dataLength, dataBuffer.length - dataOffset);
for (int i = 0; i < copyLength; i++) {
writeByte(dataBuffer[dataOffset + i]);
}
dataLength -= copyLength;
}
writeBytesZero(dataLength);
}
public void write1(int n) throws EOFException {
if (bit == 0) {
bufferBits = 0;
}
bit++;
bufferBits |= (n & 1) << (8 - bit);
if (bit == 8) {
write8(bufferBits);
bit = 0;
bufferBits = 0;
}
}
public void writeBoolean(boolean b) throws EOFException {
write1(b ? 1 : 0);
}
public void writeBits(int b, int n) throws EOFException {
for (int i = n - 1; i >= 0; i--) {
write1(b >> i);
}
}
public void writeAsciiChar(char c) throws EOFException {
writeByte((byte) c);
}
public void rewind(int newOffset) {
if (newOffset < offset) {
length += offset - newOffset;
offset = newOffset;
}
}
public void writeStringNZ(String s, int n) throws EOFException {
if (s != null) {
int copyLength = Math.min(s.length(), n);
for (int i = 0; i < copyLength; i++) {
writeAsciiChar(s.charAt(i));
}
n -= copyLength;
}
writeBytesZero(n);
}
}