00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #if defined HAVE_CONFIG_H
00028 #include <config.h>
00029 #endif
00030
00031 #include <string.h>
00032 #include "tag.h"
00033 #include "frame_impl.h"
00034 #include "field_impl.h"
00035 #include "frame_def.h"
00036 #include "field_def.h"
00037
00038 ID3_FrameImpl::ID3_FrameImpl(ID3_FrameID id)
00039 : _changed(false),
00040 _bitset(),
00041 _fields(),
00042 _encryption_id('\0'),
00043 _grouping_id('\0')
00044 {
00045 this->SetSpec(ID3V2_LATEST);
00046 this->SetID(id);
00047 }
00048
00049 ID3_FrameImpl::ID3_FrameImpl(const ID3_FrameHeader &hdr)
00050 : _changed(false),
00051 _bitset(),
00052 _fields(),
00053 _hdr(hdr),
00054 _encryption_id('\0'),
00055 _grouping_id('\0')
00056 {
00057 this->_InitFields();
00058 }
00059
00060 ID3_FrameImpl::ID3_FrameImpl(const ID3_Frame& frame)
00061 : _changed(false),
00062 _bitset(),
00063 _fields(),
00064 _encryption_id('\0'),
00065 _grouping_id('\0')
00066 {
00067 *this = frame;
00068 }
00069
00070 ID3_FrameImpl::~ID3_FrameImpl()
00071 {
00072 Clear();
00073 }
00074
00075 bool ID3_FrameImpl::_ClearFields()
00076 {
00077 for (iterator fi = _fields.begin(); fi != _fields.end(); ++fi)
00078 {
00079 delete (ID3_FieldImpl*) *fi;
00080 }
00081
00082 _fields.clear();
00083 _bitset.reset();
00084
00085 _changed = true;
00086 return true;
00087 }
00088
00089 void ID3_FrameImpl::Clear()
00090 {
00091 this->_ClearFields();
00092 _hdr.Clear();
00093 _encryption_id = '\0';
00094 _grouping_id = '\0';
00095 }
00096
00097 void ID3_FrameImpl::_InitFields()
00098 {
00099 const ID3_FrameDef* info = _hdr.GetFrameDef();
00100 if (NULL == info)
00101 {
00102
00103 ID3_Field* fld = new ID3_FieldImpl(ID3_FieldDef::DEFAULT[0]);
00104 _fields.push_back(fld);
00105 _bitset.set(fld->GetID());
00106 }
00107 else
00108 {
00109
00110 for (size_t i = 0; info->aeFieldDefs[i]._id != ID3FN_NOFIELD; ++i)
00111 {
00112 ID3_Field* fld = new ID3_FieldImpl(info->aeFieldDefs[i]);
00113 _fields.push_back(fld);
00114 _bitset.set(fld->GetID());
00115 }
00116
00117 _changed = true;
00118 }
00119 }
00120
00121 bool ID3_FrameImpl::SetID(ID3_FrameID id)
00122 {
00123 bool changed = (this->GetID() != id);
00124 if (changed)
00125 {
00126 this->_SetID(id);
00127 _changed = true;
00128 }
00129 return changed;
00130 }
00131
00132 bool ID3_FrameImpl::_SetID(ID3_FrameID id)
00133 {
00134 bool changed = this->_ClearFields();
00135 changed = _hdr.SetFrameID(id) || changed;
00136 this->_InitFields();
00137 return changed;
00138 }
00139
00140 bool ID3_FrameImpl::SetSpec(ID3_V2Spec spec)
00141 {
00142 return _hdr.SetSpec(spec);
00143 }
00144
00145 ID3_V2Spec ID3_FrameImpl::GetSpec() const
00146 {
00147 return _hdr.GetSpec();
00148 }
00149
00150 ID3_Field* ID3_FrameImpl::GetField(ID3_FieldID fieldName) const
00151 {
00152 ID3_Field* field = NULL;
00153 if (this->Contains(fieldName))
00154 {
00155 for (const_iterator fi = _fields.begin(); fi != _fields.end(); ++fi)
00156 {
00157 if ((*fi)->GetID() == fieldName)
00158 {
00159 field = *fi;
00160 break;
00161 }
00162 }
00163 }
00164 return field;
00165 }
00166
00167 size_t ID3_FrameImpl::NumFields() const
00168 {
00169 return _fields.size();
00170 }
00171
00172 size_t ID3_FrameImpl::Size()
00173 {
00174 size_t bytesUsed = _hdr.Size();
00175
00176 if (this->GetEncryptionID())
00177 {
00178 bytesUsed++;
00179 }
00180
00181 if (this->GetGroupingID())
00182 {
00183 bytesUsed++;
00184 }
00185
00186 ID3_TextEnc enc = ID3TE_ASCII;
00187 for (iterator fi = _fields.begin(); fi != _fields.end(); ++fi)
00188 {
00189 if (*fi && (*fi)->InScope(this->GetSpec()))
00190 {
00191 if ((*fi)->GetID() == ID3FN_TEXTENC)
00192 {
00193 enc = (ID3_TextEnc) (*fi)->Get();
00194 }
00195 else
00196 {
00197 (*fi)->SetEncoding(enc);
00198 }
00199 bytesUsed += (*fi)->BinSize();
00200 }
00201 }
00202
00203 return bytesUsed;
00204 }
00205
00206
00207 bool ID3_FrameImpl::HasChanged() const
00208 {
00209 bool changed = _changed;
00210
00211 for (const_iterator fi = _fields.begin(); fi != _fields.end(); ++fi)
00212 {
00213 if (*fi && (*fi)->InScope(this->GetSpec()))
00214 {
00215 changed = (*fi)->HasChanged();
00216 }
00217 }
00218
00219 return changed;
00220 }
00221
00222 ID3_FrameImpl &
00223 ID3_FrameImpl::operator=( const ID3_Frame &rFrame )
00224 {
00225 ID3_FrameID eID = rFrame.GetID();
00226 this->SetID(eID);
00227 ID3_Frame::ConstIterator* ri = rFrame.CreateIterator();
00228 iterator li = this->begin();
00229 while (li != this->end())
00230 {
00231 ID3_Field* thisFld = *li++;
00232 const ID3_Field* thatFld = ri->GetNext();
00233 if (thisFld != NULL && thatFld != NULL)
00234 {
00235 *thisFld = *thatFld;
00236 }
00237 }
00238 delete ri;
00239 this->SetEncryptionID(rFrame.GetEncryptionID());
00240 this->SetGroupingID(rFrame.GetGroupingID());
00241 this->SetCompression(rFrame.GetCompression());
00242 this->SetSpec(rFrame.GetSpec());
00243 _changed = false;
00244
00245 return *this;
00246 }
00247
00248 const char* ID3_FrameImpl::GetDescription(ID3_FrameID id)
00249 {
00250 ID3_FrameDef* myFrameDef = ID3_FindFrameDef(id);
00251 if (myFrameDef != NULL)
00252 {
00253 return myFrameDef->sDescription;
00254 }
00255 return NULL;
00256 }
00257
00258 const char* ID3_FrameImpl::GetDescription() const
00259 {
00260 const ID3_FrameDef* def = _hdr.GetFrameDef();
00261 if (def)
00262 {
00263 return def->sDescription;
00264 }
00265 return NULL;
00266 }
00267