Esempio n. 1
0
/*! \brief Delete the given data from the file.
	\details The function erases the given data from the file at the given write position. This
	operation may take a while to complete, but is faster than insertData.

	The write position is not changed and the read position	is checked for validity upon function exit.
	\param start The offset of the first byte to delete
	\param length The total number of bytes to delete
	\returns XRV_OK if the data was deleted successfully
*/
XsResultValue IoInterfaceFile::deleteData (XsFilePos start, XsSize length)
{
	if (!m_handle)
		return m_lastResult = XRV_NOFILEOPEN;
	if (m_readOnly)
		return m_lastResult = XRV_READONLY;

	gotoWrite();

	XsFilePos wPos = start;
	XsFilePos rPos = wPos + length;

	size_t read1;
	XsFilePos endPos = (start + (XsFilePos) length);
	if (endPos < m_fileSize)
	{
		XsFilePos remaining = m_fileSize - endPos;
		char buffer[512];

		// copy data
		FSEEK(rPos);

		while (remaining > 0)
		{
			if (remaining >= 512)
				read1 = fread(buffer,1,512,m_handle);
			else
				read1 = fread(buffer,1,(size_t) remaining,m_handle);

			remaining -= read1;
			rPos += read1;

			// write block to the correct position
			FSEEK(wPos);
			wPos += fwrite(buffer, 1, read1, m_handle);
			FSEEK(rPos);
		}
		m_fileSize -= length;
	}
	else
	{
		m_fileSize = start;
	}

#ifdef _WIN32
	int32_t rv = _chsize(_fileno(m_handle),(int32_t) m_fileSize);
#else
	int32_t rv = ftruncate(fileno(m_handle),(int32_t) m_fileSize);
#endif
	int32_t eno = 0;
	if (rv != 0)
		eno = errno;
	m_writePos = start;
	FSEEK(wPos);
	if (rv != 0)
	{
		switch(eno)
		{
		case EACCES:
			return m_lastResult = XRV_BUSY;
		case EBADF:
			return m_lastResult = XRV_INVALIDINSTANCE;
		case ENOSPC:
			return m_lastResult = XRV_OUTOFMEMORY;
		case EINVAL:
			return m_lastResult = XRV_INVALIDPARAM;
		default:
			return m_lastResult = XRV_ERROR;
		}
	}

	return m_lastResult = XRV_OK;
}