1
0

frameheader.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. #include "frameheader.h"
  2. #include "util.h"
  3. #include "values.h"
  4. #include "nu/ByteReader.h"
  5. #include "nu/ByteWriter.h"
  6. #include <string.h>
  7. #include "foundation/error.h"
  8. /* === ID3v2 common === */
  9. ID3v2::FrameHeader::FrameHeader(const ID3v2::Header &_header) : tagHeader(_header)
  10. {
  11. }
  12. static bool CharOK(int8_t c)
  13. {
  14. if (c >= '0' && c <= '9')
  15. return true;
  16. if (c >= 'A' && c <= 'Z')
  17. return true;
  18. return false;
  19. }
  20. /* === ID3v2.2 === */
  21. ID3v2_2::FrameHeader::FrameHeader(const ID3v2_2::FrameHeader &frame_header, const ID3v2::Header &_header) : ID3v2::FrameHeader(_header)
  22. {
  23. frameHeaderData = frame_header.frameHeaderData;
  24. }
  25. ID3v2_2::FrameHeader::FrameHeader(const ID3v2::Header &_header, const int8_t *id, int flags) : ID3v2::FrameHeader(_header)
  26. {
  27. memcpy(&frameHeaderData.id, id, 3);
  28. frameHeaderData.id[3]=0;
  29. memset(&frameHeaderData.size, 0, 3);
  30. }
  31. ID3v2_2::FrameHeader::FrameHeader(const ID3v2::Header &_header, const void *data) : ID3v2::FrameHeader(_header)
  32. {
  33. char temp_data[FrameHeader::SIZE];
  34. if (tagHeader.Unsynchronised())
  35. {
  36. ID3v2::Util::UnsynchroniseTo(temp_data, data, sizeof(temp_data));
  37. data = temp_data;
  38. }
  39. bytereader_value_t byte_reader;
  40. bytereader_init(&byte_reader, data, FrameHeader::SIZE);
  41. bytereader_read_n(&byte_reader, &frameHeaderData.id, 3);
  42. frameHeaderData.id[3]=0;
  43. bytereader_read_n(&byte_reader, &frameHeaderData.size, 3);
  44. }
  45. bool ID3v2_2::FrameHeader::IsValid() const
  46. {
  47. if (CharOK(frameHeaderData.id[0])
  48. && CharOK(frameHeaderData.id[1])
  49. && CharOK(frameHeaderData.id[2]))
  50. return true;
  51. return false;
  52. }
  53. const int8_t *ID3v2_2::FrameHeader::GetIdentifier() const
  54. {
  55. return frameHeaderData.id;
  56. }
  57. bool ID3v2_2::FrameHeader::Unsynchronised() const
  58. {
  59. return tagHeader.Unsynchronised();
  60. }
  61. uint32_t ID3v2_2::FrameHeader::FrameSize() const
  62. {
  63. return (frameHeaderData.size[0] << 16) | (frameHeaderData.size[1] << 8) | (frameHeaderData.size[2]);
  64. }
  65. void ID3v2_2::FrameHeader::SetSize(uint32_t data_size)
  66. {
  67. frameHeaderData.size[0] = data_size >> 16;
  68. frameHeaderData.size[1] = data_size >> 8;
  69. frameHeaderData.size[2] = data_size;
  70. }
  71. int ID3v2_2::FrameHeader::SerializedSize(uint32_t *written) const
  72. {
  73. if (tagHeader.Unsynchronised())
  74. {
  75. uint8_t data[SIZE];
  76. bytewriter_s byte_writer;
  77. bytewriter_init(&byte_writer, data, SIZE);
  78. bytewriter_write_n(&byte_writer, frameHeaderData.id, 3);
  79. bytewriter_write_n(&byte_writer, frameHeaderData.size, 3);
  80. *written = ID3v2::Util::SynchronisedSize(data, SIZE);
  81. }
  82. else
  83. {
  84. *written = SIZE;
  85. }
  86. return NErr_Success;
  87. }
  88. int ID3v2_2::FrameHeader::Serialize(void *data) const
  89. {
  90. if (tagHeader.Unsynchronised())
  91. {
  92. uint8_t temp[SIZE];
  93. bytewriter_s byte_writer;
  94. bytewriter_init(&byte_writer, temp, SIZE);
  95. bytewriter_write_n(&byte_writer, frameHeaderData.id, 3);
  96. bytewriter_write_n(&byte_writer, frameHeaderData.size, 3);
  97. ID3v2::Util::SynchroniseTo(data, temp, SIZE);
  98. }
  99. else
  100. {
  101. bytewriter_s byte_writer;
  102. bytewriter_init(&byte_writer, data, SIZE);
  103. bytewriter_write_n(&byte_writer, frameHeaderData.id, 3);
  104. bytewriter_write_n(&byte_writer, frameHeaderData.size, 3);
  105. }
  106. return NErr_Success;
  107. }
  108. /* === ID3v2.3+ common === */
  109. ID3v2_3::FrameHeaderBase::FrameHeaderBase(const ID3v2_3::FrameHeaderBase &frame_header_base, const ID3v2::Header &_header) : ID3v2::FrameHeader(_header)
  110. {
  111. memcpy(id, frame_header_base.id, 4);
  112. size=frame_header_base.size;
  113. flags[0] = frame_header_base.flags[0];
  114. flags[1] = frame_header_base.flags[1];
  115. }
  116. ID3v2_3::FrameHeaderBase::FrameHeaderBase(const ID3v2::Header &_header) : ID3v2::FrameHeader(_header)
  117. {
  118. }
  119. ID3v2_3::FrameHeaderBase::FrameHeaderBase(const ID3v2::Header &_header, const int8_t *_id, int _flags) : ID3v2::FrameHeader(_header)
  120. {
  121. memcpy(id, _id, 4);
  122. size=0;
  123. // TODO: flags
  124. flags[0]=0;
  125. flags[1]=0;
  126. }
  127. const int8_t *ID3v2_3::FrameHeaderBase::GetIdentifier() const
  128. {
  129. return id;
  130. }
  131. bool ID3v2_3::FrameHeaderBase::IsValid() const
  132. {
  133. if (CharOK(id[0])
  134. && CharOK(id[1])
  135. && CharOK(id[2])
  136. && CharOK(id[3]))
  137. return true;
  138. return false;
  139. }
  140. /* === ID3v2.3 === */
  141. ID3v2_3::FrameHeader::FrameHeader(const ID3v2_3::FrameHeader &frame_header, const ID3v2::Header &tag_header) : ID3v2_3::FrameHeaderBase(frame_header, tag_header)
  142. {
  143. }
  144. ID3v2_3::FrameHeader::FrameHeader(const ID3v2::Header &_header, const int8_t *id, int flags) : ID3v2_3::FrameHeaderBase(_header, id, flags)
  145. {
  146. }
  147. ID3v2_3::FrameHeader::FrameHeader(const ID3v2::Header &_header, const void *data) : ID3v2_3::FrameHeaderBase(_header)
  148. {
  149. char temp_data[FrameHeaderBase::SIZE];
  150. if (tagHeader.Unsynchronised())
  151. {
  152. ID3v2::Util::UnsynchroniseTo(temp_data, data, sizeof(temp_data));
  153. data = temp_data;
  154. }
  155. bytereader_value_t byte_reader;
  156. bytereader_init(&byte_reader, data, FrameHeaderBase::SIZE);
  157. bytereader_read_n(&byte_reader, &id, 4);
  158. size = bytereader_read_u32_be(&byte_reader);
  159. bytereader_read_n(&byte_reader, &flags, 2);
  160. }
  161. int ID3v2_3::FrameHeaderBase::SerializedSize(uint32_t *written) const
  162. {
  163. if (tagHeader.Unsynchronised())
  164. {
  165. uint8_t data[SIZE];
  166. bytewriter_s byte_writer;
  167. bytewriter_init(&byte_writer, data, SIZE);
  168. bytewriter_write_n(&byte_writer, id, 4);
  169. bytewriter_write_u32_be(&byte_writer, size);
  170. bytewriter_write_u8(&byte_writer, flags[0]);
  171. bytewriter_write_u8(&byte_writer, flags[1]);
  172. *written = ID3v2::Util::SynchronisedSize(data, SIZE);
  173. }
  174. else
  175. {
  176. *written = SIZE;
  177. }
  178. return NErr_Success;
  179. }
  180. int ID3v2_3::FrameHeaderBase::Serialize(void *data, uint32_t *written) const
  181. {
  182. if (tagHeader.Unsynchronised())
  183. {
  184. uint8_t temp[SIZE];
  185. bytewriter_s byte_writer;
  186. bytewriter_init(&byte_writer, temp, SIZE);
  187. bytewriter_write_n(&byte_writer, id, 4);
  188. bytewriter_write_u32_be(&byte_writer, size);
  189. bytewriter_write_u8(&byte_writer, flags[0]);
  190. bytewriter_write_u8(&byte_writer, flags[1]);
  191. *written = ID3v2::Util::SynchroniseTo(data, temp, SIZE);
  192. }
  193. else
  194. {
  195. bytewriter_s byte_writer;
  196. bytewriter_init(&byte_writer, data, SIZE);
  197. bytewriter_write_n(&byte_writer, id, 4);
  198. bytewriter_write_u32_be(&byte_writer, size);
  199. bytewriter_write_u8(&byte_writer, flags[0]);
  200. bytewriter_write_u8(&byte_writer, flags[1]);
  201. *written = SIZE;
  202. }
  203. return NErr_Success;
  204. }
  205. uint32_t ID3v2_3::FrameHeader::FrameSize() const
  206. {
  207. return size;
  208. }
  209. bool ID3v2_3::FrameHeader::ReadOnly() const
  210. {
  211. return !!(flags[0] & (1<<5));
  212. }
  213. bool ID3v2_3::FrameHeader::Encrypted() const
  214. {
  215. return !!(flags[1] & (1<<6));
  216. }
  217. bool ID3v2_3::FrameHeader::Unsynchronised() const
  218. {
  219. return tagHeader.Unsynchronised();
  220. }
  221. bool ID3v2_3::FrameHeader::Grouped() const
  222. {
  223. return !!(flags[1] & (1 << 5));
  224. }
  225. bool ID3v2_3::FrameHeader::Compressed() const
  226. {
  227. return !!(flags[1] & (1 << 7));
  228. }
  229. bool ID3v2_3::FrameHeader::TagAlterPreservation() const
  230. {
  231. return !!(flags[0] & (1<<7));
  232. }
  233. bool ID3v2_3::FrameHeader::FileAlterPreservation() const
  234. {
  235. return !!(flags[0] & (1<<6));
  236. }
  237. void ID3v2_3::FrameHeader::ClearCompressed()
  238. {
  239. flags[1] &= ~(1 << 7);
  240. }
  241. void ID3v2_3::FrameHeader::SetSize(uint32_t data_size)
  242. {
  243. if (Compressed())
  244. data_size+=4;
  245. if (Grouped())
  246. data_size++;
  247. size = data_size;
  248. }
  249. /* === ID3v2.4 === */
  250. ID3v2_4::FrameHeader::FrameHeader(const ID3v2_4::FrameHeader &frame_header, const ID3v2::Header &tag_header) : ID3v2_3::FrameHeaderBase(frame_header, tag_header)
  251. {
  252. }
  253. ID3v2_4::FrameHeader::FrameHeader(const ID3v2::Header &_header, const int8_t *id, int flags) : ID3v2_3::FrameHeaderBase(_header, id, flags)
  254. {
  255. }
  256. ID3v2_4::FrameHeader::FrameHeader(const ID3v2::Header &_header, const void *data) : ID3v2_3::FrameHeaderBase(_header)
  257. {
  258. bytereader_value_t byte_reader;
  259. bytereader_init(&byte_reader, data, FrameHeaderBase::SIZE);
  260. bytereader_read_n(&byte_reader, &id, 4);
  261. size = bytereader_read_u32_be(&byte_reader);
  262. bytereader_read_n(&byte_reader, &flags, 2);
  263. }
  264. uint32_t ID3v2_4::FrameHeader::FrameSize() const
  265. {
  266. // many programs write non-syncsafe sizes (iTunes is the biggest culprit)
  267. // so we'll try to detect it. unfortunately this isn't foolproof
  268. // ID3v2_4::Frame will have some additional checks
  269. int mask = size & 0x80808080;
  270. if (mask)
  271. return size;
  272. else
  273. return ID3v2::Util::Int28To32(size);
  274. }
  275. bool ID3v2_4::FrameHeader::ReadOnly() const
  276. {
  277. return !!(flags[0] & (1<<4));
  278. }
  279. bool ID3v2_4::FrameHeader::Encrypted() const
  280. {
  281. return !!(flags[1] & (1<<3));
  282. }
  283. bool ID3v2_4::FrameHeader::Unsynchronised() const
  284. {
  285. return tagHeader.Unsynchronised() || !!(flags[1] & (1 << 1));
  286. }
  287. bool ID3v2_4::FrameHeader::FrameUnsynchronised() const
  288. {
  289. return !!(flags[1] & (1 << 1));
  290. }
  291. bool ID3v2_4::FrameHeader::DataLengthIndicated() const
  292. {
  293. return !!(flags[1] & (1 << 0));
  294. }
  295. bool ID3v2_4::FrameHeader::Compressed() const
  296. {
  297. return !!(flags[1] & (1 << 3));
  298. }
  299. bool ID3v2_4::FrameHeader::Grouped() const
  300. {
  301. return !!(flags[1] & (1 << 6));
  302. }
  303. bool ID3v2_4::FrameHeader::TagAlterPreservation() const
  304. {
  305. return !!(flags[0] & (1<<6));
  306. }
  307. bool ID3v2_4::FrameHeader::FileAlterPreservation() const
  308. {
  309. return !!(flags[0] & (1<<5));
  310. }
  311. void ID3v2_4::FrameHeader::ClearUnsynchronized()
  312. {
  313. flags[1] &= ~(1 << 1);
  314. }
  315. void ID3v2_4::FrameHeader::ClearCompressed()
  316. {
  317. flags[1] &= ~(1 << 3);
  318. }
  319. void ID3v2_4::FrameHeader::SetSize(uint32_t data_size)
  320. {
  321. if (Compressed() || DataLengthIndicated())
  322. data_size+=4;
  323. if (Grouped())
  324. data_size++;
  325. size = ID3v2::Util::Int32To28(data_size);
  326. }
  327. int ID3v2_4::FrameHeader::SerializedSize(uint32_t *written) const
  328. {
  329. *written = SIZE;
  330. return NErr_Success;
  331. }
  332. int ID3v2_4::FrameHeader::Serialize(void *data, uint32_t *written) const
  333. {
  334. bytewriter_s byte_writer;
  335. bytewriter_init(&byte_writer, data, SIZE);
  336. bytewriter_write_n(&byte_writer, id, 4);
  337. bytewriter_write_u32_be(&byte_writer, size);
  338. bytewriter_write_u8(&byte_writer, flags[0]);
  339. bytewriter_write_u8(&byte_writer, flags[1]);
  340. *written = SIZE;
  341. return NErr_Success;
  342. }