⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tag.cpp

📁 FreeAMP(MP3播放)程序源代码-用来研究MP3解码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// $Id: tag.cpp,v 1.2 2001/01/16 21:08:01 robert Exp $

// id3lib: a C++ library for creating and manipulating id3v1/v2 tags
// Copyright 1999, 2000  Scott Thomas Haug

// 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/

#include "id3config.h"
#include "tag.h"
#include "readers.h"
#include "writers.h"
#include "tag_impl.h"
#include "strings.h"
#include "utils.h"

using namespace dami;

/** \mainpage id3lib Library Documentation
 **
 ** \section tutorial Quick Tutorial
 ** 
 ** This tutorial will quickly get you up and running with id3lib.
 **
 ** \subsection download Downloading id3lib
 **
 ** First, id3lib must be a part of your development environment.  The latest
 ** files can always be downloaded from the <a href="http://id3lib.sourceforge.net">id3lib homepage</a>.
 **
 ** \subsection include Preparing your source code
 **
 ** To use the basic functionality of id3lib in your C++ code, a single
 ** \c #include is necessary.
 **
 ** \code
 **   #include <id3/tag.h>
 ** \endcode
 **
 ** There are other files that must be included to access more advanced
 ** functionality, but this will do most of the core functionality.
 ** 
 ** \subsection creation Creating a tag
 ** 
 ** Almost all functionality occurs via an ID3_Tag object.  An ID3_Tag object
 ** basically encapsulates two things: a collection of ID3_Frame objects and
 ** file information.  The goal is to populate an ID3_Tag object with ID3_Frame
 ** objects, and the easiest way to do this is to associate the tag with a
 ** file.  This is done primarily via the ID3_Tag constructor, like so:
 **
 ** \code
 **   ID3_Tag myTag("song.mp3");
 ** \endcode
 **
 ** This constructor links, or associates, the object \c tag with the file
 ** "song.mp3".  In doing so, the tagging information from "song.mp3" is parsed
 ** and added to \c tag.  This association can also be accomplished by creating
 ** an empty tag and making an explicit call to Link().
 **
 ** \code
 **   ID3_Tag myTag;
 **   myTag.Link("song.mp3");
 ** \endcode
 **
 ** The default behavior of Link() is to parse all possible tagging information
 ** and convert it into ID3v2 frames.  The tagging information parsed can be
 ** limited to a particular type (or types) of tag by passing an ID3_TagType
 ** (or combination of ID3_TagType's).  For example, to read only the ID3v1
 ** tag, pass in the constant ID3TT_ID3V1.
 **
 ** \code
 **   myTag.Link("song.mp3", ID3TT_ID3V1);
 ** \endcode
 **
 ** Another example would be to read in all tags that could possibly appear at
 ** the end of the file.
 **
 ** \code
 **   myTag.Link("song.mp3", ID3TT_ID3V1 | ID3TT_LYRICS3V2 | ID3TT_MUSICMATCH);
 ** \endcode
 **
 ** \section accessing Accessing the Tag Data
 **
 ** After linking with a file, the object \c myTag now contains some or all of
 ** the tagging information present in the file "song.mp3", represented as
 ** ID3v2 frames.  How can that information be accessed?  There a variety of
 ** ways to do this.  One is to iterate through all the frames in the tag.
 **
 ** \code
 **   // use an std::auto_ptr here to handle object cleanup automatically
 **   ID3_Tag::Iterator* iter = tag.createIterator();
 **   ID3_Frame* myFrame = NULL;
 **   while (NULL != (myFrame = iter->GetNext())
 **   {
 **     // do something with myFrame
 **   }
 **   delete iter;
 ** \endcode
 **
 ** Another way to access tagging information is by searching for specific
 ** frames using the Find() method.  For example, the album frame can be found
 ** in the following manner:
 **
 ** \code
 **   ID3_Frame* myFrame = myTag.Find(ID3FID_ALBUM);
 **   if (NULL != myFrame)
 **   {
 **     // do something with myFrame
 **   }
 ** \endcode
 **
 ** The Find() method can be used to search for frames with specific
 ** information.  For example, the following code can be used to find the frame
 ** with the title "Nirvana".
 **
 ** \code
 **   ID3_Frame* myFrame = myTag.Find(ID3FID_TITLE, ID3FN_TEXT, "Nirvana")));
 **   if (NULL != myFrame)
 **   {
 **     // do something with myFrame
 **   }
 ** \endcode
 **     
 ** As indicated, the Find() method will return a NULL pointer if no such frame
 ** can be found.  If more than one frame meets the search criteria, subsequent
 ** calls to Find() with the same parameters will return the other matching
 ** frames.  The Find() method is guaranteed to return all matching frames
 ** before it wraps around to return the first matching frame.
 **
 ** All ID3_Frame objects are comprised of a collection of ID3_Field objects.
 ** These fields can represent text, numbers, or binary data.  As with frames,
 ** fields can be accessed in a variety of manners.  The fields of a frame
 ** can be iterated over in much the same manner of the frames of a tag.
 **
 ** \code
 **   // use an std::auto_ptr here to handle object cleanup automatically
 **   ID3_Frame::Iterator* iter = myFrame->createIterator();
 **   ID3_Field* myField = NULL;
 **   while (NULL != (myField = iter->GetNext())
 **   {
 **     // do something with myField
 **   }
 **   delete iter;
 ** \endcode
 **
 ** If you know which field type you're looking for, you can access it
 ** directly.
 **
 ** \code
 **   ID3_Field* myField = myFrame->GetField(ID3FN_TEXT);
 **   while (NULL != myField)
 **   {
 **     // do something with myField
 **   }
 ** \endcode
 **
 ** This documentation currently does not include a list of all possible field
 ** types, nor does it include all possible frame types and the fields they 
 ** contain.  The source code is the best resource for that information.
 **
 ** \todo List all field and frame types.
 **
 ** The ID3_Field represents a single piece of data within an ID3v2 frame.  As
 ** mentioned, an ID3_Field can represent three possible types of
 ** data: integers, binary data, and test strings.  The type of a particular
 ** field object is immutable; it is determined at the time of its construction
 ** (almost always when a frame is constructed) and can't be changed.  If in
 ** doubt, the field type can be accessed through its GetType() method.
 **
 ** Having an ID3_Field object isn't much use if you cannot access and/or 
 ** alter its data.  Luckily, the id3lib API provides overloaded \c Set and
 ** \c Get methods for all data types.
 **
 ** If the field is an integer, the following methods can be used to access
 ** the data.
 **
 ** \code
 **   uint32 val = myField->Get();
 **   myField->Set(5);
 **   (*myField) = 10;
 ** \endcode
 **
 ** All text data is accessed in a slightly different manner.  The following
 ** code example best illustrates these differences.
 **
 ** \code
 **   // for ascii strings
 **   char str1[1024];
 **   const char* p1 = "My String";
 **   const char* p2 = "My Other String";
 **
 **   myField->Set(p1);
 **   (*myField) = p2;  // equivalent to Set
 **
 **   myField->Get(str1, 1024); // copies up to 1024 bytes of the field data into str1
 **   p1 = myField->GetRawText(); // returns a pointer to the internal string
 ** \endcode
 **
 ** Binary data is similar to text data, except that its base type is a pointer
 ** to an unsigned, rather than a signed, char.
 **
 ** \code
 **   // for binary strings
 **   uchar data[1024];
 **   const uchar *p1 = getBinaryData(); // not an id3lib function
 **   size_t size = getBinarySize();     // not an id3lib function
 **
 **   myField->Set(p1, size);
 **
 **   myField->Get(data, 1024); // copies up to 1024 bytes of the field data into str1
 **   p1 = myField->GetRawBinary(); // returns a pointer to the internal string
 ** \endcode
 **
 ** \section updating Updating the Tag
 **
 ** When you're ready to save your changes back to the file, a single call to
 ** Update() is sufficient.
 **
 ** \code
 **   tag.Update();
 ** \endcode
 **
 **/

