-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
203 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/** | ||
* @file file_access.h | ||
* @brief File reading and writing. | ||
* @author Chen Zhenshuo (chenzs108@outlook.com) | ||
* @version 1.0 | ||
* @date 2020-01-10 | ||
* | ||
* @par GitHub | ||
* https://github.com/czs108/ | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <windows.h> | ||
|
||
#include <stdbool.h> | ||
|
||
/** | ||
* @brief The view of a file. | ||
*/ | ||
typedef struct _FILE_VIEW | ||
{ | ||
//! The file-mapping returned by `CreateFileMapping` API. | ||
HANDLE map; | ||
|
||
//! The base address of the file content returned by `MapViewOfFile` API. | ||
const BYTE* base; | ||
|
||
//! The size of the file. | ||
DWORD size; | ||
|
||
} FILE_VIEW; | ||
|
||
|
||
/** | ||
* @brief Write all the data to the file. | ||
* | ||
* @param file The file. | ||
* @param data The base address of the data. | ||
* @param size The size of the data. | ||
* @return `true` if the method succeeds, otherwise `false`. | ||
*/ | ||
bool WriteAllToFile( | ||
const HANDLE file, | ||
const BYTE *const data, | ||
const DWORD size); | ||
|
||
|
||
/** | ||
* @brief Open a read-only view of the file. | ||
* | ||
* @public @memberof _FILE_VIEW | ||
* | ||
* @param file The file. | ||
* @param[out] file_view The read-only view | ||
* @return `true` if the method succeeds, otherwise `false`. | ||
* | ||
* @note The constructor of `_FILE_VIEW` structure. | ||
*/ | ||
bool OpenReadViewOfFile( | ||
const HANDLE file, | ||
FILE_VIEW *const file_view); | ||
|
||
|
||
/** | ||
* @brief Close the view of a file. | ||
* | ||
* @public @memberof _FILE_VIEW | ||
* | ||
* @param file_view The view. | ||
* | ||
* @note The destructor of `_FILE_VIEW` structure. | ||
*/ | ||
void CloseViewOfFile( | ||
const FILE_VIEW *const file_view); | ||
|
||
|
||
/** | ||
* @brief Check if the size of the file is smaller than 2GB. | ||
* | ||
* @param file The file. | ||
* @return `true` if the size of the file is smaller than 2GB, otherwise `false`. | ||
* | ||
* @warning The program can only process files smaller than 2GB. | ||
*/ | ||
bool IsFileSmallerThan2G( | ||
const HANDLE file); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/** | ||
* @file file_access.c | ||
* @brief File reading and writing. | ||
* @author Chen Zhenshuo (chenzs108@outlook.com) | ||
* @version 1.0 | ||
* @date 2020-01-10 | ||
* | ||
* @par GitHub | ||
* https://github.com/czs108/ | ||
*/ | ||
|
||
#include "file_access.h" | ||
#include "error_handling.h" | ||
|
||
#include <assert.h> | ||
|
||
|
||
bool WriteAllToFile( | ||
const HANDLE file, | ||
const BYTE *const data, | ||
const DWORD size) | ||
{ | ||
assert(file != INVALID_HANDLE_VALUE); | ||
|
||
if (size == 0) | ||
{ | ||
return true; | ||
} | ||
|
||
assert(data != NULL); | ||
|
||
DWORD remaining = size; | ||
const BYTE *current = data; | ||
while (remaining > 0) | ||
{ | ||
DWORD written = 0; | ||
if (WriteFile(file, current, remaining, &written, NULL) == FALSE) | ||
{ | ||
SetLastErrorCode(); | ||
return false; | ||
} | ||
|
||
remaining -= written; | ||
current += written; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
|
||
bool OpenReadViewOfFile( | ||
const HANDLE file, | ||
FILE_VIEW *const file_view) | ||
{ | ||
assert(IsFileSmallerThan2G(file)); | ||
assert(file_view != NULL); | ||
|
||
bool success = false; | ||
ZeroMemory(file_view, sizeof(file_view)); | ||
|
||
file_view->size = GetFileSize(file, NULL); | ||
file_view->map = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL); | ||
if (file_view->map == NULL) | ||
{ | ||
SetLastErrorCode(); | ||
goto _Exit; | ||
} | ||
|
||
file_view->base = (BYTE*)MapViewOfFile(file_view->map, FILE_MAP_READ, 0, 0, 0); | ||
if (file_view->base == NULL) | ||
{ | ||
SetLastErrorCode(); | ||
goto _Exit; | ||
} | ||
|
||
success = true; | ||
|
||
_Exit: | ||
if (!success) | ||
{ | ||
CloseViewOfFile(file_view); | ||
ZeroMemory(file_view, sizeof(file_view)); | ||
} | ||
|
||
return success; | ||
} | ||
|
||
|
||
void CloseViewOfFile( | ||
const FILE_VIEW *const file_view) | ||
{ | ||
assert(file_view != NULL); | ||
|
||
if (file_view->base != NULL) | ||
{ | ||
UnmapViewOfFile(file_view->base); | ||
} | ||
|
||
if (file_view->map != NULL) | ||
{ | ||
CloseHandle(file_view->map); | ||
} | ||
} | ||
|
||
|
||
bool IsFileSmallerThan2G( | ||
const HANDLE file) | ||
{ | ||
assert(file != INVALID_HANDLE_VALUE); | ||
|
||
DWORD size_high = 0; | ||
GetFileSize(file, &size_high); | ||
return size_high == 0; | ||
} |