[ruby/prism] Parse files from Ruby API using fread, not mmap
https://github.com/ruby/prism/commit/62d4376a53
This commit is contained in:
parent
6ea01d204e
commit
b88973165a
@ -254,7 +254,7 @@ file_options(int argc, VALUE *argv, pm_string_t *input, pm_options_t *options) {
|
|||||||
|
|
||||||
const char * string_source = (const char *) pm_string_source(&options->filepath);
|
const char * string_source = (const char *) pm_string_source(&options->filepath);
|
||||||
|
|
||||||
if (!pm_string_mapped_init(input, string_source)) {
|
if (!pm_string_file_init(input, string_source)) {
|
||||||
pm_options_free(options);
|
pm_options_free(options);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -58,7 +58,7 @@ pm_string_constant_init(pm_string_t *string, const char *source, size_t length)
|
|||||||
* `MapViewOfFile`, on POSIX systems that have access to `mmap` we'll use
|
* `MapViewOfFile`, on POSIX systems that have access to `mmap` we'll use
|
||||||
* `mmap`, and on other POSIX systems we'll use `read`.
|
* `mmap`, and on other POSIX systems we'll use `read`.
|
||||||
*/
|
*/
|
||||||
bool
|
PRISM_EXPORTED_FUNCTION bool
|
||||||
pm_string_mapped_init(pm_string_t *string, const char *filepath) {
|
pm_string_mapped_init(pm_string_t *string, const char *filepath) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// Open the file for reading.
|
// Open the file for reading.
|
||||||
@ -143,6 +143,108 @@ pm_string_mapped_init(pm_string_t *string, const char *filepath) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the file indicated by the filepath parameter into source and load its
|
||||||
|
* contents and size into the given `pm_string_t`. The given `pm_string_t`
|
||||||
|
* should be freed using `pm_string_free` when it is no longer used.
|
||||||
|
*/
|
||||||
|
PRISM_EXPORTED_FUNCTION bool
|
||||||
|
pm_string_file_init(pm_string_t *string, const char *filepath) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Open the file for reading.
|
||||||
|
HANDLE file = CreateFile(filepath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
|
||||||
|
if (file == INVALID_HANDLE_VALUE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the file size.
|
||||||
|
DWORD file_size = GetFileSize(file, NULL);
|
||||||
|
if (file_size == INVALID_FILE_SIZE) {
|
||||||
|
CloseHandle(file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the file is empty, then we don't need to do anything else, we'll set
|
||||||
|
// the source to a constant empty string and return.
|
||||||
|
if (file_size == 0) {
|
||||||
|
CloseHandle(file);
|
||||||
|
const uint8_t source[] = "";
|
||||||
|
*string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 };
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a buffer to read the file into.
|
||||||
|
uint8_t *source = malloc(file_size);
|
||||||
|
if (source == NULL) {
|
||||||
|
CloseHandle(file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the contents of the file
|
||||||
|
DWORD bytes_read;
|
||||||
|
if (!ReadFile(file, source, file_size, &bytes_read, NULL)) {
|
||||||
|
CloseHandle(file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the number of bytes read
|
||||||
|
if (bytes_read != file_size) {
|
||||||
|
free(source);
|
||||||
|
CloseHandle(file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(file);
|
||||||
|
*string = (pm_string_t) { .type = PM_STRING_OWNED, .source = source, .length = (size_t) file_size };
|
||||||
|
return true;
|
||||||
|
#elif defined(_POSIX_MAPPED_FILES)
|
||||||
|
FILE *file = fopen(filepath, "rb");
|
||||||
|
if (file == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(file, 0, SEEK_END);
|
||||||
|
long file_size = ftell(file);
|
||||||
|
|
||||||
|
if (file_size == -1) {
|
||||||
|
fclose(file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file_size == 0) {
|
||||||
|
fclose(file);
|
||||||
|
const uint8_t source[] = "";
|
||||||
|
*string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 };
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t length = (size_t) file_size;
|
||||||
|
uint8_t *source = malloc(length);
|
||||||
|
if (source == NULL) {
|
||||||
|
fclose(file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(file, 0, SEEK_SET);
|
||||||
|
size_t bytes_read = fread(source, length, 1, file);
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
if (bytes_read != 1) {
|
||||||
|
free(source);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*string = (pm_string_t) { .type = PM_STRING_OWNED, .source = source, .length = length };
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
(void) string;
|
||||||
|
(void) filepath;
|
||||||
|
perror("pm_string_file_init is not implemented for this platform");
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the memory size associated with the string.
|
* Returns the memory size associated with the string.
|
||||||
*/
|
*/
|
||||||
|
@ -109,6 +109,17 @@ void pm_string_constant_init(pm_string_t *string, const char *source, size_t len
|
|||||||
*/
|
*/
|
||||||
PRISM_EXPORTED_FUNCTION bool pm_string_mapped_init(pm_string_t *string, const char *filepath);
|
PRISM_EXPORTED_FUNCTION bool pm_string_mapped_init(pm_string_t *string, const char *filepath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the file indicated by the filepath parameter into source and load its
|
||||||
|
* contents and size into the given `pm_string_t`. The given `pm_string_t`
|
||||||
|
* should be freed using `pm_string_free` when it is no longer used.
|
||||||
|
*
|
||||||
|
* @param string The string to initialize.
|
||||||
|
* @param filepath The filepath to read.
|
||||||
|
* @return Whether or not the file was successfully read.
|
||||||
|
*/
|
||||||
|
PRISM_EXPORTED_FUNCTION bool pm_string_file_init(pm_string_t *string, const char *filepath);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the memory size associated with the string.
|
* Returns the memory size associated with the string.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user