id3lib 3.8.3

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

io_decorators.cpp
Go to the documentation of this file.
1 // $Id: io_decorators.cpp,v 1.4 2002/07/02 22:13:40 t1mpy Exp $
2
3 // id3lib: a C++ library for creating and manipulating id3v1/v2 tags
4 // Copyright 1999, 2000 Scott Thomas Haug
5
6 // This library is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU Library General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or (at your
9 // option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful, but WITHOUT
12 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14 // License for more details.
15 //
16 // You should have received a copy of the GNU Library General Public License
17 // along with this library; if not, write to the Free Software Foundation,
18 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 // The id3lib authors encourage improvements and optimisations to be sent to
21 // the id3lib coordinator. Please see the README file for details on where to
22 // send such submissions. See the AUTHORS file for a list of people who have
23 // contributed to id3lib. See the ChangeLog file for a list of changes to
24 // id3lib. These files are distributed with id3lib at
25 // http://download.sourceforge.net/id3lib/
26
27 #if defined HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30
31
32
33 #include "id3/io_decorators.h" //has "readers.h" "io_helpers.h" "utils.h"
34 #include "zlib.h"
35
36 using namespace dami;
37
38 void io::WindowedReader::setWindow(pos_type beg, size_type size)
39 {
40 ID3D_NOTICE( "WindowedReader::setWindow() [beg, size] = [" <<
41 this->getBeg() << ", " << size << "]" );
42 pos_type cur = this->getCur();
43
44 // reset the end marker so as to avoid errors
45 this->setEnd(_reader.getEnd());
46
47 // set the beginning marker
48 this->setBeg(beg);
49
50 // since the characters might be more than a byte in size, we need to
51 // manually get all the chars to set the window appropriately
52 this->setCur(beg);
53 ID3D_NOTICE( "WindowedReader::setWindow(): after setCur(beg), cur = "<<
54 this->getCur() );
55
56 this->skipChars(size);
57 ID3D_NOTICE( "WindowedReader::setWindow(): after skipChars, cur = " <<
58 this->getCur() );
59
60 this->setEnd(this->getCur());
61
62 ID3D_NOTICE( "WindowedReader::setWindow() [beg, cur, end] = [" << this->getBeg() << ", " << this->getCur() << ", " << this->getEnd() << "]" );
63
64
65 // reset the stream
66 this->setCur(cur);
67 }
68
69 ID3_Reader::pos_type io::WindowedReader::setBeg(pos_type beg)
70 {
71 // make sure the position we want to set to isn't past the current
72 // end position or the superclass's beginning position
73 if (beg <= this->getEnd() && beg >= _reader.getBeg())
74 {
75 _beg = beg;
76 }
77 else if (beg > this->getEnd())
78 {
79 ID3D_WARNING( "WindowedReader::setBeg() failed, [beg, _end] = " <<
80 beg << ", " << this->getEnd() << "]" );
81 }
82 else
83 {
84 ID3D_WARNING( "WindowedReader::setBeg() failed, [beg, _beg] = " <<
85 beg << ", " << this->getBeg() << "]" );
86 }
87 return _beg;
88 }
89
90 ID3_Reader::pos_type io::WindowedReader::setEnd(pos_type end)
91 {
92 // make sure the position we want to set to isn't beforen the current
93 // beginning position or the superclass's end position
94 if (this->getBeg() <= end && end <= _reader.getEnd())
95 {
96 _end = end;
97 }
98 else
99 {
100 ID3D_WARNING( "WindowedReader::setEnd() failed, end = " << end );
101 ID3D_WARNING( "WindowedReader::setEnd() failed, beg = " <<
102 this->getBeg() );
103 ID3D_WARNING( "WindowedReader::setEnd() failed, super.end = " <<
104 _reader.getEnd() );
105
106 }
107 return _end;
108 }
109
110 ID3_Reader::int_type io::WindowedReader::readChar()
111 {
112 int_type ch = END_OF_READER;
113 if (this->inWindow())
114 {
115 ch = _reader.readChar();
116 }
117 else
118 {
119 ID3D_WARNING( "io::WindowedReader::readChar: not in window, " <<
120 "pos = " << this->getCur() << ", window = [" <<
121 this->getBeg() << ", " << this->getEnd() << "]");
122 }
123 return ch;
124 }
125
126 ID3_Reader::int_type io::WindowedReader::peekChar()
127 {
128 int_type ch = END_OF_READER;
129 if (this->inWindow())
130 {
131 ch = _reader.peekChar();
132 }
133 return ch;
134 }
135
136 ID3_Reader::size_type io::WindowedReader::readChars(char_type buf[], size_type len)
137 {
138 pos_type cur = this->getCur();
139 size_type size = 0;
140 if (this->inWindow(cur))
141 {
142 size = _reader.readChars(buf, min<size_type>(len, _end - cur));
143 }
144 return size;
145 }
146
147 ID3_Reader::size_type io::CharReader::readChars(char_type buf[], size_type len)
148 {
149 size_type numChars = 0;
150 ID3D_NOTICE( "CharReader::readChars(): len = " << len );
151 for (; numChars < len; ++numChars)
152 {
153 if (this->atEnd())
154 {
155 break;
156 }
157 char_type ch = this->readChar();
158 if (buf != NULL)
159 {
160 buf[numChars] = ch;
161 }
162 }
163 ID3D_NOTICE( "CharReader::readChars(): numChars = " << len );
164 return numChars;
165 }
166
167 ID3_Reader::int_type io::LineFeedReader::readChar()
168 {
169 if (this->atEnd())
170 {
171 return END_OF_READER;
172 }
173 char_type ch = _reader.readChar();
174 if (ch == 0x0D && this->peekChar() == 0x0A)
175 {
176 ID3D_NOTICE( "LineFeedReader::readChar(): found CRLF at pos " <<
177 this->getCur() );
178 ch = _reader.readChar();
179 }
180 return ch;
181 };
182
183 ID3_Reader::int_type io::UnsyncedReader::readChar()
184 {
185 if (this->atEnd())
186 {
187 return END_OF_READER;
188 }
189 char_type ch = _reader.readChar();
190 if (ch == 0xFF && this->peekChar() == 0x00)
191 {
192 ID3D_NOTICE( "UnsyncedReader::readChar(): found sync at pos " <<
193 this->getCur() );
194 _reader.readChar();
195 }
196 return ch;
197 }
198
199 io::CompressedReader::CompressedReader(ID3_Reader& reader, size_type newSize)
200 : _uncompressed(new char_type[newSize])
201 {
202 size_type oldSize = reader.remainingBytes();
203
204 BString binary = readBinary(reader, oldSize);
205
206 ::uncompress(_uncompressed,
207 reinterpret_cast<luint*>(&newSize),
208 reinterpret_cast<const uchar*>(binary.data()),
209 oldSize);
210 this->setBuffer(_uncompressed, newSize);
211 }
212
213 io::CompressedReader::~CompressedReader()
214 {
215 delete [] _uncompressed;
216 }
217
218 ID3_Writer::int_type io::UnsyncedWriter::writeChar(char_type ch)
219 {
220 if (_last == 0xFF && (ch == 0x00 || ch >= 0xE0))
221 {
222 _writer.writeChar('\0');
223 _numSyncs++;
224 }
225 _last = _writer.writeChar(ch);
226 return _last;
227 }
228
229 void io::UnsyncedWriter::flush()
230 {
231 if (_last == 0xFF)
232 {
233 _last = _writer.writeChar('\0');
234 _numSyncs++;
235 }
236 _writer.flush();
237 }
238
239 ID3_Writer::size_type
240 io::UnsyncedWriter::writeChars(const char_type buf[], size_type len)
241 {
242 pos_type beg = this->getCur();
243 ID3D_NOTICE( "UnsyncedWriter::writeChars(): len = " << len );
244 for (size_t i = 0; i < len; ++i)
245 {
246 if (this->atEnd())
247 {
248 break;
249 }
250 this->writeChar(buf[i]);
251 }
252 size_type numChars = this->getCur() - beg;
253 ID3D_NOTICE( "CharWriter::writeChars(): numChars = " << numChars );
254 return numChars;
255 }
256
257 void io::CompressedWriter::flush()
258 {
259 if (_data.size() == 0)
260 {
261 return;
262 }
263 const char_type* data = reinterpret_cast<const char_type*>(_data.data());
264 size_type dataSize = _data.size();
265 _origSize = dataSize;
266 // The zlib documentation specifies that the destination size needs to
267 // be an unsigned long at least 0.1% larger than the source buffer,
268 // plus 12 bytes
269 unsigned long newDataSize = dataSize + (dataSize / 10) + 12;
270 char_type* newData = new char_type[newDataSize];
271 if (::compress(newData, &newDataSize, data, dataSize) != Z_OK)
272 {
273 // log this
274 ID3D_WARNING("io::CompressedWriter: error compressing");
275 _writer.writeChars(data, dataSize);
276 }
277 else if (newDataSize < dataSize)
278 {
279 ID3D_NOTICE("io::CompressedWriter: compressed size = " << newDataSize << ", original size = " << dataSize );
280 _writer.writeChars(newData, newDataSize);
281 }
282 else
283 {
284 ID3D_NOTICE("io::CompressedWriter: no compression!compressed size = " << newDataSize << ", original size = " << dataSize );
285 _writer.writeChars(data, dataSize);
286 }
287 delete [] newData;
288 _data.erase();
289 }
290
291 ID3_Writer::size_type
292 io::CompressedWriter::writeChars(const char_type buf[], size_type len)
293 {
294 ID3D_NOTICE("io::CompressedWriter: writing chars: " << len );
295 _data.append(buf, len);
296 return len;
297 }
298
ID3_Writer::size_type
uint32 size_type
Definition: writer.h:36
ID3_Writer::int_type
int16 int_type
Definition: writer.h:40
ID3_Reader::int_type
int16 int_type
Definition: reader.h:40
dami::BString
std::basic_string< unsigned char > BString
Definition: id3lib_strings.h:199
ID3_Reader
Definition: reader.h:33
ID3_Reader::remainingBytes
virtual size_type remainingBytes()
Definition: reader.h:109
ID3_Reader::size_type
uint32 size_type
Definition: reader.h:36
NULL
#define NULL
Definition: globals.h:743
ID3_Reader::pos_type
uint32 pos_type
Definition: reader.h:38