/** \class ID3_Tag tag.h id3/tag.h
 ** \brief The representative class of an id3 tag.
 ** 
 ** The ID3_Tag is, at its simplest, a container for ID3v2 frames.  At its
 ** most complicated, it's a kitchen-sink, monolithic "catch-all" class for
 ** handling almost every task associated with creating, parsing, rendering,
 ** and manipulating digital audio data using id3lib.
 ** 
 ** This simple \c #include does it all.  In order to read an existing tag, do
 ** the following:
 **
 ** \code
 **   ID3_Tag myTag;
 **   myTag.Link("something.mp3");
 ** \endcode
 ** 
 ** That is all there is to it.  Now all you have to do is use the Find()
 ** method to locate the frames you are interested in is the following:
 ** 
 ** \code
 **   ID3_Frame* myFrame = myTag.Find(ID3FID_TITLE);
 **   if (NULL != myFrame)
 **   {
 **     const char* title = myFrame->GetField(ID3FN_TEXT)->GetText();
 **     cout << "Title: " << title << endl;
 **   }
 ** \endcode
 ** 
 ** This code snippet locates the ID3FID_TITLE frame and displays the
 ** text field.
 **
 ** When using the ID3_Tag::Link() method, you automatically gain access to any
 ** ID3v1/1.1, ID3v2, Lyrics3 v2.0, and MusicMatch tags present in the file.
 ** The class will automaticaly parse and convert any of these foreign tag
 ** formats into ID3v2 tags.  Also, id3lib will correctly parse any correctly
 ** formatted 'CDM' frames from the unreleased ID3v2 2.01 draft specification.
 **
 ** \author Dirk Mahoney
 ** \version $Id: tag.cpp,v 1.2 2001/01/16 21:08:01 robert Exp $
 ** \sa ID3_Frame
 ** \sa ID3_Field
 ** \sa ID3_Err
 **/

