Example #1
0
bool BadaFileStream::seek(int32 offs, int whence) {
	bool result = false;
	switch (whence) {
	case SEEK_SET:
		// set from start of file
		SetLastResult(file->Seek(FILESEEKPOSITION_BEGIN, offs));
		result = (E_SUCCESS == GetLastResult());
		break;

	case SEEK_CUR:
		// set relative to offs
		if (bufferIndex < bufferLength && bufferIndex > (uint32)-offs) {
			// re-position within the buffer
			SetLastResult(E_SUCCESS);
			bufferIndex += offs;
			return true;
		} else {
			offs -= (bufferLength - bufferIndex);
			if (offs < 0 && file->Tell() + offs < 0) {
				// avoid negative positioning
				offs = 0;
			}
			if (offs != 0) {
				SetLastResult(file->Seek(FILESEEKPOSITION_CURRENT, offs));
				result = (E_SUCCESS == GetLastResult());
			} else {
				result = true;
			}
		}
		break;

	case SEEK_END:
		// set relative to end - positive will increase the file size
		SetLastResult(file->Seek(FILESEEKPOSITION_END, offs));
		result = (E_SUCCESS == GetLastResult());
		break;

	default:
		AppLog("Invalid whence %d", whence);
		return false;
	}

	if (!result) {
		AppLog("seek failed");
	}

	bufferIndex = bufferLength = 0;
	return result;
}
Example #2
0
int32 BadaFileStream::size() const {
	int32 oldPos = file->Tell();
	file->Seek(FILESEEKPOSITION_END, 0);

	int32 length = file->Tell();
	SetLastResult(file->Seek(FILESEEKPOSITION_BEGIN, oldPos));

	return length;
}
Example #3
0
bool WaitObjectContainer::Wait(unsigned long milliseconds)
{
	if (m_noWait || (m_handles.empty() && !m_firstEventTime))
	{
		SetLastResult(LASTRESULT_NOWAIT);
		return true;
	}

	bool timeoutIsScheduledEvent = false;

	if (m_firstEventTime)
	{
		double timeToFirstEvent = SaturatingSubtract(m_firstEventTime, m_eventTimer.ElapsedTimeAsDouble());

		if (timeToFirstEvent <= milliseconds)
		{
			milliseconds = (unsigned long)timeToFirstEvent;
			timeoutIsScheduledEvent = true;
		}

		if (m_handles.empty() || !milliseconds)
		{
			if (milliseconds)
				Sleep(milliseconds);
			SetLastResult(timeoutIsScheduledEvent ? LASTRESULT_SCHEDULED : LASTRESULT_TIMEOUT);
			return timeoutIsScheduledEvent;
		}
	}

	if (m_handles.size() > MAXIMUM_WAIT_OBJECTS)
	{
		// too many wait objects for a single WaitForMultipleObjects call, so use multiple threads
		static const unsigned int WAIT_OBJECTS_PER_THREAD = MAXIMUM_WAIT_OBJECTS-1;
		unsigned int nThreads = (unsigned int)((m_handles.size() + WAIT_OBJECTS_PER_THREAD - 1) / WAIT_OBJECTS_PER_THREAD);
		if (nThreads > MAXIMUM_WAIT_OBJECTS)	// still too many wait objects, maybe implement recursive threading later?
			throw Err("WaitObjectContainer: number of wait objects exceeds limit");
		CreateThreads(nThreads);
		DWORD error = S_OK;
		
		for (unsigned int i=0; i<m_threads.size(); i++)
		{
			WaitingThreadData &thread = *m_threads[i];
			while (!thread.waitingToWait)	// spin until thread is in the initial "waiting to wait" state
				Sleep(0);
			if (i<nThreads)
			{
				thread.waitHandles = &m_handles[i*WAIT_OBJECTS_PER_THREAD];
				thread.count = UnsignedMin(WAIT_OBJECTS_PER_THREAD, m_handles.size() - i*WAIT_OBJECTS_PER_THREAD);
				thread.error = &error;
			}
			else
				thread.count = 0;
		}

		ResetEvent(m_stopWaiting);
		PulseEvent(m_startWaiting);

		DWORD result = ::WaitForSingleObject(m_stopWaiting, milliseconds);
		if (result == WAIT_OBJECT_0)
		{
			if (error == S_OK)
				return true;
			else
				throw Err("WaitObjectContainer: WaitForMultipleObjects in thread failed with error " + IntToString(error));
		}
		SetEvent(m_stopWaiting);
		if (result == WAIT_TIMEOUT)
		{
			SetLastResult(timeoutIsScheduledEvent ? LASTRESULT_SCHEDULED : LASTRESULT_TIMEOUT);
			return timeoutIsScheduledEvent;
		}
		else
			throw Err("WaitObjectContainer: WaitForSingleObject failed with error " + IntToString(::GetLastError()));
	}
	else
	{
#if TRACE_WAIT
		static Timer t(Timer::MICROSECONDS);
		static unsigned long lastTime = 0;
		unsigned long timeBeforeWait = t.ElapsedTime();
#endif
		DWORD result = ::WaitForMultipleObjects((DWORD)m_handles.size(), &m_handles[0], FALSE, milliseconds);
#if TRACE_WAIT
		if (milliseconds > 0)
		{
			unsigned long timeAfterWait = t.ElapsedTime();
			OutputDebugString(("Handles " + IntToString(m_handles.size()) + ", Woke up by " + IntToString(result-WAIT_OBJECT_0) + ", Busied for " + IntToString(timeBeforeWait-lastTime) + " us, Waited for " + IntToString(timeAfterWait-timeBeforeWait) + " us, max " + IntToString(milliseconds) + "ms\n").c_str());
			lastTime = timeAfterWait;
		}
#endif
		if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + m_handles.size())
		{
			if (result == m_lastResult)
				m_sameResultCount++;
			else
			{
				m_lastResult = result;
				m_sameResultCount = 0;
			}
			return true;
		}
		else if (result == WAIT_TIMEOUT)
		{
			SetLastResult(timeoutIsScheduledEvent ? LASTRESULT_SCHEDULED : LASTRESULT_TIMEOUT);
			return timeoutIsScheduledEvent;
		}
		else
			throw Err("WaitObjectContainer: WaitForMultipleObjects failed with error " + IntToString(::GetLastError()));
	}
}
Example #4
0
void BadaFileStream::clearErr() {
	SetLastResult(E_SUCCESS);
}
Example #5
0
bool BadaFileStream::flush() {
	logEntered();
	SetLastResult(file->Flush());
	return (E_SUCCESS == GetLastResult());
}
Example #6
0
uint32 BadaFileStream::write(const void *ptr, uint32 len) {
	result r = file->Write(ptr, len);
	SetLastResult(r);
	return (r == E_SUCCESS ? len : 0);
}