PikaStdData_FILEIO.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include "PikaStdData_FILEIO.h"
  2. #include <stdio.h>
  3. #include "PikaStdData_List.h"
  4. int PikaStdData_FILEIO_init(PikaObj* self, char* path, char* mode) {
  5. if (obj_isArgExist(self, "_f")) {
  6. /* already initialized */
  7. return 0;
  8. }
  9. FILE* f = __platform_fopen(path, mode);
  10. if (f == NULL) {
  11. return 1;
  12. }
  13. obj_setPtr(self, "_f", f);
  14. obj_setStr(self, "_mode", mode);
  15. return 0;
  16. }
  17. void PikaStdData_FILEIO_close(PikaObj* self) {
  18. FILE* f = obj_getPtr(self, "_f");
  19. if (f == NULL) {
  20. return;
  21. }
  22. __platform_fclose(f);
  23. obj_setPtr(self, "_f", NULL);
  24. }
  25. Arg* PikaStdData_FILEIO_read(PikaObj* self, int size) {
  26. if (size <= 0) {
  27. /* read all */
  28. size = PIKA_READ_FILE_BUFF_SIZE;
  29. }
  30. FILE* f = obj_getPtr(self, "_f");
  31. if (f == NULL) {
  32. return NULL;
  33. }
  34. Arg* buf_arg = arg_newBytes(NULL, size);
  35. uint8_t* buf = arg_getBytes(buf_arg);
  36. /* read */
  37. int n = __platform_fread(buf, 1, size, f);
  38. if (n < size) {
  39. /* EOF */
  40. buf[n] = '\0';
  41. }
  42. char* mode = obj_getStr(self, "_mode");
  43. if (strIsContain(mode, 'b')) {
  44. /* binary */
  45. Arg* res = arg_newBytes(buf, n);
  46. arg_deinit(buf_arg);
  47. return res;
  48. } else {
  49. /* text */
  50. Arg* res = arg_newStr((char*)buf);
  51. arg_deinit(buf_arg);
  52. return res;
  53. }
  54. }
  55. int PikaStdData_FILEIO_write(PikaObj* self, Arg* s) {
  56. FILE* f = obj_getPtr(self, "_f");
  57. int res = -1;
  58. if (f == NULL) {
  59. obj_setErrorCode(self, PIKA_RES_ERR_IO);
  60. __platform_printf("Error: can't write to file\n");
  61. return res;
  62. }
  63. char* mode = obj_getStr(self, "_mode");
  64. if (strIsContain(mode, 'b')) {
  65. /* binary */
  66. res = __platform_fwrite(arg_getBytes(s), 1, arg_getSize(s), f);
  67. } else {
  68. /* text */
  69. char* str = arg_getStr(s);
  70. res = __platform_fwrite(str, 1, strlen(str), f);
  71. }
  72. return res;
  73. }
  74. int PikaStdData_FILEIO_seek(PikaObj* self, int offset, PikaTuple* fromwhere) {
  75. FILE* f = obj_getPtr(self, "_f");
  76. if (f == NULL) {
  77. obj_setErrorCode(self, PIKA_RES_ERR_IO);
  78. __platform_printf("Error: can't seek in file\n");
  79. return -1;
  80. }
  81. if (tuple_getSize(fromwhere) == 1) {
  82. int whence = tuple_getInt(fromwhere, 0);
  83. __platform_fseek(f, offset, whence);
  84. return __platform_ftell(f);
  85. }
  86. __platform_fseek(f, offset, 0);
  87. return __platform_ftell(f);
  88. }
  89. int PikaStdData_FILEIO_tell(PikaObj* self) {
  90. FILE* f = obj_getPtr(self, "_f");
  91. if (f == NULL) {
  92. obj_setErrorCode(self, PIKA_RES_ERR_IO);
  93. __platform_printf("Error: can't tell in file\n");
  94. return -1;
  95. }
  96. return __platform_ftell(f);
  97. }
  98. char* PikaStdData_FILEIO_readline(PikaObj* self) {
  99. FILE* f = obj_getPtr(self, "_f");
  100. if (f == NULL) {
  101. obj_setErrorCode(self, PIKA_RES_ERR_IO);
  102. __platform_printf("Error: can't read line from file\n");
  103. return NULL;
  104. }
  105. obj_setBytes(self, "_line_buff", NULL, PIKA_LINE_BUFF_SIZE);
  106. char* line_buff = (char*)obj_getBytes(self, "_line_buff");
  107. while (1) {
  108. char char_buff[2] = {0};
  109. int n = __platform_fread(char_buff, 1, 1, f);
  110. if (n == 0) {
  111. /* EOF */
  112. return NULL;
  113. }
  114. if (char_buff[0] == '\n') {
  115. /* end of line */
  116. strAppend(line_buff, char_buff);
  117. return line_buff;
  118. }
  119. if (strGetSize(line_buff) >= PIKA_LINE_BUFF_SIZE) {
  120. /* line too long */
  121. obj_setErrorCode(self, PIKA_RES_ERR_IO);
  122. __platform_printf("Error: line too long\n");
  123. return NULL;
  124. }
  125. strAppend(line_buff, char_buff);
  126. }
  127. }
  128. PikaObj* PikaStdData_FILEIO_readlines(PikaObj* self) {
  129. FILE* f = obj_getPtr(self, "_f");
  130. if (f == NULL) {
  131. obj_setErrorCode(self, PIKA_RES_ERR_IO);
  132. __platform_printf("Error: can't read lines from file\n");
  133. return NULL;
  134. }
  135. PikaObj* line_list = newNormalObj(New_PikaStdData_List);
  136. PikaStdData_List___init__(line_list);
  137. while (1) {
  138. char* line = PikaStdData_FILEIO_readline(self);
  139. if (line == NULL) {
  140. break;
  141. }
  142. Arg* arg_str = arg_newStr(line);
  143. PikaStdData_List_append(line_list, arg_str);
  144. arg_deinit(arg_str);
  145. }
  146. return line_list;
  147. }
  148. void PikaStdData_FILEIO_writelines(PikaObj* self, PikaObj* lines) {
  149. FILE* f = obj_getPtr(self, "_f");
  150. if (f == NULL) {
  151. obj_setErrorCode(self, PIKA_RES_ERR_IO);
  152. __platform_printf("Error: can't write lines to file\n");
  153. return;
  154. }
  155. PikaList* list = obj_getPtr(lines, "list");
  156. if (list == NULL) {
  157. obj_setErrorCode(self, PIKA_RES_ERR_IO);
  158. __platform_printf("Error: can't write lines to file\n");
  159. return;
  160. }
  161. for (size_t i = 0; i < list_getSize(list); i++) {
  162. char* line = list_getStr(list, i);
  163. Arg* arg_str = arg_newStr(line);
  164. PikaStdData_FILEIO_write(self, arg_str);
  165. arg_deinit(arg_str);
  166. }
  167. return;
  168. }