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