From 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 24 Sep 2024 14:54:57 +0200 Subject: Initial community commit --- Src/replicant/nsapev2/nsapev2_common.cpp | 465 +++++++++++++++++++++++++++++++ 1 file changed, 465 insertions(+) create mode 100644 Src/replicant/nsapev2/nsapev2_common.cpp (limited to 'Src/replicant/nsapev2/nsapev2_common.cpp') diff --git a/Src/replicant/nsapev2/nsapev2_common.cpp b/Src/replicant/nsapev2/nsapev2_common.cpp new file mode 100644 index 00000000..badcb100 --- /dev/null +++ b/Src/replicant/nsapev2/nsapev2_common.cpp @@ -0,0 +1,465 @@ +#include "nsapev2.h" +#include "nsapev2/header.h" +#include "nsapev2/tag.h" +#include + +int NSAPEv2_Header_Valid(const void *header_data) + +{ + if (APEv2::Header(header_data).Valid()) + return NErr_Success; + else + return NErr_False; +} + +int NSAPEv2_Header_Create(nsapev2_header_t *header, const void *header_data, size_t header_len) +{ + if (header_len < 10 || NSAPEv2_Header_Valid(header_data) != NErr_Success) + return NErr_Error; + + nsapev2_header_t new_header = (nsapev2_header_t)new (std::nothrow) APEv2::Header(header_data); + if (!new_header) + return NErr_OutOfMemory; + *header = new_header; + return NErr_Success; +} + +int NSAPEv2_Header_TagSize(const nsapev2_header_t h, uint32_t *tag_size) +{ + const APEv2::Header *header = (const APEv2::Header *)h; + if (!header) + return NErr_NullPointer; + + *tag_size = header->TagSize(); + return NErr_Success; +} + +int NSAPEv2_Header_HasHeader(nsapev2_header_t h) +{ + const APEv2::Header *header = (const APEv2::Header *)h; + if (!header) + return NErr_NullPointer; + + if (header->HasHeader()) + return NErr_Success; + else + return NErr_False; +} + +int NSAPEv2_Header_Destroy(nsapev2_header_t h) +{ + const APEv2::Header *header = (const APEv2::Header *)h; + if (!header) + return NErr_NullPointer; + + delete header; + return NErr_Success; +} + +int NSAPEv2_Tag_Create(nsapev2_tag_t *t, const nsapev2_header_t h, const void *bytes, size_t bytes_len) +{ + const APEv2::Header *header = (const APEv2::Header *)h; + if (!header) + return NErr_NullPointer; + + APEv2::Tag *tag = new (std::nothrow) APEv2::Tag; + if (!tag) + return NErr_OutOfMemory; + + int ret = tag->Parse(header, bytes, bytes_len); + if (ret != NErr_Success) + { + delete tag; + return ret; + } + + *t = (nsapev2_tag_t)tag; + return ret; +} + +int NSAPEv2_Tag_New(nsapev2_tag_t *t) +{ + APEv2::Header *new_header = new (std::nothrow) APEv2::Header(); + if (!new_header) + return NErr_OutOfMemory; + + APEv2::Tag *tag = new (std::nothrow) APEv2::Tag; + if (!tag) + { + delete new_header; + return NErr_OutOfMemory; + } + + *t = (nsapev2_tag_t)tag; + return NErr_Success; +} + +int NSAPEv2_Tag_SerializedSize(const nsapev2_tag_t t, size_t *bytes) +{ + const APEv2::Tag *tag = (const APEv2::Tag *)t; + if (!tag) + return NErr_BadParameter; + + *bytes = tag->EncodeSize(); + return NErr_Success; +} + +int NSAPEv2_Tag_Serialize(const nsapev2_tag_t t, void *data, size_t bytes) +{ + const APEv2::Tag *tag = (const APEv2::Tag *)t; + if (!tag) + return NErr_BadParameter; + + return tag->Encode(data, bytes); +} + +int NSAPEv2_Tag_Destroy(nsapev2_tag_t t) +{ + APEv2::Tag *tag = (APEv2::Tag *)t; + if (!tag) + return NErr_NullPointer; + delete tag; + return NErr_Success; +} + +int NSAPEv2_Tag_GetFlags(nsapev2_tag_t t, uint32_t *flags) +{ + APEv2::Tag *tag = (APEv2::Tag *)t; + if (!tag) + return NErr_BadParameter; + + return tag->GetFlags(flags); +} + +int NSAPEv2_Tag_SetFlags(nsapev2_tag_t t, uint32_t flags, uint32_t mask) +{ + APEv2::Tag *tag = (APEv2::Tag *)t; + if (!tag) + return NErr_BadParameter; + + return tag->SetFlags(flags, mask); +} + +int NSAPEv2_Tag_GetString(const nsapev2_tag_t t, const char *key, unsigned int index, nx_string_t *value) +{ + const APEv2::Tag *tag = (const APEv2::Tag *)t; + if (!tag) + return NErr_Empty; + + const void *data; + size_t data_len; + int ret = tag->GetData(key, index, &data, &data_len); + if (ret != NErr_Success) + return ret; + + return NXStringCreateWithBytes(value, data, data_len, nx_charset_utf8); +} + +int NSAPEv2_Tag_SetString(nsapev2_tag_t t, const char *key, unsigned int index, nx_string_t value) +{ + APEv2::Tag *tag = (APEv2::Tag *)t; + if (!tag) + return NErr_BadParameter; + + if (value) + { + APEv2::Item *item; + int ret = tag->GetItem(key, index, &item); + if (ret == NErr_Success) + { + return item->Set(value); + } + else + { + /* no such item, need to make a new one */ + item = new (std::nothrow) APEv2::Item; + if (!item) + return NErr_OutOfMemory; + + ret = item->SetKey(key); + if (ret != NErr_Success) + { + delete item; + return ret; + } + + ret = item->Set(value); + if (ret != NErr_Success) + { + delete item; + return ret; + } + + ret = tag->AddItem(item); + if (ret != NErr_Success) + { + delete item; + return ret; + } + + return NErr_Success; + } + } + else + { + tag->Remove(key, index); + return NErr_Success; + } +} + +int NSAPEv2_Tag_GetBinary(const nsapev2_tag_t t, const char *key, unsigned int index, const void **bytes, size_t *length) +{ + const APEv2::Tag *tag = (const APEv2::Tag *)t; + if (!tag) + return NErr_Empty; + + return tag->GetData(key, index, bytes, length); +} + +int NSAPEv2_Tag_SetBinary(nsapev2_tag_t t, const char *key, unsigned int index, const void *bytes, size_t length) +{ + APEv2::Tag *tag = (APEv2::Tag *)t; + if (!tag) + return NErr_BadParameter; + + if (bytes) + { + APEv2::Item *item; + int ret = tag->GetItem(key, index, &item); + if (ret == NErr_Success) + { + return item->Set(bytes, length, nsapev2_item_type_binary); + } + else + { + /* no such item, need to make a new one */ + item = new (std::nothrow) APEv2::Item; + if (!item) + return NErr_OutOfMemory; + + ret = item->SetKey(key); + if (ret != NErr_Success) + { + delete item; + return ret; + } + + ret = item->Set(bytes, length, nsapev2_item_type_binary); + if (ret != NErr_Success) + { + delete item; + return ret; + } + + ret = tag->AddItem(item); + if (ret != NErr_Success) + { + delete item; + return ret; + } + + return NErr_Success; + } + } + else + { + tag->Remove(key, index); + return NErr_Success; + } +} + +static int SetArtwork(APEv2::Item *item, const char *filename, const void *bytes, size_t length) +{ + + size_t filename_length = filename?strlen(filename):0; + size_t total_length = filename_length + + 1 /* null separator */ + + length; + + void *item_data; + int ret = item->New(total_length, nsapev2_item_type_binary, &item_data); + if (ret != NErr_Success) + return ret; + + bytewriter_s byte_writer; + bytewriter_init(&byte_writer, item_data, total_length); + bytewriter_write_n(&byte_writer, filename, filename_length); + bytewriter_write_u8(&byte_writer, 0); + bytewriter_write_n(&byte_writer, bytes, length); + + return NErr_Success; +} + +int NSAPEv2_Tag_SetArtwork(nsapev2_tag_t t, const char *key, unsigned int index, const char *filename, const void *bytes, size_t length) +{ + APEv2::Tag *tag = (APEv2::Tag *)t; + if (!tag) + return NErr_BadParameter; + + if (bytes) + { + + APEv2::Item *item; + int ret = tag->GetItem(key, index, &item); + if (ret == NErr_Success) + { + return SetArtwork(item, filename, bytes, length); + } + else + { + /* no such item, need to make a new one */ + item = new (std::nothrow) APEv2::Item; + if (!item) + return NErr_OutOfMemory; + + ret = item->SetKey(key); + if (ret != NErr_Success) + { + delete item; + return ret; + } + + ret = SetArtwork(item, filename, bytes, length); + if (ret != NErr_Success) + { + delete item; + return ret; + } + + ret = tag->AddItem(item); + if (ret != NErr_Success) + { + delete item; + return ret; + } + + return NErr_Success; + } + } + else + { + tag->Remove(key, index); + return NErr_Success; + } +} + +int NSAPEv2_Tag_EnumerateItems(const nsapev2_tag_t t, const nsapev2_item_t s, nsapev2_item_t *next) +{ + const APEv2::Tag *tag = (const APEv2::Tag *)t; + if (!tag) + return NErr_NullPointer; + + const APEv2::Item *start = (const APEv2::Item *)s; + return tag->EnumerateItems(start, (APEv2::Item **)next); +} + +int NSAPEv2_Tag_GetItemCount(const nsapev2_tag_t t, size_t *count) +{ + const APEv2::Tag *tag = (const APEv2::Tag *)t; + if (!tag) + return NErr_NullPointer; + + return tag->GetItemCount(count); +} + + +int NSAPEv2_Tag_GetItemAtIndex(const nsapev2_tag_t t, unsigned int index, nsapev2_item_t *item) +{ + APEv2::Tag *tag = (APEv2::Tag *)t; + if (!tag) + return NErr_NullPointer; + + return tag->GetItemAtIndex(index, (APEv2::Item **)item); +} + +int NSAPEv2_Item_GetInformation(const nsapev2_item_t i, const char **key, uint32_t *flags) +{ + const APEv2::Item *item = (const APEv2::Item *)i; + if (!item) + return NErr_NullPointer; + + if (key) + { + int ret = item->GetKey(key); + if (ret != NErr_Success) + return ret; + } + + if (flags) + *flags = item->GetFlags(); + return NErr_Success; + +} + +int NSAPEv2_Item_GetString(const nsapev2_item_t i, nx_string_t *value) +{ + const APEv2::Item *item = (const APEv2::Item *)i; + if (!item) + return NErr_BadParameter; + + const void *data; + size_t data_len; + int ret = item->Get(&data, &data_len); + if (ret != NErr_Success) + return ret; + + return NXStringCreateWithBytes(value, data, data_len, nx_charset_utf8); +} + +int NSAPEv2_Item_GetBinary(const nsapev2_item_t i, const void **bytes, size_t *length) +{ + const APEv2::Item *item = (const APEv2::Item *)i; + if (!item) + return NErr_BadParameter; + + return item->Get(bytes, length); +} + +int NSAPEv2_Item_SetKey(nsapev2_item_t i, const char *key) +{ + APEv2::Item *item = (APEv2::Item *)i; + if (!item) + return NErr_BadParameter; + + return item->SetKey(key); +} + +int NSAPEv2_Item_SetString(nsapev2_item_t i, nx_string_t value) +{ + APEv2::Item *item = (APEv2::Item *)i; + if (!item) + return NErr_BadParameter; + + return item->Set(value); +} + +int NSAPEv2_Tag_RemoveItem(nsapev2_tag_t t, nsapev2_item_t i) +{ + APEv2::Tag *tag = (APEv2::Tag *)t; + if (!tag) + return NErr_BadParameter; + + APEv2::Item *item = (APEv2::Item *)i; + if (!item) + return NErr_BadParameter; + + tag->RemoveItem(item); + return NErr_Success; +} + +int NSAPEv2_Tag_AddItem(nsapev2_tag_t t, nsapev2_item_t *i) +{ + APEv2::Tag *tag = (APEv2::Tag *)t; + if (!tag) + return NErr_BadParameter; + + APEv2::Item **item = (APEv2::Item **)i; + if (!item) + return NErr_NullPointer; + + *item = new (std::nothrow) APEv2::Item; + if (!*item) + return NErr_OutOfMemory; + + return tag->AddItem(*item); +} \ No newline at end of file -- cgit