PikaStdData_FILEIO.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #include "PikaStdData_FILEIO.h"
  2. #include <stdio.h>
  3. #include "PikaCompiler.h"
  4. #include "PikaStdData_List.h"
  5. int PikaStdData_FILEIO_init(PikaObj* self, char* path, char* mode) {
  6. if (obj_isArgExist(self, "_f")) {
  7. /* already initialized */
  8. return 0;
  9. }
  10. if (strIsStartWith(path, "/pikafs/")) {
  11. pikafs_FILE* f = pikafs_fopen(path + 8, "rb");
  12. if (f == NULL) {
  13. return 1;
  14. }
  15. obj_setInt(self, "pikafs", PIKA_TRUE);
  16. obj_setPtr(self, "_f", f);
  17. obj_setStr(self, "_mode", mode);
  18. return 0;
  19. }
  20. FILE* f = __platform_fopen(path, mode);
  21. if (f == NULL) {
  22. return 1;
  23. }
  24. obj_setPtr(self, "_f", f);
  25. obj_setStr(self, "_mode", mode);
  26. return 0;
  27. }
  28. void PikaStdData_FILEIO_close(PikaObj* self) {
  29. if (PIKA_TRUE == obj_getInt(self, "pikafs")) {
  30. pikafs_FILE* f = obj_getPtr(self, "_f");
  31. if (NULL == f) {
  32. return;
  33. }
  34. pikafs_fclose(f);
  35. obj_setPtr(self, "_f", NULL);
  36. return;
  37. }
  38. FILE* f = obj_getPtr(self, "_f");
  39. if (NULL == f) {
  40. return;
  41. }
  42. __platform_fclose(f);
  43. obj_setPtr(self, "_f", NULL);
  44. }
  45. Arg* PikaStdData_FILEIO_read(PikaObj* self, PikaTuple* size_) {
  46. int size = 0;
  47. if (pikaTuple_getSize(size_) == 0) {
  48. size = -1;
  49. } else {
  50. size = pikaTuple_getInt(size_, 0);
  51. }
  52. if (size <= 0) {
  53. /* read all */
  54. size = PIKA_READ_FILE_BUFF_SIZE;
  55. }
  56. Arg* buf_arg = arg_newBytes(NULL, size);
  57. uint8_t* buf = arg_getBytes(buf_arg);
  58. int n = 0;
  59. /* read */
  60. if (PIKA_TRUE == obj_getInt(self, "pikafs")) {
  61. pikafs_FILE* f = obj_getPtr(self, "_f");
  62. if (NULL == f) {
  63. return NULL;
  64. }
  65. n = pikafs_fread(buf, 1, size, f);
  66. } else {
  67. FILE* f = obj_getPtr(self, "_f");
  68. if (f == NULL) {
  69. return NULL;
  70. }
  71. n = __platform_fread(buf, 1, size, f);
  72. }
  73. if (n < size) {
  74. /* EOF */
  75. buf[n] = '\0';
  76. }
  77. char* mode = obj_getStr(self, "_mode");
  78. if (strIsContain(mode, 'b')) {
  79. /* binary */
  80. Arg* res = arg_newBytes(buf, n);
  81. arg_deinit(buf_arg);
  82. return res;
  83. } else {
  84. /* text */
  85. Arg* res = arg_newStr((char*)buf);
  86. arg_deinit(buf_arg);
  87. return res;
  88. }
  89. }
  90. int PikaStdData_FILEIO_write(PikaObj* self, Arg* s) {
  91. if (PIKA_TRUE == obj_getInt(self, "pikafs")) {
  92. return 1;
  93. }
  94. FILE* f = obj_getPtr(self, "_f");
  95. int res = -1;
  96. if (f == NULL) {
  97. obj_setErrorCode(self, PIKA_RES_ERR_IO);
  98. obj_setSysOut(self, "Error: can't write to file");
  99. return res;
  100. }
  101. char* mode = obj_getStr(self, "_mode");
  102. if (strIsContain(mode, 'b')) {
  103. if (arg_getType(s) != ARG_TYPE_BYTES) {
  104. obj_setSysOut(
  105. self, "TypeError: a bytes-like object is required, not 'str'");
  106. obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
  107. return -1;
  108. }
  109. /* binary */
  110. res = __platform_fwrite(arg_getBytes(s), 1, arg_getBytesSize(s), f);
  111. } else {
  112. /* text */
  113. char* str = arg_getStr(s);
  114. res = __platform_fwrite(str, 1, strlen(str), f);
  115. }
  116. return res;
  117. }
  118. int PikaStdData_FILEIO_seek(PikaObj* self, int offset, PikaTuple* fromwhere) {
  119. FILE* f = obj_getPtr(self, "_f");
  120. if (f == NULL) {
  121. obj_setErrorCode(self, PIKA_RES_ERR_IO);
  122. obj_setSysOut(self, "Error: can't seek in file");
  123. return -1;
  124. }
  125. if (pikaTuple_getSize(fromwhere) == 1) {
  126. int whence = pikaTuple_getInt(fromwhere, 0);
  127. __platform_fseek(f, offset, whence);
  128. return __platform_ftell(f);
  129. }
  130. __platform_fseek(f, offset, 0);
  131. return __platform_ftell(f);
  132. }
  133. int PikaStdData_FILEIO_tell(PikaObj* self) {
  134. FILE* f = obj_getPtr(self, "_f");
  135. if (f == NULL) {
  136. obj_setErrorCode(self, PIKA_RES_ERR_IO);
  137. obj_setSysOut(self, "Error: can't tell in file");
  138. return -1;
  139. }
  140. return __platform_ftell(f);
  141. }
  142. char* PikaStdData_FILEIO_readline(PikaObj* self) {
  143. FILE* f = obj_getPtr(self, "_f");
  144. if (f == NULL) {
  145. obj_setErrorCode(self, PIKA_RES_ERR_IO);
  146. obj_setSysOut(self, "Error: can't read line from file");
  147. return NULL;
  148. }
  149. int line_buff_size = 16;
  150. int line_size = 0;
  151. char* line_buff = (char*)pika_platform_malloc(line_buff_size);
  152. pika_platform_memset(line_buff, 0, line_buff_size);
  153. while (1) {
  154. char char_buff[2] = {0};
  155. int n = __platform_fread(char_buff, 1, 1, f);
  156. if (n == 0) {
  157. /* EOF */
  158. if (strGetSize(line_buff) == 0) {
  159. pika_platform_free(line_buff);
  160. return NULL;
  161. }
  162. obj_setStr(self, "@sc", line_buff);
  163. pika_platform_free(line_buff);
  164. return obj_getStr(self, "@sc");
  165. }
  166. line_size++;
  167. if (line_size >= line_buff_size) {
  168. /* line too long, double buff and realloc */
  169. line_buff_size *= 2;
  170. line_buff = (char*)pika_reallocn(line_buff, line_buff_size / 2,
  171. line_buff_size);
  172. pika_platform_memset(line_buff + line_size, 0,
  173. line_buff_size - line_size);
  174. }
  175. if (char_buff[0] == '\n') {
  176. /* end of line */
  177. line_buff[line_size - 1] = '\n';
  178. obj_setStr(self, "@sc", line_buff);
  179. pika_platform_free(line_buff);
  180. return obj_getStr(self, "@sc");
  181. }
  182. line_buff[line_size - 1] = char_buff[0];
  183. }
  184. }
  185. PikaObj* PikaStdData_FILEIO_readlines(PikaObj* self) {
  186. FILE* f = obj_getPtr(self, "_f");
  187. if (f == NULL) {
  188. obj_setErrorCode(self, PIKA_RES_ERR_IO);
  189. obj_setSysOut(self, "Error: can't read lines from file");
  190. return NULL;
  191. }
  192. PikaObj* line_list = newNormalObj(New_PikaStdData_List);
  193. PikaStdData_List___init__(line_list);
  194. while (1) {
  195. char* line = PikaStdData_FILEIO_readline(self);
  196. if (line == NULL) {
  197. break;
  198. }
  199. Arg* arg_str = arg_newStr(line);
  200. PikaStdData_List_append(line_list, arg_str);
  201. arg_deinit(arg_str);
  202. }
  203. return line_list;
  204. }
  205. void PikaStdData_FILEIO_writelines(PikaObj* self, PikaObj* lines) {
  206. FILE* f = obj_getPtr(self, "_f");
  207. if (f == NULL) {
  208. obj_setErrorCode(self, PIKA_RES_ERR_IO);
  209. obj_setSysOut(self, "Error: can't write lines to file");
  210. return;
  211. }
  212. for (size_t i = 0; i < pikaList_getSize(lines); i++) {
  213. char* line = pikaList_getStr(lines, i);
  214. Arg* arg_str = arg_newStr(line);
  215. PikaStdData_FILEIO_write(self, arg_str);
  216. arg_deinit(arg_str);
  217. }
  218. return;
  219. }