2022-07-15 02:06:23 +00:00
|
|
|
#include "PikaStdData_FILEIO.h"
|
|
|
|
#include <stdio.h>
|
2022-07-18 13:53:39 +08:00
|
|
|
#include "PikaStdData_List.h"
|
2022-07-15 02:06:23 +00:00
|
|
|
|
2022-08-06 17:59:32 +08:00
|
|
|
int PikaStdData_FILEIO_init(PikaObj* self, char* path, char* mode) {
|
2022-07-15 02:06:23 +00:00
|
|
|
if (obj_isArgExist(self, "_f")) {
|
|
|
|
/* already initialized */
|
2022-08-06 17:59:32 +08:00
|
|
|
return 0;
|
2022-07-15 02:06:23 +00:00
|
|
|
}
|
|
|
|
FILE* f = __platform_fopen(path, mode);
|
|
|
|
if (f == NULL) {
|
2022-08-06 17:59:32 +08:00
|
|
|
return 1;
|
2022-07-15 02:06:23 +00:00
|
|
|
}
|
|
|
|
obj_setPtr(self, "_f", f);
|
|
|
|
obj_setStr(self, "_mode", mode);
|
2022-08-06 17:59:32 +08:00
|
|
|
return 0;
|
2022-07-15 02:06:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void PikaStdData_FILEIO_close(PikaObj* self) {
|
|
|
|
FILE* f = obj_getPtr(self, "_f");
|
|
|
|
if (f == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
__platform_fclose(f);
|
|
|
|
obj_setPtr(self, "_f", NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
Arg* PikaStdData_FILEIO_read(PikaObj* self, int size) {
|
2022-07-15 10:30:38 +08:00
|
|
|
if (size <= 0) {
|
|
|
|
/* read all */
|
|
|
|
size = PIKA_READ_FILE_BUFF_SIZE;
|
|
|
|
}
|
2022-07-15 02:06:23 +00:00
|
|
|
FILE* f = obj_getPtr(self, "_f");
|
|
|
|
if (f == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2022-07-20 10:32:01 +08:00
|
|
|
Arg* buf_arg = arg_newBytes(NULL, size);
|
2022-07-15 02:06:23 +00:00
|
|
|
uint8_t* buf = arg_getBytes(buf_arg);
|
|
|
|
/* read */
|
|
|
|
int n = __platform_fread(buf, 1, size, f);
|
|
|
|
if (n < size) {
|
|
|
|
/* EOF */
|
|
|
|
buf[n] = '\0';
|
|
|
|
}
|
|
|
|
char* mode = obj_getStr(self, "_mode");
|
|
|
|
if (strIsContain(mode, 'b')) {
|
|
|
|
/* binary */
|
2022-07-20 10:32:01 +08:00
|
|
|
Arg* res = arg_newBytes(buf, n);
|
2022-07-15 10:30:38 +08:00
|
|
|
arg_deinit(buf_arg);
|
|
|
|
return res;
|
2022-07-15 02:06:23 +00:00
|
|
|
} else {
|
|
|
|
/* text */
|
2022-07-20 10:32:01 +08:00
|
|
|
Arg* res = arg_newStr((char*)buf);
|
2022-07-15 02:06:23 +00:00
|
|
|
arg_deinit(buf_arg);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-18 05:29:43 +00:00
|
|
|
int PikaStdData_FILEIO_write(PikaObj* self, Arg* s) {
|
2022-07-15 02:06:23 +00:00
|
|
|
FILE* f = obj_getPtr(self, "_f");
|
2022-07-18 05:29:43 +00:00
|
|
|
int res = -1;
|
2022-07-15 02:06:23 +00:00
|
|
|
if (f == NULL) {
|
|
|
|
obj_setErrorCode(self, PIKA_RES_ERR_IO);
|
|
|
|
__platform_printf("Error: can't write to file\n");
|
2022-07-18 05:29:43 +00:00
|
|
|
return res;
|
2022-07-15 02:06:23 +00:00
|
|
|
}
|
|
|
|
char* mode = obj_getStr(self, "_mode");
|
|
|
|
if (strIsContain(mode, 'b')) {
|
|
|
|
/* binary */
|
2022-07-18 05:29:43 +00:00
|
|
|
res = __platform_fwrite(arg_getBytes(s), 1, arg_getSize(s), f);
|
2022-07-15 02:06:23 +00:00
|
|
|
} else {
|
|
|
|
/* text */
|
|
|
|
char* str = arg_getStr(s);
|
2022-07-18 05:29:43 +00:00
|
|
|
res = __platform_fwrite(str, 1, strlen(str), f);
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2022-08-06 17:59:32 +08:00
|
|
|
int PikaStdData_FILEIO_seek(PikaObj* self, int offset, PikaTuple* fromwhere) {
|
2022-07-18 05:29:43 +00:00
|
|
|
FILE* f = obj_getPtr(self, "_f");
|
|
|
|
if (f == NULL) {
|
|
|
|
obj_setErrorCode(self, PIKA_RES_ERR_IO);
|
|
|
|
__platform_printf("Error: can't seek in file\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (tuple_getSize(fromwhere) == 1) {
|
|
|
|
int whence = tuple_getInt(fromwhere, 0);
|
|
|
|
__platform_fseek(f, offset, whence);
|
|
|
|
return __platform_ftell(f);
|
|
|
|
}
|
|
|
|
__platform_fseek(f, offset, 0);
|
|
|
|
return __platform_ftell(f);
|
|
|
|
}
|
|
|
|
|
|
|
|
int PikaStdData_FILEIO_tell(PikaObj* self) {
|
|
|
|
FILE* f = obj_getPtr(self, "_f");
|
|
|
|
if (f == NULL) {
|
|
|
|
obj_setErrorCode(self, PIKA_RES_ERR_IO);
|
|
|
|
__platform_printf("Error: can't tell in file\n");
|
|
|
|
return -1;
|
2022-07-15 02:06:23 +00:00
|
|
|
}
|
2022-07-18 05:29:43 +00:00
|
|
|
return __platform_ftell(f);
|
2022-07-15 02:06:23 +00:00
|
|
|
}
|
2022-07-18 13:53:39 +08:00
|
|
|
|
|
|
|
char* PikaStdData_FILEIO_readline(PikaObj* self) {
|
|
|
|
FILE* f = obj_getPtr(self, "_f");
|
|
|
|
if (f == NULL) {
|
|
|
|
obj_setErrorCode(self, PIKA_RES_ERR_IO);
|
|
|
|
__platform_printf("Error: can't read line from file\n");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
obj_setBytes(self, "_line_buff", NULL, PIKA_LINE_BUFF_SIZE);
|
|
|
|
char* line_buff = (char*)obj_getBytes(self, "_line_buff");
|
|
|
|
while (1) {
|
|
|
|
char char_buff[2] = {0};
|
|
|
|
int n = __platform_fread(char_buff, 1, 1, f);
|
|
|
|
if (n == 0) {
|
|
|
|
/* EOF */
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (char_buff[0] == '\n') {
|
|
|
|
/* end of line */
|
|
|
|
strAppend(line_buff, char_buff);
|
|
|
|
return line_buff;
|
|
|
|
}
|
|
|
|
if (strGetSize(line_buff) >= PIKA_LINE_BUFF_SIZE) {
|
|
|
|
/* line too long */
|
|
|
|
obj_setErrorCode(self, PIKA_RES_ERR_IO);
|
|
|
|
__platform_printf("Error: line too long\n");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
strAppend(line_buff, char_buff);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PikaObj* PikaStdData_FILEIO_readlines(PikaObj* self) {
|
|
|
|
FILE* f = obj_getPtr(self, "_f");
|
|
|
|
if (f == NULL) {
|
|
|
|
obj_setErrorCode(self, PIKA_RES_ERR_IO);
|
|
|
|
__platform_printf("Error: can't read lines from file\n");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
PikaObj* line_list = newNormalObj(New_PikaStdData_List);
|
|
|
|
PikaStdData_List___init__(line_list);
|
|
|
|
while (1) {
|
|
|
|
char* line = PikaStdData_FILEIO_readline(self);
|
|
|
|
if (line == NULL) {
|
|
|
|
break;
|
|
|
|
}
|
2022-07-20 10:32:01 +08:00
|
|
|
Arg* arg_str = arg_newStr(line);
|
2022-07-18 13:53:39 +08:00
|
|
|
PikaStdData_List_append(line_list, arg_str);
|
|
|
|
arg_deinit(arg_str);
|
|
|
|
}
|
|
|
|
return line_list;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PikaStdData_FILEIO_writelines(PikaObj* self, PikaObj* lines) {
|
|
|
|
FILE* f = obj_getPtr(self, "_f");
|
|
|
|
if (f == NULL) {
|
|
|
|
obj_setErrorCode(self, PIKA_RES_ERR_IO);
|
|
|
|
__platform_printf("Error: can't write lines to file\n");
|
2022-07-18 15:46:35 +08:00
|
|
|
return;
|
2022-07-18 13:53:39 +08:00
|
|
|
}
|
|
|
|
PikaList* list = obj_getPtr(lines, "list");
|
|
|
|
if (list == NULL) {
|
|
|
|
obj_setErrorCode(self, PIKA_RES_ERR_IO);
|
|
|
|
__platform_printf("Error: can't write lines to file\n");
|
2022-07-18 15:46:35 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (size_t i = 0; i < list_getSize(list); i++) {
|
|
|
|
char* line = list_getStr(list, i);
|
2022-07-20 10:32:01 +08:00
|
|
|
Arg* arg_str = arg_newStr(line);
|
2022-07-18 15:46:35 +08:00
|
|
|
PikaStdData_FILEIO_write(self, arg_str);
|
|
|
|
arg_deinit(arg_str);
|
2022-07-18 13:53:39 +08:00
|
|
|
}
|
2022-07-18 15:46:35 +08:00
|
|
|
return;
|
2022-07-18 13:53:39 +08:00
|
|
|
}
|