1
0

nsid3v1.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. #include "nsid3v1.h"
  2. #include "tag.h"
  3. #include "foundation/error.h"
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <new>
  8. int NSID3v1_Header_Valid(const void *data, size_t len)
  9. {
  10. // return NErr_True or NErr_False depending on whether or not you detect that it's valid ID3v1
  11. if (memcmp(data, "TAG", 3) == 0)
  12. {
  13. return NErr_True;
  14. }
  15. return NErr_False;
  16. }
  17. int NSID3v1_Tag_Create(const void *data, size_t len, nsid3v1_tag_t *out_tag)
  18. {
  19. ID3v1::Tag *tag = new (std::nothrow) ID3v1::Tag();
  20. if (!tag)
  21. return NErr_OutOfMemory;
  22. int ret = tag->Parse(data, len);
  23. if (ret != NErr_Success)
  24. return ret;
  25. *out_tag = (nsid3v1_tag_t)tag;
  26. return NErr_Success;
  27. }
  28. int NSID3v1_Tag_New(nsid3v1_tag_t *out_tag)
  29. {
  30. ID3v1::Tag *tag = new (std::nothrow) ID3v1::Tag();
  31. if (!tag)
  32. return NErr_OutOfMemory;
  33. tag->New();
  34. *out_tag = (nsid3v1_tag_t)tag;
  35. return NErr_Success;
  36. }
  37. int NSID3v1_Tag_Serialize(const nsid3v1_tag_t t, void *data, size_t len)
  38. {
  39. ID3v1::Tag *tag = (ID3v1::Tag *)t;
  40. if (!tag)
  41. return NErr_BadParameter;
  42. return tag->Serialize(data, len);
  43. }
  44. int NSID3v1_Tag_Destroy(nsid3v1_tag_t t)
  45. {
  46. ID3v1::Tag *tag = (ID3v1::Tag *)t;
  47. if (!tag)
  48. return NErr_BadParameter;
  49. delete tag;
  50. return NErr_Success;
  51. }
  52. // Field getters
  53. int NSID3v1_Field_Text_Get(const nsid3v1_tag_t t, const int field, nx_string_t *out_value)
  54. {
  55. const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
  56. char track_num[4] = { 0, 0, 0 };
  57. if (tag)
  58. {
  59. switch (field)
  60. {
  61. case NSID3V1_TITLE:
  62. return NSID3v1_Get_Title(t, out_value);
  63. case NSID3V1_ARTIST:
  64. return NSID3v1_Get_Artist(t, out_value);
  65. case NSID3V1_ALBUM:
  66. return NSID3v1_Get_Album(t, out_value);
  67. case NSID3V1_YEAR:
  68. return NSID3v1_Get_Year(t, out_value);
  69. case NSID3V1_COMMENT:
  70. return NSID3v1_Get_Comment(t, out_value);
  71. case NSID3V1_TRACK:
  72. return NSID3v1_Get_Track(t, out_value);
  73. //case NSID3V1_GENRE:
  74. //return NSID3v1_Get_Genre(t, out_value);
  75. default:
  76. return NErr_Unknown;
  77. }
  78. }
  79. else
  80. return NErr_Empty;
  81. }
  82. int NSID3v1_Get_Title(nsid3v1_tag_t t, nx_string_t *value)
  83. {
  84. const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
  85. if (tag)
  86. {
  87. size_t value_length = tag->GetTitleLength();
  88. if (value_length > 0)
  89. return NXStringCreateWithBytes(value, tag->GetTitle(), value_length, nx_charset_latin1);
  90. else
  91. return NErr_Empty;
  92. return NErr_Success;
  93. }
  94. return NErr_Empty;
  95. }
  96. int NSID3v1_Get_Artist(nsid3v1_tag_t t, nx_string_t *value)
  97. {
  98. const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
  99. if (tag)
  100. {
  101. size_t value_length = tag->GetArtistLength();
  102. if (value_length > 0)
  103. return NXStringCreateWithBytes(value, tag->GetArtist(), value_length, nx_charset_latin1);
  104. else
  105. return NErr_Empty;
  106. return NErr_Success;
  107. }
  108. return NErr_Empty;
  109. }
  110. int NSID3v1_Get_Album(nsid3v1_tag_t t, nx_string_t *value)
  111. {
  112. const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
  113. if (tag)
  114. {
  115. size_t value_length = tag->GetAlbumLength();
  116. if (value_length > 0)
  117. return NXStringCreateWithBytes(value, tag->GetAlbum(), value_length, nx_charset_latin1);
  118. else
  119. return NErr_Empty;
  120. return NErr_Success;
  121. }
  122. return NErr_Empty;
  123. }
  124. int NSID3v1_Get_Year(nsid3v1_tag_t t, nx_string_t *value)
  125. {
  126. const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
  127. if (tag)
  128. {
  129. size_t value_length = tag->GetYearLength();
  130. if (value_length > 0)
  131. return NXStringCreateWithBytes(value, tag->GetYear(), value_length, nx_charset_latin1);
  132. else
  133. return NErr_Empty;
  134. }
  135. return NErr_Empty;
  136. }
  137. int NSID3v1_Get_Comment(nsid3v1_tag_t t, nx_string_t *value)
  138. {
  139. const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
  140. if (tag)
  141. {
  142. size_t value_length = tag->GetCommentLength();
  143. if (value_length > 0)
  144. return NXStringCreateWithBytes(value, tag->GetComment(), value_length, nx_charset_latin1);
  145. else
  146. return NErr_Empty;
  147. }
  148. return NErr_Empty;
  149. }
  150. int NSID3v1_Get_Track(nsid3v1_tag_t t, nx_string_t *value)
  151. {
  152. const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
  153. if (tag)
  154. {
  155. unsigned char track = tag->GetTrack();
  156. if (track > 0)
  157. return NXStringCreateWithUInt64(value, track);
  158. else
  159. return NErr_Empty;
  160. return NErr_Success;
  161. }
  162. return NErr_Empty;
  163. }
  164. int NSID3v1_Int_Get_Year(nsid3v1_tag_t t, unsigned int *value)
  165. {
  166. const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
  167. if (tag)
  168. {
  169. char year[5];
  170. memcpy(year, tag->GetYear(), 4);
  171. year[4]=0;
  172. *value = strtoul(year, 0, 10);
  173. return NErr_Success;
  174. }
  175. return NErr_Empty;
  176. }
  177. int NSID3v1_Int_Get_Track(nsid3v1_tag_t t, uint8_t *value)
  178. {
  179. const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
  180. if (tag)
  181. {
  182. *value = tag->GetTrack();
  183. return NErr_Success;
  184. }
  185. return NErr_Empty;
  186. }
  187. int NSID3v1_Int_Get_Genre(nsid3v1_tag_t t, uint8_t *value)
  188. {
  189. const ID3v1::Tag *tag = (const ID3v1::Tag *)t;
  190. if (tag)
  191. {
  192. *value = tag->GetGenre();
  193. return NErr_Success;
  194. }
  195. return NErr_Empty;
  196. }
  197. /* ================= setters ================= */
  198. typedef void (ID3v1::Tag::*Setter)(const char *, size_t length);
  199. template <size_t limit>
  200. static int SetFromString(ID3v1::Tag *tag, Setter setter, nx_string_t value)
  201. {
  202. if (!value)
  203. {
  204. (tag->*setter)(0, 0);
  205. return NErr_Success;
  206. }
  207. char temp[limit];
  208. size_t bytes_copied;
  209. int ret = NXStringGetBytes(&bytes_copied, value, temp, limit, nx_charset_latin1, 0);
  210. if (ret != NErr_Success)
  211. return ret;
  212. (tag->*setter)(temp, bytes_copied);
  213. return NErr_Success;
  214. }
  215. int NSID3v1_Set_Title(nsid3v1_tag_t t, nx_string_t value)
  216. {
  217. ID3v1::Tag *tag = (ID3v1::Tag *)t;
  218. if (!t)
  219. return NErr_BadParameter;
  220. return SetFromString<30>(tag, &ID3v1::Tag::SetTitle, value);
  221. }
  222. int NSID3v1_Set_Artist(nsid3v1_tag_t t, nx_string_t value)
  223. {
  224. ID3v1::Tag *tag = (ID3v1::Tag *)t;
  225. if (!t)
  226. return NErr_BadParameter;
  227. return SetFromString<30>(tag, &ID3v1::Tag::SetArtist, value);
  228. }
  229. int NSID3v1_Set_Album(nsid3v1_tag_t t, nx_string_t value)
  230. {
  231. ID3v1::Tag *tag = (ID3v1::Tag *)t;
  232. if (!t)
  233. return NErr_BadParameter;
  234. return SetFromString<30>(tag, &ID3v1::Tag::SetAlbum, value);
  235. }
  236. int NSID3v1_Set_Year(nsid3v1_tag_t t, nx_string_t value)
  237. {
  238. ID3v1::Tag *tag = (ID3v1::Tag *)t;
  239. if (!t)
  240. return NErr_BadParameter;
  241. return SetFromString<4>(tag, &ID3v1::Tag::SetYear, value);
  242. }
  243. int NSID3v1_Set_Comment(nsid3v1_tag_t t, nx_string_t value)
  244. {
  245. ID3v1::Tag *tag = (ID3v1::Tag *)t;
  246. if (!t)
  247. return NErr_BadParameter;
  248. return SetFromString<28>(tag, &ID3v1::Tag::SetComment, value);
  249. }
  250. int NSID3v1_Set_Track(nsid3v1_tag_t t, nx_string_t value)
  251. {
  252. ID3v1::Tag *tag = (ID3v1::Tag *)t;
  253. if (!t)
  254. return NErr_BadParameter;
  255. if (!value)
  256. {
  257. tag->SetTrack(0);
  258. return NErr_Success;
  259. }
  260. int temp=0;
  261. int ret = NXStringGetIntegerValue(value, &temp);
  262. if (ret != NErr_Success)
  263. return ret;
  264. if (temp < 0 || temp > 255)
  265. return NErr_ParameterOutOfRange;
  266. tag->SetTrack((uint8_t)temp);
  267. return NErr_Success;
  268. }
  269. int NSID3v1_Int_Set_Year(nsid3v1_tag_t t, unsigned int value)
  270. {
  271. ID3v1::Tag *tag = (ID3v1::Tag *)t;
  272. if (!t)
  273. return NErr_BadParameter;
  274. if (value > 9999)
  275. return NErr_ParameterOutOfRange;
  276. char temp[5];
  277. sprintf(temp, "%u", value);
  278. tag->SetYear(temp, 4);
  279. return NErr_Success;
  280. }
  281. int NSID3v1_Int_Set_Track(nsid3v1_tag_t t, uint8_t value)
  282. {
  283. ID3v1::Tag *tag = (ID3v1::Tag *)t;
  284. if (!t)
  285. return NErr_BadParameter;
  286. tag->SetTrack(value);
  287. return NErr_Success;
  288. }
  289. int NSID3v1_Int_Set_Genre(nsid3v1_tag_t t, uint8_t value)
  290. {
  291. ID3v1::Tag *tag = (ID3v1::Tag *)t;
  292. if (!t)
  293. return NErr_BadParameter;
  294. tag->SetGenre(value);
  295. return NErr_Success;
  296. }