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

View file

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

View file

@ -39,6 +39,12 @@ typedef void* ragephoto_t;
/** Opens a \p ragephoto_t instance. */ /** Opens a \p ragephoto_t instance. */
LIBRAGEPHOTO_C_BINDING ragephoto_t ragephoto_open(); 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. /** Resets the \p ragephoto_t instance to default values.
* \param instance \p ragephoto_t instance * \param instance \p ragephoto_t instance
*/ */
@ -163,15 +169,15 @@ LIBRAGEPHOTO_C_BINDING void ragephoto_setbufferoffsets(ragephoto_t instance);
/** Sets the internal RagePhotoData object. /** Sets the internal RagePhotoData object.
* \param instance \p ragephoto_t instance * \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. /** Copies RagePhotoData object to internal RagePhotoData object.
* \param instance \p ragephoto_t instance * \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. /** Sets the Photo description.
* \param instance \p ragephoto_t instance * \param instance \p ragephoto_t instance