diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/replicant/nsid3v2/nsid3v2_common.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/replicant/nsid3v2/nsid3v2_common.cpp')
-rw-r--r-- | Src/replicant/nsid3v2/nsid3v2_common.cpp | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/Src/replicant/nsid3v2/nsid3v2_common.cpp b/Src/replicant/nsid3v2/nsid3v2_common.cpp new file mode 100644 index 00000000..e1e53e5d --- /dev/null +++ b/Src/replicant/nsid3v2/nsid3v2_common.cpp @@ -0,0 +1,366 @@ +#include "nsid3v2/nsid3v2.h" +#include "nsid3v2/header.h" +#include "nsid3v2/tag.h" +#include <string.h> // for memcmp +#include <new> + +int NSID3v2_Header_Valid(const void *header_data) +{ + ID3v2::Header header(header_data); + if (header.Valid()) + return NErr_Success; + else + return NErr_False; +} + +int NSID3v2_Header_FooterValid(const void *footer_data) +{ + ID3v2::Header footer(footer_data); + if (footer.FooterValid()) + return NErr_Success; + else + return NErr_False; +} + +int NSID3v2_Header_Create(nsid3v2_header_t *h, const void *header_data, size_t header_len) +{ + if (header_len < 10) + return NErr_NeedMoreData; + + ID3v2::Header header(header_data); + if (!header.Valid()) + return NErr_Error; + + nsid3v2_header_t new_header = (nsid3v2_header_t)new (std::nothrow) ID3v2::Header(header); + if (!new_header) + return NErr_OutOfMemory; + *h = new_header; + return NErr_Success; +} + +int NSID3v2_Header_New(nsid3v2_header_t *h, uint8_t version, uint8_t revision) +{ + nsid3v2_header_t new_header = (nsid3v2_header_t)new (std::nothrow) ID3v2::Header(version, revision); + if (!new_header) + return NErr_OutOfMemory; + *h = new_header; + return NErr_Success; +} + +int NSID3v2_Header_FooterCreate(nsid3v2_header_t *f, const void *footer_data, size_t footer_len) +{ + if (footer_len < 10) + return NErr_NeedMoreData; + + ID3v2::Header footer(footer_data); + if (!footer.FooterValid()) + return NErr_Error; + + nsid3v2_header_t new_header = (nsid3v2_header_t)new (std::nothrow) ID3v2::Header(footer); + if (!new_header) + return NErr_OutOfMemory; + *f = new_header; + return NErr_Success; +} + +int NSID3v2_Header_TagSize(const nsid3v2_header_t h, uint32_t *tag_size) +{ + const ID3v2::Header *header = (const ID3v2::Header *)h; + if (!header) + return NErr_NullPointer; + + *tag_size = header->TagSize(); + return NErr_Success; +} + +int NSID3v2_Header_HasFooter(const nsid3v2_header_t h) +{ + const ID3v2::Header *header = (const ID3v2::Header *)h; + if (!header) + return NErr_NullPointer; + + if (header->HasFooter()) + return NErr_Success; + else + return NErr_False; +} + +int NSID3v2_Header_Destroy(nsid3v2_header_t h) +{ + const ID3v2::Header *header = (const ID3v2::Header *)h; + if (!header) + return NErr_NullPointer; + + delete header; + return NErr_Success; +} + +/* +================== Tag ================== += = +========================================= +*/ + +int NSID3v2_Tag_Create(nsid3v2_tag_t *t, const nsid3v2_header_t h, const void *bytes, size_t bytes_len) +{ + const ID3v2::Header *header = (const ID3v2::Header *)h; + if (!header) + return NErr_NullPointer; + + switch(header->GetVersion()) + { + case 2: + { + ID3v2_2::Tag *tag = new (std::nothrow) ID3v2_2::Tag(*header); + if (!tag) + return NErr_OutOfMemory; + tag->Parse(bytes, bytes_len); + *t = (nsid3v2_tag_t)tag; + return NErr_Success; + } + case 3: + { + ID3v2_3::Tag *tag = new (std::nothrow) ID3v2_3::Tag(*header); + if (!tag) + return NErr_OutOfMemory; + tag->Parse(bytes, bytes_len); + *t = (nsid3v2_tag_t)tag; + return NErr_Success; + } + case 4: + { + ID3v2_4::Tag *tag = new (std::nothrow) ID3v2_4::Tag(*header); + if (!tag) + return NErr_OutOfMemory; + tag->Parse(bytes, bytes_len); + *t = (nsid3v2_tag_t)tag; + return NErr_Success; + } + default: + return NErr_NotImplemented; + } +} + +int NSID3v2_Tag_Destroy(nsid3v2_tag_t t) +{ + ID3v2::Tag *tag = (ID3v2::Tag *)t; + delete tag; + return NErr_Success; +} + +int NSID3v2_Tag_RemoveFrame(nsid3v2_tag_t t, nsid3v2_frame_t f) +{ + ID3v2::Tag *tag = (ID3v2::Tag *)t; + ID3v2::Frame *frame = (ID3v2::Frame *)f; + tag->RemoveFrame(frame); + return NErr_Success; +} + +int NSID3v2_Tag_CreateFrame(nsid3v2_tag_t t, int frame_enum, int flags, nsid3v2_frame_t *f) +{ + ID3v2::Tag *tag = (ID3v2::Tag *)t; + *f = (nsid3v2_frame_t)tag->NewFrame(frame_enum, flags); + return NErr_Success; +} + +int NSID3v2_Tag_AddFrame(nsid3v2_tag_t t, nsid3v2_frame_t f) +{ + ID3v2::Tag *tag = (ID3v2::Tag *)t; + ID3v2::Frame *frame = (ID3v2::Frame *)f; + tag->AddFrame(frame); + return NErr_Success; +} + +int NSID3v2_Tag_GetFrame(const nsid3v2_tag_t t, int frame_enum, nsid3v2_frame_t *frame) +{ + ID3v2::Tag *tag = (ID3v2::Tag *)t; + ID3v2::Frame *found_frame = tag->FindFirstFrame(frame_enum); + if (found_frame) + { + *frame = (nsid3v2_frame_t)found_frame; + return NErr_Success; + } + else + return NErr_Empty; +} + +int NSID3v2_Tag_GetNextFrame(const nsid3v2_tag_t t, const nsid3v2_frame_t f, nsid3v2_frame_t *frame) +{ + ID3v2::Tag *tag = (ID3v2::Tag *)t; + ID3v2::Frame *start_frame = (ID3v2::Frame *)f; + + ID3v2::Frame *found_frame = tag->FindNextFrame(start_frame); + if (found_frame) + { + *frame = (nsid3v2_frame_t)found_frame; + return NErr_Success; + } + else + return NErr_EndOfEnumeration; +} + +int NSID3v2_Frame_Binary_Get(nsid3v2_frame_t f, const void **binary, size_t *length) +{ + ID3v2::Frame *frame = (ID3v2::Frame *)f; + if (!frame) + return NErr_BadParameter; + + return frame->GetData(binary, length); +} + +int NSID3v2_Tag_EnumerateFrame(const nsid3v2_tag_t t, nsid3v2_frame_t p, nsid3v2_frame_t *f) +{ + const ID3v2::Tag *tag = (const ID3v2::Tag *)t; + const ID3v2::Frame *frame = tag->EnumerateFrame((const ID3v2::Frame *)p); + *f = (nsid3v2_frame_t)frame; + if (frame) + { + return NErr_Success; + } + else + { + return NErr_Error; + } +} + +int NSID3v2_Tag_GetInformation(nsid3v2_tag_t t, uint8_t *version, uint8_t *revision, int *flags) +{ + const ID3v2::Tag *tag = (const ID3v2::Tag *)t; + if (!tag) + return NErr_BadParameter; + + *version = tag->GetVersion(); + *revision = tag->GetRevision(); + + int local_flags=0; + if (tag->HasExtendedHeader()) + local_flags |= NSID3V2_TAGFLAG_EXTENDED_HEADER; + + if (tag->Unsynchronised()) + local_flags |= NSID3V2_TAGFLAG_UNSYNCHRONIZED; + if (tag->HasFooter()) + local_flags |= NSID3V2_TAGFLAG_HASFOOTER; + + *flags = local_flags; + + return NErr_Success; +} + +int NSID3v2_Tag_SerializedSize(nsid3v2_tag_t t, uint32_t *length, uint32_t padding_size, int flags) +{ + const ID3v2::Tag *tag = (const ID3v2::Tag *)t; + if (!tag) + return NErr_BadParameter; + + return tag->SerializedSize(length, padding_size, flags); +} + +int NSID3v2_Tag_Serialize(nsid3v2_tag_t t, void *data, uint32_t len, int flags) +{ + const ID3v2::Tag *tag = (const ID3v2::Tag *)t; + if (!tag) + return NErr_BadParameter; + + return tag->Serialize(data, len, flags); +} +/* +================= Frame ================= += = +========================================= +*/ + +int NSID3v2_Frame_GetIdentifier(nsid3v2_frame_t f, const char **identifier) +{ + ID3v2::Frame *frame = (ID3v2::Frame *)f; + if (!frame) + return NErr_BadParameter; + + *identifier = (const char *)frame->GetIdentifier(); + return NErr_Success; +} + + +int NSID3v2_Frame_GetInformation(nsid3v2_frame_t f, int *type, int *flags) +{ + ID3v2::Frame *frame = (ID3v2::Frame *)f; + if (!frame) + return NErr_BadParameter; + + const char *identifier=0; + int ret = NSID3v2_Frame_GetIdentifier(f, &identifier); + if (ret != NErr_Success) + return ret; + + /* TODO: make a method to get the version from the frame */ + + /* ok this is a bit of hack job */ + if (!memcmp(identifier, "TXX", 4) || !memcmp(identifier, "TXXX", 4)) + { + *type = NSID3V2_FRAMETYPE_USERTEXT; + } + else if (!memcmp(identifier, "COM", 4) || !memcmp(identifier, "COMM", 4)) + { + *type = NSID3V2_FRAMETYPE_COMMENTS; + } + else if (identifier[0] == 'T') /* check for text */ + { + *type = NSID3V2_FRAMETYPE_TEXT; + } + else if (!memcmp(identifier, "WXX", 4) || !memcmp(identifier, "WXXX", 4)) + { + *type = NSID3V2_FRAMETYPE_USERURL; + } + else if (identifier[0] == 'W') /* check for URL */ + { + *type = NSID3V2_FRAMETYPE_URL; + } + else if (!memcmp(identifier, "PRIV", 4)) + { + *type = NSID3V2_FRAMETYPE_PRIVATE; + } + else if (!memcmp(identifier, "GEO", 4) || !memcmp(identifier, "GEOB", 4)) + { + *type = NSID3V2_FRAMETYPE_OBJECT; + } + else if (!memcmp(identifier, "POP", 4) || !memcmp(identifier, "POPM", 4)) + { + *type = NSID3V2_FRAMETYPE_POPULARITY; + } + else if (!memcmp(identifier, "PIC", 4) || !memcmp(identifier, "APIC", 4)) + { + *type = NSID3V2_FRAMETYPE_PICTURE; + } + else if (!memcmp(identifier, "UFI", 4) || !memcmp(identifier, "UFID", 4)) + { + *type = NSID3V2_FRAMETYPE_ID; + } + else + { + *type = NSID3V2_FRAMETYPE_UNKNOWN; + } + + if (flags) + { + int local_flags=0; + if (frame->TagAlterPreservation()) + local_flags |= NSID3V2_FRAMEFLAG_TAG_ALTER_PRESERVATION; + if (frame->FileAlterPreservation()) + local_flags |= NSID3V2_FRAMEFLAG_FILE_ALTER_PRESERVATION; + if (frame->Encrypted()) + local_flags |= NSID3V2_FRAMEFLAG_ENCRYPTED; + if (frame->Compressed()) + local_flags |= NSID3V2_FRAMEFLAG_COMPRESSED; + if (frame->Grouped()) + local_flags |= NSID3V2_FRAMEFLAG_GROUPED; + if (frame->ReadOnly()) + local_flags |= NSID3V2_FRAMEFLAG_READONLY; + if (frame->FrameUnsynchronised()) + local_flags |= NSID3V2_FRAMEFLAG_UNSYNCHRONIZED; + if (frame->DataLengthIndicated()) + local_flags |= NSID3V2_FRAMEFLAG_DATALENGTHINDICATED; + *flags = local_flags; + } + + return NErr_Success; +} + |