1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Utility Library
3e5c31af7Sopenharmony_ci * ----------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *//*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief File abstraction.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "deFile.h"
25e5c31af7Sopenharmony_ci#include "deMemory.h"
26e5c31af7Sopenharmony_ci
27e5c31af7Sopenharmony_ci#if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_IOS) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_SYMBIAN) || (DE_OS == DE_OS_QNX) || (DE_OS == DE_OS_FUCHSIA)
28e5c31af7Sopenharmony_ci
29e5c31af7Sopenharmony_ci#include <sys/types.h>
30e5c31af7Sopenharmony_ci#include <sys/stat.h>
31e5c31af7Sopenharmony_ci#include <fcntl.h>
32e5c31af7Sopenharmony_ci#include <unistd.h>
33e5c31af7Sopenharmony_ci#include <errno.h>
34e5c31af7Sopenharmony_ci
35e5c31af7Sopenharmony_cistruct deFile_s
36e5c31af7Sopenharmony_ci{
37e5c31af7Sopenharmony_ci	int fd;
38e5c31af7Sopenharmony_ci};
39e5c31af7Sopenharmony_ci
40e5c31af7Sopenharmony_cideBool deFileExists (const char* filename)
41e5c31af7Sopenharmony_ci{
42e5c31af7Sopenharmony_ci	struct stat st;
43e5c31af7Sopenharmony_ci	int result = stat(filename, &st);
44e5c31af7Sopenharmony_ci	return result == 0;
45e5c31af7Sopenharmony_ci}
46e5c31af7Sopenharmony_ci
47e5c31af7Sopenharmony_cideBool deDeleteFile (const char* filename)
48e5c31af7Sopenharmony_ci{
49e5c31af7Sopenharmony_ci	return unlink(filename) == 0;
50e5c31af7Sopenharmony_ci}
51e5c31af7Sopenharmony_ci
52e5c31af7Sopenharmony_cideFile* deFile_createFromHandle (deUintptr handle)
53e5c31af7Sopenharmony_ci{
54e5c31af7Sopenharmony_ci	int		fd		= (int)handle;
55e5c31af7Sopenharmony_ci	deFile* file	= (deFile*)deCalloc(sizeof(deFile));
56e5c31af7Sopenharmony_ci	if (!file)
57e5c31af7Sopenharmony_ci	{
58e5c31af7Sopenharmony_ci		close(fd);
59e5c31af7Sopenharmony_ci		return file;
60e5c31af7Sopenharmony_ci	}
61e5c31af7Sopenharmony_ci
62e5c31af7Sopenharmony_ci	file->fd = fd;
63e5c31af7Sopenharmony_ci	return file;
64e5c31af7Sopenharmony_ci}
65e5c31af7Sopenharmony_ci
66e5c31af7Sopenharmony_cistatic int mapOpenMode (deFileMode mode)
67e5c31af7Sopenharmony_ci{
68e5c31af7Sopenharmony_ci	int flag = 0;
69e5c31af7Sopenharmony_ci
70e5c31af7Sopenharmony_ci	/* Read, write or read and write access is required. */
71e5c31af7Sopenharmony_ci	DE_ASSERT((mode & DE_FILEMODE_READ) != 0 || ((mode & DE_FILEMODE_WRITE) != 0));
72e5c31af7Sopenharmony_ci
73e5c31af7Sopenharmony_ci	/* Create, open or create and open mode is required. */
74e5c31af7Sopenharmony_ci	DE_ASSERT((mode & DE_FILEMODE_OPEN) != 0 || ((mode & DE_FILEMODE_CREATE) != 0));
75e5c31af7Sopenharmony_ci
76e5c31af7Sopenharmony_ci	/* Require write when using create. */
77e5c31af7Sopenharmony_ci	DE_ASSERT(!(mode & DE_FILEMODE_CREATE) || (mode & DE_FILEMODE_WRITE));
78e5c31af7Sopenharmony_ci
79e5c31af7Sopenharmony_ci	/* Require write and open when using truncate */
80e5c31af7Sopenharmony_ci	DE_ASSERT(!(mode & DE_FILEMODE_TRUNCATE) || ((mode & DE_FILEMODE_WRITE) && (mode & DE_FILEMODE_OPEN)));
81e5c31af7Sopenharmony_ci
82e5c31af7Sopenharmony_ci	if (mode & DE_FILEMODE_READ)
83e5c31af7Sopenharmony_ci		flag |= O_RDONLY;
84e5c31af7Sopenharmony_ci
85e5c31af7Sopenharmony_ci	if (mode & DE_FILEMODE_WRITE)
86e5c31af7Sopenharmony_ci		flag |= O_WRONLY;
87e5c31af7Sopenharmony_ci
88e5c31af7Sopenharmony_ci	if (mode & DE_FILEMODE_TRUNCATE)
89e5c31af7Sopenharmony_ci		flag |= O_TRUNC;
90e5c31af7Sopenharmony_ci
91e5c31af7Sopenharmony_ci	if (mode & DE_FILEMODE_CREATE)
92e5c31af7Sopenharmony_ci		flag |= O_CREAT;
93e5c31af7Sopenharmony_ci
94e5c31af7Sopenharmony_ci	if (!(mode & DE_FILEMODE_OPEN))
95e5c31af7Sopenharmony_ci		flag |= O_EXCL;
96e5c31af7Sopenharmony_ci
97e5c31af7Sopenharmony_ci	return flag;
98e5c31af7Sopenharmony_ci}
99e5c31af7Sopenharmony_ci
100e5c31af7Sopenharmony_cideFile* deFile_create (const char* filename, deUint32 mode)
101e5c31af7Sopenharmony_ci{
102e5c31af7Sopenharmony_ci	int fd = open(filename, mapOpenMode(mode), 0777);
103e5c31af7Sopenharmony_ci	if (fd >= 0)
104e5c31af7Sopenharmony_ci		return deFile_createFromHandle((deUintptr)fd);
105e5c31af7Sopenharmony_ci	else
106e5c31af7Sopenharmony_ci		return DE_NULL;
107e5c31af7Sopenharmony_ci}
108e5c31af7Sopenharmony_ci
109e5c31af7Sopenharmony_civoid deFile_destroy (deFile* file)
110e5c31af7Sopenharmony_ci{
111e5c31af7Sopenharmony_ci	close(file->fd);
112e5c31af7Sopenharmony_ci	deFree(file);
113e5c31af7Sopenharmony_ci}
114e5c31af7Sopenharmony_ci
115e5c31af7Sopenharmony_cideBool deFile_setFlags (deFile* file, deUint32 flags)
116e5c31af7Sopenharmony_ci{
117e5c31af7Sopenharmony_ci	/* Non-blocking. */
118e5c31af7Sopenharmony_ci	{
119e5c31af7Sopenharmony_ci		int oldFlags = fcntl(file->fd, F_GETFL, 0);
120e5c31af7Sopenharmony_ci		int newFlags = (flags & DE_FILE_NONBLOCKING) ? (oldFlags | O_NONBLOCK) : (oldFlags & ~O_NONBLOCK);
121e5c31af7Sopenharmony_ci		if (fcntl(file->fd, F_SETFL, newFlags) != 0)
122e5c31af7Sopenharmony_ci			return DE_FALSE;
123e5c31af7Sopenharmony_ci	}
124e5c31af7Sopenharmony_ci
125e5c31af7Sopenharmony_ci	/* Close on exec. */
126e5c31af7Sopenharmony_ci	{
127e5c31af7Sopenharmony_ci		int oldFlags = fcntl(file->fd, F_GETFD, 0);
128e5c31af7Sopenharmony_ci		int newFlags = (flags & DE_FILE_CLOSE_ON_EXEC) ? (oldFlags | FD_CLOEXEC) : (oldFlags & ~FD_CLOEXEC);
129e5c31af7Sopenharmony_ci		if (fcntl(file->fd, F_SETFD, newFlags) != 0)
130e5c31af7Sopenharmony_ci			return DE_FALSE;
131e5c31af7Sopenharmony_ci	}
132e5c31af7Sopenharmony_ci
133e5c31af7Sopenharmony_ci	return DE_TRUE;
134e5c31af7Sopenharmony_ci}
135e5c31af7Sopenharmony_ci
136e5c31af7Sopenharmony_cistatic int mapSeekPosition (deFilePosition position)
137e5c31af7Sopenharmony_ci{
138e5c31af7Sopenharmony_ci	switch (position)
139e5c31af7Sopenharmony_ci	{
140e5c31af7Sopenharmony_ci		case DE_FILEPOSITION_BEGIN:		return SEEK_SET;
141e5c31af7Sopenharmony_ci		case DE_FILEPOSITION_END:		return SEEK_END;
142e5c31af7Sopenharmony_ci		case DE_FILEPOSITION_CURRENT:	return SEEK_CUR;
143e5c31af7Sopenharmony_ci		default:
144e5c31af7Sopenharmony_ci			DE_ASSERT(DE_FALSE);
145e5c31af7Sopenharmony_ci			return 0;
146e5c31af7Sopenharmony_ci	}
147e5c31af7Sopenharmony_ci}
148e5c31af7Sopenharmony_ci
149e5c31af7Sopenharmony_cideBool deFile_seek (deFile* file, deFilePosition base, deInt64 offset)
150e5c31af7Sopenharmony_ci{
151e5c31af7Sopenharmony_ci	return lseek(file->fd, (off_t)offset, mapSeekPosition(base)) >= 0;
152e5c31af7Sopenharmony_ci}
153e5c31af7Sopenharmony_ci
154e5c31af7Sopenharmony_cideInt64 deFile_getPosition (const deFile* file)
155e5c31af7Sopenharmony_ci{
156e5c31af7Sopenharmony_ci	return lseek(file->fd, 0, SEEK_CUR);
157e5c31af7Sopenharmony_ci}
158e5c31af7Sopenharmony_ci
159e5c31af7Sopenharmony_cideInt64 deFile_getSize (const deFile* file)
160e5c31af7Sopenharmony_ci{
161e5c31af7Sopenharmony_ci	deInt64 size	= 0;
162e5c31af7Sopenharmony_ci	deInt64 curPos	= lseek(file->fd, 0, SEEK_CUR);
163e5c31af7Sopenharmony_ci
164e5c31af7Sopenharmony_ci	if (curPos < 0)
165e5c31af7Sopenharmony_ci		return -1;
166e5c31af7Sopenharmony_ci
167e5c31af7Sopenharmony_ci	size = lseek(file->fd, 0, SEEK_END);
168e5c31af7Sopenharmony_ci
169e5c31af7Sopenharmony_ci	if (size < 0)
170e5c31af7Sopenharmony_ci		return -1;
171e5c31af7Sopenharmony_ci
172e5c31af7Sopenharmony_ci	lseek(file->fd, (off_t)curPos, SEEK_SET);
173e5c31af7Sopenharmony_ci
174e5c31af7Sopenharmony_ci	return size;
175e5c31af7Sopenharmony_ci}
176e5c31af7Sopenharmony_ci
177e5c31af7Sopenharmony_cistatic deFileResult mapReadWriteResult (deInt64 numBytes)
178e5c31af7Sopenharmony_ci{
179e5c31af7Sopenharmony_ci	if (numBytes > 0)
180e5c31af7Sopenharmony_ci		return DE_FILERESULT_SUCCESS;
181e5c31af7Sopenharmony_ci	else if (numBytes == 0)
182e5c31af7Sopenharmony_ci		return DE_FILERESULT_END_OF_FILE;
183e5c31af7Sopenharmony_ci	else
184e5c31af7Sopenharmony_ci		return errno == EAGAIN ? DE_FILERESULT_WOULD_BLOCK : DE_FILERESULT_ERROR;
185e5c31af7Sopenharmony_ci}
186e5c31af7Sopenharmony_ci
187e5c31af7Sopenharmony_cideFileResult deFile_read (deFile* file, void* buf, deInt64 bufSize, deInt64* numReadPtr)
188e5c31af7Sopenharmony_ci{
189e5c31af7Sopenharmony_ci	deInt64 numRead = read(file->fd, buf, (size_t)bufSize);
190e5c31af7Sopenharmony_ci
191e5c31af7Sopenharmony_ci	if (numReadPtr)
192e5c31af7Sopenharmony_ci		*numReadPtr = numRead;
193e5c31af7Sopenharmony_ci
194e5c31af7Sopenharmony_ci	return mapReadWriteResult(numRead);
195e5c31af7Sopenharmony_ci}
196e5c31af7Sopenharmony_ci
197e5c31af7Sopenharmony_cideFileResult deFile_write (deFile* file, const void* buf, deInt64 bufSize, deInt64* numWrittenPtr)
198e5c31af7Sopenharmony_ci{
199e5c31af7Sopenharmony_ci	deInt64 numWritten = write(file->fd, buf, (size_t)bufSize);
200e5c31af7Sopenharmony_ci
201e5c31af7Sopenharmony_ci	if (numWrittenPtr)
202e5c31af7Sopenharmony_ci		*numWrittenPtr = numWritten;
203e5c31af7Sopenharmony_ci
204e5c31af7Sopenharmony_ci	return mapReadWriteResult(numWritten);
205e5c31af7Sopenharmony_ci}
206e5c31af7Sopenharmony_ci
207e5c31af7Sopenharmony_ci#elif (DE_OS == DE_OS_WIN32)
208e5c31af7Sopenharmony_ci
209e5c31af7Sopenharmony_ci#define VC_EXTRALEAN
210e5c31af7Sopenharmony_ci#define WIN32_LEAN_AND_MEAN
211e5c31af7Sopenharmony_ci#include <windows.h>
212e5c31af7Sopenharmony_ci
213e5c31af7Sopenharmony_cistruct deFile_s
214e5c31af7Sopenharmony_ci{
215e5c31af7Sopenharmony_ci	HANDLE handle;
216e5c31af7Sopenharmony_ci};
217e5c31af7Sopenharmony_ci
218e5c31af7Sopenharmony_cideBool deFileExists (const char* filename)
219e5c31af7Sopenharmony_ci{
220e5c31af7Sopenharmony_ci	return GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES;
221e5c31af7Sopenharmony_ci}
222e5c31af7Sopenharmony_ci
223e5c31af7Sopenharmony_cideBool deDeleteFile (const char* filename)
224e5c31af7Sopenharmony_ci{
225e5c31af7Sopenharmony_ci	return DeleteFile(filename) == TRUE;
226e5c31af7Sopenharmony_ci}
227e5c31af7Sopenharmony_ci
228e5c31af7Sopenharmony_cideFile* deFile_createFromHandle (deUintptr handle)
229e5c31af7Sopenharmony_ci{
230e5c31af7Sopenharmony_ci	deFile* file = (deFile*)deCalloc(sizeof(deFile));
231e5c31af7Sopenharmony_ci	if (!file)
232e5c31af7Sopenharmony_ci	{
233e5c31af7Sopenharmony_ci		CloseHandle((HANDLE)handle);
234e5c31af7Sopenharmony_ci		return file;
235e5c31af7Sopenharmony_ci	}
236e5c31af7Sopenharmony_ci
237e5c31af7Sopenharmony_ci	file->handle = (HANDLE)handle;
238e5c31af7Sopenharmony_ci	return file;
239e5c31af7Sopenharmony_ci}
240e5c31af7Sopenharmony_ci
241e5c31af7Sopenharmony_cideFile* deFile_create (const char* filename, deUint32 mode)
242e5c31af7Sopenharmony_ci{
243e5c31af7Sopenharmony_ci	DWORD	access		= 0;
244e5c31af7Sopenharmony_ci	DWORD	create		= OPEN_EXISTING;
245e5c31af7Sopenharmony_ci	HANDLE	handle		= DE_NULL;
246e5c31af7Sopenharmony_ci
247e5c31af7Sopenharmony_ci	/* Read, write or read and write access is required. */
248e5c31af7Sopenharmony_ci	DE_ASSERT((mode & DE_FILEMODE_READ) != 0 || ((mode & DE_FILEMODE_WRITE) != 0));
249e5c31af7Sopenharmony_ci
250e5c31af7Sopenharmony_ci	/* Create, open or create and open mode is required. */
251e5c31af7Sopenharmony_ci	DE_ASSERT((mode & DE_FILEMODE_OPEN) != 0 || ((mode & DE_FILEMODE_CREATE) != 0));
252e5c31af7Sopenharmony_ci
253e5c31af7Sopenharmony_ci	/* Require write when using create. */
254e5c31af7Sopenharmony_ci	DE_ASSERT(!(mode & DE_FILEMODE_CREATE) || (mode & DE_FILEMODE_WRITE));
255e5c31af7Sopenharmony_ci
256e5c31af7Sopenharmony_ci	/* Require write and open when using truncate */
257e5c31af7Sopenharmony_ci	DE_ASSERT(!(mode & DE_FILEMODE_TRUNCATE) || ((mode & DE_FILEMODE_WRITE) && (mode & DE_FILEMODE_OPEN)));
258e5c31af7Sopenharmony_ci
259e5c31af7Sopenharmony_ci
260e5c31af7Sopenharmony_ci	if (mode & DE_FILEMODE_READ)
261e5c31af7Sopenharmony_ci		access |= GENERIC_READ;
262e5c31af7Sopenharmony_ci
263e5c31af7Sopenharmony_ci	if (mode & DE_FILEMODE_WRITE)
264e5c31af7Sopenharmony_ci		access |= GENERIC_WRITE;
265e5c31af7Sopenharmony_ci
266e5c31af7Sopenharmony_ci	if ((mode & DE_FILEMODE_TRUNCATE))
267e5c31af7Sopenharmony_ci	{
268e5c31af7Sopenharmony_ci		if ((mode & DE_FILEMODE_CREATE) && (mode & DE_FILEMODE_OPEN))
269e5c31af7Sopenharmony_ci			create = CREATE_ALWAYS;
270e5c31af7Sopenharmony_ci		else if (mode & DE_FILEMODE_OPEN)
271e5c31af7Sopenharmony_ci			create = TRUNCATE_EXISTING;
272e5c31af7Sopenharmony_ci		else
273e5c31af7Sopenharmony_ci			DE_ASSERT(DE_FALSE);
274e5c31af7Sopenharmony_ci	}
275e5c31af7Sopenharmony_ci	else
276e5c31af7Sopenharmony_ci	{
277e5c31af7Sopenharmony_ci		if ((mode & DE_FILEMODE_CREATE) && (mode & DE_FILEMODE_OPEN))
278e5c31af7Sopenharmony_ci			create = OPEN_ALWAYS;
279e5c31af7Sopenharmony_ci		else if (mode & DE_FILEMODE_CREATE)
280e5c31af7Sopenharmony_ci			create = CREATE_NEW;
281e5c31af7Sopenharmony_ci		else if (mode & DE_FILEMODE_OPEN)
282e5c31af7Sopenharmony_ci			create = OPEN_EXISTING;
283e5c31af7Sopenharmony_ci		else
284e5c31af7Sopenharmony_ci			DE_ASSERT(DE_FALSE);
285e5c31af7Sopenharmony_ci	}
286e5c31af7Sopenharmony_ci
287e5c31af7Sopenharmony_ci	handle = CreateFile(filename, access, FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE, DE_NULL, create, FILE_ATTRIBUTE_NORMAL, DE_NULL);
288e5c31af7Sopenharmony_ci	if (handle == INVALID_HANDLE_VALUE)
289e5c31af7Sopenharmony_ci		return DE_NULL;
290e5c31af7Sopenharmony_ci
291e5c31af7Sopenharmony_ci	return deFile_createFromHandle((deUintptr)handle);
292e5c31af7Sopenharmony_ci}
293e5c31af7Sopenharmony_ci
294e5c31af7Sopenharmony_civoid deFile_destroy (deFile* file)
295e5c31af7Sopenharmony_ci{
296e5c31af7Sopenharmony_ci	CloseHandle(file->handle);
297e5c31af7Sopenharmony_ci	deFree(file);
298e5c31af7Sopenharmony_ci}
299e5c31af7Sopenharmony_ci
300e5c31af7Sopenharmony_cideBool deFile_setFlags (deFile* file, deUint32 flags)
301e5c31af7Sopenharmony_ci{
302e5c31af7Sopenharmony_ci	/* Non-blocking. */
303e5c31af7Sopenharmony_ci	if (flags & DE_FILE_NONBLOCKING)
304e5c31af7Sopenharmony_ci		return DE_FALSE; /* Not supported. */
305e5c31af7Sopenharmony_ci
306e5c31af7Sopenharmony_ci	/* Close on exec. */
307e5c31af7Sopenharmony_ci	if (!SetHandleInformation(file->handle, HANDLE_FLAG_INHERIT, (flags & DE_FILE_CLOSE_ON_EXEC) ? HANDLE_FLAG_INHERIT : 0))
308e5c31af7Sopenharmony_ci		return DE_FALSE;
309e5c31af7Sopenharmony_ci
310e5c31af7Sopenharmony_ci	return DE_TRUE;
311e5c31af7Sopenharmony_ci}
312e5c31af7Sopenharmony_ci
313e5c31af7Sopenharmony_cideBool deFile_seek (deFile* file, deFilePosition base, deInt64 offset)
314e5c31af7Sopenharmony_ci{
315e5c31af7Sopenharmony_ci	DWORD	method		= 0;
316e5c31af7Sopenharmony_ci	LONG	lowBits		= (LONG)(offset & 0xFFFFFFFFll);
317e5c31af7Sopenharmony_ci	LONG	highBits	= (LONG)((offset >> 32) & 0xFFFFFFFFll);
318e5c31af7Sopenharmony_ci
319e5c31af7Sopenharmony_ci	switch (base)
320e5c31af7Sopenharmony_ci	{
321e5c31af7Sopenharmony_ci		case DE_FILEPOSITION_BEGIN:		method = FILE_BEGIN;	break;
322e5c31af7Sopenharmony_ci		case DE_FILEPOSITION_END:		method = FILE_END;		break;
323e5c31af7Sopenharmony_ci		case DE_FILEPOSITION_CURRENT:	method = FILE_CURRENT;	break;
324e5c31af7Sopenharmony_ci		default:
325e5c31af7Sopenharmony_ci			DE_ASSERT(DE_FALSE);
326e5c31af7Sopenharmony_ci			return DE_FALSE;
327e5c31af7Sopenharmony_ci	}
328e5c31af7Sopenharmony_ci
329e5c31af7Sopenharmony_ci	return SetFilePointer(file->handle, lowBits, &highBits, method) != INVALID_SET_FILE_POINTER;
330e5c31af7Sopenharmony_ci}
331e5c31af7Sopenharmony_ci
332e5c31af7Sopenharmony_cideInt64 deFile_getPosition (const deFile* file)
333e5c31af7Sopenharmony_ci{
334e5c31af7Sopenharmony_ci	LONG	highBits	= 0;
335e5c31af7Sopenharmony_ci	LONG	lowBits		= SetFilePointer(file->handle, 0, &highBits, FILE_CURRENT);
336e5c31af7Sopenharmony_ci
337e5c31af7Sopenharmony_ci	return (deInt64)(((deUint64)highBits << 32) | (deUint64)lowBits);
338e5c31af7Sopenharmony_ci}
339e5c31af7Sopenharmony_ci
340e5c31af7Sopenharmony_cideInt64 deFile_getSize (const deFile* file)
341e5c31af7Sopenharmony_ci{
342e5c31af7Sopenharmony_ci	DWORD	highBits	= 0;
343e5c31af7Sopenharmony_ci	DWORD	lowBits		= GetFileSize(file->handle, &highBits);
344e5c31af7Sopenharmony_ci
345e5c31af7Sopenharmony_ci	return (deInt64)(((deUint64)highBits << 32) | (deUint64)lowBits);
346e5c31af7Sopenharmony_ci}
347e5c31af7Sopenharmony_ci
348e5c31af7Sopenharmony_cistatic deFileResult mapReadWriteResult (BOOL retVal, DWORD numBytes)
349e5c31af7Sopenharmony_ci{
350e5c31af7Sopenharmony_ci	if (retVal && numBytes > 0)
351e5c31af7Sopenharmony_ci		return DE_FILERESULT_SUCCESS;
352e5c31af7Sopenharmony_ci	else if (retVal && numBytes == 0)
353e5c31af7Sopenharmony_ci		return DE_FILERESULT_END_OF_FILE;
354e5c31af7Sopenharmony_ci	else
355e5c31af7Sopenharmony_ci	{
356e5c31af7Sopenharmony_ci		DWORD error = GetLastError();
357e5c31af7Sopenharmony_ci
358e5c31af7Sopenharmony_ci		if (error == ERROR_HANDLE_EOF)
359e5c31af7Sopenharmony_ci			return DE_FILERESULT_END_OF_FILE;
360e5c31af7Sopenharmony_ci		else
361e5c31af7Sopenharmony_ci			return DE_FILERESULT_ERROR;
362e5c31af7Sopenharmony_ci	}
363e5c31af7Sopenharmony_ci}
364e5c31af7Sopenharmony_ci
365e5c31af7Sopenharmony_cideFileResult deFile_read (deFile* file, void* buf, deInt64 bufSize, deInt64* numReadPtr)
366e5c31af7Sopenharmony_ci{
367e5c31af7Sopenharmony_ci	DWORD	bufSize32	= (DWORD)bufSize;
368e5c31af7Sopenharmony_ci	DWORD	numRead32	= 0;
369e5c31af7Sopenharmony_ci	BOOL	result;
370e5c31af7Sopenharmony_ci
371e5c31af7Sopenharmony_ci	/* \todo [2011-10-03 pyry] 64-bit IO. */
372e5c31af7Sopenharmony_ci	DE_ASSERT((deInt64)bufSize32 == bufSize);
373e5c31af7Sopenharmony_ci
374e5c31af7Sopenharmony_ci	result = ReadFile(file->handle, buf, bufSize32, &numRead32, DE_NULL);
375e5c31af7Sopenharmony_ci
376e5c31af7Sopenharmony_ci	if (numReadPtr)
377e5c31af7Sopenharmony_ci		*numReadPtr = (deInt64)numRead32;
378e5c31af7Sopenharmony_ci
379e5c31af7Sopenharmony_ci	return mapReadWriteResult(result, numRead32);
380e5c31af7Sopenharmony_ci}
381e5c31af7Sopenharmony_ci
382e5c31af7Sopenharmony_cideFileResult deFile_write (deFile* file, const void* buf, deInt64 bufSize, deInt64* numWrittenPtr)
383e5c31af7Sopenharmony_ci{
384e5c31af7Sopenharmony_ci	DWORD	bufSize32		= (DWORD)bufSize;
385e5c31af7Sopenharmony_ci	DWORD	numWritten32	= 0;
386e5c31af7Sopenharmony_ci	BOOL	result;
387e5c31af7Sopenharmony_ci
388e5c31af7Sopenharmony_ci	/* \todo [2011-10-03 pyry] 64-bit IO. */
389e5c31af7Sopenharmony_ci	DE_ASSERT((deInt64)bufSize32 == bufSize);
390e5c31af7Sopenharmony_ci
391e5c31af7Sopenharmony_ci	result = WriteFile(file->handle, buf, bufSize32, &numWritten32, DE_NULL);
392e5c31af7Sopenharmony_ci
393e5c31af7Sopenharmony_ci	if (numWrittenPtr)
394e5c31af7Sopenharmony_ci		*numWrittenPtr = (deInt64)numWritten32;
395e5c31af7Sopenharmony_ci
396e5c31af7Sopenharmony_ci	return mapReadWriteResult(result, numWritten32);
397e5c31af7Sopenharmony_ci}
398e5c31af7Sopenharmony_ci
399e5c31af7Sopenharmony_ci#else
400e5c31af7Sopenharmony_ci#	error Implement deFile for your OS.
401e5c31af7Sopenharmony_ci#endif
402