Preferred use byte_buffer as APIs

This commit is contained in:
halx99 2023-09-29 01:57:41 +08:00
parent 1fcb6abfc2
commit 4065b90039
11 changed files with 99 additions and 264 deletions

View File

@ -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;
} }

View File

@ -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("");
} }

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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)

View File

@ -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.

View File

@ -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;
} }

View File

@ -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()

View File

@ -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);
} }
} }

View File

@ -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));
} }