20 .type = PM_STRING_SHARED,
22 .length = (size_t) (end - start)
32 .type = PM_STRING_OWNED,
44 .type = PM_STRING_CONSTANT,
45 .source = (
const uint8_t *) source,
61 } pm_string_file_handle_t;
68 pm_string_file_handle_open(pm_string_file_handle_t *handle,
const char *filepath) {
69 int length = MultiByteToWideChar(CP_UTF8, 0, filepath, -1, NULL, 0);
72 handle->path =
xmalloc(
sizeof(WCHAR) * ((
size_t) length));
73 if ((handle->path == NULL) || (MultiByteToWideChar(CP_UTF8, 0, filepath, -1, handle->path, length) == 0)) {
78 handle->file = CreateFileW(handle->path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
79 if (handle->file == INVALID_HANDLE_VALUE) {
82 if (GetLastError() == ERROR_ACCESS_DENIED) {
83 DWORD attributes = GetFileAttributesW(handle->path);
84 if ((attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
100 pm_string_file_handle_close(pm_string_file_handle_t *handle) {
102 CloseHandle(handle->file);
121 pm_string_file_handle_t handle;
126 DWORD file_size = GetFileSize(handle.file, NULL);
127 if (file_size == INVALID_FILE_SIZE) {
128 pm_string_file_handle_close(&handle);
134 if (file_size == 0) {
135 pm_string_file_handle_close(&handle);
136 const uint8_t source[] =
"";
137 *
string = (
pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 };
142 HANDLE mapping = CreateFileMapping(handle.file, NULL, PAGE_READONLY, 0, 0, NULL);
143 if (mapping == NULL) {
144 pm_string_file_handle_close(&handle);
149 uint8_t *source = (uint8_t *) MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
150 CloseHandle(mapping);
151 pm_string_file_handle_close(&handle);
153 if (source == NULL) {
157 *
string = (
pm_string_t) { .type = PM_STRING_MAPPED, .source = source, .length = (size_t) file_size };
159 #elif defined(_POSIX_MAPPED_FILES)
161 int fd = open(filepath, O_RDONLY);
168 if (fstat(fd, &sb) == -1) {
174 if (S_ISDIR(sb.st_mode)) {
180 size_t size = (size_t) sb.st_size;
181 uint8_t *source = NULL;
185 const uint8_t source[] =
"";
186 *
string = (
pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 };
190 source = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
191 if (source == MAP_FAILED) {
197 *
string = (
pm_string_t) { .type = PM_STRING_MAPPED, .source = source, .length = size };
213 pm_string_file_handle_t handle;
218 DWORD file_size = GetFileSize(handle.file, NULL);
219 if (file_size == INVALID_FILE_SIZE) {
220 pm_string_file_handle_close(&handle);
226 if (file_size == 0) {
227 pm_string_file_handle_close(&handle);
228 const uint8_t source[] =
"";
229 *
string = (
pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 };
234 uint8_t *source =
xmalloc(file_size);
235 if (source == NULL) {
236 pm_string_file_handle_close(&handle);
242 if (!ReadFile(handle.file, source, file_size, &bytes_read, NULL)) {
243 pm_string_file_handle_close(&handle);
248 if (bytes_read != file_size) {
250 pm_string_file_handle_close(&handle);
254 pm_string_file_handle_close(&handle);
255 *
string = (
pm_string_t) { .type = PM_STRING_OWNED, .source = source, .length = (size_t) file_size };
257 #elif defined(PRISM_HAS_FILESYSTEM)
259 int fd = open(filepath, O_RDONLY);
266 if (fstat(fd, &sb) == -1) {
272 if (S_ISDIR(sb.st_mode)) {
278 size_t size = (size_t) sb.st_size;
281 const uint8_t source[] =
"";
282 *
string = (
pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 };
286 size_t length = (size_t) size;
287 uint8_t *source =
xmalloc(length);
288 if (source == NULL) {
293 long bytes_read = (long) read(fd, source, length);
296 if (bytes_read == -1) {
301 *
string = (
pm_string_t) { .type = PM_STRING_OWNED, .source = source, .length = length };
306 perror(
"pm_string_file_init is not implemented for this platform");
317 if (string->
type == PM_STRING_OWNED)
return;
322 uint8_t *memory =
xmalloc(length);
326 memcpy((
void *) string->
source, source, length);
340 if (left_length < right_length) {
342 }
else if (left_length > right_length) {
354 return string->length;
362 return string->source;
370 void *memory = (
void *) string->
source;
372 if (string->
type == PM_STRING_OWNED) {
374 #ifdef PRISM_HAS_MMAP
375 }
else if (string->
type == PM_STRING_MAPPED && string->
length) {
377 UnmapViewOfFile(memory);
378 #elif defined(_POSIX_MAPPED_FILES)
379 munmap(memory, string->
length);
#define xfree
Old name of ruby_xfree.
#define xmalloc
Old name of ruby_xmalloc.
A generic string type that can have various ownership semantics.
PRISM_EXPORTED_FUNCTION size_t pm_string_length(const pm_string_t *string)
Returns the length associated with the string.
void pm_string_ensure_owned(pm_string_t *string)
Ensure the string is owned.
void pm_string_constant_init(pm_string_t *string, const char *source, size_t length)
Initialize a constant string that doesn't own its memory source.
void pm_string_owned_init(pm_string_t *string, uint8_t *source, size_t length)
Initialize an owned string that is responsible for freeing allocated memory.
pm_string_init_result_t
Represents the result of calling pm_string_mapped_init or pm_string_file_init.
@ PM_STRING_INIT_SUCCESS
Indicates that the string was successfully initialized.
@ PM_STRING_INIT_ERROR_GENERIC
Indicates a generic error from a string_*_init function, where the type of error should be read from ...
@ PM_STRING_INIT_ERROR_DIRECTORY
Indicates that the file that was attempted to be opened was a directory.
void pm_string_shared_init(pm_string_t *string, const uint8_t *start, const uint8_t *end)
Initialize a shared string that is based on initial input.
PRISM_EXPORTED_FUNCTION pm_string_init_result_t 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...
PRISM_EXPORTED_FUNCTION void pm_string_free(pm_string_t *string)
Free the associated memory of the given string.
PRISM_EXPORTED_FUNCTION size_t pm_string_sizeof(void)
Returns the size of the pm_string_t struct.
PRISM_EXPORTED_FUNCTION const uint8_t * pm_string_source(const pm_string_t *string)
Returns the start pointer associated with the string.
int pm_string_compare(const pm_string_t *left, const pm_string_t *right)
Compare the underlying lengths and bytes of two strings.
PRISM_EXPORTED_FUNCTION pm_string_init_result_t pm_string_file_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...
#define PRISM_EXPORTED_FUNCTION
By default, we compile with -fvisibility=hidden.
A generic string type that can have various ownership semantics.
const uint8_t * source
A pointer to the start of the string.
size_t length
The length of the string in bytes of memory.
enum pm_string_t::@98 type
The type of the string.