3static const uint8_t empty_source[] =
"";
10pm_string_sizeof(
void) {
18pm_string_shared_init(
pm_string_t *
string,
const uint8_t *start,
const uint8_t *end) {
22 .type = PM_STRING_SHARED,
24 .length = (size_t) (end - start)
32pm_string_owned_init(
pm_string_t *
string, uint8_t *source,
size_t length) {
34 .type = PM_STRING_OWNED,
44pm_string_constant_init(
pm_string_t *
string,
const char *source,
size_t length) {
46 .type = PM_STRING_CONSTANT,
47 .source = (
const uint8_t *) source,
63} pm_string_file_handle_t;
70pm_string_file_handle_open(pm_string_file_handle_t *handle,
const char *filepath) {
71 int length = MultiByteToWideChar(CP_UTF8, 0, filepath, -1, NULL, 0);
74 handle->path =
xmalloc(
sizeof(WCHAR) * ((
size_t) length));
75 if ((handle->path == NULL) || (MultiByteToWideChar(CP_UTF8, 0, filepath, -1, handle->path, length) == 0)) {
80 handle->file = CreateFileW(handle->path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
81 if (handle->file == INVALID_HANDLE_VALUE) {
84 if (GetLastError() == ERROR_ACCESS_DENIED) {
85 DWORD attributes = GetFileAttributesW(handle->path);
86 if ((attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
102pm_string_file_handle_close(pm_string_file_handle_t *handle) {
104 CloseHandle(handle->file);
123 pm_string_file_handle_t handle;
128 DWORD file_size = GetFileSize(handle.file, NULL);
129 if (file_size == INVALID_FILE_SIZE) {
130 pm_string_file_handle_close(&handle);
136 if (file_size == 0) {
137 pm_string_file_handle_close(&handle);
138 *
string = (
pm_string_t) { .type = PM_STRING_CONSTANT, .source = empty_source, .length = 0 };
143 HANDLE mapping = CreateFileMapping(handle.file, NULL, PAGE_READONLY, 0, 0, NULL);
144 if (mapping == NULL) {
145 pm_string_file_handle_close(&handle);
150 uint8_t *source = (uint8_t *) MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
151 CloseHandle(mapping);
152 pm_string_file_handle_close(&handle);
154 if (source == NULL) {
158 *
string = (
pm_string_t) { .type = PM_STRING_MAPPED, .source = source, .length = (size_t) file_size };
160#elif defined(_POSIX_MAPPED_FILES)
162 int fd = open(filepath, O_RDONLY);
169 if (fstat(fd, &sb) == -1) {
175 if (S_ISDIR(sb.st_mode)) {
181 size_t size = (size_t) sb.st_size;
182 uint8_t *source = NULL;
186 *
string = (
pm_string_t) { .type = PM_STRING_CONSTANT, .source = empty_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 *
string = (
pm_string_t) { .type = PM_STRING_CONSTANT, .source = empty_source, .length = 0 };
233 uint8_t *source =
xmalloc(file_size);
234 if (source == NULL) {
235 pm_string_file_handle_close(&handle);
241 if (!ReadFile(handle.file, source, file_size, &bytes_read, NULL)) {
242 pm_string_file_handle_close(&handle);
247 if (bytes_read != file_size) {
249 pm_string_file_handle_close(&handle);
253 pm_string_file_handle_close(&handle);
254 *
string = (
pm_string_t) { .type = PM_STRING_OWNED, .source = source, .length = (size_t) file_size };
256#elif defined(PRISM_HAS_FILESYSTEM)
258 int fd = open(filepath, O_RDONLY);
265 if (fstat(fd, &sb) == -1) {
271 if (S_ISDIR(sb.st_mode)) {
277 size_t size = (size_t) sb.st_size;
280 *
string = (
pm_string_t) { .type = PM_STRING_CONSTANT, .source = empty_source, .length = 0 };
284 size_t length = (size_t) size;
285 uint8_t *source =
xmalloc(length);
286 if (source == NULL) {
291 long bytes_read = (long) read(fd, source, length);
294 if (bytes_read == -1) {
299 *
string = (
pm_string_t) { .type = PM_STRING_OWNED, .source = source, .length = length };
304 perror(
"pm_string_file_init is not implemented for this platform");
315 if (string->
type == PM_STRING_OWNED)
return;
320 uint8_t *memory =
xmalloc(length);
323 pm_string_owned_init(
string, memory, length);
324 memcpy((
void *) string->
source, source, length);
338 if (left_length < right_length) {
340 }
else if (left_length > right_length) {
352 return string->length;
360 return string->source;
368 void *memory = (
void *) string->
source;
370 if (string->
type == PM_STRING_OWNED) {
373 }
else if (string->
type == PM_STRING_MAPPED && string->
length) {
375 UnmapViewOfFile(memory);
376#elif defined(_POSIX_MAPPED_FILES)
377 munmap(memory, string->
length);
#define xfree
Old name of ruby_xfree.
#define xmalloc
Old name of ruby_xmalloc.
PRISM_EXPORTED_FUNCTION size_t pm_string_length(const pm_string_t *string)
Returns the length associated with the string.
PRISM_EXPORTED_FUNCTION const uint8_t * pm_string_source(const pm_string_t *string)
Returns the start pointer associated with the string.
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 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...
A generic string type that can have various ownership semantics.
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.
#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::@102 type
The type of the string.