filemap.c 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include "filemap.h"
  2. #include "common.h"
  3. #ifndef _WIN32
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <sys/fcntl.h> /* open */
  7. #include <unistd.h> /* close */
  8. #include <stdio.h> /* perror */
  9. void aFileReset(struct AFile *file) {
  10. file->size = 0;
  11. file->impl_.fd = -1;
  12. }
  13. enum AFileResult aFileOpen(struct AFile *file, const char *filename) {
  14. file->impl_.fd = open(filename, O_RDONLY);
  15. if (file->impl_.fd < 0)
  16. return AFile_Fail;
  17. struct stat stat;
  18. fstat(file->impl_.fd, &stat);
  19. file->size = stat.st_size;
  20. return AFile_Success;
  21. }
  22. size_t aFileReadAtOffset(struct AFile *file, size_t off, size_t size, void *buffer) {
  23. ssize_t rd = pread(file->impl_.fd, buffer, size, off);
  24. if (rd < 0)
  25. perror("pread(fd)");
  26. return rd;
  27. }
  28. void aFileClose(struct AFile *file) {
  29. if (file->impl_.fd > 0) {
  30. close(file->impl_.fd);
  31. aFileReset(file);
  32. }
  33. }
  34. #else
  35. void aFileReset(struct AFile *file) {
  36. file->size = 0;
  37. file->impl_.handle = INVALID_HANDLE_VALUE;
  38. }
  39. enum AFileResult aFileOpen(struct AFile *file, const char *filename) {
  40. const int filename_len = strlen(filename);
  41. char *slashes = _alloca(filename_len + 1);
  42. for (int i = 0; filename[i] != '\0'; ++i)
  43. slashes[i] = filename[i] != '/' ? filename[i] : '\\';
  44. slashes[filename_len] = '\0';
  45. wchar_t *filename_w;
  46. const int buf_length = MultiByteToWideChar(CP_UTF8, 0, slashes, -1, NULL, 0);
  47. filename_w = _alloca(buf_length);
  48. MultiByteToWideChar(CP_UTF8, 0, slashes, -1, filename_w, buf_length);
  49. file->impl_.handle = CreateFileW(filename_w, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  50. if (file->impl_.handle == INVALID_HANDLE_VALUE)
  51. return AFile_Fail;
  52. LARGE_INTEGER splurge_integer = { 0 };
  53. if (!GetFileSizeEx(file->impl_.handle, &splurge_integer)) {
  54. CloseHandle(file->impl_.handle);
  55. file->impl_.handle = INVALID_HANDLE_VALUE;
  56. return AFile_Fail;
  57. }
  58. file->size = (size_t)splurge_integer.QuadPart;
  59. return AFile_Success;
  60. }
  61. size_t aFileReadAtOffset(struct AFile *file, size_t off, size_t size, void *buffer) {
  62. OVERLAPPED overlapped;
  63. memset(&overlapped, 0, sizeof(overlapped));
  64. overlapped.Offset = off;
  65. DWORD read = 0;
  66. if (!ReadFile(file->impl_.handle, buffer, size, &read, &overlapped))
  67. PRINTF("Failed to read from file %p", file->impl_.handle);
  68. return read;
  69. }
  70. void aFileClose(struct AFile *file) {
  71. CloseHandle(file->impl_.handle);
  72. }
  73. #endif