A collection of basic/generally desirable code I use across multiple C++ projects.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

225 lines
5.2 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. #ifndef _CRT_SECURE_NO_WARNINGS
  2. #define _CRT_SECURE_NO_WARNINGS
  3. #include <stdio.h> // fopen, fseek, ftell, fclose
  4. #endif
  5. #include "alloc.h"
  6. #include "array.hpp"
  7. #include "file.h"
  8. #include "print.h"
  9. #include "types.h"
  10. FILE* File :: Open(const char* path, const char* mode) {
  11. ULE_TYPES_H_FTAG;
  12. return fopen(path, mode);
  13. }
  14. FILE* File :: Open(const char* path, size_t* outSize, const char* mode) {
  15. ULE_TYPES_H_FTAG;
  16. FILE* fp = File :: Open(path, mode);
  17. if (fp == null) {
  18. return null;
  19. }
  20. // get the file's size in bytes
  21. fseek(fp, 0, SEEK_END);
  22. *outSize = ftell(fp);
  23. fseek(fp, 0L, SEEK_SET);
  24. return fp;
  25. }
  26. void File :: Close(FILE* file) {
  27. fclose(file);
  28. }
  29. size_t File :: Size(const char* path) {
  30. ULE_TYPES_H_FTAG;
  31. FILE* fp = File :: Open(path);
  32. // get the file's size in bytes
  33. fseek(fp, 0, SEEK_END);
  34. size_t size = ftell(fp);
  35. fseek(fp, 0L, SEEK_SET);
  36. fclose(fp);
  37. return size;
  38. }
  39. size_t File :: Size(FILE* fp) {
  40. ULE_TYPES_H_FTAG;
  41. fseek(fp, 0, SEEK_END);
  42. size_t size = ftell(fp);
  43. fseek(fp, 0L, SEEK_SET);
  44. return size;
  45. }
  46. u8* File :: Read(const char* path) {
  47. ULE_TYPES_H_FTAG;
  48. FILE* fp = File :: Open(path, "rb");
  49. if (fp == null) {
  50. return null;
  51. }
  52. // get the file's size in bytes
  53. fseek(fp, 0, SEEK_END);
  54. u32 size = ftell(fp);
  55. fseek(fp, 0L, SEEK_SET);
  56. char* buffer = (char*) pMalloc(size + 1);
  57. fread(buffer, sizeof (char), size + 1, fp);
  58. buffer[size] = '\0';
  59. fclose(fp);
  60. return (u8*) buffer;
  61. }
  62. u8* File :: Read(const char* path, size_t* outSize) {
  63. ULE_TYPES_H_FTAG;
  64. FILE* fp = File :: Open(path, "rb");
  65. if (fp == null) {
  66. return null;
  67. }
  68. // get the file's size in bytes
  69. fseek(fp, 0, SEEK_END);
  70. size_t size = ftell(fp);
  71. // if we got a valid pointer to a size_t we should report the size back.
  72. if (outSize != null) {
  73. *outSize = size;
  74. }
  75. fseek(fp, 0L, SEEK_SET);
  76. char* buffer = (char*) pMalloc(size + 1);
  77. fread(buffer, sizeof (char), size + 1, fp);
  78. buffer[size] = '\0';
  79. fclose(fp);
  80. return (u8*) buffer;
  81. }
  82. size_t File :: Read(FILE* fp, void* destination) {
  83. ULE_TYPES_H_FTAG;
  84. fseek(fp, 0, SEEK_END);
  85. size_t size = ftell(fp);
  86. fseek(fp, 0L, SEEK_SET);
  87. fread(destination, sizeof (char), size + 1, fp);
  88. return size;
  89. }
  90. size_t File :: Read(FILE* fp, void* destination, size_t size) {
  91. ULE_TYPES_H_FTAG;
  92. return fread(destination, sizeof (char), size + 1, fp);
  93. }
  94. s32 File :: Write(const char* path, char* data, u32 count) {
  95. ULE_TYPES_H_FTAG;
  96. FILE* fp = File :: Open(path, "wb");
  97. if (fp == null) {
  98. return -1; // failed to open the file
  99. }
  100. size_t writtenCount = fwrite(data, 1, count, fp);
  101. fclose(fp);
  102. if (writtenCount != count) {
  103. return -2; // wrote only partially
  104. }
  105. return 0;
  106. }
  107. #if _WIN32
  108. #include <windows.h>
  109. // writes the filenames into the provided array |outFileNames|, must be allocated ahead of time.
  110. void File :: GetFileNamesInFolder(const char* path, Array<char*>* outFileNames) {
  111. ULE_TYPES_H_FTAG;
  112. massert(path != null, "provided 'null' for path argument");
  113. massert(outFileNames != null, "provided 'null' for array argument");
  114. WIN32_FIND_DATAA findData;
  115. HANDLE hFind = INVALID_HANDLE_VALUE;
  116. String str;
  117. if (path[String::len(path) - 1] != '/') {
  118. str = String64f("%s/*", path);
  119. } else {
  120. str = String64f("%s*", path);
  121. }
  122. hFind = FindFirstFileA(str.c_str(), &findData);
  123. if (hFind == INVALID_HANDLE_VALUE) die("failed to open folder: %s", path);
  124. while (FindNextFileA(hFind, &findData) != 0) {
  125. if (findData.cFileName[0] != '.') {
  126. outFileNames->push(String::cpy(findData.cFileName));
  127. }
  128. }
  129. FindClose(hFind);
  130. }
  131. #else
  132. #include <dirent.h>
  133. void File :: GetFileNamesInFolder(const char* path, Array<char*>* outFileNames) {
  134. ULE_TYPES_H_FTAG;
  135. massert(path != null, "provided 'null' for path argument");
  136. massert(outFileNames != null, "provided 'null' for array argument");
  137. DIR* dir = opendir(path);
  138. struct dirent* d;
  139. if (dir == null) die("failed to open folder: %s", path);
  140. do {
  141. d = readdir(dir);
  142. if (d == null) break;
  143. if (d->d_name[0] != '.') outFileNames->push(String::cpy(d->d_name));
  144. } while (1);
  145. closedir(dir);
  146. }
  147. #endif
  148. #include <sys/types.h>
  149. #include <sys/stat.h>
  150. #ifndef WIN32
  151. #include <unistd.h>
  152. #endif
  153. // msvc provides a 'stat' equivalent as _stat.
  154. #ifdef WIN32
  155. #define stat _stat
  156. #endif
  157. time_t File :: LastModified(const char* path) {
  158. ULE_TYPES_H_FTAG;
  159. struct stat result;
  160. if (stat(path, &result) == 0) {
  161. return result.st_mtime;
  162. }
  163. massert(false, "failed to get last modified timestamp.");
  164. return -1;
  165. }
  166. #undef stat
  167. s32 File :: Rename(const char* oldFilename, const char* newFilename) {
  168. return rename(oldFilename, newFilename);
  169. }
  170. s32 File :: Remove(const char* path) {
  171. return remove(path);
  172. }
  173. #ifdef _WIN32
  174. #include <winbase.h>
  175. FILE* OpenExclusive(const char* path) {
  176. HFILE result = OpenFile(path, null, OF_SHARE_EXCLUSIVE);
  177. if (result == HFILE_ERROR) {
  178. println("failed");
  179. }
  180. return null;
  181. }
  182. #else
  183. FILE* OpenExclusive(const char* path) {
  184. return null;
  185. }
  186. #endif