| // $Id: frame.cpp,v 1.35 2002/08/10 10:42:42 t1mpy Exp $ |
| |
| // id3lib: a C++ library for creating and manipulating id3v1/v2 tags |
| // Copyright 1999, 2000 Scott Thomas Haug |
| // Copyright 2002 Thijmen Klok (thijmen@id3lib.org) |
| |
| // This library is free software; you can redistribute it and/or modify it |
| // under the terms of the GNU Library General Public License as published by |
| // the Free Software Foundation; either version 2 of the License, or (at your |
| // option) any later version. |
| // |
| // This library is distributed in the hope that it will be useful, but WITHOUT |
| // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public |
| // License for more details. |
| // |
| // You should have received a copy of the GNU Library General Public License |
| // along with this library; if not, write to the Free Software Foundation, |
| // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| |
| // The id3lib authors encourage improvements and optimisations to be sent to |
| // the id3lib coordinator. Please see the README file for details on where to |
| // send such submissions. See the AUTHORS file for a list of people who have |
| // contributed to id3lib. See the ChangeLog file for a list of changes to |
| // id3lib. These files are distributed with id3lib at |
| // http://download.sourceforge.net/id3lib/ |
| |
| #if defined HAVE_CONFIG_H |
| #include <config.h> |
| #endif |
| |
| //#include "frame.h" |
| #include "readers.h" |
| #include "frame_impl.h" |
| |
| /** \class ID3_Frame frame.h id3/frame.h |
| ** \brief The representative class of an id3v2 frame. |
| ** |
| ** id3lib defines frames in a funny way. Using some nice c++ conventions, |
| ** ID3_FrameImpl class objects appear to be quite polymorphic; that is, they |
| ** can take on many forms. The same ID3_FrameImpl class provides the |
| ** facilities for the implementation of a complex APIC frame and for a simple |
| ** text frame. |
| ** |
| ** @author Dirk Mahoney |
| ** @version $Id: frame.cpp,v 1.35 2002/08/10 10:42:42 t1mpy Exp $ |
| ** @see ID3_Tag |
| ** @see ID3_Field |
| ** @see ID3_Err |
| **/ |
| |
| /** Default constructor; accepts as a default parameter the type of frame |
| ** to create. |
| ** |
| ** The parameter which will internally set the frame's structure. See |
| ** SetID() for more details. |
| ** |
| ** @param id The type of frame to create |
| ** @see ID3_FrameID |
| ** @see SetID |
| **/ |
| ID3_Frame::ID3_Frame(ID3_FrameID id) |
| : _impl(new ID3_FrameImpl(id)) |
| { |
| } |
| |
| ID3_Frame::ID3_Frame(const ID3_Frame& frame) |
| : _impl(new ID3_FrameImpl(frame)) |
| { |
| } |
| |
| ID3_Frame::~ID3_Frame() |
| { |
| delete _impl; |
| } |
| |
| /** Clears the frame of all data and resets the frame such that it can take |
| ** on the form of any id3v2 frame that id3lib supports. |
| ** |
| ** @see ID3_Tag::Clear |
| **/ |
| void ID3_Frame::Clear() |
| { |
| _impl->Clear(); |
| } |
| |
| /** Returns the type of frame that the object represents. |
| ** |
| ** Useful in conjunction with ID3_Tag::Find() method |
| ** |
| ** @returns The type, or id, of the frame |
| ** @see ID3_Tag::Find |
| **/ |
| ID3_FrameID ID3_Frame::GetID() const |
| { |
| return _impl->GetID(); |
| } |
| |
| /** Establishes the internal structure of an ID3_FrameImpl object so |
| ** that it represents the id3v2 frame indicated by the parameter |
| ** |
| ** Given an ID3_FrameID (a list of which is found in <id3/field.h>), |
| ** SetID() will structure the object according to the |
| ** frame you wish to implement. |
| ** |
| ** Either using this call or via the constructor, this must be the first |
| ** command performed on an ID3_FrameImpl object. |
| ** |
| ** \code |
| ** myFrame.SetID(ID3FID_TITLE); |
| ** \endcode |
| ** |
| ** @param id The type of frame this frame should be set to |
| ** @see ID3_FrameID |
| **/ |
| bool ID3_Frame::SetID(ID3_FrameID id) |
| { |
| return _impl->SetID(id); |
| } |
| |
| bool ID3_Frame::SetSpec(ID3_V2Spec spec) |
| { |
| return _impl->SetSpec(spec); |
| } |
| |
| ID3_V2Spec ID3_Frame::GetSpec() const |
| { |
| return _impl->GetSpec(); |
| } |
| |
| /** Returns a pointer to the frame's internal field indicated by the |
| ** parameter. |
| ** |
| ** \code |
| ** ID3_TextEnc enc; |
| ** enc = (ID3_TextEnc) myFrame.GetField(ID3FN_TEXTENC)->Get(); |
| ** \endcode |
| ** |
| ** @param name The name of the field to be retrieved |
| ** @returns A reference to the desired field |
| **/ |
| ID3_Field& ID3_Frame::Field(ID3_FieldID fieldName) const |
| { |
| return *this->GetField(fieldName); |
| } |
| |
| ID3_Field* ID3_Frame::GetField(ID3_FieldID fieldName) const |
| { |
| return _impl->GetField(fieldName); |
| } |
| |
| size_t ID3_Frame::NumFields() const |
| { |
| return _impl->NumFields(); |
| } |
| |
| /* |
| ID3_Field* ID3_Frame::GetFieldNum(size_t index) const |
| { |
| return _impl->GetFieldNum(index); |
| } |
| */ |
| |
| size_t ID3_Frame::Size() |
| { |
| return _impl->Size(); |
| } |
| |
| |
| bool ID3_Frame::HasChanged() const |
| { |
| return _impl->HasChanged(); |
| } |
| |
| ID3_Frame& ID3_Frame::operator=( const ID3_Frame &rFrame ) |
| { |
| if (this != &rFrame) |
| { |
| *_impl = rFrame; |
| } |
| return *this; |
| } |
| |
| const char* ID3_Frame::GetDescription(ID3_FrameID id) |
| { |
| return ID3_FrameImpl::GetDescription(id); |
| } |
| |
| const char* ID3_Frame::GetDescription() const |
| { |
| return _impl->GetDescription(); |
| } |
| |
| const char* ID3_Frame::GetTextID() const |
| { |
| return _impl->GetTextID(); |
| } |
| |
| bool ID3_Frame::Parse(ID3_Reader& reader) |
| { |
| try // Klenotic: Catch errors and return false instead of crashing. |
| { |
| return _impl->Parse(reader); |
| } |
| catch(...) |
| { |
| ID3D_WARNING( "ID3_Frame::Parse: call to _impl->Parse() failed"); |
| return false; |
| } |
| } |
| |
| void ID3_Frame::Render(ID3_Writer& writer) const |
| { |
| _impl->Render(writer); |
| } |
| |
| bool ID3_Frame::Contains(ID3_FieldID id) const |
| { |
| return _impl->Contains(id); |
| } |
| |
| /** Sets the compression flag within the frame. When the compression flag is |
| ** is set, compression will be attempted. However, the frame might not |
| ** actually be compressed after it is rendered if the "compressed" data is |
| ** no smaller than the "uncompressed" data. |
| **/ |
| bool ID3_Frame::SetCompression(bool b) |
| { |
| return _impl->SetCompression(b); |
| } |
| |
| /** Returns whether or not the compression flag is set. After parsing a tag, |
| ** this will indicate whether or not the frame was compressed. After |
| ** rendering a tag, however, it does not actually indicate if the frame is |
| ** compressed rendering. It only indicates whether or not compression was |
| ** attempted. A frame will not be compressed, even whent the compression |
| ** flag is set, if the "compressed" data is no smaller than the |
| ** "uncompressed" data. |
| **/ |
| bool ID3_Frame::GetCompression() const |
| { |
| return _impl->GetCompression(); |
| } |
| |
| size_t ID3_Frame::GetDataSize() const |
| { |
| return _impl->GetDataSize(); |
| } |
| |
| bool ID3_Frame::SetEncryptionID(uchar id) |
| { |
| return _impl->SetEncryptionID(id); |
| } |
| |
| uchar ID3_Frame::GetEncryptionID() const |
| { |
| return _impl->GetEncryptionID(); |
| } |
| |
| bool ID3_Frame::SetGroupingID(uchar id) |
| { |
| return _impl->SetGroupingID(id); |
| } |
| |
| uchar ID3_Frame::GetGroupingID() const |
| { |
| return _impl->GetGroupingID(); |
| } |
| |
| namespace |
| { |
| class IteratorImpl : public ID3_Frame::Iterator |
| { |
| ID3_FrameImpl::iterator _cur; |
| ID3_FrameImpl::iterator _end; |
| public: |
| IteratorImpl(ID3_FrameImpl& frame) |
| : _cur(frame.begin()), _end(frame.end()) |
| { |
| } |
| |
| ID3_Field* GetNext() |
| { |
| ID3_Field* next = NULL; |
| while (next == NULL && _cur != _end) |
| { |
| next = *_cur; |
| ++_cur; |
| } |
| return next; |
| } |
| }; |
| |
| |
| class ConstIteratorImpl : public ID3_Frame::ConstIterator |
| { |
| ID3_FrameImpl::const_iterator _cur; |
| ID3_FrameImpl::const_iterator _end; |
| public: |
| ConstIteratorImpl(ID3_FrameImpl& frame) |
| : _cur(frame.begin()), _end(frame.end()) |
| { |
| } |
| const ID3_Field* GetNext() |
| { |
| ID3_Field* next = NULL; |
| while (next == NULL && _cur != _end) |
| { |
| next = *_cur; |
| ++_cur; |
| } |
| return next; |
| } |
| }; |
| } |
| |
| ID3_Frame::Iterator* |
| ID3_Frame::CreateIterator() |
| { |
| return new IteratorImpl(*_impl); |
| } |
| |
| ID3_Frame::ConstIterator* |
| ID3_Frame::CreateIterator() const |
| { |
| return new ConstIteratorImpl(*_impl); |
| } |