1/*-------------------------------------------------------------------------
2 * drawElements Quality Program Execution Server
3 * ---------------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief File Reader.
22 *//*--------------------------------------------------------------------*/
23
24#include "xsPosixFileReader.hpp"
25
26#include <vector>
27
28namespace xs
29{
30namespace posix
31{
32
33FileReader::FileReader (int blockSize, int numBlocks)
34	: m_file		(DE_NULL)
35	, m_buf			(blockSize, numBlocks)
36	, m_isRunning	(false)
37{
38}
39
40FileReader::~FileReader (void)
41{
42}
43
44void FileReader::start (const char* filename)
45{
46	DE_ASSERT(!m_isRunning);
47
48	m_file = deFile_create(filename, DE_FILEMODE_OPEN|DE_FILEMODE_READ);
49	XS_CHECK(m_file);
50
51#if (DE_OS != DE_OS_IOS)
52	// Set to non-blocking mode.
53	if (!deFile_setFlags(m_file, DE_FILE_NONBLOCKING))
54	{
55		deFile_destroy(m_file);
56		m_file = DE_NULL;
57		XS_FAIL("Failed to set non-blocking mode");
58	}
59#endif
60
61	m_isRunning	= true;
62
63	de::Thread::start();
64}
65
66void FileReader::run (void)
67{
68	std::vector<deUint8>	tmpBuf		(FILEREADER_TMP_BUFFER_SIZE);
69	deInt64					numRead		= 0;
70
71	while (!m_buf.isCanceled())
72	{
73		deFileResult result = deFile_read(m_file, &tmpBuf[0], (deInt64)tmpBuf.size(), &numRead);
74
75		if (result == DE_FILERESULT_SUCCESS)
76		{
77			// Write to buffer.
78			try
79			{
80				m_buf.write((int)numRead, &tmpBuf[0]);
81				m_buf.flush();
82			}
83			catch (const ThreadedByteBuffer::CanceledException&)
84			{
85				// Canceled.
86				break;
87			}
88		}
89		else if (result == DE_FILERESULT_END_OF_FILE ||
90				 result == DE_FILERESULT_WOULD_BLOCK)
91		{
92			// Wait for more data.
93			deSleep(FILEREADER_IDLE_SLEEP);
94		}
95		else
96			break; // Error.
97	}
98}
99
100void FileReader::stop (void)
101{
102	if (!m_isRunning)
103		return; // Nothing to do.
104
105	m_buf.cancel();
106
107	// Join thread.
108	join();
109
110	// Destroy file.
111	deFile_destroy(m_file);
112	m_file = DE_NULL;
113
114	// Reset buffer.
115	m_buf.clear();
116
117	m_isRunning = false;
118}
119
120} // posix
121} // xs
122