📄 fscoder.java
字号:
/**
* Returns a copy of the array of bytes.
*
* @return a copy of the internal buffer.
*/
public byte[] getData()
{
int length = (ptr + 7) >> 3;
byte[] bytes = new byte[length];
System.arraycopy(data, 0, bytes, 0, length);
return bytes;
}
/**
* Sets the array of bytes used to read or write data to.
*
* @param order the byte-order for words, either FSCoder.LITTLE_ENDIAN or
* FSCoder.BIG_ENDIAN.
*
* @param bytes a byte array that will be used as the internal buffer.
*/
public void setData(int order, byte[] bytes)
{
byteOrder = order;
data = new byte[bytes.length];
System.arraycopy(bytes, 0, data, 0, bytes.length);
ptr = 0;
end = data.length << 3;
}
/**
* Increases the size of the internal buffer. This method is used when
* encoding data to automatically adjust the buffer size to avoid overflows.
*
* @param size the number of bytes to add to the buffer.
*/
public void addCapacity(int size)
{
int length = (end >>> 3) + size;
byte[] bytes = new byte[length];
System.arraycopy(data, 0, bytes, 0, data.length);
data = bytes;
end = data.length << 3;
}
/**
* Return the size of the internal buffer in bytes.
*
* @return the size of the buffer.
*/
public int getCapacity()
{
return end >>> 3;
}
/*
* Methods for adjusting the locaion from where data is read or written
*/
/**
* Returns the offset, in bits, from the start of the buffer where the next
* value will be read or written.
*
* @return the offset in bits where the next value will be read or written.
*/
public int getPointer()
{
return ptr;
}
/**
* Sets the offset, in bits, from the start of the buffer where the next
* value will be read or written. If the offset falls outside of the bits
* range supported by the buffer then an IllegalArgumentException will
* be thrown.
*
* @param location the offset in bits from the start of the array of bytes.
*/
public void setPointer(int location)
{
if (location < 0 || location > end)
throw new IllegalArgumentException();
ptr = location;
}
/**
* Adds offset, in bits, to the internal pointer to change the location
* where the next value will be read or written. If the adjust causes the
* point to fall outside the bounds of the internal data then the value
* is clamped to either the start of end of the array.
*
* @param offset the offset in bits from the start of the array of bytes.
*/
public void adjustPointer(int offset)
{
ptr += offset;
if (ptr < 0)
ptr = 0;
else if (ptr >= end)
ptr = end;
}
/**
* Moves the internal pointer forward so it is aligned on a byte boundary.
* All word values read and written to the internal buffer must be
* byte-aligned.
*/
public void alignToByte()
{
ptr = (ptr+7) & ~7;
}
/**
* Returns true of the internal pointer is at the end of the buffer.
*
* @return true if the pointer is at the end of the buffer, false otherwise.
*/
public boolean eof()
{
return ptr >= end;
}
/*
* Core methods for readig and writing bits and multibyte words
*/
/**
* Read a bit field from the internal buffer.
*
* If a buffer overflow would occur then the bits which would cause the
* error when read will be set to zero.
*
* @param numberOfBits the number of bits to read.
*
* @param signed a boolean flag indicating whether the value read should
* be sign extended.
*
* @return the value read.
*/
public int readBits(int numberOfBits, boolean signed)
{
int value = 0;
if (numberOfBits < 0 || numberOfBits > 32)
throw new IllegalArgumentException("Number of bits must be in the range 1..32.");
if (numberOfBits == 0)
return 0;
int index = ptr >> 3;
int base = (data.length - index > 4) ? 0 : (4 - (data.length - index))*8;
for (int i=32; i>base; i-=8, index++)
value |= (data[index] & 0x000000FF) << (i-8);
value <<= ptr % 8;
if (signed)
value >>= 32 - numberOfBits;
else
value >>>= 32 - numberOfBits;
ptr += numberOfBits;
if (ptr > (data.length << 3))
ptr = data.length << 3;
return value;
}
/**
* Write a bit value to the internal buffer. The buffer will resize
* automatically if required.
*
* @param value an integer containing the value to be written.
* @param numberOfBits the least significant n bits from the value that
* will be written to the buffer.
*/
public void writeBits(int value, int numberOfBits)
{
if (numberOfBits < 0 || numberOfBits > 32)
throw new IllegalArgumentException("Number of bits must be in the range 1..32.");
if (ptr+32 > end)
addCapacity(data.length/2+4);
int index = ptr >> 3;
value <<= (32 - numberOfBits);
value = value >>> (ptr % 8);
value = value | (data[index] << 24);
for (int i=24; i>=0; i-=8, index++)
data[index] = (byte)(value >>> i);
ptr += numberOfBits;
if (ptr > (data.length << 3))
ptr = data.length << 3;
}
/**
* Read a word from the internal buffer.
*
* If a buffer overflow would occur then the bytes which would cause the
* error when read will be set to zero.
*
* @param numberOfBytes the number of bytes read in the range 1..4.
*
* @param signed a boolean flag indicating whether the value read should be
* sign extended.
*
* @return the value read.
*/
public int readWord(int numberOfBytes, boolean signed)
{
int value = 0;
if (numberOfBytes < 0 || numberOfBytes > 4)
throw new IllegalArgumentException("Number of bytes must be in the range 1..4.");
int index = ptr >> 3;
if (index + numberOfBytes > data.length)
numberOfBytes = data.length - index;
int numberOfBits = numberOfBytes*8;
if (byteOrder == LITTLE_ENDIAN)
{
for (int i=0; i<numberOfBits; i+=8, ptr+=8, index++)
value += (data[index] & 0x000000FF) << i;
}
else
{
for (int i=0; i<numberOfBits; i+=8, ptr+=8, index++)
{
value = value << 8;
value += data[index] & 0x000000FF;
}
}
if (signed)
{
value <<= 32 - numberOfBits;
value >>= 32 - numberOfBits;
}
return value;
}
/**
* Write a word to the internal buffer. The buffer will resize automatically
* if required.
*
* @param value an integer containing the value to be written.
* @param numberOfBytes the least significant n bytes from the value that
* will be written to the buffer.
*/
public void writeWord(int value, int numberOfBytes)
{
if (numberOfBytes < 0 || numberOfBytes > 4)
throw new IllegalArgumentException("Number of bytes must be in the range 1..4.");
int numberOfBits = numberOfBytes*8;
if (ptr+numberOfBits > end)
addCapacity(data.length/2+numberOfBytes);
if (byteOrder == LITTLE_ENDIAN)
{
int index = ptr >>> 3;
for (int i=0; i<numberOfBits; i+=8, ptr+=8, value >>>= 8, index++)
data[index] = (byte)value;
}
else
{
int index = (ptr + numberOfBits - 8) >>> 3;
for (int i=0; i<numberOfBits; i+=8, ptr+=8, value >>>= 8, index--)
data[index] = (byte)value;
}
}
/**
* Reads an array of bytes from the internal buffer. If a read overflow
* would occur while reading the internal buffer then the remaining bytes
* in the array will not be filled. The method returns the number of bytes
* read.
*
* @param bytes the array that will contain the bytes read.
* @return the number of bytes read from the buffer.
*/
public int readBytes(byte[] bytes)
{
int bytesRead = 0;
if (bytes == null || bytes.length == 0)
return bytesRead;
int index = ptr >>> 3;
int numberOfBytes = bytes.length;
if (index + numberOfBytes > data.length)
numberOfBytes = data.length - index;
for (int i=0; i<numberOfBytes; i++, ptr+=8, index++, bytesRead++)
bytes[i] = data[index];
return bytesRead;
}
/**
* Writes an array of bytes from the internal buffer. The internal buffer
* will be resized automatically if required.
*
* @param bytes the array containing the data to be written.
* @return the number of bytes written to the buffer.
*/
public int writeBytes(byte[] bytes)
{
int bytesWritten = 0;
if (ptr+(bytes.length << 3) > end)
addCapacity(data.length/2+bytes.length);
if (bytes == null || bytes.length == 0)
return bytesWritten;
int index = ptr >>> 3;
int numberOfBytes = bytes.length;
for (int i=0; i<numberOfBytes; i++, ptr+=8, index++, bytesWritten++)
data[index] = bytes[i];
return bytesWritten;
}
/*
* Methods to lookahead at the data without reading.
*/
/**
* Read a bit field without adjusting the internal pointer.
*
* @param numberOfBits the number of bits to read.
*
* @param signed a boolean flag indicating whether the value read should
* be sign extended.
*
* @return the value read.
*/
public int scanBits(int numberOfBits, boolean signed)
{
int start = ptr;
int value = readBits(numberOfBits, signed);
ptr = start;
return value;
}
/**
* Read a word without adjusting the internal pointer.
*
* @param numberOfBytes the number of bytes to read.
*
* @param signed a boolean flag indicating whether the value read should
* be sign extended.
*
* @return the value read.
*/
public int scanWord(int numberOfBytes, boolean signed)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -