libragephoto: add custom parser feature

- RagePhoto: add addParser()
- RagePhotoC: add ragephoto_addparser()
- RagePhoto(C): rename all ragePhotoData to rp_data
This commit is contained in:
Syping 2023-02-20 11:27:14 +01:00
parent 659feb0cbf
commit 2a8070b75e
3 changed files with 117 additions and 58 deletions

View file

@ -129,6 +129,10 @@ RagePhoto::RagePhoto()
if (!m_data)
throw std::runtime_error("RagePhotoData data struct can't be allocated");
std::memset(m_data, 0, sizeof(RagePhotoData));
m_parser = static_cast<RagePhotoFormatParser*>(std::malloc(sizeof(RagePhotoFormatParser)));
if (!m_parser)
throw std::runtime_error("RagePhotoFormatParser parser struct can't be allocated");
std::memset(m_parser, 0, sizeof(RagePhotoFormatParser));
setBufferDefault();
}
@ -140,6 +144,24 @@ RagePhoto::~RagePhoto()
std::free(m_data->header);
std::free(m_data->title);
std::free(m_data);
std::free(m_parser);
}
void RagePhoto::addParser(RagePhotoFormatParser *rp_parser)
{
if (rp_parser) {
RagePhotoFormatParser n_parser[1]{};
if (!std::memcmp(&n_parser[0], rp_parser, sizeof(RagePhotoFormatParser)))
return;
size_t length;
for (length = 0; std::memcmp(&n_parser[0], &m_parser[length], sizeof(RagePhotoFormatParser)); length++);
RagePhotoFormatParser *t_parser = static_cast<RagePhotoFormatParser*>(std::realloc(m_parser, (length + 2 * sizeof(RagePhotoFormatParser))));
if (!t_parser)
throw std::runtime_error("RagePhotoFormatParser array can't be expanded");
m_parser = t_parser;
std::memcpy(&m_parser[length], rp_parser, sizeof(RagePhotoFormatParser));
std::memset(&m_parser[length+1], 0, sizeof(RagePhotoFormatParser));
}
}
void RagePhoto::clear()
@ -521,6 +543,14 @@ bool RagePhoto::load(const char *data, size_t length)
return false;
#endif
}
else if (m_parser) {
RagePhotoFormatParser n_parser[1]{};
for (size_t i = 0; std::memcmp(&n_parser[0], &m_parser[i], sizeof(RagePhotoFormatParser)); i++) {
if (m_data->photoFormat == m_parser[i].photoFormat)
if (m_parser[i].funcLoad)
return (m_parser[i].funcLoad)(m_data, data, length);
}
}
m_data->error = Error::IncompatibleFormat; // 2
return false;
}
@ -813,6 +843,14 @@ bool RagePhoto::save(char *data, uint32_t photoFormat)
return false;
#endif
}
else if (m_parser) {
RagePhotoFormatParser n_parser[1]{};
for (size_t i = 0; std::memcmp(&n_parser[0], &m_parser[i], sizeof(RagePhotoFormatParser)); i++) {
if (photoFormat == m_parser[i].photoFormat)
if (m_parser[i].funcSave)
return (m_parser[i].funcSave)(m_data, data, photoFormat);
}
}
m_data->error = Error::IncompatibleFormat; // 2
return false;
@ -868,24 +906,31 @@ bool RagePhoto::saveFile(const std::string &filename)
return saveFile(filename, m_data->photoFormat);
}
inline size_t RagePhoto::saveSize(RagePhotoData *ragePhotoData, uint32_t photoFormat)
inline size_t RagePhoto::saveSize(RagePhotoData *rp_data, RagePhotoFormatParser *rp_parser, uint32_t photoFormat)
{
if (photoFormat == PhotoFormat::GTA5)
return (ragePhotoData->jpegBuffer + ragePhotoData->jsonBuffer + ragePhotoData->titlBuffer + ragePhotoData->descBuffer + GTA5_HEADERSIZE + 56UL);
return (rp_data->jpegBuffer + rp_data->jsonBuffer + rp_data->titlBuffer + rp_data->descBuffer + GTA5_HEADERSIZE + 56UL);
else if (photoFormat == PhotoFormat::RDR2)
return (ragePhotoData->jpegBuffer + ragePhotoData->jsonBuffer + ragePhotoData->titlBuffer + ragePhotoData->descBuffer + RDR2_HEADERSIZE + 56UL);
else
return (rp_data->jpegBuffer + rp_data->jsonBuffer + rp_data->titlBuffer + rp_data->descBuffer + RDR2_HEADERSIZE + 56UL);
else if (rp_parser) {
RagePhotoFormatParser n_parser[1]{};
for (size_t i = 0; std::memcmp(&n_parser[0], &rp_parser[i], sizeof(RagePhotoFormatParser)); i++) {
if (photoFormat == rp_parser[i].photoFormat)
if (rp_parser[i].funcSaveSz)
return (rp_parser[i].funcSaveSz)(rp_data, photoFormat);
}
}
return 0;
}
inline size_t RagePhoto::saveSize(RagePhotoData *ragePhotoData)
inline size_t RagePhoto::saveSize(RagePhotoData *rp_data, RagePhotoFormatParser *rp_parser)
{
return saveSize(ragePhotoData, ragePhotoData->photoFormat);
return saveSize(rp_data, rp_parser, rp_data->photoFormat);
}
inline size_t RagePhoto::saveSize(uint32_t photoFormat)
{
return saveSize(m_data, photoFormat);
return saveSize(m_data, m_parser, photoFormat);
}
inline size_t RagePhoto::saveSize()
@ -898,12 +943,12 @@ inline void RagePhoto::setBufferDefault()
setBufferDefault(m_data);
}
inline void RagePhoto::setBufferDefault(RagePhotoData *ragePhotoData)
inline void RagePhoto::setBufferDefault(RagePhotoData *rp_data)
{
ragePhotoData->descBuffer = DEFAULT_DESCBUFFER;
ragePhotoData->jsonBuffer = DEFAULT_JSONBUFFER;
ragePhotoData->titlBuffer = DEFAULT_TITLBUFFER;
setBufferOffsets(ragePhotoData);
rp_data->descBuffer = DEFAULT_DESCBUFFER;
rp_data->jsonBuffer = DEFAULT_JSONBUFFER;
rp_data->titlBuffer = DEFAULT_TITLBUFFER;
setBufferOffsets(rp_data);
}
inline void RagePhoto::setBufferOffsets()
@ -911,17 +956,17 @@ inline void RagePhoto::setBufferOffsets()
setBufferOffsets(m_data);
}
inline void RagePhoto::setBufferOffsets(RagePhotoData *ragePhotoData)
inline void RagePhoto::setBufferOffsets(RagePhotoData *rp_data)
{
ragePhotoData->jsonOffset = ragePhotoData->jpegBuffer + 28;
ragePhotoData->titlOffset = ragePhotoData->jsonOffset + ragePhotoData->jsonBuffer + 8;
ragePhotoData->descOffset = ragePhotoData->titlOffset + ragePhotoData->titlBuffer + 8;
ragePhotoData->endOfFile = ragePhotoData->descOffset + ragePhotoData->descBuffer + 12;
rp_data->jsonOffset = rp_data->jpegBuffer + 28;
rp_data->titlOffset = rp_data->jsonOffset + rp_data->jsonBuffer + 8;
rp_data->descOffset = rp_data->titlOffset + rp_data->titlBuffer + 8;
rp_data->endOfFile = rp_data->descOffset + rp_data->descBuffer + 12;
}
bool RagePhoto::setData(RagePhotoData *ragePhotoData, bool takeOwnership)
bool RagePhoto::setData(RagePhotoData *rp_data, bool takeOwnership)
{
if (m_data == ragePhotoData)
if (m_data == rp_data)
return true;
if (takeOwnership) {
@ -932,60 +977,60 @@ bool RagePhoto::setData(RagePhotoData *ragePhotoData, bool takeOwnership)
std::free(m_data->title);
std::free(m_data);
m_data = ragePhotoData;
m_data = rp_data;
}
else {
clear();
m_data->photoFormat = ragePhotoData->photoFormat;
m_data->photoFormat = rp_data->photoFormat;
if (ragePhotoData->header) {
const size_t headerSize = strlen(ragePhotoData->header) + 1;
if (rp_data->header) {
const size_t headerSize = strlen(rp_data->header) + 1;
m_data->header = static_cast<char*>(std::malloc(headerSize));
if (!m_data->header)
return false;
std::memcpy(m_data->header, ragePhotoData->header, headerSize);
m_data->headerSum = ragePhotoData->headerSum;
std::memcpy(m_data->header, rp_data->header, headerSize);
m_data->headerSum = rp_data->headerSum;
}
if (ragePhotoData->jpeg) {
m_data->jpeg = static_cast<char*>(std::malloc(ragePhotoData->jpegSize));
if (rp_data->jpeg) {
m_data->jpeg = static_cast<char*>(std::malloc(rp_data->jpegSize));
if (!m_data->jpeg)
return false;
std::memcpy(m_data->jpeg, ragePhotoData->jpeg, ragePhotoData->jpegSize);
m_data->jpegSize = ragePhotoData->jpegSize;
m_data->jpegBuffer = ragePhotoData->jpegBuffer;
std::memcpy(m_data->jpeg, rp_data->jpeg, rp_data->jpegSize);
m_data->jpegSize = rp_data->jpegSize;
m_data->jpegBuffer = rp_data->jpegBuffer;
}
if (ragePhotoData->json) {
const size_t jsonSize = strlen(ragePhotoData->json) + 1;
if (rp_data->json) {
const size_t jsonSize = strlen(rp_data->json) + 1;
m_data->json = static_cast<char*>(std::malloc(jsonSize));
if (!m_data->json)
return false;
std::memcpy(m_data->json, ragePhotoData->json, jsonSize);
m_data->jsonBuffer = ragePhotoData->jsonBuffer;
std::memcpy(m_data->json, rp_data->json, jsonSize);
m_data->jsonBuffer = rp_data->jsonBuffer;
}
if (ragePhotoData->title) {
const size_t titleSize = strlen(ragePhotoData->title) + 1;
if (rp_data->title) {
const size_t titleSize = strlen(rp_data->title) + 1;
m_data->title = static_cast<char*>(std::malloc(titleSize));
if (!m_data->title)
return false;
std::memcpy(m_data->title, ragePhotoData->title, titleSize);
m_data->titlBuffer = ragePhotoData->titlBuffer;
std::memcpy(m_data->title, rp_data->title, titleSize);
m_data->titlBuffer = rp_data->titlBuffer;
}
if (ragePhotoData->description) {
const size_t descriptionSize = strlen(ragePhotoData->description) + 1;
if (rp_data->description) {
const size_t descriptionSize = strlen(rp_data->description) + 1;
m_data->description = static_cast<char*>(std::malloc(descriptionSize));
if (!m_data->description)
return false;
std::memcpy(m_data->description, ragePhotoData->description, descriptionSize);
m_data->descBuffer = ragePhotoData->descBuffer;
std::memcpy(m_data->description, rp_data->description, descriptionSize);
m_data->descBuffer = rp_data->descBuffer;
}
m_data->unnamedSum1 = ragePhotoData->unnamedSum1;
m_data->unnamedSum2 = ragePhotoData->unnamedSum2;
m_data->unnamedSum1 = rp_data->unnamedSum1;
m_data->unnamedSum2 = rp_data->unnamedSum2;
setBufferOffsets();
}
@ -1104,6 +1149,12 @@ ragephoto_t ragephoto_open()
return static_cast<ragephoto_t>(new RagePhoto);
}
void ragephoto_addparser(ragephoto_t instance, RagePhotoFormatParser *rp_parser)
{
RagePhoto *ragePhoto = static_cast<RagePhoto*>(instance);
ragePhoto->addParser(rp_parser);
}
void ragephoto_clear(ragephoto_t instance)
{
RagePhoto *ragePhoto = static_cast<RagePhoto*>(instance);
@ -1244,16 +1295,16 @@ void ragephoto_setbufferoffsets(ragephoto_t instance)
ragePhoto->setBufferOffsets();
}
ragephoto_bool_t ragephoto_setphotodata(ragephoto_t instance, RagePhotoData *ragePhotoData)
ragephoto_bool_t ragephoto_setphotodata(ragephoto_t instance, RagePhotoData *rp_data)
{
RagePhoto *ragePhoto = static_cast<RagePhoto*>(instance);
return ragePhoto->setData(ragePhotoData, true);
return ragePhoto->setData(rp_data, true);
}
ragephoto_bool_t ragephoto_setphotodatac(ragephoto_t instance, RagePhotoData *ragePhotoData)
ragephoto_bool_t ragephoto_setphotodatac(ragephoto_t instance, RagePhotoData *rp_data)
{
RagePhoto *ragePhoto = static_cast<RagePhoto*>(instance);
return ragePhoto->setData(ragePhotoData, false);
return ragePhoto->setData(rp_data, false);
}
void ragephoto_setphotodesc(ragephoto_t instance, const char *description, uint32_t bufferSize)

View file

@ -94,6 +94,7 @@ public:
};
RagePhoto();
~RagePhoto();
void addParser(RagePhotoFormatParser *rp_parser); /**< Add a custom defined RagePhotoFormatParser. */
void clear(); /**< Resets the RagePhoto instance to default values. */
RagePhotoData* data(); /**< Returns the internal RagePhotoData object. */
/** Loads a Photo from a const char*.
@ -139,15 +140,15 @@ public:
const std::string save(bool *ok = nullptr);
bool saveFile(const std::string &filename, uint32_t photoFormat); /**< Saves a Photo to a file. */
bool saveFile(const std::string &filename); /**< Saves a Photo to a file. */
static size_t saveSize(RagePhotoData *ragePhotoData, uint32_t photoFormat); /**< Returns the Photo save file size. */
static size_t saveSize(RagePhotoData *ragePhotoData); /**< Returns the Photo save file size. */
static size_t saveSize(RagePhotoData *rp_data, RagePhotoFormatParser *rp_parser, uint32_t photoFormat); /**< Returns the Photo save file size. */
static size_t saveSize(RagePhotoData *rp_data, RagePhotoFormatParser *rp_parser); /**< Returns the Photo save file size. */
size_t saveSize(uint32_t photoFormat); /**< Returns the Photo save file size. */
size_t saveSize(); /**< Returns the Photo save file size. */
void setBufferDefault(); /**< Sets all cross-format Buffer to default size. */
static void setBufferDefault(RagePhotoData *ragePhotoData); /**< Sets all cross-format Buffer to default size. */
static void setBufferDefault(RagePhotoData *rp_data); /**< Sets all cross-format Buffer to default size. */
void setBufferOffsets(); /**< Moves all Buffer offsets to correct position. */
static void setBufferOffsets(RagePhotoData *ragePhotoData); /**< Moves all Buffer offsets to correct position. */
bool setData(RagePhotoData *ragePhotoData, bool takeOwnership = true); /**< Sets the internal RagePhotoData object. */
static void setBufferOffsets(RagePhotoData *rp_data); /**< Moves all Buffer offsets to correct position. */
bool setData(RagePhotoData *rp_data, bool takeOwnership = true); /**< Sets the internal RagePhotoData object. */
void setDescription(const char *description, uint32_t bufferSize = 0); /**< Sets the Photo description. */
void setFormat(uint32_t photoFormat); /**< Sets the Photo Format (GTA V or RDR 2). */
void setJson(const char *json, uint32_t bufferSize = 0); /**< Sets the Photo JSON data. */
@ -167,6 +168,7 @@ public:
private:
RagePhotoData *m_data;
RagePhotoFormatParser *m_parser;
};
#else
#include "RagePhotoC.h"

View file

@ -39,6 +39,12 @@ typedef void* ragephoto_t;
/** Opens a \p ragephoto_t instance. */
LIBRAGEPHOTO_C_BINDING ragephoto_t ragephoto_open();
/** Add a custom defined RagePhotoFormatParser.
* \param instance \p ragephoto_t instance
* \param rp_parser RagePhotoFormatParser parser to add
*/
LIBRAGEPHOTO_C_BINDING void ragephoto_addparser(ragephoto_t instance, RagePhotoFormatParser *rp_parser);
/** Resets the \p ragephoto_t instance to default values.
* \param instance \p ragephoto_t instance
*/
@ -163,15 +169,15 @@ LIBRAGEPHOTO_C_BINDING void ragephoto_setbufferoffsets(ragephoto_t instance);
/** Sets the internal RagePhotoData object.
* \param instance \p ragephoto_t instance
* \param ragePhotoData RagePhotoData object being set
* \param rp_data RagePhotoData object being set
*/
LIBRAGEPHOTO_C_BINDING ragephoto_bool_t ragephoto_setphotodata(ragephoto_t instance, RagePhotoData *ragePhotoData);
LIBRAGEPHOTO_C_BINDING ragephoto_bool_t ragephoto_setphotodata(ragephoto_t instance, RagePhotoData *rp_data);
/** Copies RagePhotoData object to internal RagePhotoData object.
* \param instance \p ragephoto_t instance
* \param ragePhotoData RagePhotoData object being copied
* \param rp_data RagePhotoData object being copied
*/
LIBRAGEPHOTO_C_BINDING ragephoto_bool_t ragephoto_setphotodatac(ragephoto_t instance, RagePhotoData *ragePhotoData);
LIBRAGEPHOTO_C_BINDING ragephoto_bool_t ragephoto_setphotodatac(ragephoto_t instance, RagePhotoData *rp_data);
/** Sets the Photo description.
* \param instance \p ragephoto_t instance