frame_object.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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 ParsedObject
  13. {
  14. ParsedString mime;
  15. ParsedString filename;
  16. ParsedString description;
  17. const void *object_data;
  18. size_t object_byte_length;
  19. };
  20. static int ParseObject(const void *data, size_t data_len, ParsedObject &parsed)
  21. {
  22. int ret;
  23. if (data_len == 0)
  24. return NErr_Insufficient;
  25. bytereader_value_t byte_reader;
  26. bytereader_init(&byte_reader, data, data_len);
  27. /* encoding */
  28. uint8_t encoding = bytereader_read_u8(&byte_reader);
  29. /* read mime type (Always latin-1) */
  30. ret = ParseNullTerminatedString(&byte_reader, 0, parsed.mime);
  31. if (ret != NErr_Success)
  32. return ret;
  33. /* read filename */
  34. ret = ParseNullTerminatedString(&byte_reader, encoding, parsed.filename);
  35. if (ret != NErr_Success)
  36. return ret;
  37. /* read content description */
  38. ret = ParseNullTerminatedString(&byte_reader, encoding, parsed.description);
  39. if (ret != NErr_Success)
  40. return ret;
  41. parsed.object_data = bytereader_pointer(&byte_reader);
  42. parsed.object_byte_length = bytereader_size(&byte_reader);
  43. return NErr_Success;
  44. }
  45. int NSID3v2_Frame_Object_Get(const nsid3v2_frame_t f, nx_string_t *mime, nx_string_t *filename, nx_string_t *description, const void **out_data, size_t *length, int text_flags)
  46. {
  47. const ID3v2::Frame *frame = (const ID3v2::Frame *)f;
  48. if (frame)
  49. {
  50. const void *data;
  51. size_t data_len;
  52. ParsedObject parsed;
  53. if (frame->GetData(&data, &data_len) == NErr_Success && data_len > 0 && ParseObject(data, data_len, parsed) == NErr_Success)
  54. {
  55. int ret = NXStringCreateFromParsedString(mime, parsed.mime, text_flags);
  56. if (ret != NErr_Success)
  57. return ret;
  58. ret = NXStringCreateFromParsedString(filename, parsed.filename, text_flags);
  59. if (ret != NErr_Success)
  60. return ret;
  61. ret = NXStringCreateFromParsedString(description, parsed.description, text_flags);
  62. if (ret != NErr_Success)
  63. return ret;
  64. *out_data = parsed.object_data;
  65. *length = parsed.object_byte_length;
  66. return NErr_Success;
  67. }
  68. }
  69. return NErr_Empty;
  70. }