00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <wmaattribute.h>
00023 #include <wmafile.h>
00024
00025 using namespace TagLib;
00026
00027 class WMA::Attribute::AttributePrivate
00028 {
00029 public:
00030 AttributeTypes type;
00031 String name;
00032 String value_string;
00033 ByteVector value_bytes;
00034 union {
00035 int value_int;
00036 long long value_longlong;
00037 };
00038 };
00039
00041
00043
00044 WMA::Attribute::Attribute()
00045 {
00046 d = new AttributePrivate;
00047 d->name = String::null;
00048 d->type = UnicodeType;
00049 }
00050
00051 WMA::Attribute::Attribute(WMA::File &file)
00052 {
00053 d = new AttributePrivate;
00054 parse(file);
00055 }
00056
00057 WMA::Attribute::Attribute(const String &name, const String &value)
00058 {
00059 d = new AttributePrivate;
00060 d->name = name;
00061 d->type = UnicodeType;
00062 d->value_string = value;
00063 }
00064
00065 WMA::Attribute::Attribute(const String &name, const ByteVector &value)
00066 {
00067 d = new AttributePrivate;
00068 d->name = name;
00069 d->type = BytesType;
00070 d->value_bytes = value;
00071 }
00072
00073 WMA::Attribute::Attribute(const String &name, unsigned int value)
00074 {
00075 d = new AttributePrivate;
00076 d->name = name;
00077 d->type = DWordType;
00078 d->value_int = value;
00079 }
00080
00081 WMA::Attribute::Attribute(const String &name, unsigned long long value)
00082 {
00083 d = new AttributePrivate;
00084 d->name = name;
00085 d->type = QWordType;
00086 d->value_longlong = value;
00087 }
00088
00089 WMA::Attribute::Attribute(const String &name, unsigned short value)
00090 {
00091 d = new AttributePrivate;
00092 d->name = name;
00093 d->type = WordType;
00094 d->value_int = value;
00095 }
00096
00097 WMA::Attribute::Attribute(const String &name, bool value)
00098 {
00099 d = new AttributePrivate;
00100 d->name = name;
00101 d->type = BoolType;
00102 d->value_int = value;
00103 }
00104
00105 WMA::Attribute::Attribute(const Attribute &attr)
00106 {
00107 d = new AttributePrivate(*attr.d);
00108 }
00109
00110 WMA::Attribute::~Attribute()
00111 {
00112 if(d)
00113 delete d;
00114 }
00115
00116 String WMA::Attribute::name() const
00117 {
00118 return d->name;
00119 }
00120
00121 WMA::Attribute::AttributeTypes WMA::Attribute::type() const
00122 {
00123 return d->type;
00124 }
00125
00126 String WMA::Attribute::toString() const
00127 {
00128 return d->value_string;
00129 }
00130
00131 ByteVector WMA::Attribute::toByteVector() const
00132 {
00133 return d->value_bytes;
00134 }
00135
00136 int WMA::Attribute::toInt() const
00137 {
00138 if (d->type == UnicodeType)
00139 return d->value_string.toInt();
00140 else
00141 return d->value_int;
00142 }
00143
00144 long long WMA::Attribute::toLongLong() const
00145 {
00146 return d->value_longlong;
00147 }
00148
00149 bool WMA::Attribute::parse(WMA::File &f)
00150 {
00151 int size = f.readWORD();
00152 f.readString(size, d->name);
00153
00154 d->type = (WMA::Attribute::AttributeTypes)f.readWORD();
00155 size = f.readWORD();
00156
00157 switch(d->type) {
00158 case WordType:
00159 d->value_int = f.readWORD();
00160 break;
00161
00162 case BoolType:
00163 case DWordType:
00164 d->value_int = f.readDWORD();
00165 break;
00166
00167 case QWordType:
00168 d->value_longlong = f.readQWORD();
00169 break;
00170
00171 case UnicodeType:
00172 f.readString(size, d->value_string);
00173 break;
00174
00175 case BytesType:
00176 d->value_bytes = f.readBlock(size);
00177 break;
00178
00179 default:
00180 return false;
00181 }
00182
00183 return true;
00184 }
00185
00186 ByteVector WMA::Attribute::render() const
00187 {
00188 ByteVector data;
00189
00190 ByteVector v = d->name.data(String::UTF16LE);
00191 data.append(ByteVector::fromShort(v.size() + 2, false));
00192 data.append(v + ByteVector::fromShort(0, false));
00193
00194 data.append(ByteVector::fromShort((int)d->type, false));
00195
00196 switch (d->type) {
00197 case WordType:
00198 data.append(ByteVector::fromShort(2, false));
00199 data.append(ByteVector::fromShort(d->value_int, false));
00200 break;
00201
00202 case BoolType:
00203 case DWordType:
00204 data.append(ByteVector::fromShort(4, false));
00205 data.append(ByteVector::fromUInt(d->value_int, false));
00206 break;
00207
00208 case QWordType:
00209 data.append(ByteVector::fromShort(8, false));
00210 data.append(ByteVector::fromLongLong(d->value_longlong, false));
00211 break;
00212
00213 case UnicodeType:
00214 v = d->value_string.data(String::UTF16LE);
00215 data.append(ByteVector::fromShort(v.size() + 2, false));
00216 data.append(v + ByteVector::fromShort(0, false));
00217 break;
00218
00219 case BytesType:
00220 data.append(ByteVector::fromShort(d->value_bytes.size(), false));
00221 data.append(d->value_bytes);
00222 break;
00223
00224 default:
00225 return ByteVector::null;
00226 }
00227
00228 return data;
00229 }
00230
00231