axmol/extensions/fairygui/utils/ByteBuffer.cpp

229 lines
4.8 KiB
C++
Raw Normal View History

2020-08-04 12:31:33 +08:00
#include "ByteBuffer.h"
NS_FGUI_BEGIN
using namespace std;
ByteBuffer::ByteBuffer(char* buffer, int offset, int len, bool transferOwnerShip = false)
: _buffer(buffer),
_position(0),
_offset(offset),
_length(len),
_littleEndian(false),
_ownsBuffer(transferOwnerShip),
_stringTable(nullptr),
version(0)
{
}
ByteBuffer::~ByteBuffer()
{
if (_ownsBuffer && _buffer != nullptr)
delete _buffer;
}
int ByteBuffer::getBytesAvailable() const
{
return _length - _position;
}
char ByteBuffer::readByte()
{
signed char val = _buffer[_offset + _position];
if (val > 127)
val = val - 255;
_position += 1;
return val;
}
unsigned char ByteBuffer::readUbyte()
{
unsigned char val = _buffer[_offset + _position];
_position += 1;
return val;
}
bool ByteBuffer::readBool()
{
return readByte() == 1;
}
short ByteBuffer::readShort()
{
int startIndex = _offset + _position;
_position += 2;
unsigned char* pbyte = (unsigned char*)(_buffer + startIndex);
if (_littleEndian)
return (short)((*pbyte) | (*(pbyte + 1) << 8));
else
return (short)((*pbyte << 8) | (*(pbyte + 1)));
}
unsigned short ByteBuffer::readUshort()
{
return (unsigned short)readShort();
}
int ByteBuffer::readInt()
{
int startIndex = _offset + _position;
_position += 4;
unsigned char* pbyte = (unsigned char*)(_buffer + startIndex);
if (_littleEndian)
return (*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24);
else
return (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3));
}
unsigned int ByteBuffer::readUint()
{
return (unsigned int)readInt();
}
float ByteBuffer::readFloat()
{
int val = readInt();
return *(float*)&val;
}
std::string ByteBuffer::readString()
{
int len = readUshort();
return readString(len);
}
std::string ByteBuffer::readString(int len)
{
char* value = new char[len + 1];
value[len] = '\0';
memcpy(value, _buffer + _position, len);
_position += len;
string str(value);
delete[] value;
value = nullptr;
return str;
}
const std::string& ByteBuffer::readS()
{
int index = readUshort();
if (index == 65534 || index == 65533)
return cocos2d::STD_STRING_EMPTY;
else
return (*_stringTable)[index];
}
bool ByteBuffer::readS(std::string& result)
{
int index = readUshort();
if (index == 65534) //null
return false;
else if (index == 65533)
{
result.clear();
return true;
}
else
{
result = (*_stringTable)[index];
return true;
}
}
const string* ByteBuffer::readSP()
{
int index = readUshort();
if (index == 65534) //null
return nullptr;
else if (index == 65533)
return &cocos2d::STD_STRING_EMPTY;
else
return &(*_stringTable)[index];
}
void ByteBuffer::readSArray(std::vector<std::string>& arr, int count)
{
for (int i = 0; i < count; i++)
arr.push_back(readS());
}
void ByteBuffer::writeS(const std::string& value)
{
int index = readUshort();
if (index != 65534 && index != 65533)
(*_stringTable)[index] = value;
}
cocos2d::Color4B ByteBuffer::readColor()
{
int startIndex = _offset + _position;
#if COCOS2D_VERSION >= 0x00040000
uint8_t r = _buffer[startIndex];
uint8_t g = _buffer[startIndex + 1];
uint8_t b = _buffer[startIndex + 2];
uint8_t a = _buffer[startIndex + 3];
#else
GLubyte r = _buffer[startIndex];
GLubyte g = _buffer[startIndex + 1];
GLubyte b = _buffer[startIndex + 2];
GLubyte a = _buffer[startIndex + 3];
#endif
_position += 4;
return cocos2d::Color4B(r, g, b, a);
}
ByteBuffer* ByteBuffer::readBuffer()
{
int count = readInt();
char* p = (char*)malloc(count);
memcpy(p, _buffer + _position, count);
ByteBuffer* ba = new ByteBuffer(p, 0, count, true);
ba->_stringTable = _stringTable;
ba->version = version;
_position += count;
return ba;
}
bool ByteBuffer::seek(int indexTablePos, int blockIndex)
{
int tmp = _position;
_position = indexTablePos;
int segCount = _buffer[_offset + _position++];
if (blockIndex < segCount)
{
bool useShort = _buffer[_offset + _position++] == 1;
int newPos;
if (useShort)
{
_position += 2 * blockIndex;
newPos = readShort();
}
else
{
_position += 4 * blockIndex;
newPos = readInt();
}
if (newPos > 0)
{
_position = indexTablePos + newPos;
return true;
}
else
{
_position = tmp;
return false;
}
}
else
{
_position = tmp;
return false;
}
}
NS_FGUI_END