2022-07-15 02:06:23 +00:00
|
|
|
#include "PikaStdData_FILEIO.h"
|
|
|
|
#include <stdio.h>
|
2022-12-01 16:11:25 +08:00
|
|
|
#include "PikaCompiler.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
|
|
|
}
|
2022-12-01 16:11:25 +08:00
|
|
|
if (strIsStartWith(path, "pikafs/")) {
|
2023-02-12 11:12:28 +08:00
|
|
|
pikafs_FILE* f = pikafs_fopen(path + 7, "rb");
|
2022-12-01 16:11:25 +08:00
|
|
|
obj_setInt(self, "pikafs", PIKA_TRUE);
|
|
|
|
obj_setPtr(self, "_f", f);
|
|
|
|
obj_setStr(self, "_mode", mode);
|
|
|
|
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) {
|
2022-12-01 16:11:25 +08:00
|
|
|
if (PIKA_TRUE == obj_getInt(self, "pikafs")) {
|
2023-02-12 11:12:28 +08:00
|
|
|
pikafs_FILE* f = obj_getPtr(self, "_f");
|
2022-12-01 16:11:25 +08:00
|
|
|
if (NULL == f) {
|
|
|
|
return;
|
|
|
|
}
|
2023-02-12 11:12:28 +08:00
|
|
|
pikafs_fclose(f);
|
2022-12-01 18:11:58 +08:00
|
|
|
obj_setPtr(self, "_f", NULL);
|
2022-12-01 16:11:25 +08:00
|
|
|
return;
|
|
|
|
}
|
2022-07-15 02:06:23 +00:00
|
|
|
FILE* f = obj_getPtr(self, "_f");
|
2022-12-01 16:11:25 +08:00
|
|
|
if (NULL == f) {
|
2022-07-15 02:06:23 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
__platform_fclose(f);
|
|
|
|
obj_setPtr(self, "_f", NULL);
|
|
|
|
}
|
|
|
|
|
2022-11-25 17:32:10 +08:00
|
|
|
Arg* PikaStdData_FILEIO_read(PikaObj* self, PikaTuple* size_) {
|
|
|
|
int size = 0;
|
|
|
|
if (pikaTuple_getSize(size_) == 0) {
|
|
|
|
size = -1;
|
2022-12-01 16:11:25 +08:00
|
|
|
} else {
|
2022-11-25 17:32:10 +08:00
|
|
|
size = pikaTuple_getInt(size_, 0);
|
|
|
|
}
|
2022-07-15 10:30:38 +08:00
|
|
|
if (size <= 0) {
|
|
|
|
/* read all */
|
|
|
|
size = PIKA_READ_FILE_BUFF_SIZE;
|
|
|
|
}
|
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);
|
2022-12-01 16:11:25 +08:00
|
|
|
int n = 0;
|
2022-07-15 02:06:23 +00:00
|
|
|
/* read */
|
2022-12-01 16:11:25 +08:00
|
|
|
if (PIKA_TRUE == obj_getInt(self, "pikafs")) {
|
2023-02-12 11:12:28 +08:00
|
|
|
pikafs_FILE* f = obj_getPtr(self, "_f");
|
2022-12-01 16:11:25 +08:00
|
|
|
if (NULL == f) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2023-02-12 11:12:28 +08:00
|
|
|
n = pikafs_fread(buf, 1, size, f);
|
2022-12-01 16:11:25 +08:00
|
|
|
} else {
|
|
|
|
FILE* f = obj_getPtr(self, "_f");
|
|
|
|
if (f == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
n = __platform_fread(buf, 1, size, f);
|
|
|
|
}
|
2022-07-15 02:06:23 +00:00
|
|
|
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-12-01 16:11:25 +08:00
|
|
|
if (PIKA_TRUE == obj_getInt(self, "pikafs")) {
|
|
|
|
return 1;
|
|
|
|
}
|
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')) {
|
2022-12-02 15:03:52 +08:00
|
|
|
if (arg_getType(s) != ARG_TYPE_BYTES) {
|
|
|
|
__platform_printf(
|
|
|
|
"TypeError: a bytes-like object is required, not 'str'\r\n");
|
|
|
|
obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
|
|
|
|
return -1;
|
|
|
|
}
|
2022-07-15 02:06:23 +00:00
|
|
|
/* binary */
|
2022-11-04 13:34:34 +08:00
|
|
|
res = __platform_fwrite(arg_getBytes(s), 1, arg_getBytesSize(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;
|
|
|
|
}
|
2022-11-19 19:11:34 +08:00
|
|
|
if (pikaTuple_getSize(fromwhere) == 1) {
|
|
|
|
int whence = pikaTuple_getInt(fromwhere, 0);
|
2022-07-18 05:29:43 +00:00
|
|
|
__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;
|
|
|
|
}
|
2022-11-19 19:11:34 +08:00
|
|
|
for (size_t i = 0; i < pikaList_getSize(list); i++) {
|
|
|
|
char* line = pikaList_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
|
|
|
}
|