1 /***************************************************************************
2     copyright            : (C) 2002 - 2008 by Scott Wheeler
3     email                : wheeler@kde.org
4  ***************************************************************************/
5 
6 /***************************************************************************
7  *   This library is free software; you can redistribute it and/or modify  *
8  *   it under the terms of the GNU Lesser General Public License version   *
9  *   2.1 as published by the Free Software Foundation.                     *
10  *                                                                         *
11  *   This library is distributed in the hope that it will be useful, but   *
12  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
14  *   Lesser General Public License for more details.                       *
15  *                                                                         *
16  *   You should have received a copy of the GNU Lesser General Public      *
17  *   License along with this library; if not, write to the Free Software   *
18  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA         *
19  *   02110-1301  USA                                                       *
20  *                                                                         *
21  *   Alternatively, this file is available under the Mozilla Public        *
22  *   License Version 1.1.  You may obtain a copy of the License at         *
23  *   http://www.mozilla.org/MPL/                                           *
24  ***************************************************************************/
25 
26 #include <bitset>
27 
28 #include <tstring.h>
29 #include <tdebug.h>
30 #include <tpropertymap.h>
31 #include <tagutils.h>
32 
33 #include "vorbisfile.h"
34 
35 using namespace TagLib;
36 
37 class Vorbis::File::FilePrivate
38 {
39 public:
FilePrivate()40   FilePrivate() :
41     comment(0),
42     properties(0) {}
43 
~FilePrivate()44   ~FilePrivate()
45   {
46     delete comment;
47     delete properties;
48   }
49 
50   Ogg::XiphComment *comment;
51   Properties *properties;
52 };
53 
54 namespace TagLib {
55   /*!
56    * Vorbis headers can be found with one type ID byte and the string "vorbis" in
57    * an Ogg stream.  0x03 indicates the comment header.
58    */
59   static const char vorbisCommentHeaderID[] = { 0x03, 'v', 'o', 'r', 'b', 'i', 's', 0 };
60 }
61 
62 ////////////////////////////////////////////////////////////////////////////////
63 // static members
64 ////////////////////////////////////////////////////////////////////////////////
65 
isSupported(IOStream * stream)66 bool Vorbis::File::isSupported(IOStream *stream)
67 {
68   // An Ogg Vorbis file has IDs "OggS" and "\x01vorbis" somewhere.
69 
70   const ByteVector buffer = Utils::readHeader(stream, bufferSize(), false);
71   return (buffer.find("OggS") >= 0 && buffer.find("\x01vorbis") >= 0);
72 }
73 
74 ////////////////////////////////////////////////////////////////////////////////
75 // public members
76 ////////////////////////////////////////////////////////////////////////////////
77 
File(FileName file,bool readProperties,Properties::ReadStyle)78 Vorbis::File::File(FileName file, bool readProperties, Properties::ReadStyle) :
79   Ogg::File(file),
80   d(new FilePrivate())
81 {
82   if(isOpen())
83     read(readProperties);
84 }
85 
File(IOStream * stream,bool readProperties,Properties::ReadStyle)86 Vorbis::File::File(IOStream *stream, bool readProperties, Properties::ReadStyle) :
87   Ogg::File(stream),
88   d(new FilePrivate())
89 {
90   if(isOpen())
91     read(readProperties);
92 }
93 
~File()94 Vorbis::File::~File()
95 {
96   delete d;
97 }
98 
tag() const99 Ogg::XiphComment *Vorbis::File::tag() const
100 {
101   return d->comment;
102 }
103 
properties() const104 PropertyMap Vorbis::File::properties() const
105 {
106   return d->comment->properties();
107 }
108 
setProperties(const PropertyMap & properties)109 PropertyMap Vorbis::File::setProperties(const PropertyMap &properties)
110 {
111   return d->comment->setProperties(properties);
112 }
113 
audioProperties() const114 Vorbis::Properties *Vorbis::File::audioProperties() const
115 {
116   return d->properties;
117 }
118 
save()119 bool Vorbis::File::save()
120 {
121   ByteVector v(vorbisCommentHeaderID);
122 
123   if(!d->comment)
124     d->comment = new Ogg::XiphComment();
125   v.append(d->comment->render());
126 
127   setPacket(1, v);
128 
129   return Ogg::File::save();
130 }
131 
132 ////////////////////////////////////////////////////////////////////////////////
133 // private members
134 ////////////////////////////////////////////////////////////////////////////////
135 
read(bool readProperties)136 void Vorbis::File::read(bool readProperties)
137 {
138   ByteVector commentHeaderData = packet(1);
139 
140   if(commentHeaderData.mid(0, 7) != vorbisCommentHeaderID) {
141     debug("Vorbis::File::read() - Could not find the Vorbis comment header.");
142     setValid(false);
143     return;
144   }
145 
146   d->comment = new Ogg::XiphComment(commentHeaderData.mid(7));
147 
148   if(readProperties)
149     d->properties = new Properties(this);
150 }
151