nsid3v2_common.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. #include "nsid3v2/nsid3v2.h"
  2. #include "nsid3v2/header.h"
  3. #include "nsid3v2/tag.h"
  4. #include <string.h> // for memcmp
  5. #include <new>
  6. int NSID3v2_Header_Valid(const void *header_data)
  7. {
  8. ID3v2::Header header(header_data);
  9. if (header.Valid())
  10. return NErr_Success;
  11. else
  12. return NErr_False;
  13. }
  14. int NSID3v2_Header_FooterValid(const void *footer_data)
  15. {
  16. ID3v2::Header footer(footer_data);
  17. if (footer.FooterValid())
  18. return NErr_Success;
  19. else
  20. return NErr_False;
  21. }
  22. int NSID3v2_Header_Create(nsid3v2_header_t *h, const void *header_data, size_t header_len)
  23. {
  24. if (header_len < 10)
  25. return NErr_NeedMoreData;
  26. ID3v2::Header header(header_data);
  27. if (!header.Valid())
  28. return NErr_Error;
  29. nsid3v2_header_t new_header = (nsid3v2_header_t)new (std::nothrow) ID3v2::Header(header);
  30. if (!new_header)
  31. return NErr_OutOfMemory;
  32. *h = new_header;
  33. return NErr_Success;
  34. }
  35. int NSID3v2_Header_New(nsid3v2_header_t *h, uint8_t version, uint8_t revision)
  36. {
  37. nsid3v2_header_t new_header = (nsid3v2_header_t)new (std::nothrow) ID3v2::Header(version, revision);
  38. if (!new_header)
  39. return NErr_OutOfMemory;
  40. *h = new_header;
  41. return NErr_Success;
  42. }
  43. int NSID3v2_Header_FooterCreate(nsid3v2_header_t *f, const void *footer_data, size_t footer_len)
  44. {
  45. if (footer_len < 10)
  46. return NErr_NeedMoreData;
  47. ID3v2::Header footer(footer_data);
  48. if (!footer.FooterValid())
  49. return NErr_Error;
  50. nsid3v2_header_t new_header = (nsid3v2_header_t)new (std::nothrow) ID3v2::Header(footer);
  51. if (!new_header)
  52. return NErr_OutOfMemory;
  53. *f = new_header;
  54. return NErr_Success;
  55. }
  56. int NSID3v2_Header_TagSize(const nsid3v2_header_t h, uint32_t *tag_size)
  57. {
  58. const ID3v2::Header *header = (const ID3v2::Header *)h;
  59. if (!header)
  60. return NErr_NullPointer;
  61. *tag_size = header->TagSize();
  62. return NErr_Success;
  63. }
  64. int NSID3v2_Header_HasFooter(const nsid3v2_header_t h)
  65. {
  66. const ID3v2::Header *header = (const ID3v2::Header *)h;
  67. if (!header)
  68. return NErr_NullPointer;
  69. if (header->HasFooter())
  70. return NErr_Success;
  71. else
  72. return NErr_False;
  73. }
  74. int NSID3v2_Header_Destroy(nsid3v2_header_t h)
  75. {
  76. const ID3v2::Header *header = (const ID3v2::Header *)h;
  77. if (!header)
  78. return NErr_NullPointer;
  79. delete header;
  80. return NErr_Success;
  81. }
  82. /*
  83. ================== Tag ==================
  84. = =
  85. =========================================
  86. */
  87. int NSID3v2_Tag_Create(nsid3v2_tag_t *t, const nsid3v2_header_t h, const void *bytes, size_t bytes_len)
  88. {
  89. const ID3v2::Header *header = (const ID3v2::Header *)h;
  90. if (!header)
  91. return NErr_NullPointer;
  92. switch(header->GetVersion())
  93. {
  94. case 2:
  95. {
  96. ID3v2_2::Tag *tag = new (std::nothrow) ID3v2_2::Tag(*header);
  97. if (!tag)
  98. return NErr_OutOfMemory;
  99. tag->Parse(bytes, bytes_len);
  100. *t = (nsid3v2_tag_t)tag;
  101. return NErr_Success;
  102. }
  103. case 3:
  104. {
  105. ID3v2_3::Tag *tag = new (std::nothrow) ID3v2_3::Tag(*header);
  106. if (!tag)
  107. return NErr_OutOfMemory;
  108. tag->Parse(bytes, bytes_len);
  109. *t = (nsid3v2_tag_t)tag;
  110. return NErr_Success;
  111. }
  112. case 4:
  113. {
  114. ID3v2_4::Tag *tag = new (std::nothrow) ID3v2_4::Tag(*header);
  115. if (!tag)
  116. return NErr_OutOfMemory;
  117. tag->Parse(bytes, bytes_len);
  118. *t = (nsid3v2_tag_t)tag;
  119. return NErr_Success;
  120. }
  121. default:
  122. return NErr_NotImplemented;
  123. }
  124. }
  125. int NSID3v2_Tag_Destroy(nsid3v2_tag_t t)
  126. {
  127. ID3v2::Tag *tag = (ID3v2::Tag *)t;
  128. delete tag;
  129. return NErr_Success;
  130. }
  131. int NSID3v2_Tag_RemoveFrame(nsid3v2_tag_t t, nsid3v2_frame_t f)
  132. {
  133. ID3v2::Tag *tag = (ID3v2::Tag *)t;
  134. ID3v2::Frame *frame = (ID3v2::Frame *)f;
  135. tag->RemoveFrame(frame);
  136. return NErr_Success;
  137. }
  138. int NSID3v2_Tag_CreateFrame(nsid3v2_tag_t t, int frame_enum, int flags, nsid3v2_frame_t *f)
  139. {
  140. ID3v2::Tag *tag = (ID3v2::Tag *)t;
  141. *f = (nsid3v2_frame_t)tag->NewFrame(frame_enum, flags);
  142. return NErr_Success;
  143. }
  144. int NSID3v2_Tag_AddFrame(nsid3v2_tag_t t, nsid3v2_frame_t f)
  145. {
  146. ID3v2::Tag *tag = (ID3v2::Tag *)t;
  147. ID3v2::Frame *frame = (ID3v2::Frame *)f;
  148. tag->AddFrame(frame);
  149. return NErr_Success;
  150. }
  151. int NSID3v2_Tag_GetFrame(const nsid3v2_tag_t t, int frame_enum, nsid3v2_frame_t *frame)
  152. {
  153. ID3v2::Tag *tag = (ID3v2::Tag *)t;
  154. ID3v2::Frame *found_frame = tag->FindFirstFrame(frame_enum);
  155. if (found_frame)
  156. {
  157. *frame = (nsid3v2_frame_t)found_frame;
  158. return NErr_Success;
  159. }
  160. else
  161. return NErr_Empty;
  162. }
  163. int NSID3v2_Tag_GetNextFrame(const nsid3v2_tag_t t, const nsid3v2_frame_t f, nsid3v2_frame_t *frame)
  164. {
  165. ID3v2::Tag *tag = (ID3v2::Tag *)t;
  166. ID3v2::Frame *start_frame = (ID3v2::Frame *)f;
  167. ID3v2::Frame *found_frame = tag->FindNextFrame(start_frame);
  168. if (found_frame)
  169. {
  170. *frame = (nsid3v2_frame_t)found_frame;
  171. return NErr_Success;
  172. }
  173. else
  174. return NErr_EndOfEnumeration;
  175. }
  176. int NSID3v2_Frame_Binary_Get(nsid3v2_frame_t f, const void **binary, size_t *length)
  177. {
  178. ID3v2::Frame *frame = (ID3v2::Frame *)f;
  179. if (!frame)
  180. return NErr_BadParameter;
  181. return frame->GetData(binary, length);
  182. }
  183. int NSID3v2_Tag_EnumerateFrame(const nsid3v2_tag_t t, nsid3v2_frame_t p, nsid3v2_frame_t *f)
  184. {
  185. const ID3v2::Tag *tag = (const ID3v2::Tag *)t;
  186. const ID3v2::Frame *frame = tag->EnumerateFrame((const ID3v2::Frame *)p);
  187. *f = (nsid3v2_frame_t)frame;
  188. if (frame)
  189. {
  190. return NErr_Success;
  191. }
  192. else
  193. {
  194. return NErr_Error;
  195. }
  196. }
  197. int NSID3v2_Tag_GetInformation(nsid3v2_tag_t t, uint8_t *version, uint8_t *revision, int *flags)
  198. {
  199. const ID3v2::Tag *tag = (const ID3v2::Tag *)t;
  200. if (!tag)
  201. return NErr_BadParameter;
  202. *version = tag->GetVersion();
  203. *revision = tag->GetRevision();
  204. int local_flags=0;
  205. if (tag->HasExtendedHeader())
  206. local_flags |= NSID3V2_TAGFLAG_EXTENDED_HEADER;
  207. if (tag->Unsynchronised())
  208. local_flags |= NSID3V2_TAGFLAG_UNSYNCHRONIZED;
  209. if (tag->HasFooter())
  210. local_flags |= NSID3V2_TAGFLAG_HASFOOTER;
  211. *flags = local_flags;
  212. return NErr_Success;
  213. }
  214. int NSID3v2_Tag_SerializedSize(nsid3v2_tag_t t, uint32_t *length, uint32_t padding_size, int flags)
  215. {
  216. const ID3v2::Tag *tag = (const ID3v2::Tag *)t;
  217. if (!tag)
  218. return NErr_BadParameter;
  219. return tag->SerializedSize(length, padding_size, flags);
  220. }
  221. int NSID3v2_Tag_Serialize(nsid3v2_tag_t t, void *data, uint32_t len, int flags)
  222. {
  223. const ID3v2::Tag *tag = (const ID3v2::Tag *)t;
  224. if (!tag)
  225. return NErr_BadParameter;
  226. return tag->Serialize(data, len, flags);
  227. }
  228. /*
  229. ================= Frame =================
  230. = =
  231. =========================================
  232. */
  233. int NSID3v2_Frame_GetIdentifier(nsid3v2_frame_t f, const char **identifier)
  234. {
  235. ID3v2::Frame *frame = (ID3v2::Frame *)f;
  236. if (!frame)
  237. return NErr_BadParameter;
  238. *identifier = (const char *)frame->GetIdentifier();
  239. return NErr_Success;
  240. }
  241. int NSID3v2_Frame_GetInformation(nsid3v2_frame_t f, int *type, int *flags)
  242. {
  243. ID3v2::Frame *frame = (ID3v2::Frame *)f;
  244. if (!frame)
  245. return NErr_BadParameter;
  246. const char *identifier=0;
  247. int ret = NSID3v2_Frame_GetIdentifier(f, &identifier);
  248. if (ret != NErr_Success)
  249. return ret;
  250. /* TODO: make a method to get the version from the frame */
  251. /* ok this is a bit of hack job */
  252. if (!memcmp(identifier, "TXX", 4) || !memcmp(identifier, "TXXX", 4))
  253. {
  254. *type = NSID3V2_FRAMETYPE_USERTEXT;
  255. }
  256. else if (!memcmp(identifier, "COM", 4) || !memcmp(identifier, "COMM", 4))
  257. {
  258. *type = NSID3V2_FRAMETYPE_COMMENTS;
  259. }
  260. else if (identifier[0] == 'T') /* check for text */
  261. {
  262. *type = NSID3V2_FRAMETYPE_TEXT;
  263. }
  264. else if (!memcmp(identifier, "WXX", 4) || !memcmp(identifier, "WXXX", 4))
  265. {
  266. *type = NSID3V2_FRAMETYPE_USERURL;
  267. }
  268. else if (identifier[0] == 'W') /* check for URL */
  269. {
  270. *type = NSID3V2_FRAMETYPE_URL;
  271. }
  272. else if (!memcmp(identifier, "PRIV", 4))
  273. {
  274. *type = NSID3V2_FRAMETYPE_PRIVATE;
  275. }
  276. else if (!memcmp(identifier, "GEO", 4) || !memcmp(identifier, "GEOB", 4))
  277. {
  278. *type = NSID3V2_FRAMETYPE_OBJECT;
  279. }
  280. else if (!memcmp(identifier, "POP", 4) || !memcmp(identifier, "POPM", 4))
  281. {
  282. *type = NSID3V2_FRAMETYPE_POPULARITY;
  283. }
  284. else if (!memcmp(identifier, "PIC", 4) || !memcmp(identifier, "APIC", 4))
  285. {
  286. *type = NSID3V2_FRAMETYPE_PICTURE;
  287. }
  288. else if (!memcmp(identifier, "UFI", 4) || !memcmp(identifier, "UFID", 4))
  289. {
  290. *type = NSID3V2_FRAMETYPE_ID;
  291. }
  292. else
  293. {
  294. *type = NSID3V2_FRAMETYPE_UNKNOWN;
  295. }
  296. if (flags)
  297. {
  298. int local_flags=0;
  299. if (frame->TagAlterPreservation())
  300. local_flags |= NSID3V2_FRAMEFLAG_TAG_ALTER_PRESERVATION;
  301. if (frame->FileAlterPreservation())
  302. local_flags |= NSID3V2_FRAMEFLAG_FILE_ALTER_PRESERVATION;
  303. if (frame->Encrypted())
  304. local_flags |= NSID3V2_FRAMEFLAG_ENCRYPTED;
  305. if (frame->Compressed())
  306. local_flags |= NSID3V2_FRAMEFLAG_COMPRESSED;
  307. if (frame->Grouped())
  308. local_flags |= NSID3V2_FRAMEFLAG_GROUPED;
  309. if (frame->ReadOnly())
  310. local_flags |= NSID3V2_FRAMEFLAG_READONLY;
  311. if (frame->FrameUnsynchronised())
  312. local_flags |= NSID3V2_FRAMEFLAG_UNSYNCHRONIZED;
  313. if (frame->DataLengthIndicated())
  314. local_flags |= NSID3V2_FRAMEFLAG_DATALENGTHINDICATED;
  315. *flags = local_flags;
  316. }
  317. return NErr_Success;
  318. }