1 /* 2 3 Interface for applicative tag classes 4 5 copyright (c) 2004 squell <squell@alumina.nl> 6 7 use, modification, copying and distribution of this software is permitted 8 under the conditions described in the file 'COPYING'. 9 10 Usage: 11 12 Use a handler object to specify the changes to make and use the modify() 13 member to make those changes to multiple files. If rewrite() is used and no 14 changes were specified, modify() will remove any tags it encounters. To add 15 tags to files that don't already have them, also use create() 16 17 modify() parses "%x" variables using string_parm::edit 18 19 Restrictions: 20 21 vmodify() should throw tag::failure on critical errors. 22 23 virtual destructor in tag::handler and tag::provider ommitted for 24 filesize issues with gcc3. 25 26 */ 27 28 #ifndef __ZF_SET_BASE_HPP 29 #define __ZF_SET_BASE_HPP 30 31 #include <string> 32 #include <utility> 33 #include <vector> 34 #include <stdexcept> 35 #include "sedit.h" 36 37 namespace tag { 38 39 enum ID3field { 40 title, artist, album, year, cmnt, track, genre, FIELD_MAX 41 }; 42 43 class writer; // interface for writing to files 44 class reader; // interface for providing readers 45 class handler; // abstract base class 46 47 class metadata; // class abstracting tag info 48 49 class failure; // exception class 50 51 } 52 53 54 namespace tag { 55 56 /////////////////////////////////////////////////////// 57 // tag writing interface // 58 /////////////////////////////////////////////////////// 59 60 class writer { 61 public: 62 typedef stredit::function function; 63 64 bool modify(const char* fn, const function& sub = stredit::identity()) const 65 { return vmodify(fn, sub); } 66 modify(const char * fn,const T * var)67 template<class T> bool modify(const char* fn, const T* var) const 68 { return vmodify(fn, stredit::array(var)); } 69 70 protected: 71 virtual bool vmodify(const char*, const function&) const = 0; ~writer()72 ~writer() { } // disable outside destruction 73 }; 74 75 /////////////////////////////////////////////////////// 76 // tag reading interface // 77 /////////////////////////////////////////////////////// 78 79 class reader { 80 public: 81 virtual metadata* read(const char*) const = 0; 82 protected: ~reader()83 ~reader() { } 84 }; 85 86 class metadata { 87 public: 88 typedef stredit::function::result value_string; 89 typedef std::vector< std::pair<std::string, value_string> > array; 90 91 virtual value_string operator[](ID3field) const = 0; 92 virtual array listing() const = 0; 93 virtual operator bool() const = 0; ~metadata()94 virtual ~metadata() { } 95 96 protected: // a pre-defined factory 97 template<class Instance> struct factory : reader { readfactory98 virtual metadata* read(const char* fn) const 99 { return new Instance(fn); } 100 }; 101 }; 102 103 /////////////////////////////////////////////////////// 104 // tag setting/getting interface // 105 /////////////////////////////////////////////////////// 106 107 class handler : public writer { 108 public: 109 110 // standard state set methods 111 112 virtual handler& set(ID3field, std::string) = 0; 113 virtual handler& rewrite(bool = true) = 0; 114 virtual handler& create(bool = true) = 0; 115 116 // free-form set methods (optional - default to no-op) 117 118 virtual handler& reserve(std::size_t req = 0) 119 { return *this; } set(std::string,std::string)120 virtual bool set(std::string, std::string) 121 { return false; } rm(std::string)122 virtual bool rm(std::string) 123 { return false; } from(const char * fn)124 virtual bool from(const char* fn) 125 { return false; } 126 127 protected: ~handler()128 ~handler() { } // disable outside destruction 129 }; 130 131 /////////////////////////////////////////////////////// 132 // severe error reporting // 133 /////////////////////////////////////////////////////// 134 135 class failure : public std::runtime_error { 136 public: 137 explicit failure(const std::string& err, const std::string& extra = std::string()) 138 : std::runtime_error(err + extra) { } 139 }; 140 141 } 142 143 #endif 144 145