metadata.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #pragma once
  2. #ifndef metadata_H_
  3. #define metadata_H_
  4. #include <map>
  5. #include "ID3miniParsers.h"
  6. #include "unicode/uniFile.h"
  7. // metadata class. Mostly just a container for key/value pairs
  8. // stored ala ID3V2. Some helper functions also to aid in
  9. // ID3V1 mapping
  10. /*
  11. metadata strings are stored in utf8 format
  12. */
  13. class metadata
  14. {
  15. public:
  16. // The metadata values are polymorphic since they may contain all sorts of differnt
  17. // types of information depending on the specific tag. All you can do with them
  18. // is clone them or convert them to xml
  19. class metaValue_base
  20. {
  21. public:
  22. virtual ~metaValue_base(){}
  23. virtual metaValue_base* clone() const throw() = 0;
  24. virtual metaValue_base* clone(const std::vector<uniString::utf8> &s) const = 0;
  25. virtual uniString::utf8 toXML(const std::string &tag) const throw() = 0;
  26. virtual uniString::utf8 toString() const throw() = 0;
  27. };
  28. // templatized subclass of metaValue_base. You instantiate this with a class or
  29. // struct of your creation that represents the specific data for a tag.
  30. // The most interesting part is the constructor. You must provide
  31. // an overload in the ID3V2 space (see ID3miniParsers.h) of the function
  32. // fromStringList() which loads your struct from a list of unicode strings. A string
  33. // list is adequate to represent all data coming out of ID3V2. Even binary hunks which
  34. // get base64 encoded before being passed in a list to your constructor.
  35. template<typename T>
  36. class metaValue: public metaValue_base
  37. {
  38. T m_value;
  39. std::vector<uniString::utf8> m_originalStringList;
  40. public:
  41. metaValue() {}
  42. metaValue(const T &v, const std::vector<uniString::utf8> &slist) : m_value(v), m_originalStringList(slist) {}
  43. metaValue(const std::vector<uniString::utf8> &slist) : m_originalStringList(slist)
  44. {
  45. ID3V2::fromStringList(slist,m_value);
  46. }
  47. virtual metaValue_base* clone() const throw()
  48. { return new metaValue<T>(m_originalStringList); }
  49. virtual metaValue_base* clone(const std::vector<uniString::utf8> &slist) const // clone with new data
  50. { return new metaValue<T>(slist); }
  51. virtual uniString::utf8 toString() const throw()
  52. { return ID3V2::toString(m_value); }
  53. virtual uniString::utf8 toXML(const std::string &tag) const throw()
  54. { return ID3V2::toXML(uniString::utf8(tag),m_value); }
  55. const T& value() const throw() { return m_value; }
  56. };
  57. private:
  58. typedef std::multimap<std::string,metaValue_base*> keyValueMap_t;
  59. keyValueMap_t m_keyValueMap;
  60. // make a copy of this object. Necessary because data is allocated on heap
  61. void copy(const metadata &m) throw();
  62. public:
  63. metadata() { m_keyValueMap.clear(); }
  64. // force our private copy() to be called in all copy scenarios
  65. metadata(const metadata &m);
  66. metadata& operator=(const metadata &m);
  67. /////////
  68. ~metadata() throw();
  69. void clear() throw();
  70. bool empty() const throw() { return m_keyValueMap.empty(); }
  71. // return true if a particular value exists at least once
  72. bool valueExists(const std::string &key) const throw();
  73. // note: setValue() takes ownership of the 'value' parameter. This will
  74. // add another key/value pair. Since we have a multimap, existing values of "key" are
  75. // not replaced.
  76. void setValue(const std::string &key,metaValue_base* value) throw();
  77. void removeValue(const std::string &key) throw(); // remove all values for key
  78. // only returns first one found
  79. const metaValue_base* getValue(const std::string &key) const throw();
  80. // returns a string representation of first instance found
  81. uniString::utf8 getValueAsString(const std::string &key) const throw();
  82. // V1 mappings
  83. static const std::string& NAME() throw() { static const std::string k("TIT2"); return k; }
  84. static const std::string& ARTIST() throw() { static const std::string k("TPE1"); return k; }
  85. static const std::string& ALBUM() throw() { static const std::string k("TALB"); return k; }
  86. static const std::string& YEAR() throw() { static const std::string k("TYER"); return k; }
  87. static const std::string& COMMENT() throw() { static const std::string k("COMM"); return k; }
  88. static const std::string& GENRE() throw() { static const std::string k("TCON"); return k; }
  89. // other mappings (flac/ogg/internal etc)
  90. static const std::string& COMPOSER() throw() { static const std::string k("TCOM"); return k; }
  91. static const std::string& PUBLISHER() throw() { static const std::string k("TPUB"); return k; }
  92. static const std::string& TRACKNUMBER() throw() { static const std::string k("TRCK"); return k; }
  93. static const std::string& DISKNUMBER() throw() { static const std::string k("TPOS"); return k; }
  94. static const std::string& ALBUMARTIST() throw() { static const std::string k("TPE2"); return k; }
  95. static const std::string& BAND() throw() { static const std::string k("TPE2"); return k; }
  96. static const std::string& PERFORMER() throw() { static const std::string k("TPE2"); return k; }
  97. static const std::string& CONDUCTOR() throw() { static const std::string k("TPE3"); return k; }
  98. static const std::string& BEATSPERMINUTE() throw() { static const std::string k("TBPM"); return k; }
  99. static const std::string& LYRICS() throw() { static const std::string k("USLT"); return k; }
  100. static const std::string& ENCODERSETTINGS() throw() { static const std::string k("TSSE"); return k; }
  101. static const std::string& RATING() throw() { static const std::string k("POPM"); return k; }
  102. static const std::string& PICTURE() throw() { static const std::string k("APIC"); return k; }
  103. static const std::string& CUSTOMTEXT() throw() { static const std::string k("TXXX"); return k; }
  104. static const std::string& VERSION() throw() { static const std::string k("TPE4"); return k; }
  105. static const std::string& COPYRIGHT() throw() { static const std::string k("TCOP"); return k; }
  106. static const std::string& LICENSE() throw() { static const std::string k("TOWN"); return k; }
  107. static const std::string& ISRC() throw() { static const std::string k("TSRC"); return k; }
  108. static const std::string& DJ() throw() { static const std::string k("DJ"); return k; }
  109. static const std::string& URL() throw() { static const std::string k("URL"); return k; }
  110. // output xml. "safe" functions deal with null value scenario without barfing
  111. static uniString::utf8 safeXML(const std::string &tag,const metaValue_base *m) throw();
  112. static uniString::utf8 safeString(const metaValue_base *m) throw();
  113. uniString::utf8 toXML() const throw();
  114. static uniString::utf8 toXML_fromFilename(const uniFile::filenameType &filename,
  115. const uniFile::filenameType &url,
  116. const uniString::utf8 &pattern) throw();
  117. static uniString::utf8 toFixedString(const uniFile::filenameType &filename) throw();
  118. bool get_replayGain(double &gain) const throw(); // return true if value found
  119. bool get_replayGain() const throw(); // same, but just the return value
  120. bool noMeaningfulMetadata() const throw(); // return true if metadata is empty, or stuff in there is not
  121. // useful for user (like replaygain).
  122. typedef size_t streamID_t;
  123. static uniString::utf8 convert_3902_to_shoutcast1(const uniString::utf8 &d, const streamID_t id) throw(std::runtime_error);
  124. static uniString::utf8 get_song_title_from_3902(const uniString::utf8 &d);
  125. static uniString::utf8 get_XX_from_3902(const uniString::utf8& node, const uniString::utf8 &d, const uniString::utf8 &old) throw(std::runtime_error);
  126. static std::vector<uniString::utf8> get_nextsongs_from_3902(const uniString::utf8 &d, std::vector<uniString::utf8>& oldSongList, bool first = false) throw(std::runtime_error);
  127. };
  128. extern const uniString::utf8 METADATA;
  129. extern const uniString::utf8 E_METADATA;
  130. #endif