/** Default constructor; it can accept an optional filename as a parameter.
 **
 ** If this file exists, it will be opened and all id3lib-supported tags will
 ** be parsed and converted to ID3v2 if necessary.  After the conversion, the
 ** file will remain unchanged, and will continue to do so until you use the
 ** Update() method on the tag (if you choose to Update() at all).
 **
 ** \param name The filename of the mp3 file to link to
 **/
ID3_Tag::ID3_Tag(const char *name)
  : _impl(new ID3_TagImpl(name))
{
}

/** Standard copy constructor.
 **
 ** \param tag What is copied into this tag
 **/
ID3_Tag::ID3_Tag(const ID3_Tag &tag)
  : _impl(new ID3_TagImpl(tag))
{
}

ID3_Tag::~ID3_Tag()
{
  delete _impl;
}

/** Clears the object and disassociates it from any files.
 **
 ** Frees any resources for which the object is responsible, including all
 ** frames and files.  After a call to Clear(), the object can be used
 ** again for any new or existing tag.
 **/
void ID3_Tag::Clear()
{
  _impl->Clear();
}


/** Indicates whether the tag has been altered since the last parse, render,
 ** or update.
 **
 ** If you have a tag linked to a file, you do not need this method since the
 ** Update() method will check for changes before writing the tag.
 ** 
 ** This method is primarily intended as a status indicator for applications
 ** and for applications that use the Parse() and Render() methods.
 **
 ** Setting a field, changed the ID of an attached frame, setting or grouping
 ** or encryption IDs, and clearing a frame or field all constitute a change
 ** to the tag, as do calls to the SetUnsync(), SetExtendedHeader(), and
 ** SetPadding() methods.
 ** 
 ** \code
 **   if (myTag.HasChanged())
 **   {
 **     // render and output the tag
 **   }
 ** \endcode
 ** 
 ** \return Whether or not the tag has been altered.
 **/
bool ID3_Tag::HasChanged() const
{
  return _impl->HasChanged();
}

/** Returns an over estimate of the number of bytes required to store a
 ** binary version of a tag. 
 ** 
 ** When using Render() to render a binary tag to a
 ** memory buffer, first use the result of this call to allocate a buffer of
 ** unsigned chars.
 ** 
 ** \code
 **   if (myTag.HasChanged())
 **   {
 **     size_t tagSize; = myTag.Size();
 **     if (tagSize > 0)
 **     {
 **       uchar *buffer = new uchar[tagSize];
 **       if (NULL != buffer)
 **       {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -