/*
- * Copyright (C) 2005-2008 Team XBMC
- * http://www.xbmc.org
+ * Copyright (C) 2005-2013 Team XBMC
+ * http://xbmc.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with XBMC; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- * http://www.gnu.org/copyleft/gpl.html
+ * along with XBMC; see the file COPYING. If not, see
+ * <http://www.gnu.org/licenses/>.
*
*/
#include "limits.h"
m_bIsOpen = false;
}
m_strFileName = strFileName;
+ m_bIsReadOnly = readOnly || !m_bIsOpen;
}
/*!
/*!
* Reads a block of size \a length at the current get pointer.
*/
-ByteVector TagLibVFSStream::readBlock(ulong length)
+ByteVector TagLibVFSStream::readBlock(TagLib::ulong length)
{
ByteVector byteVector(static_cast<TagLib::uint>(length));
byteVector.resize(m_file.Read(byteVector.data(), length));
* \note This method is slow since it requires rewriting all of the file
* after the insertion point.
*/
-void TagLibVFSStream::insert(const ByteVector &data, ulong start, ulong replace)
+void TagLibVFSStream::insert(const ByteVector &data, TagLib::ulong start, TagLib::ulong replace)
{
if (data.size() == replace)
{
// First, make sure that we're working with a buffer that is longer than
// the *differnce* in the tag sizes. We want to avoid overwriting parts
// that aren't yet in memory, so this is necessary.
- ulong bufferLength = bufferSize();
+ TagLib::ulong bufferLength = bufferSize();
while (data.size() - replace > bufferLength)
bufferLength += bufferSize();
// Check to see if we just read the last block. We need to call clear()
// if we did so that the last write succeeds.
- if (ulong(bytesRead) < bufferLength)
+ if (TagLib::ulong(bytesRead) < bufferLength)
clear();
// Seek to the write position and write our buffer. Increment the
* \note This method is slow since it involves rewriting all of the file
* after the removed portion.
*/
-void TagLibVFSStream::removeBlock(ulong start, ulong length)
+void TagLibVFSStream::removeBlock(TagLib::ulong start, TagLib::ulong length)
{
- ulong bufferLength = bufferSize();
+ TagLib::ulong bufferLength = bufferSize();
long readPosition = start + length;
long writePosition = start;
ByteVector buffer(static_cast<TagLib::uint>(bufferLength));
- ulong bytesRead = 1;
+ TagLib::ulong bytesRead = 1;
while(bytesRead != 0)
{
*/
void TagLibVFSStream::seek(long offset, Position p)
{
+ const long fileLen = length();
+ if (m_bIsReadOnly && fileLen > 0)
+ {
+ long startPos;
+ if (p == Beginning)
+ startPos = 0;
+ else if (p == Current)
+ startPos = tell();
+ else if (p == End)
+ startPos = fileLen;
+ else
+ return; // wrong Position value
+
+ // When parsing some broken files, taglib may try to seek above end of file.
+ // If underlying VFS does not move I/O pointer in this case, taglib will parse
+ // same part of file several times and ends with error. To prevent this
+ // situation, force seek to last valid position so VFS move I/O pointer.
+ if (startPos >= 0)
+ {
+ if (offset < 0 && startPos + offset < 0)
+ {
+ m_file.Seek(0, SEEK_SET);
+ return;
+ }
+ if (offset > 0 && startPos + offset > fileLen)
+ {
+ m_file.Seek(fileLen, SEEK_SET);
+ return;
+ }
+ }
+ }
+
switch(p)
{
case Beginning:
*/
long TagLibVFSStream::length()
{
- return m_file.GetLength();
+ return (long)m_file.GetLength();
}
/*!