nsapev2_common.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. #include "nsapev2.h"
  2. #include "nsapev2/header.h"
  3. #include "nsapev2/tag.h"
  4. #include <new>
  5. int NSAPEv2_Header_Valid(const void *header_data)
  6. {
  7. if (APEv2::Header(header_data).Valid())
  8. return NErr_Success;
  9. else
  10. return NErr_False;
  11. }
  12. int NSAPEv2_Header_Create(nsapev2_header_t *header, const void *header_data, size_t header_len)
  13. {
  14. if (header_len < 10 || NSAPEv2_Header_Valid(header_data) != NErr_Success)
  15. return NErr_Error;
  16. nsapev2_header_t new_header = (nsapev2_header_t)new (std::nothrow) APEv2::Header(header_data);
  17. if (!new_header)
  18. return NErr_OutOfMemory;
  19. *header = new_header;
  20. return NErr_Success;
  21. }
  22. int NSAPEv2_Header_TagSize(const nsapev2_header_t h, uint32_t *tag_size)
  23. {
  24. const APEv2::Header *header = (const APEv2::Header *)h;
  25. if (!header)
  26. return NErr_NullPointer;
  27. *tag_size = header->TagSize();
  28. return NErr_Success;
  29. }
  30. int NSAPEv2_Header_HasHeader(nsapev2_header_t h)
  31. {
  32. const APEv2::Header *header = (const APEv2::Header *)h;
  33. if (!header)
  34. return NErr_NullPointer;
  35. if (header->HasHeader())
  36. return NErr_Success;
  37. else
  38. return NErr_False;
  39. }
  40. int NSAPEv2_Header_Destroy(nsapev2_header_t h)
  41. {
  42. const APEv2::Header *header = (const APEv2::Header *)h;
  43. if (!header)
  44. return NErr_NullPointer;
  45. delete header;
  46. return NErr_Success;
  47. }
  48. int NSAPEv2_Tag_Create(nsapev2_tag_t *t, const nsapev2_header_t h, const void *bytes, size_t bytes_len)
  49. {
  50. const APEv2::Header *header = (const APEv2::Header *)h;
  51. if (!header)
  52. return NErr_NullPointer;
  53. APEv2::Tag *tag = new (std::nothrow) APEv2::Tag;
  54. if (!tag)
  55. return NErr_OutOfMemory;
  56. int ret = tag->Parse(header, bytes, bytes_len);
  57. if (ret != NErr_Success)
  58. {
  59. delete tag;
  60. return ret;
  61. }
  62. *t = (nsapev2_tag_t)tag;
  63. return ret;
  64. }
  65. int NSAPEv2_Tag_New(nsapev2_tag_t *t)
  66. {
  67. APEv2::Header *new_header = new (std::nothrow) APEv2::Header();
  68. if (!new_header)
  69. return NErr_OutOfMemory;
  70. APEv2::Tag *tag = new (std::nothrow) APEv2::Tag;
  71. if (!tag)
  72. {
  73. delete new_header;
  74. return NErr_OutOfMemory;
  75. }
  76. *t = (nsapev2_tag_t)tag;
  77. return NErr_Success;
  78. }
  79. int NSAPEv2_Tag_SerializedSize(const nsapev2_tag_t t, size_t *bytes)
  80. {
  81. const APEv2::Tag *tag = (const APEv2::Tag *)t;
  82. if (!tag)
  83. return NErr_BadParameter;
  84. *bytes = tag->EncodeSize();
  85. return NErr_Success;
  86. }
  87. int NSAPEv2_Tag_Serialize(const nsapev2_tag_t t, void *data, size_t bytes)
  88. {
  89. const APEv2::Tag *tag = (const APEv2::Tag *)t;
  90. if (!tag)
  91. return NErr_BadParameter;
  92. return tag->Encode(data, bytes);
  93. }
  94. int NSAPEv2_Tag_Destroy(nsapev2_tag_t t)
  95. {
  96. APEv2::Tag *tag = (APEv2::Tag *)t;
  97. if (!tag)
  98. return NErr_NullPointer;
  99. delete tag;
  100. return NErr_Success;
  101. }
  102. int NSAPEv2_Tag_GetFlags(nsapev2_tag_t t, uint32_t *flags)
  103. {
  104. APEv2::Tag *tag = (APEv2::Tag *)t;
  105. if (!tag)
  106. return NErr_BadParameter;
  107. return tag->GetFlags(flags);
  108. }
  109. int NSAPEv2_Tag_SetFlags(nsapev2_tag_t t, uint32_t flags, uint32_t mask)
  110. {
  111. APEv2::Tag *tag = (APEv2::Tag *)t;
  112. if (!tag)
  113. return NErr_BadParameter;
  114. return tag->SetFlags(flags, mask);
  115. }
  116. int NSAPEv2_Tag_GetString(const nsapev2_tag_t t, const char *key, unsigned int index, nx_string_t *value)
  117. {
  118. const APEv2::Tag *tag = (const APEv2::Tag *)t;
  119. if (!tag)
  120. return NErr_Empty;
  121. const void *data;
  122. size_t data_len;
  123. int ret = tag->GetData(key, index, &data, &data_len);
  124. if (ret != NErr_Success)
  125. return ret;
  126. return NXStringCreateWithBytes(value, data, data_len, nx_charset_utf8);
  127. }
  128. int NSAPEv2_Tag_SetString(nsapev2_tag_t t, const char *key, unsigned int index, nx_string_t value)
  129. {
  130. APEv2::Tag *tag = (APEv2::Tag *)t;
  131. if (!tag)
  132. return NErr_BadParameter;
  133. if (value)
  134. {
  135. APEv2::Item *item;
  136. int ret = tag->GetItem(key, index, &item);
  137. if (ret == NErr_Success)
  138. {
  139. return item->Set(value);
  140. }
  141. else
  142. {
  143. /* no such item, need to make a new one */
  144. item = new (std::nothrow) APEv2::Item;
  145. if (!item)
  146. return NErr_OutOfMemory;
  147. ret = item->SetKey(key);
  148. if (ret != NErr_Success)
  149. {
  150. delete item;
  151. return ret;
  152. }
  153. ret = item->Set(value);
  154. if (ret != NErr_Success)
  155. {
  156. delete item;
  157. return ret;
  158. }
  159. ret = tag->AddItem(item);
  160. if (ret != NErr_Success)
  161. {
  162. delete item;
  163. return ret;
  164. }
  165. return NErr_Success;
  166. }
  167. }
  168. else
  169. {
  170. tag->Remove(key, index);
  171. return NErr_Success;
  172. }
  173. }
  174. int NSAPEv2_Tag_GetBinary(const nsapev2_tag_t t, const char *key, unsigned int index, const void **bytes, size_t *length)
  175. {
  176. const APEv2::Tag *tag = (const APEv2::Tag *)t;
  177. if (!tag)
  178. return NErr_Empty;
  179. return tag->GetData(key, index, bytes, length);
  180. }
  181. int NSAPEv2_Tag_SetBinary(nsapev2_tag_t t, const char *key, unsigned int index, const void *bytes, size_t length)
  182. {
  183. APEv2::Tag *tag = (APEv2::Tag *)t;
  184. if (!tag)
  185. return NErr_BadParameter;
  186. if (bytes)
  187. {
  188. APEv2::Item *item;
  189. int ret = tag->GetItem(key, index, &item);
  190. if (ret == NErr_Success)
  191. {
  192. return item->Set(bytes, length, nsapev2_item_type_binary);
  193. }
  194. else
  195. {
  196. /* no such item, need to make a new one */
  197. item = new (std::nothrow) APEv2::Item;
  198. if (!item)
  199. return NErr_OutOfMemory;
  200. ret = item->SetKey(key);
  201. if (ret != NErr_Success)
  202. {
  203. delete item;
  204. return ret;
  205. }
  206. ret = item->Set(bytes, length, nsapev2_item_type_binary);
  207. if (ret != NErr_Success)
  208. {
  209. delete item;
  210. return ret;
  211. }
  212. ret = tag->AddItem(item);
  213. if (ret != NErr_Success)
  214. {
  215. delete item;
  216. return ret;
  217. }
  218. return NErr_Success;
  219. }
  220. }
  221. else
  222. {
  223. tag->Remove(key, index);
  224. return NErr_Success;
  225. }
  226. }
  227. static int SetArtwork(APEv2::Item *item, const char *filename, const void *bytes, size_t length)
  228. {
  229. size_t filename_length = filename?strlen(filename):0;
  230. size_t total_length = filename_length
  231. + 1 /* null separator */
  232. + length;
  233. void *item_data;
  234. int ret = item->New(total_length, nsapev2_item_type_binary, &item_data);
  235. if (ret != NErr_Success)
  236. return ret;
  237. bytewriter_s byte_writer;
  238. bytewriter_init(&byte_writer, item_data, total_length);
  239. bytewriter_write_n(&byte_writer, filename, filename_length);
  240. bytewriter_write_u8(&byte_writer, 0);
  241. bytewriter_write_n(&byte_writer, bytes, length);
  242. return NErr_Success;
  243. }
  244. int NSAPEv2_Tag_SetArtwork(nsapev2_tag_t t, const char *key, unsigned int index, const char *filename, const void *bytes, size_t length)
  245. {
  246. APEv2::Tag *tag = (APEv2::Tag *)t;
  247. if (!tag)
  248. return NErr_BadParameter;
  249. if (bytes)
  250. {
  251. APEv2::Item *item;
  252. int ret = tag->GetItem(key, index, &item);
  253. if (ret == NErr_Success)
  254. {
  255. return SetArtwork(item, filename, bytes, length);
  256. }
  257. else
  258. {
  259. /* no such item, need to make a new one */
  260. item = new (std::nothrow) APEv2::Item;
  261. if (!item)
  262. return NErr_OutOfMemory;
  263. ret = item->SetKey(key);
  264. if (ret != NErr_Success)
  265. {
  266. delete item;
  267. return ret;
  268. }
  269. ret = SetArtwork(item, filename, bytes, length);
  270. if (ret != NErr_Success)
  271. {
  272. delete item;
  273. return ret;
  274. }
  275. ret = tag->AddItem(item);
  276. if (ret != NErr_Success)
  277. {
  278. delete item;
  279. return ret;
  280. }
  281. return NErr_Success;
  282. }
  283. }
  284. else
  285. {
  286. tag->Remove(key, index);
  287. return NErr_Success;
  288. }
  289. }
  290. int NSAPEv2_Tag_EnumerateItems(const nsapev2_tag_t t, const nsapev2_item_t s, nsapev2_item_t *next)
  291. {
  292. const APEv2::Tag *tag = (const APEv2::Tag *)t;
  293. if (!tag)
  294. return NErr_NullPointer;
  295. const APEv2::Item *start = (const APEv2::Item *)s;
  296. return tag->EnumerateItems(start, (APEv2::Item **)next);
  297. }
  298. int NSAPEv2_Tag_GetItemCount(const nsapev2_tag_t t, size_t *count)
  299. {
  300. const APEv2::Tag *tag = (const APEv2::Tag *)t;
  301. if (!tag)
  302. return NErr_NullPointer;
  303. return tag->GetItemCount(count);
  304. }
  305. int NSAPEv2_Tag_GetItemAtIndex(const nsapev2_tag_t t, unsigned int index, nsapev2_item_t *item)
  306. {
  307. APEv2::Tag *tag = (APEv2::Tag *)t;
  308. if (!tag)
  309. return NErr_NullPointer;
  310. return tag->GetItemAtIndex(index, (APEv2::Item **)item);
  311. }
  312. int NSAPEv2_Item_GetInformation(const nsapev2_item_t i, const char **key, uint32_t *flags)
  313. {
  314. const APEv2::Item *item = (const APEv2::Item *)i;
  315. if (!item)
  316. return NErr_NullPointer;
  317. if (key)
  318. {
  319. int ret = item->GetKey(key);
  320. if (ret != NErr_Success)
  321. return ret;
  322. }
  323. if (flags)
  324. *flags = item->GetFlags();
  325. return NErr_Success;
  326. }
  327. int NSAPEv2_Item_GetString(const nsapev2_item_t i, nx_string_t *value)
  328. {
  329. const APEv2::Item *item = (const APEv2::Item *)i;
  330. if (!item)
  331. return NErr_BadParameter;
  332. const void *data;
  333. size_t data_len;
  334. int ret = item->Get(&data, &data_len);
  335. if (ret != NErr_Success)
  336. return ret;
  337. return NXStringCreateWithBytes(value, data, data_len, nx_charset_utf8);
  338. }
  339. int NSAPEv2_Item_GetBinary(const nsapev2_item_t i, const void **bytes, size_t *length)
  340. {
  341. const APEv2::Item *item = (const APEv2::Item *)i;
  342. if (!item)
  343. return NErr_BadParameter;
  344. return item->Get(bytes, length);
  345. }
  346. int NSAPEv2_Item_SetKey(nsapev2_item_t i, const char *key)
  347. {
  348. APEv2::Item *item = (APEv2::Item *)i;
  349. if (!item)
  350. return NErr_BadParameter;
  351. return item->SetKey(key);
  352. }
  353. int NSAPEv2_Item_SetString(nsapev2_item_t i, nx_string_t value)
  354. {
  355. APEv2::Item *item = (APEv2::Item *)i;
  356. if (!item)
  357. return NErr_BadParameter;
  358. return item->Set(value);
  359. }
  360. int NSAPEv2_Tag_RemoveItem(nsapev2_tag_t t, nsapev2_item_t i)
  361. {
  362. APEv2::Tag *tag = (APEv2::Tag *)t;
  363. if (!tag)
  364. return NErr_BadParameter;
  365. APEv2::Item *item = (APEv2::Item *)i;
  366. if (!item)
  367. return NErr_BadParameter;
  368. tag->RemoveItem(item);
  369. return NErr_Success;
  370. }
  371. int NSAPEv2_Tag_AddItem(nsapev2_tag_t t, nsapev2_item_t *i)
  372. {
  373. APEv2::Tag *tag = (APEv2::Tag *)t;
  374. if (!tag)
  375. return NErr_BadParameter;
  376. APEv2::Item **item = (APEv2::Item **)i;
  377. if (!item)
  378. return NErr_NullPointer;
  379. *item = new (std::nothrow) APEv2::Item;
  380. if (!*item)
  381. return NErr_OutOfMemory;
  382. return tag->AddItem(*item);
  383. }