frame_popm.cpp 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include "nsid3v2.h"
  2. #include "nsid3v2/header.h"
  3. #include "nsid3v2/tag.h"
  4. #include "nsid3v2/frame_utils.h"
  5. #include "nu/ByteReader.h"
  6. #include "nx/nxstring.h"
  7. #if defined(_WIN32) && !defined(strcasecmp)
  8. #define strcasecmp _stricmp
  9. #else
  10. #include <strings.h>
  11. #endif
  12. struct ParsedPopularimeter
  13. {
  14. ParsedString email;
  15. uint8_t rating;
  16. uint64_t playcount;
  17. };
  18. static int ParsePopularimeter(const void *data, size_t data_len, ParsedPopularimeter &parsed)
  19. {
  20. int ret;
  21. if (data_len < 6)
  22. return NErr_Insufficient;
  23. bytereader_value_t byte_reader;
  24. bytereader_init(&byte_reader, data, data_len);
  25. /* read email (Always latin-1) */
  26. ret = ParseNullTerminatedString(&byte_reader, 0, parsed.email);
  27. if (ret != NErr_Success)
  28. return ret;
  29. if (bytereader_size(&byte_reader) == 0)
  30. return NErr_Insufficient;
  31. parsed.rating = bytereader_read_u8(&byte_reader);
  32. parsed.playcount=0;
  33. while (bytereader_size(&byte_reader))
  34. {
  35. parsed.playcount <<= 8;
  36. parsed.playcount |= bytereader_read_u8(&byte_reader);
  37. }
  38. return NErr_Success;
  39. }
  40. int NSID3v2_Tag_Popularimeter_GetRatingPlaycount(const nsid3v2_tag_t t, const char *email, uint8_t *rating, uint64_t *playcount)
  41. {
  42. const ID3v2::Tag *tag = (const ID3v2::Tag *)t;
  43. if (!tag)
  44. return NErr_Empty;
  45. const ID3v2::Frame *frame = tag->FindFirstFrame(NSID3V2_FRAME_POPULARIMETER);
  46. while (frame)
  47. {
  48. const void *data;
  49. size_t data_len;
  50. ParsedPopularimeter parsed;
  51. if (frame->GetData(&data, &data_len) == NErr_Success && data_len > 0 && ParsePopularimeter(data, data_len, parsed) == NErr_Success)
  52. {
  53. if (!strcasecmp(email, (const char *)parsed.email.data))
  54. {
  55. *rating = parsed.rating;
  56. *playcount = parsed.playcount;
  57. return NErr_Success;
  58. }
  59. }
  60. frame = tag->FindNextFrame(frame);
  61. }
  62. return NErr_Empty;
  63. }
  64. int NSID3v2_Frame_Popularity_Get(nsid3v2_frame_t f, nx_string_t *email, uint8_t *rating, uint64_t *playcount, int text_flags)
  65. {
  66. const ID3v2::Frame *frame = (const ID3v2::Frame *)f;
  67. if (frame)
  68. {
  69. const void *data;
  70. size_t data_len;
  71. ParsedPopularimeter parsed;
  72. if (frame->GetData(&data, &data_len) == NErr_Success && data_len > 0 && ParsePopularimeter(data, data_len, parsed) == NErr_Success)
  73. {
  74. int ret = NXStringCreateFromParsedString(email, parsed.email, text_flags);
  75. if (ret != NErr_Success)
  76. return ret;
  77. *rating = parsed.rating;
  78. *playcount = parsed.playcount;
  79. return NErr_Success;
  80. }
  81. }
  82. return NErr_Empty;
  83. }