header.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #include "header.h"
  2. #include "values.h"
  3. #include "util.h"
  4. #include <assert.h>
  5. #include "nu/ByteReader.h"
  6. #include "nu/ByteWriter.h"
  7. #include <string.h>
  8. #include "foundation/error.h"
  9. ID3v2::Header::Header()
  10. {
  11. marker[0]=0;
  12. marker[1]=0;
  13. marker[2]=0;
  14. version=0;
  15. revision=0;
  16. flags=0;
  17. size=0;
  18. }
  19. ID3v2::Header::Header(uint8_t version, uint8_t revision)
  20. {
  21. marker[0]='I';
  22. marker[1]='D';
  23. marker[2]='3';
  24. this->version=version;
  25. this->revision=revision;
  26. this->flags=0;
  27. this->size=0;
  28. }
  29. ID3v2::Header::Header(const void *data)
  30. {
  31. Parse(data);
  32. }
  33. ID3v2::Header::Header(const ID3v2::Header *copy, uint32_t new_size)
  34. {
  35. marker[0]=copy->marker[0];
  36. marker[1]=copy->marker[1];
  37. marker[2]=copy->marker[2];
  38. version=copy->version;
  39. revision=copy->revision;
  40. flags=copy->flags;
  41. size = Util::Int32To28(new_size);
  42. }
  43. void ID3v2::Header::Parse(const void *data)
  44. {
  45. bytereader_value_t byte_reader;
  46. bytereader_init(&byte_reader, data, Header::SIZE);
  47. bytereader_read_n(&byte_reader, &marker, 3);
  48. version = bytereader_read_u8(&byte_reader);
  49. revision = bytereader_read_u8(&byte_reader);
  50. flags = bytereader_read_u8(&byte_reader);
  51. size = bytereader_read_u32_be(&byte_reader);
  52. }
  53. int ID3v2::Header::Serialize(void *data)
  54. {
  55. bytewriter_s byte_writer;
  56. bytewriter_init(&byte_writer, data, 10);
  57. bytewriter_write_n(&byte_writer, marker, 3);
  58. bytewriter_write_u8(&byte_writer, version);
  59. bytewriter_write_u8(&byte_writer, revision);
  60. bytewriter_write_u8(&byte_writer, flags);
  61. bytewriter_write_u32_be(&byte_writer, size);
  62. return NErr_Success;
  63. }
  64. int ID3v2::Header::SerializeAsHeader(void *data)
  65. {
  66. bytewriter_s byte_writer;
  67. bytewriter_init(&byte_writer, data, 10);
  68. bytewriter_write_n(&byte_writer, "ID3", 3);
  69. bytewriter_write_u8(&byte_writer, version);
  70. bytewriter_write_u8(&byte_writer, revision);
  71. bytewriter_write_u8(&byte_writer, flags);
  72. bytewriter_write_u32_be(&byte_writer, size);
  73. return NErr_Success;
  74. }
  75. int ID3v2::Header::SerializeAsFooter(void *data)
  76. {
  77. bytewriter_s byte_writer;
  78. bytewriter_init(&byte_writer, data, 10);
  79. bytewriter_write_n(&byte_writer, "3DI", 3);
  80. bytewriter_write_u8(&byte_writer, version);
  81. bytewriter_write_u8(&byte_writer, revision);
  82. bytewriter_write_u8(&byte_writer, flags);
  83. bytewriter_write_u32_be(&byte_writer, size);
  84. return NErr_Success;
  85. }
  86. bool ID3v2::Header::Valid() const
  87. {
  88. if (marker[0] != 'I'
  89. || marker[1] != 'D'
  90. || marker[2] != '3')
  91. return false;
  92. if (!Values::KnownVersion(version, revision))
  93. return false;
  94. if (flags & ~Values::ValidHeaderMask(version, revision))
  95. return false;
  96. if (size & 0x80808080)
  97. return false;
  98. return true;
  99. }
  100. bool ID3v2::Header::FooterValid() const
  101. {
  102. if (marker[0] != '3'
  103. || marker[1] != 'D'
  104. || marker[2] != 'I')
  105. return false;
  106. if (!Values::KnownVersion(version, revision))
  107. return false;
  108. if (flags & ~Values::ValidHeaderMask(version, revision))
  109. return false;
  110. if (size & 0x80808080)
  111. return false;
  112. return true;
  113. }
  114. uint32_t ID3v2::Header::TagSize() const
  115. {
  116. uint32_t size = Util::Int28To32(this->size);
  117. return size;
  118. }
  119. bool ID3v2::Header::HasExtendedHeader() const
  120. {
  121. return !!(flags & ID3v2::Values::ExtendedHeaderFlag(version, revision));
  122. }
  123. uint8_t ID3v2::Header::GetVersion() const
  124. {
  125. return version;
  126. }
  127. uint8_t ID3v2::Header::GetRevision() const
  128. {
  129. return revision;
  130. }
  131. bool ID3v2::Header::Unsynchronised() const
  132. {
  133. return !!(flags & (1 << 7));
  134. }
  135. bool ID3v2::Header::HasFooter() const
  136. {
  137. if (version < 4)
  138. return false;
  139. return !!(flags & 0x10);
  140. }
  141. void ID3v2::Header::ClearExtendedHeader()
  142. {
  143. flags &= ~ID3v2::Values::ExtendedHeaderFlag(version, revision);
  144. }
  145. void ID3v2::Header::ClearUnsynchronized()
  146. {
  147. flags &= ~(1 << 7);
  148. }
  149. void ID3v2::Header::SetFooter(bool footer)
  150. {
  151. if (version >= 4)
  152. {
  153. if (footer)
  154. flags |= 0x10;
  155. else
  156. flags &= 0x10;
  157. }
  158. }