mirror of https://github.com/axmolengine/axmol.git
Preferred use byte_buffer as APIs
This commit is contained in:
parent
1fcb6abfc2
commit
4065b90039
|
@ -436,7 +436,6 @@ bool ParticleSystem::initWithDictionary(const ValueMap& dictionary)
|
||||||
bool ParticleSystem::initWithDictionary(const ValueMap& dictionary, std::string_view dirname)
|
bool ParticleSystem::initWithDictionary(const ValueMap& dictionary, std::string_view dirname)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
unsigned char* buffer = nullptr;
|
|
||||||
Image* image = nullptr;
|
Image* image = nullptr;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -635,20 +634,18 @@ bool ParticleSystem::initWithDictionary(const ValueMap& dictionary, std::string_
|
||||||
if (dataLen != 0)
|
if (dataLen != 0)
|
||||||
{
|
{
|
||||||
// if it fails, try to get it from the base64-gzipped data
|
// if it fails, try to get it from the base64-gzipped data
|
||||||
int decodeLen =
|
yasio::byte_buffer buffer = utils::base64Decode(textureData);
|
||||||
utils::base64Decode((unsigned char*)textureData.c_str(), (unsigned int)dataLen, &buffer);
|
AXASSERT(!buffer.empty(), "CCParticleSystem: error decoding textureImageData");
|
||||||
AXASSERT(buffer != nullptr, "CCParticleSystem: error decoding textureImageData");
|
AX_BREAK_IF(buffer.empty());
|
||||||
AX_BREAK_IF(!buffer);
|
|
||||||
|
|
||||||
unsigned char* deflated = nullptr;
|
auto deflated = ZipUtils::decompressGZ(std::span{buffer});
|
||||||
ssize_t deflatedLen = ZipUtils::inflateMemory(buffer, decodeLen, &deflated);
|
AXASSERT(!deflated.empty(), "CCParticleSystem: error ungzipping textureImageData");
|
||||||
AXASSERT(deflated != nullptr, "CCParticleSystem: error ungzipping textureImageData");
|
AX_BREAK_IF(deflated.empty());
|
||||||
AX_BREAK_IF(!deflated);
|
|
||||||
|
|
||||||
// For android, we should retain it in VolatileTexture::addImage which invoked in
|
// For android, we should retain it in VolatileTexture::addImage which invoked in
|
||||||
// Director::getInstance()->getTextureCache()->addUIImage()
|
// Director::getInstance()->getTextureCache()->addUIImage()
|
||||||
image = new Image();
|
image = new Image();
|
||||||
bool isOK = image->initWithImageData(deflated, deflatedLen, true);
|
bool isOK = image->initWithImageData(deflated.release_pointer(), deflated.size(), true);
|
||||||
AXASSERT(isOK, "CCParticleSystem: error init image with Data");
|
AXASSERT(isOK, "CCParticleSystem: error init image with Data");
|
||||||
AX_BREAK_IF(!isOK);
|
AX_BREAK_IF(!isOK);
|
||||||
|
|
||||||
|
@ -666,7 +663,6 @@ bool ParticleSystem::initWithDictionary(const ValueMap& dictionary, std::string_
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
} while (0);
|
} while (0);
|
||||||
free(buffer);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -446,11 +446,8 @@ void TMXMapInfo::startElement(void* /*ctx*/, const char* name, const char** atts
|
||||||
Vec2 layerSize = layer->_layerSize;
|
Vec2 layerSize = layer->_layerSize;
|
||||||
int tilesAmount = static_cast<int>(layerSize.width * layerSize.height);
|
int tilesAmount = static_cast<int>(layerSize.width * layerSize.height);
|
||||||
|
|
||||||
uint32_t* tiles = (uint32_t*)malloc(tilesAmount * sizeof(uint32_t));
|
layer->_tiles =
|
||||||
// set all value to 0
|
(uint32_t*)axstd::byte_buffer{tilesAmount * sizeof(uint32_t), 0, std::true_type{}}.release_pointer();
|
||||||
memset(tiles, 0, tilesAmount * sizeof(int));
|
|
||||||
|
|
||||||
layer->_tiles = tiles;
|
|
||||||
}
|
}
|
||||||
else if (encoding == "base64")
|
else if (encoding == "base64")
|
||||||
{
|
{
|
||||||
|
@ -690,10 +687,8 @@ void TMXMapInfo::endElement(void* /*ctx*/, const char* name)
|
||||||
TMXLayerInfo* layer = tmxMapInfo->getLayers().back();
|
TMXLayerInfo* layer = tmxMapInfo->getLayers().back();
|
||||||
auto currentString = tmxMapInfo->getCurrentString();
|
auto currentString = tmxMapInfo->getCurrentString();
|
||||||
|
|
||||||
unsigned char* buffer;
|
auto buffer = utils::base64Decode(currentString);
|
||||||
auto len = utils::base64Decode((unsigned char*)currentString.data(), (unsigned int)currentString.length(),
|
if (buffer.empty())
|
||||||
&buffer);
|
|
||||||
if (!buffer)
|
|
||||||
{
|
{
|
||||||
AXLOG("axmol: TiledMap: decode data error");
|
AXLOG("axmol: TiledMap: decode data error");
|
||||||
return;
|
return;
|
||||||
|
@ -701,36 +696,30 @@ void TMXMapInfo::endElement(void* /*ctx*/, const char* name)
|
||||||
|
|
||||||
if (tmxMapInfo->getLayerAttribs() & (TMXLayerAttribGzip | TMXLayerAttribZlib))
|
if (tmxMapInfo->getLayerAttribs() & (TMXLayerAttribGzip | TMXLayerAttribZlib))
|
||||||
{
|
{
|
||||||
unsigned char* deflated = nullptr;
|
|
||||||
Vec2 s = layer->_layerSize;
|
Vec2 s = layer->_layerSize;
|
||||||
// int sizeHint = s.width * s.height * sizeof(uint32_t);
|
// int sizeHint = s.width * s.height * sizeof(uint32_t);
|
||||||
ssize_t sizeHint = s.width * s.height * sizeof(unsigned int);
|
ssize_t sizeHint = s.width * s.height * sizeof(unsigned int);
|
||||||
|
|
||||||
ssize_t AX_UNUSED inflatedLen = ZipUtils::inflateMemoryWithHint(buffer, len, &deflated, sizeHint);
|
buffer = ZipUtils::decompressGZ(std::span{buffer}, sizeHint);
|
||||||
AXASSERT(inflatedLen == sizeHint, "inflatedLen should be equal to sizeHint!");
|
AXASSERT(buffer.size() == sizeHint, "inflatedLen should be equal to sizeHint!");
|
||||||
|
|
||||||
free(buffer);
|
if (buffer.empty())
|
||||||
buffer = nullptr;
|
|
||||||
|
|
||||||
if (!deflated)
|
|
||||||
{
|
{
|
||||||
AXLOG("axmol: TiledMap: inflate data error");
|
AXLOG("axmol: TiledMap: inflate data error");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
layer->_tiles = reinterpret_cast<uint32_t*>(deflated);
|
layer->_tiles = reinterpret_cast<uint32_t*>(buffer.release_pointer());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
layer->_tiles = reinterpret_cast<uint32_t*>(buffer);
|
layer->_tiles = reinterpret_cast<uint32_t*>(buffer.release_pointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
tmxMapInfo->setCurrentString("");
|
tmxMapInfo->setCurrentString("");
|
||||||
}
|
}
|
||||||
else if (tmxMapInfo->getLayerAttribs() & TMXLayerAttribCSV)
|
else if (tmxMapInfo->getLayerAttribs() & TMXLayerAttribCSV)
|
||||||
{
|
{
|
||||||
unsigned char* buffer;
|
|
||||||
|
|
||||||
TMXLayerInfo* layer = tmxMapInfo->getLayers().back();
|
TMXLayerInfo* layer = tmxMapInfo->getLayers().back();
|
||||||
|
|
||||||
tmxMapInfo->setStoringCharacters(false);
|
tmxMapInfo->setStoringCharacters(false);
|
||||||
|
@ -751,14 +740,8 @@ void TMXMapInfo::endElement(void* /*ctx*/, const char* name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 32-bits per gid
|
// 32-bits per gid
|
||||||
buffer = (unsigned char*)malloc(gidTokens.size() * 4);
|
axstd::byte_buffer buffer{gidTokens.size() * 4, std::true_type{}};
|
||||||
if (!buffer)
|
uint32_t* bufferPtr = reinterpret_cast<uint32_t*>(buffer.data());
|
||||||
{
|
|
||||||
AXLOG("axmol: TiledMap: CSV buffer not allocated.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t* bufferPtr = reinterpret_cast<uint32_t*>(buffer);
|
|
||||||
for (const auto& gidToken : gidTokens)
|
for (const auto& gidToken : gidTokens)
|
||||||
{
|
{
|
||||||
auto tileGid = (uint32_t)strtoul(gidToken.c_str(), nullptr, 10);
|
auto tileGid = (uint32_t)strtoul(gidToken.c_str(), nullptr, 10);
|
||||||
|
@ -766,7 +749,7 @@ void TMXMapInfo::endElement(void* /*ctx*/, const char* name)
|
||||||
bufferPtr++;
|
bufferPtr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
layer->_tiles = reinterpret_cast<uint32_t*>(buffer);
|
layer->_tiles = reinterpret_cast<uint32_t*>(buffer.release_pointer());
|
||||||
|
|
||||||
tmxMapInfo->setCurrentString("");
|
tmxMapInfo->setCurrentString("");
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,24 +31,19 @@ NS_AX_BEGIN
|
||||||
|
|
||||||
const Data Data::Null;
|
const Data Data::Null;
|
||||||
|
|
||||||
Data::Data() : _bytes(nullptr), _size(0)
|
Data::Data()
|
||||||
{
|
{
|
||||||
AXLOGINFO("In the empty constructor of Data.");
|
AXLOGINFO("In the empty constructor of Data.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Data::Data(Data&& other) : _bytes(nullptr), _size(0)
|
Data::Data(Data&& other) : _impl(std::move(other))
|
||||||
{
|
{
|
||||||
AXLOGINFO("In the move constructor of Data.");
|
AXLOGINFO("In the move constructor of Data.");
|
||||||
move(other);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Data::Data(const Data& other) : _bytes(nullptr), _size(0)
|
Data::Data(const Data& other) : _impl(other._impl)
|
||||||
{
|
{
|
||||||
AXLOGINFO("In the copy constructor of Data.");
|
AXLOGINFO("In the copy constructor of Data.");
|
||||||
if (other._bytes && other._size)
|
|
||||||
{
|
|
||||||
copy(other._bytes, other._size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Data::~Data()
|
Data::~Data()
|
||||||
|
@ -62,7 +57,7 @@ Data& Data::operator=(const Data& other)
|
||||||
if (this != &other)
|
if (this != &other)
|
||||||
{
|
{
|
||||||
AXLOGINFO("In the copy assignment of Data.");
|
AXLOGINFO("In the copy assignment of Data.");
|
||||||
copy(other._bytes, other._size);
|
_impl = other._impl;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -79,29 +74,22 @@ Data& Data::operator=(Data&& other)
|
||||||
|
|
||||||
void Data::move(Data& other)
|
void Data::move(Data& other)
|
||||||
{
|
{
|
||||||
if (_bytes != other._bytes)
|
this->_impl = std::move(other._impl);
|
||||||
clear();
|
|
||||||
|
|
||||||
_bytes = other._bytes;
|
|
||||||
_size = other._size;
|
|
||||||
|
|
||||||
other._bytes = nullptr;
|
|
||||||
other._size = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Data::isNull() const
|
bool Data::isNull() const
|
||||||
{
|
{
|
||||||
return (_bytes == nullptr || _size == 0);
|
return _impl.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* Data::getBytes() const
|
uint8_t* Data::getBytes() const
|
||||||
{
|
{
|
||||||
return _bytes;
|
return _impl.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t Data::getSize() const
|
ssize_t Data::getSize() const
|
||||||
{
|
{
|
||||||
return _size;
|
return _impl.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t Data::copy(const unsigned char* bytes, const ssize_t size)
|
ssize_t Data::copy(const unsigned char* bytes, const ssize_t size)
|
||||||
|
@ -109,47 +97,27 @@ ssize_t Data::copy(const unsigned char* bytes, const ssize_t size)
|
||||||
AXASSERT(size >= 0, "copy size should be non-negative");
|
AXASSERT(size >= 0, "copy size should be non-negative");
|
||||||
AXASSERT(bytes, "bytes should not be nullptr");
|
AXASSERT(bytes, "bytes should not be nullptr");
|
||||||
|
|
||||||
if (size <= 0)
|
_impl.assign(bytes, bytes + size);
|
||||||
return 0;
|
return size;
|
||||||
|
|
||||||
if (bytes != _bytes)
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
_bytes = (unsigned char*)malloc(sizeof(unsigned char) * size);
|
|
||||||
memcpy(_bytes, bytes, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
_size = size;
|
|
||||||
return _size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* Data::resize(ssize_t size)
|
uint8_t* Data::resize(ssize_t size)
|
||||||
{
|
{
|
||||||
if (_size < size)
|
_impl.resize_fit(size);
|
||||||
{
|
return this->data();
|
||||||
auto newmb = (uint8_t*)realloc(_bytes, size);
|
|
||||||
if (!newmb)
|
|
||||||
return _bytes;
|
|
||||||
_bytes = newmb;
|
|
||||||
}
|
|
||||||
_size = size;
|
|
||||||
return _bytes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Data::fastSet(uint8_t* bytes, const ssize_t size)
|
void Data::fastSet(uint8_t* bytes, const ssize_t size)
|
||||||
{
|
{
|
||||||
AXASSERT(size >= 0, "fastSet size should be non-negative");
|
AXASSERT(size >= 0, "fastSet size should be non-negative");
|
||||||
// AXASSERT(bytes, "bytes should not be nullptr");
|
// AXASSERT(bytes, "bytes should not be nullptr");
|
||||||
_bytes = bytes;
|
_impl.attach(bytes, size);
|
||||||
_size = size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Data::clear()
|
void Data::clear()
|
||||||
{
|
{
|
||||||
if (_bytes)
|
_impl.clear();
|
||||||
free(_bytes);
|
_impl.shrink_to_fit();
|
||||||
_bytes = nullptr;
|
|
||||||
_size = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* Data::takeBuffer(ssize_t* size)
|
uint8_t* Data::takeBuffer(ssize_t* size)
|
||||||
|
@ -157,8 +125,7 @@ uint8_t* Data::takeBuffer(ssize_t* size)
|
||||||
auto buffer = getBytes();
|
auto buffer = getBytes();
|
||||||
if (size)
|
if (size)
|
||||||
*size = getSize();
|
*size = getSize();
|
||||||
fastSet(nullptr, 0);
|
return _impl.release_pointer();
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_AX_END
|
NS_AX_END
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <stdint.h> // for ssize_t on android
|
#include <stdint.h> // for ssize_t on android
|
||||||
#include <string> // for ssize_t on linux
|
#include <string> // for ssize_t on linux
|
||||||
#include "platform/StdC.h" // for ssize_t on window
|
#include "platform/StdC.h" // for ssize_t on window
|
||||||
|
#include "base/axstd.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @addtogroup base
|
* @addtogroup base
|
||||||
|
@ -47,8 +48,11 @@ public:
|
||||||
|
|
||||||
/* stl compatible */
|
/* stl compatible */
|
||||||
using value_type = uint8_t;
|
using value_type = uint8_t;
|
||||||
size_t size() const { return _size; }
|
size_t size() const { return _impl.size(); }
|
||||||
uint8_t* data() const { return _bytes; }
|
const uint8_t* data() const { return _impl.data(); }
|
||||||
|
uint8_t* data() { return _impl.data(); }
|
||||||
|
|
||||||
|
operator yasio::byte_buffer&(){ return _impl; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This parameter is defined for convenient reference if a null Data object is needed.
|
* This parameter is defined for convenient reference if a null Data object is needed.
|
||||||
|
@ -155,9 +159,7 @@ public:
|
||||||
private:
|
private:
|
||||||
void move(Data& other);
|
void move(Data& other);
|
||||||
|
|
||||||
private:
|
mutable axstd::byte_buffer _impl;
|
||||||
uint8_t* _bytes;
|
|
||||||
ssize_t _size;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_AX_END
|
NS_AX_END
|
||||||
|
|
|
@ -427,7 +427,7 @@ signed char Properties::readChar()
|
||||||
{
|
{
|
||||||
if (eof())
|
if (eof())
|
||||||
return EOF;
|
return EOF;
|
||||||
return _data->_bytes[(*_dataIdx)++];
|
return static_cast<axstd::byte_buffer&>(*_data)[(*_dataIdx)++];
|
||||||
}
|
}
|
||||||
|
|
||||||
char* Properties::readLine(char* output, int num)
|
char* Properties::readLine(char* output, int num)
|
||||||
|
@ -439,9 +439,9 @@ char* Properties::readLine(char* output, int num)
|
||||||
const ssize_t dataIdx = *_dataIdx;
|
const ssize_t dataIdx = *_dataIdx;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < num && dataIdx + i < _data->_size; i++)
|
for (i = 0; i < num && dataIdx + i < _data->size(); i++)
|
||||||
{
|
{
|
||||||
auto c = _data->_bytes[dataIdx + i];
|
auto c = static_cast<axstd::byte_buffer&>(*_data)[dataIdx + i];
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
break;
|
break;
|
||||||
output[i] = c;
|
output[i] = c;
|
||||||
|
@ -464,7 +464,7 @@ bool Properties::seekFromCurrent(int offset)
|
||||||
|
|
||||||
bool Properties::eof()
|
bool Properties::eof()
|
||||||
{
|
{
|
||||||
return (*_dataIdx >= _data->_size);
|
return (*_dataIdx >= _data->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Properties::skipWhiteSpace()
|
void Properties::skipWhiteSpace()
|
||||||
|
|
|
@ -791,9 +791,9 @@ std::string urlDecode(std::string_view st)
|
||||||
return decoded;
|
return decoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
AX_DLL std::string base64Encode(std::string_view s)
|
AX_DLL std::string base64Encode(std::span<uint8_t> s)
|
||||||
{
|
{
|
||||||
size_t n = ax::base64::encoded_size(s.length());
|
size_t n = ax::base64::encoded_size(s.size());
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
{
|
{
|
||||||
std::string ret;
|
std::string ret;
|
||||||
|
@ -809,7 +809,7 @@ AX_DLL std::string base64Encode(std::string_view s)
|
||||||
ret.resize_and_overwrite(n, [&](char* p, size_t) { return ax::base64::encode(p, s.data(), s.length()); });
|
ret.resize_and_overwrite(n, [&](char* p, size_t) { return ax::base64::encode(p, s.data(), s.length()); });
|
||||||
#else
|
#else
|
||||||
ret.resize(n);
|
ret.resize(n);
|
||||||
ret.resize(ax::base64::encode(&ret.front(), s.data(), s.length()));
|
ret.resize(ax::base64::encode(&ret.front(), s.data(), s.size()));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -817,23 +817,16 @@ AX_DLL std::string base64Encode(std::string_view s)
|
||||||
return std::string{};
|
return std::string{};
|
||||||
}
|
}
|
||||||
|
|
||||||
AX_DLL std::string base64Decode(std::string_view s)
|
AX_DLL yasio::byte_buffer base64Decode(std::string_view s)
|
||||||
{
|
{
|
||||||
size_t n = ax::base64::decoded_size(s.length());
|
size_t n = ax::base64::decoded_size(s.length());
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
{
|
{
|
||||||
std::string ret;
|
axstd::byte_buffer ret{n, std::true_type{}};
|
||||||
|
ret.resize_fit(ax::base64::decode(&ret.front(), s.data(), s.size()));
|
||||||
#if _AX_HAS_CXX23
|
|
||||||
ret.resize_and_overwrite(n, [&](char* p, size_t) { return ax::base64::decode(p, s.data(), s.length()); });
|
|
||||||
#else
|
|
||||||
ret.resize(n);
|
|
||||||
ret.resize(ax::base64::decode(&ret.front(), s.data(), s.length()));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return std::string{};
|
return yasio::byte_buffer{};
|
||||||
}
|
}
|
||||||
|
|
||||||
int base64Encode(const unsigned char* in, unsigned int inLength, char** out)
|
int base64Encode(const unsigned char* in, unsigned int inLength, char** out)
|
||||||
|
|
|
@ -37,6 +37,7 @@ THE SOFTWARE.
|
||||||
#include "renderer/backend/Types.h"
|
#include "renderer/backend/Types.h"
|
||||||
#include "math/Mat4.h"
|
#include "math/Mat4.h"
|
||||||
#include "math/Mat3.h"
|
#include "math/Mat3.h"
|
||||||
|
#include "base/axstd.h"
|
||||||
|
|
||||||
/** @file ccUtils.h
|
/** @file ccUtils.h
|
||||||
Misc free functions
|
Misc free functions
|
||||||
|
@ -412,7 +413,7 @@ AX_DLL std::string urlDecode(std::string_view st);
|
||||||
*
|
*
|
||||||
@since axmol-1.0.0
|
@since axmol-1.0.0
|
||||||
*/
|
*/
|
||||||
AX_DLL std::string base64Encode(std::string_view s);
|
AX_DLL std::string base64Encode(std::span<uint8_t> s);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes a 64base encoded buffer
|
* Decodes a 64base encoded buffer
|
||||||
|
@ -420,7 +421,7 @@ AX_DLL std::string base64Encode(std::string_view s);
|
||||||
*
|
*
|
||||||
@since axmol-1.0.0
|
@since axmol-1.0.0
|
||||||
*/
|
*/
|
||||||
AX_DLL std::string base64Decode(std::string_view s);
|
AX_DLL yasio::byte_buffer base64Decode(std::string_view s);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encodes bytes into a 64base encoded memory with terminating '\0' character.
|
* Encodes bytes into a 64base encoded memory with terminating '\0' character.
|
||||||
|
|
|
@ -175,7 +175,22 @@ _L_end:
|
||||||
inflateEnd(&d_stream);
|
inflateEnd(&d_stream);
|
||||||
if (err != Z_STREAM_END)
|
if (err != Z_STREAM_END)
|
||||||
{
|
{
|
||||||
|
switch (err)
|
||||||
|
{
|
||||||
|
case Z_MEM_ERROR:
|
||||||
|
AXLOG("axmol: ZipUtils: Out of memory while decompressing map data!");
|
||||||
|
break;
|
||||||
|
case Z_VERSION_ERROR:
|
||||||
|
AXLOG("axmol: ZipUtils: Incompatible zlib version!");
|
||||||
|
break;
|
||||||
|
case Z_DATA_ERROR:
|
||||||
|
AXLOG("axmol: ZipUtils: Incorrect zlib compressed data!");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
AXLOG("axmol: ZipUtils: Unknown error while decompressing map data!");
|
||||||
|
}
|
||||||
output.clear();
|
output.clear();
|
||||||
|
output.shrink_to_fit();
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
@ -273,112 +288,13 @@ inline unsigned int ZipUtils::checksumPvr(const unsigned int* data, ssize_t len)
|
||||||
return cs;
|
return cs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// memory in iPhone is precious
|
|
||||||
// Should buffer factor be 1.5 instead of 2 ?
|
|
||||||
#define BUFFER_INC_FACTOR (2)
|
|
||||||
|
|
||||||
int ZipUtils::inflateMemoryWithHint(unsigned char* in,
|
|
||||||
ssize_t inLength,
|
|
||||||
unsigned char** out,
|
|
||||||
ssize_t* outLength,
|
|
||||||
ssize_t outLengthHint)
|
|
||||||
{
|
|
||||||
/* ret value */
|
|
||||||
int err = Z_OK;
|
|
||||||
|
|
||||||
ssize_t bufferSize = outLengthHint;
|
|
||||||
*out = (unsigned char*)malloc(bufferSize);
|
|
||||||
|
|
||||||
z_stream d_stream; /* decompression stream */
|
|
||||||
d_stream.zalloc = (alloc_func)0;
|
|
||||||
d_stream.zfree = (free_func)0;
|
|
||||||
d_stream.opaque = (voidpf)0;
|
|
||||||
|
|
||||||
d_stream.next_in = in;
|
|
||||||
d_stream.avail_in = static_cast<unsigned int>(inLength);
|
|
||||||
d_stream.next_out = *out;
|
|
||||||
d_stream.avail_out = static_cast<unsigned int>(bufferSize);
|
|
||||||
|
|
||||||
/* window size to hold 256k */
|
|
||||||
if ((err = inflateInit2(&d_stream, 15 + 32)) != Z_OK)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
err = inflate(&d_stream, Z_NO_FLUSH);
|
|
||||||
|
|
||||||
if (err == Z_STREAM_END)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (err)
|
|
||||||
{
|
|
||||||
case Z_NEED_DICT:
|
|
||||||
err = Z_DATA_ERROR;
|
|
||||||
case Z_DATA_ERROR:
|
|
||||||
case Z_MEM_ERROR:
|
|
||||||
inflateEnd(&d_stream);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not enough memory ?
|
|
||||||
if (err != Z_STREAM_END)
|
|
||||||
{
|
|
||||||
*out = (unsigned char*)realloc(*out, bufferSize * BUFFER_INC_FACTOR);
|
|
||||||
|
|
||||||
/* not enough memory, ouch */
|
|
||||||
if (!*out)
|
|
||||||
{
|
|
||||||
AXLOG("axmol: ZipUtils: realloc failed");
|
|
||||||
inflateEnd(&d_stream);
|
|
||||||
return Z_MEM_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
d_stream.next_out = *out + bufferSize;
|
|
||||||
d_stream.avail_out = static_cast<unsigned int>(bufferSize);
|
|
||||||
bufferSize *= BUFFER_INC_FACTOR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*outLength = bufferSize - d_stream.avail_out;
|
|
||||||
err = inflateEnd(&d_stream);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssize_t ZipUtils::inflateMemoryWithHint(unsigned char* in, ssize_t inLength, unsigned char** out, ssize_t outLengthHint)
|
ssize_t ZipUtils::inflateMemoryWithHint(unsigned char* in, ssize_t inLength, unsigned char** out, ssize_t outLengthHint)
|
||||||
{
|
{
|
||||||
ssize_t outLength = 0;
|
auto outBuffer = decompressGZ(std::span{in, in + inLength}, static_cast<int>(outLengthHint));
|
||||||
int err = inflateMemoryWithHint(in, inLength, out, &outLength, outLengthHint);
|
auto outLen = outBuffer.size();
|
||||||
|
if (out)
|
||||||
if (err != Z_OK || *out == nullptr)
|
*out = outBuffer.release_pointer();
|
||||||
{
|
return outLen;
|
||||||
if (err == Z_MEM_ERROR)
|
|
||||||
{
|
|
||||||
AXLOG("axmol: ZipUtils: Out of memory while decompressing map data!");
|
|
||||||
}
|
|
||||||
else if (err == Z_VERSION_ERROR)
|
|
||||||
{
|
|
||||||
AXLOG("axmol: ZipUtils: Incompatible zlib version!");
|
|
||||||
}
|
|
||||||
else if (err == Z_DATA_ERROR)
|
|
||||||
{
|
|
||||||
AXLOG("axmol: ZipUtils: Incorrect zlib compressed data!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AXLOG("axmol: ZipUtils: Unknown error while decompressing map data!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*out)
|
|
||||||
{
|
|
||||||
free(*out);
|
|
||||||
*out = nullptr;
|
|
||||||
}
|
|
||||||
outLength = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return outLength;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t ZipUtils::inflateMemory(unsigned char* in, ssize_t inLength, unsigned char** out)
|
ssize_t ZipUtils::inflateMemory(unsigned char* in, ssize_t inLength, unsigned char** out)
|
||||||
|
@ -403,24 +319,16 @@ int ZipUtils::inflateGZipFile(const char* path, unsigned char** out)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 512k initial decompress buffer */
|
/* 512k initial decompress buffer */
|
||||||
unsigned int bufferSize = 512 * 1024;
|
yasio::byte_buffer buffer{512};
|
||||||
unsigned int totalBufferSize = bufferSize;
|
|
||||||
|
|
||||||
*out = (unsigned char*)malloc(bufferSize);
|
uint8_t readBuffer[512];
|
||||||
if (*out == NULL)
|
|
||||||
{
|
|
||||||
AXLOG("axmol: ZipUtils: out of memory");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
len = gzread(inFile, *out + offset, bufferSize);
|
len = gzread(inFile, readBuffer, sizeof(readBuffer));
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
{
|
{
|
||||||
AXLOG("axmol: ZipUtils: error in gzread");
|
AXLOG("axmol: ZipUtils: error in gzread");
|
||||||
free(*out);
|
|
||||||
*out = nullptr;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
|
@ -428,27 +336,7 @@ int ZipUtils::inflateGZipFile(const char* path, unsigned char** out)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += len;
|
buffer.append(readBuffer, readBuffer + 512);
|
||||||
|
|
||||||
// finish reading the file
|
|
||||||
if ((unsigned int)len < bufferSize)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
bufferSize *= BUFFER_INC_FACTOR;
|
|
||||||
totalBufferSize += bufferSize;
|
|
||||||
unsigned char* tmp = (unsigned char*)realloc(*out, totalBufferSize);
|
|
||||||
|
|
||||||
if (!tmp)
|
|
||||||
{
|
|
||||||
AXLOG("axmol: ZipUtils: out of memory");
|
|
||||||
free(*out);
|
|
||||||
*out = nullptr;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*out = tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gzclose(inFile) != Z_OK)
|
if (gzclose(inFile) != Z_OK)
|
||||||
|
@ -456,7 +344,11 @@ int ZipUtils::inflateGZipFile(const char* path, unsigned char** out)
|
||||||
AXLOG("axmol: ZipUtils: gzclose failed");
|
AXLOG("axmol: ZipUtils: gzclose failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
return offset;
|
|
||||||
|
auto totalSize = buffer.size();
|
||||||
|
if (out)
|
||||||
|
*out = buffer.release_pointer();
|
||||||
|
return totalSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZipUtils::isCCZFile(const char* path)
|
bool ZipUtils::isCCZFile(const char* path)
|
||||||
|
@ -576,26 +468,24 @@ int ZipUtils::inflateCCZBuffer(const unsigned char* buffer, ssize_t bufferLen, u
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int len = AX_SWAP_INT32_BIG_TO_HOST(header->len);
|
unsigned int len = AX_SWAP_INT32_BIG_TO_HOST(header->len);
|
||||||
|
if (!len)
|
||||||
*out = (unsigned char*)malloc(len);
|
|
||||||
if (!*out)
|
|
||||||
{
|
{
|
||||||
AXLOG("axmol: CCZ: Failed to allocate memory for texture");
|
AXLOG("axmol: CCZ: Failed to allocate memory for texture");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
axstd::byte_buffer outBuffer{len, std::true_type{}};
|
||||||
|
|
||||||
unsigned long destlen = len;
|
unsigned long destlen = len;
|
||||||
size_t source = (size_t)buffer + sizeof(*header);
|
size_t source = (size_t)buffer + sizeof(*header);
|
||||||
int ret = uncompress(*out, &destlen, (Bytef*)source, static_cast<uLong>(bufferLen - sizeof(*header)));
|
int ret = uncompress(outBuffer.data(), &destlen, (Bytef*)source, static_cast<uLong>(bufferLen - sizeof(*header)));
|
||||||
|
|
||||||
if (ret != Z_OK)
|
if (ret != Z_OK)
|
||||||
{
|
{
|
||||||
AXLOG("axmol: CCZ: Failed to uncompress data");
|
AXLOG("axmol: CCZ: Failed to uncompress data");
|
||||||
free(*out);
|
|
||||||
*out = nullptr;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
*out = outBuffer.release_pointer();
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <span>
|
||||||
#include "pod_vector.h"
|
#include "pod_vector.h"
|
||||||
|
#include "yasio/byte_buffer.hpp"
|
||||||
|
|
||||||
// Tests whether compiler has c++23 support
|
// Tests whether compiler has c++23 support
|
||||||
#if (defined(__cplusplus) && __cplusplus > 202002L) || \
|
#if (defined(__cplusplus) && __cplusplus > 202002L) || \
|
||||||
|
@ -19,6 +21,9 @@
|
||||||
|
|
||||||
namespace axstd
|
namespace axstd
|
||||||
{
|
{
|
||||||
|
using byte_buffer = yasio::byte_buffer;
|
||||||
|
using sbyte_buffer = yasio::sbyte_buffer;
|
||||||
|
|
||||||
/* make_unique_for_overwrite since c++20, but not all platformm support */
|
/* make_unique_for_overwrite since c++20, but not all platformm support */
|
||||||
template <class _Ty, std::enable_if_t<!std::is_array_v<_Ty>, int> = 0>
|
template <class _Ty, std::enable_if_t<!std::is_array_v<_Ty>, int> = 0>
|
||||||
inline std::unique_ptr<_Ty> make_unique_for_overwrite()
|
inline std::unique_ptr<_Ty> make_unique_for_overwrite()
|
||||||
|
|
|
@ -216,9 +216,9 @@ static std::string getUriStringFromArgs(ArgType* args)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string getDataURI(std::string_view data, std::string_view mime_type)
|
static std::string getDataURI(const ax::Data& data, std::string_view mime_type)
|
||||||
{
|
{
|
||||||
auto encodedData = utils::base64Encode(data);
|
auto encodedData = utils::base64Encode(std::span{data.getBytes(), data.getBytes() + data.getSize()});
|
||||||
return std::string{"data:"}.append(mime_type).append(";base64,").append(utils::urlEncode(encodedData));
|
return std::string{"data:"}.append(mime_type).append(";base64,").append(utils::urlEncode(encodedData));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -669,9 +669,7 @@ void WebViewImpl::loadData(const Data& data,
|
||||||
{
|
{
|
||||||
if (_createSucceeded)
|
if (_createSucceeded)
|
||||||
{
|
{
|
||||||
const std::string dataString(reinterpret_cast<char*>(data.getBytes()),
|
const auto url = getDataURI(data, MIMEType);
|
||||||
static_cast<unsigned int>(data.getSize()));
|
|
||||||
const auto url = getDataURI(dataString, MIMEType);
|
|
||||||
_systemWebControl->loadURL(url, false);
|
_systemWebControl->loadURL(url, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,7 @@ public:
|
||||||
for (auto& data : _pageDatas)
|
for (auto& data : _pageDatas)
|
||||||
{
|
{
|
||||||
auto compData = ZipUtils::compressGZ(std::span{data});
|
auto compData = ZipUtils::compressGZ(std::span{data});
|
||||||
auto pixels = utils::base64Encode(std::string_view{reinterpret_cast<const char*>(compData.data()), compData.size()});
|
auto pixels = utils::base64Encode(std::span{compData});
|
||||||
pages.push_back(std::move(pixels));
|
pages.push_back(std::move(pixels));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue