PikaStdData_FILEIO.c 6.2 KB

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