frame_text.cpp 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include "nsid3v2.h"
  2. #include "nsid3v2/header.h"
  3. #include "nsid3v2/tag.h"
  4. #include "nu/ByteReader.h"
  5. #include "nx/nxstring.h"
  6. #include "nu/ByteWriter.h"
  7. #include "nsid3v2/frame_utils.h"
  8. static int ParseText(const void *data, size_t data_len, ParsedString &parsed)
  9. {
  10. if (data_len == 0)
  11. return NErr_Insufficient;
  12. bytereader_value_t byte_reader;
  13. bytereader_init(&byte_reader, data, data_len);
  14. return ParseFrameTerminatedString(&byte_reader, bytereader_read_u8(&byte_reader), parsed);
  15. }
  16. int NSID3v2_Frame_Text_Get(const nsid3v2_frame_t f, nx_string_t *value, int text_flags)
  17. {
  18. const ID3v2::Frame *frame = (const ID3v2::Frame *)f;
  19. if (frame)
  20. {
  21. const void *data;
  22. size_t data_len;
  23. ParsedString parsed;
  24. if (frame->GetData(&data, &data_len) == NErr_Success && data_len > 0 && ParseText(data, data_len, parsed) == NErr_Success)
  25. {
  26. return NXStringCreateFromParsedString(value, parsed, text_flags);
  27. }
  28. }
  29. return NErr_Empty;
  30. }
  31. int NSID3v2_Tag_Text_Get(const nsid3v2_tag_t t, int frame_enum, nx_string_t *value, int text_flags)
  32. {
  33. const ID3v2::Tag *tag = (const ID3v2::Tag *)t;
  34. if (!tag)
  35. return NErr_Empty;
  36. const ID3v2::Frame *frame = tag->FindFirstFrame(frame_enum);
  37. return NSID3v2_Frame_Text_Get((const nsid3v2_frame_t)frame, value, text_flags);
  38. }
  39. /* ---------------- Setters ---------------- */
  40. int NSID3v2_Frame_Text_Set(nsid3v2_frame_t f, nx_string_t value, int text_flags)
  41. {
  42. ID3v2::Frame *frame = (ID3v2::Frame *)f;
  43. if (frame)
  44. {
  45. /* benski> for now, we're going to store UTF-16LE always. in the future, we'll add functions to NXString to determine a 'best' encoding */
  46. size_t byte_count=0;
  47. int ret = NXStringGetBytesSize(&byte_count, value, nx_charset_utf16le, 0);
  48. if (ret != NErr_DirectPointer && ret != NErr_Success)
  49. return ret;
  50. void *data;
  51. size_t data_len;
  52. byte_count+=3; // need one byte for encoding type, two bytes for BOM
  53. ret = frame->NewData(byte_count, &data, &data_len);
  54. if (ret != NErr_Success)
  55. return ret;
  56. bytewriter_s byte_writer;
  57. bytewriter_init(&byte_writer, data, data_len);
  58. bytewriter_write_u8(&byte_writer, 1); /* mark as UTF-16LE */
  59. bytewriter_write_u16_le(&byte_writer, 0xFEFF); /* BOM */
  60. size_t bytes_copied;
  61. return NXStringGetBytes(&bytes_copied, value, bytewriter_pointer(&byte_writer), bytewriter_size(&byte_writer), nx_charset_utf16le, 0);
  62. }
  63. return NErr_Empty;
  64. }
  65. int NSID3v2_Tag_Text_Set(nsid3v2_tag_t t, int frame_enum, nx_string_t value, int text_flags)
  66. {
  67. ID3v2::Tag *tag = (ID3v2::Tag *)t;
  68. if (!tag)
  69. return NErr_Empty;
  70. ID3v2::Frame *frame = tag->FindFirstFrame(frame_enum);
  71. if (!frame)
  72. {
  73. frame = tag->NewFrame(frame_enum, 0);
  74. if (!frame)
  75. return NErr_OutOfMemory;
  76. tag->AddFrame(frame);
  77. }
  78. return NSID3v2_Frame_Text_Set((nsid3v2_frame_t)frame, value, text_flags);
  79. }