aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.World/ByteBuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Minecraft.World/ByteBuffer.cpp')
-rw-r--r--Minecraft.World/ByteBuffer.cpp478
1 files changed, 478 insertions, 0 deletions
diff --git a/Minecraft.World/ByteBuffer.cpp b/Minecraft.World/ByteBuffer.cpp
new file mode 100644
index 00000000..66514737
--- /dev/null
+++ b/Minecraft.World/ByteBuffer.cpp
@@ -0,0 +1,478 @@
+#include "stdafx.h"
+
+#include "IntBuffer.h"
+#include "FloatBuffer.h"
+#include "ByteBuffer.h"
+
+ByteBuffer::ByteBuffer( unsigned int capacity ) : Buffer( capacity )
+{
+ hasBackingArray = false;
+ buffer = new byte[capacity];
+ memset( buffer,0,sizeof(byte)*capacity);
+ byteOrder = BIGENDIAN;
+}
+
+//Allocates a new direct byte buffer.
+//The new buffer's position will be zero, its limit will be its capacity, and its mark will be undefined. Whether or not it has a backing array is unspecified.
+//
+//Parameters:
+//capacity - The new buffer's capacity, in bytes
+//Returns:
+//The new byte buffer
+ByteBuffer *ByteBuffer::allocateDirect(int capacity)
+{
+ return new ByteBuffer(capacity);
+}
+
+
+ByteBuffer::ByteBuffer( unsigned int capacity, byte *backingArray ) : Buffer( capacity )
+{
+ hasBackingArray = true;
+ buffer = backingArray;
+}
+
+ByteBuffer::~ByteBuffer()
+{
+ if( !hasBackingArray )
+ delete[] buffer;
+}
+
+//Wraps a byte array into a buffer.
+//The new buffer will be backed by the given byte array; that is, modifications to the buffer will cause the array
+//to be modified and vice versa. The new buffer's capacity and limit will be array.length, its position will be zero,
+//and its mark will be undefined. Its backing array will be the given array, and its array offset will be zero.
+//
+//Parameters:
+//array - The array that will back this buffer
+//Returns:
+//The new byte buffer
+ByteBuffer *ByteBuffer::wrap(byteArray &b)
+{
+ return new ByteBuffer( b.length, b.data );
+}
+
+//Allocates a new byte buffer.
+//The new buffer's position will be zero, its limit will be its capacity, and its mark will be undefined.
+//It will have a backing array, and its array offset will be zero.
+//
+//Parameters:
+//capacity - The new buffer's capacity, in bytes
+//Returns:
+//The new byte buffer
+ByteBuffer *ByteBuffer::allocate(unsigned int capacity)
+{
+ return new ByteBuffer( capacity );
+}
+
+//Modifies this buffer's byte order.
+//Parameters:
+//bo - The new byte order, either BIGENDIAN or LITTLEENDIAN
+void ByteBuffer::order(ByteOrder bo)
+{
+ byteOrder = bo;
+}
+
+//Flips this buffer. The limit is set to the current position and then the position is set to zero.
+//If the mark is defined then it is discarded.
+//
+//Returns:
+//This buffer
+ByteBuffer *ByteBuffer::flip()
+{
+ m_limit = m_position;
+ m_position = 0;
+ return this;
+}
+
+// 4J Added so we can write this to a file
+byte *ByteBuffer::getBuffer()
+{
+ return buffer;
+}
+
+int ByteBuffer::getSize()
+{
+ // TODO 4J Stu - Should this be the capcity and not the limit?
+ return m_limit;
+}
+// End 4J
+
+//Absolute get method. Reads the byte at the given index.
+//Parameters:
+//index - The index from which the byte will be read
+//Returns:
+//The byte at the given index
+//Throws:
+//IndexOutOfBoundsException - If index is negative or not smaller than the buffer's limit
+BYTE ByteBuffer::get(int index)
+{
+ assert( index < m_limit );
+ assert( index >= 0 );
+
+ return buffer[index];
+}
+
+//Relative get method for reading an int value.
+//Reads the next four bytes at this buffer's current position, composing them into an int value according to the
+//current byte order, and then increments the position by four.
+//
+//Returns:
+//The int value at the buffer's current position
+int ByteBuffer::getInt()
+{
+ assert( m_position+3 < m_limit );
+
+ int value = 0;
+
+ int b1 = buffer[ m_position ];
+ int b2 = buffer[ m_position+1 ];
+ int b3 = buffer[ m_position+2 ];
+ int b4 = buffer[ m_position+3 ];
+
+ m_position += 4;
+
+ if( byteOrder == BIGENDIAN )
+ {
+ value = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
+ }
+ else if( byteOrder == LITTLEENDIAN )
+ {
+ value = b1 | (b2 << 8) | (b3 << 16) | (b4 << 24);
+ }
+ return value;
+}
+
+//Absolute get method for reading an int value.
+//Reads four bytes at the given index, composing them into a int value according to the current byte order.
+//
+//Parameters:
+//index - The index from which the bytes will be read
+//Returns:
+//The int value at the given index
+int ByteBuffer::getInt(unsigned int index)
+{
+ assert( index+3 < m_limit );
+ int value = 0;
+
+ int b1 = buffer[ index ];
+ int b2 = buffer[ index+1 ];
+ int b3 = buffer[ index+2 ];
+ int b4 = buffer[ index+3 ];
+
+ if( byteOrder == BIGENDIAN )
+ {
+ value = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
+ }
+ else if( byteOrder == LITTLEENDIAN )
+ {
+ value = b1 | (b2 << 8) | (b3 << 16) | (b4 << 24);
+ }
+ return value;
+}
+
+//Relative get method for reading a long value.
+//Reads the next eight bytes at this buffer's current position, composing them into a long value according to the current byte order,
+//and then increments the position by eight.
+//
+//Returns:
+//The long value at the buffer's current position
+__int64 ByteBuffer::getLong()
+{
+ assert( m_position+8 < m_limit );
+
+ __int64 value = 0;
+
+ __int64 b1 = buffer[ m_position ];
+ __int64 b2 = buffer[ m_position+1 ];
+ __int64 b3 = buffer[ m_position+2 ];
+ __int64 b4 = buffer[ m_position+3 ];
+ __int64 b5 = buffer[ m_position+4 ];
+ __int64 b6 = buffer[ m_position+5 ];
+ __int64 b7 = buffer[ m_position+6 ];
+ __int64 b8 = buffer[ m_position+7 ];
+
+ m_position += 8;
+
+ if( byteOrder == BIGENDIAN )
+ {
+ value = (b1 << 56) | (b2 << 48) | (b3 << 40) | (b4 << 32) | (b5 << 24) | (b6 << 16) | (b7 << 8) | b8;
+ }
+ else if( byteOrder == LITTLEENDIAN )
+ {
+ value = b1 | (b2 << 8) | (b3 << 16) | (b4 << 24) | (b5 << 32) | (b6 << 40) | (b7 << 48) | (b8 << 56);
+ }
+ return value;
+}
+
+//Relative get method for reading a short value.
+//Reads the next two bytes at this buffer's current position, composing them into a short value according to the current
+//byte order, and then increments the position by two.
+//
+//Returns:
+//The short value at the buffer's current position
+short ByteBuffer::getShort()
+{
+ assert( m_position+1 < m_limit );
+
+ short value = 0;
+
+ short b1 = buffer[ m_position ];
+ short b2 = buffer[ m_position+1 ];
+
+ m_position += 2;
+
+ if( byteOrder == BIGENDIAN )
+ {
+ value = (b1 << 8) | b2;
+ }
+ else if( byteOrder == LITTLEENDIAN )
+ {
+ value = b1 | (b2 << 8);
+ }
+ return value;
+}
+
+void ByteBuffer::getShortArray(shortArray &s)
+{
+ // TODO 4J Stu - Should this function be writing from the start of the buffer, or from position?
+ // And should it update position?
+ assert( s.length >= m_limit/2 );
+
+ // 4J Stu - Assumes big endian
+ memcpy( s.data, buffer, (m_limit-m_position) );
+}
+
+//Absolute put method (optional operation).
+//Writes the given byte into this buffer at the given index.
+//
+//Parameters:
+//index - The index at which the byte will be written
+//b - The byte value to be written
+//Returns:
+//This buffer
+//Throws:
+//IndexOutOfBoundsException - If index is negative or not smaller than the buffer's limit
+//ReadOnlyBufferException - If this buffer is read-only
+ByteBuffer *ByteBuffer::put(int index, byte b)
+{
+ assert( index < m_limit );
+ assert( index >= 0 );
+
+ buffer[index] = b;
+ return this;
+}
+
+
+//Relative put method for writing an int value (optional operation).
+//Writes four bytes containing the given int value, in the current byte order, into this buffer at the current position,
+//and then increments the position by four.
+//
+//Parameters:
+//value - The int value to be written
+//Returns:
+//This buffer
+ByteBuffer *ByteBuffer::putInt(int value)
+{
+ assert( m_position+3 < m_limit );
+
+ if( byteOrder == BIGENDIAN )
+ {
+ buffer[m_position] = (value >> 24) & 0xFF;
+ buffer[m_position+1] = (value >> 16) & 0xFF;
+ buffer[m_position+2] = (value >> 8) & 0xFF;
+ buffer[m_position+3] = value & 0xFF;
+ }
+ else if( byteOrder == LITTLEENDIAN )
+ {
+ buffer[m_position] = value & 0xFF;
+ buffer[m_position+1] = (value >> 8) & 0xFF;
+ buffer[m_position+2] = (value >> 16) & 0xFF;
+ buffer[m_position+3] = (value >> 24) & 0xFF;
+ }
+
+ m_position += 4;
+
+ return this;
+}
+
+//Absolute put method for writing an int value (optional operation).
+//Writes four bytes containing the given int value, in the current byte order, into this buffer at the given index.
+//
+//Parameters:
+//index - The index at which the bytes will be written
+//value - The int value to be written
+//Returns:
+//This buffer
+ByteBuffer *ByteBuffer::putInt(unsigned int index, int value)
+{
+ assert( index+3 < m_limit );
+
+ if( byteOrder == BIGENDIAN )
+ {
+ buffer[index] = (value >> 24) & 0xFF;
+ buffer[index+1] = (value >> 16) & 0xFF;
+ buffer[index+2] = (value >> 8) & 0xFF;
+ buffer[index+3] = value & 0xFF;
+ }
+ else if( byteOrder == LITTLEENDIAN )
+ {
+ buffer[index] = value & 0xFF;
+ buffer[index+1] = (value >> 8) & 0xFF;
+ buffer[index+2] = (value >> 16) & 0xFF;
+ buffer[index+3] = (value >> 24) & 0xFF;
+ }
+
+ return this;
+}
+
+//Relative put method for writing a short value (optional operation).
+//Writes two bytes containing the given short value, in the current byte order, into this buffer at the current position,
+//and then increments the position by two.
+//
+//Parameters:
+//value - The short value to be written
+//Returns:
+//This buffer
+ByteBuffer *ByteBuffer::putShort(short value)
+{
+ assert( m_position+1 < m_limit );
+
+ if( byteOrder == BIGENDIAN )
+ {
+ buffer[m_position] = (value >> 8) & 0xFF;
+ buffer[m_position+1] = value & 0xFF;
+ }
+ else if( byteOrder == LITTLEENDIAN )
+ {
+ buffer[m_position] = value & 0xFF;
+ buffer[m_position+1] = (value >> 8) & 0xFF;
+ }
+
+ m_position += 2;
+
+ return this;
+}
+
+ByteBuffer *ByteBuffer::putShortArray(shortArray &s)
+{
+ // TODO 4J Stu - Should this function be writing from the start of the buffer, or from position?
+ // And should it update position?
+ assert( s.length*2 <= m_limit);
+
+ // 4J Stu - Assumes big endian
+ memcpy( buffer, s.data, s.length*2 );
+
+ return this;
+}
+
+//Relative put method for writing a long value (optional operation).
+//Writes eight bytes containing the given long value, in the current byte order, into this buffer at the current position,
+//and then increments the position by eight.
+//
+//Parameters:
+//value - The long value to be written
+//Returns:
+//This buffer
+ByteBuffer *ByteBuffer::putLong(__int64 value)
+{
+ assert( m_position+7 < m_limit );
+
+ if( byteOrder == BIGENDIAN )
+ {
+ buffer[m_position] = (value >> 56) & 0xFF;
+ buffer[m_position+1] = (value >> 48) & 0xFF;
+ buffer[m_position+2] = (value >> 40) & 0xFF;
+ buffer[m_position+3] = (value >> 32) & 0xFF;
+ buffer[m_position+4] = (value >> 24) & 0xFF;
+ buffer[m_position+5] = (value >> 16) & 0xFF;
+ buffer[m_position+6] = (value >> 8) & 0xFF;
+ buffer[m_position+7] = value & 0xFF;
+ }
+ else if( byteOrder == LITTLEENDIAN )
+ {
+ buffer[m_position] = value & 0xFF;
+ buffer[m_position+1] = (value >> 8) & 0xFF;
+ buffer[m_position+2] = (value >> 16) & 0xFF;
+ buffer[m_position+3] = (value >> 24) & 0xFF;
+ buffer[m_position+4] = (value >> 32) & 0xFF;
+ buffer[m_position+5] = (value >> 40) & 0xFF;
+ buffer[m_position+6] = (value >> 48) & 0xFF;
+ buffer[m_position+7] = (value >> 56) & 0xFF;
+ }
+
+ return this;
+}
+
+//Relative bulk put method (optional operation).
+//This method transfers the entire content of the given source byte array into this buffer.
+//An invocation of this method of the form dst.put(a) behaves in exactly the same way as the invocation
+//
+// dst.put(a, 0, a.length)
+//Returns:
+//This buffer
+ByteBuffer *ByteBuffer::put(byteArray inputArray)
+{
+ if( inputArray.length > remaining() )
+ assert( false ); //TODO 4J Stu - Some kind of exception?
+
+ std::copy( inputArray.data, inputArray.data + inputArray.length, buffer+m_position );
+
+ m_position += inputArray.length;
+
+ return this;
+}
+
+byteArray ByteBuffer::array()
+{
+ return byteArray( buffer, m_capacity );
+}
+
+//Creates a view of this byte buffer as an int buffer.
+//The content of the new buffer will start at this buffer's current position. Changes to this buffer's content
+//will be visible in the new buffer, and vice versa; the two buffers' position, limit, and mark values will be independent.
+//
+//The new buffer's position will be zero, its capacity and its limit will be the number of bytes remaining in this buffer
+//divided by four, and its mark will be undefined. The new buffer will be direct if, and only if, this buffer is direct, and
+//it will be read-only if, and only if, this buffer is read-only.
+//
+//Returns:
+//A new int buffer
+IntBuffer *ByteBuffer::asIntBuffer()
+{
+ // TODO 4J Stu - Is it safe to just cast our byte array pointer to another type?
+ return new IntBuffer( (m_limit-m_position)/4, (int *) (buffer+m_position) );
+}
+
+//Creates a view of this byte buffer as a float buffer.
+//The content of the new buffer will start at this buffer's current position. Changes to this buffer's content will be
+//visible in the new buffer, and vice versa; the two buffers' position, limit, and mark values will be independent.
+//
+//The new buffer's position will be zero, its capacity and its limit will be the number of bytes remaining in this buffer
+//divided by four, and its mark will be undefined. The new buffer will be direct if, and only if, this buffer is direct,
+//and it will be read-only if, and only if, this buffer is read-only.
+//
+//Returns:
+//A new float buffer
+FloatBuffer *ByteBuffer::asFloatBuffer()
+{
+ // TODO 4J Stu - Is it safe to just cast our byte array pointer to another type?
+ return new FloatBuffer( (m_limit-m_position)/4, (float *) (buffer+m_position) );
+}
+
+
+
+#ifdef __PS3__
+// we're using the RSX now to upload textures to vram, so we need th main ram textures allocated from io space
+ByteBuffer_IO::ByteBuffer_IO( unsigned int capacity )
+ : ByteBuffer(capacity, (byte*)RenderManager.allocIOMem(capacity, 64))
+{
+ memset( buffer,0,sizeof(byte)*capacity);
+ byteOrder = BIGENDIAN;
+}
+
+ByteBuffer_IO::~ByteBuffer_IO()
+{
+// delete buffer;
+ RenderManager.freeIOMem(buffer);
+}
+#endif // __PS3__ \ No newline at end of file