diff --git a/examples/BuiltIn/seek.py b/examples/BuiltIn/seek.py new file mode 100644 index 000000000..9e3efaf55 --- /dev/null +++ b/examples/BuiltIn/seek.py @@ -0,0 +1,4 @@ +f = open('test/assets/test.jpg', 'rb') +len = f.seek(0, 2) +print(len) +f.close() \ No newline at end of file diff --git a/package/PikaStdLib/PikaStdData.pyi b/package/PikaStdLib/PikaStdData.pyi index 649a7f095..aacfce77d 100644 --- a/package/PikaStdLib/PikaStdData.pyi +++ b/package/PikaStdLib/PikaStdData.pyi @@ -80,7 +80,7 @@ class String: def strip(self) -> str: ... -class ByteArray(TinyObj): +class ByteArray: # convert a string to ByteArray def __init__(self, bytes: any): ... # support for loop @@ -97,8 +97,10 @@ class ByteArray(TinyObj): class FILEIO: def init(self, path: str, mode: str): ... def read(self, size: int) -> any: ... - def write(self, s: any): ... + def write(self, s: any) -> int: ... def close(self): ... + def seek(self, offset: int, *fromwhere) -> int: ... + def tell(self) -> int: ... class Utils: diff --git a/package/PikaStdLib/PikaStdData_FILEIO.c b/package/PikaStdLib/PikaStdData_FILEIO.c index 4c06ceda8..612f69cfe 100644 --- a/package/PikaStdLib/PikaStdData_FILEIO.c +++ b/package/PikaStdLib/PikaStdData_FILEIO.c @@ -55,20 +55,48 @@ Arg* PikaStdData_FILEIO_read(PikaObj* self, int size) { } } -void PikaStdData_FILEIO_write(PikaObj* self, Arg* s) { +int PikaStdData_FILEIO_write(PikaObj* self, Arg* s) { FILE* f = obj_getPtr(self, "_f"); + int res = -1; if (f == NULL) { obj_setErrorCode(self, PIKA_RES_ERR_IO); __platform_printf("Error: can't write to file\n"); - return; + return res; } char* mode = obj_getStr(self, "_mode"); if (strIsContain(mode, 'b')) { /* binary */ - __platform_fwrite(arg_getBytes(s), 1, arg_getSize(s), f); + res = __platform_fwrite(arg_getBytes(s), 1, arg_getSize(s), f); } else { /* text */ char* str = arg_getStr(s); - __platform_fwrite(str, 1, strlen(str), f); + res = __platform_fwrite(str, 1, strlen(str), f); } + return res; +} + +int PikaStdData_FILEIO_seek(PikaObj* self, PikaTuple* fromwhere, int offset) { + 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; + } + return __platform_ftell(f); } diff --git a/port/linux/package/pikascript/PikaStdData.pyi b/port/linux/package/pikascript/PikaStdData.pyi index 649a7f095..aacfce77d 100644 --- a/port/linux/package/pikascript/PikaStdData.pyi +++ b/port/linux/package/pikascript/PikaStdData.pyi @@ -80,7 +80,7 @@ class String: def strip(self) -> str: ... -class ByteArray(TinyObj): +class ByteArray: # convert a string to ByteArray def __init__(self, bytes: any): ... # support for loop @@ -97,8 +97,10 @@ class ByteArray(TinyObj): class FILEIO: def init(self, path: str, mode: str): ... def read(self, size: int) -> any: ... - def write(self, s: any): ... + def write(self, s: any) -> int: ... def close(self): ... + def seek(self, offset: int, *fromwhere) -> int: ... + def tell(self) -> int: ... class Utils: diff --git a/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdData_FILEIO.c b/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdData_FILEIO.c index 4c06ceda8..612f69cfe 100644 --- a/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdData_FILEIO.c +++ b/port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdData_FILEIO.c @@ -55,20 +55,48 @@ Arg* PikaStdData_FILEIO_read(PikaObj* self, int size) { } } -void PikaStdData_FILEIO_write(PikaObj* self, Arg* s) { +int PikaStdData_FILEIO_write(PikaObj* self, Arg* s) { FILE* f = obj_getPtr(self, "_f"); + int res = -1; if (f == NULL) { obj_setErrorCode(self, PIKA_RES_ERR_IO); __platform_printf("Error: can't write to file\n"); - return; + return res; } char* mode = obj_getStr(self, "_mode"); if (strIsContain(mode, 'b')) { /* binary */ - __platform_fwrite(arg_getBytes(s), 1, arg_getSize(s), f); + res = __platform_fwrite(arg_getBytes(s), 1, arg_getSize(s), f); } else { /* text */ char* str = arg_getStr(s); - __platform_fwrite(str, 1, strlen(str), f); + res = __platform_fwrite(str, 1, strlen(str), f); } + return res; +} + +int PikaStdData_FILEIO_seek(PikaObj* self, PikaTuple* fromwhere, int offset) { + 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; + } + return __platform_ftell(f); } diff --git a/port/linux/test/builtin-test.cpp b/port/linux/test/builtin-test.cpp index 80da9bf10..a4df94492 100644 --- a/port/linux/test/builtin-test.cpp +++ b/port/linux/test/builtin-test.cpp @@ -35,3 +35,21 @@ TEST(builtin, type1) { EXPECT_EQ(pikaMemNow(), 0); } #endif + +#if PIKA_SYNTAX_LEVEL == PIKA_SYNTAX_LEVEL_MAXIMAL +TEST(builtin, seek) { + /* init */ + pikaMemInfo.heapUsedMax = 0; + PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); + /* run */ + __platform_printf("BEGIN\r\n"); + pikaVM_runSingleFile(pikaMain, "../../examples/BuiltIn/seek.py"); + /* collect */ + int len = obj_getInt(pikaMain, "len"); + /* assert */ + EXPECT_EQ(len, 3576); + /* deinit */ + obj_deinit(pikaMain); + EXPECT_EQ(pikaMemNow(), 0); +} +#endif diff --git a/src/PikaPlatform.c b/src/PikaPlatform.c index 7f0d16e72..edc549182 100644 --- a/src/PikaPlatform.c +++ b/src/PikaPlatform.c @@ -101,6 +101,7 @@ PIKA_WEAK void __platform_wait(void) { while (1) { }; } + PIKA_WEAK void* __platform_memset(void* mem, int ch, size_t size) { return memset(mem, ch, size); } @@ -119,6 +120,7 @@ PIKA_WEAK char __platform_getchar(void) { #endif } +/* fopen */ PIKA_WEAK FILE* __platform_fopen(const char* filename, const char* modes) { #if defined(__linux) || defined(_WIN32) return fopen(filename, modes); @@ -129,6 +131,7 @@ PIKA_WEAK FILE* __platform_fopen(const char* filename, const char* modes) { #endif } +/* fclose */ PIKA_WEAK int __platform_fclose(FILE* stream) { #if defined(__linux) || defined(_WIN32) return fclose(stream); @@ -139,6 +142,7 @@ PIKA_WEAK int __platform_fclose(FILE* stream) { #endif } +/* fwrite */ PIKA_WEAK size_t __platform_fwrite(const void* ptr, size_t size, size_t n, @@ -152,6 +156,7 @@ PIKA_WEAK size_t __platform_fwrite(const void* ptr, #endif } +/* fread */ PIKA_WEAK size_t __platform_fread(void* ptr, size_t size, size_t n, @@ -164,3 +169,25 @@ PIKA_WEAK size_t __platform_fread(void* ptr, } #endif } + +/* fseek */ +PIKA_WEAK int __platform_fseek(FILE* stream, long offset, int whence) { +#if defined(__linux) || defined(_WIN32) + return fseek(stream, offset, whence); +#else + __platform_printf("[error]: __platform_fseek need implementation!\r\n"); + while (1) { + } +#endif +} + +/* ftell */ +PIKA_WEAK long __platform_ftell(FILE* stream) { +#if defined(__linux) || defined(_WIN32) + return ftell(stream); +#else + __platform_printf("[error]: __platform_ftell need implementation!\r\n"); + while (1) { + } +#endif +} diff --git a/src/PikaPlatform.h b/src/PikaPlatform.h index 6c76453f8..0d33dc984 100644 --- a/src/PikaPlatform.h +++ b/src/PikaPlatform.h @@ -152,8 +152,10 @@ FILE* __platform_fopen(const char* filename, const char* modes); int __platform_fclose(FILE* stream); size_t __platform_fwrite(const void* ptr, size_t size, size_t n, FILE* stream); size_t __platform_fread(void* ptr, size_t size, size_t n, FILE* stream); +int __platform_fseek(FILE* stream, long offset, int whence); /* error */ void __platform_error_handle(void); +long __platform_ftell(FILE* stream); #endif diff --git a/src/PikaVersion.h b/src/PikaVersion.h index 2f054827b..1a52af280 100644 --- a/src/PikaVersion.h +++ b/src/PikaVersion.h @@ -2,4 +2,4 @@ #define PIKA_VERSION_MINOR 9 #define PIKA_VERSION_MICRO 1 -#define PIKA_EDIT_TIME "2022/07/15 10:48:23" +#define PIKA_EDIT_TIME "2022/07/18 13:14:40" diff --git a/src/dataArgs.c b/src/dataArgs.c index 6c76fb6c1..16bb6707d 100644 --- a/src/dataArgs.c +++ b/src/dataArgs.c @@ -551,6 +551,26 @@ Arg* list_getArg(PikaList* self, int index) { return args_getArg(&self->super, i_str); } +int list_getInt(PikaList* self, int index) { + Arg* arg = list_getArg(self, index); + return arg_getInt(arg); +} + +double list_getFloat(PikaList* self, int index) { + Arg* arg = list_getArg(self, index); + return arg_getFloat(arg); +} + +char* list_getStr(PikaList* self, int index) { + Arg* arg = list_getArg(self, index); + return arg_getStr(arg); +} + +void* list_getPtr(PikaList* self, int index) { + Arg* arg = list_getArg(self, index); + return arg_getPtr(arg); +} + PIKA_RES list_append(PikaList* self, Arg* arg) { int top = args_getInt(&self->super, "top"); char buff[11]; diff --git a/src/dataArgs.h b/src/dataArgs.h index 763e43c4a..96e830f4a 100644 --- a/src/dataArgs.h +++ b/src/dataArgs.h @@ -162,6 +162,10 @@ PikaDict* New_dict(void); #define list_deinit(self) (args_deinit((&((self)->super)))) PIKA_RES list_append(PikaList* self, Arg* arg); PIKA_RES list_setArg(PikaList* self, int index, Arg* arg); +int list_getInt(PikaList* self, int index); +double list_getFloat(PikaList* self, int index); +char* list_getStr(PikaList* self, int index); +void* list_getPtr(PikaList* self, int index); Arg* list_getArg(PikaList* self, int index); size_t list_getSize(PikaList* self); char* strsFormatArg(Args* out_buffs, char* fmt, Arg* arg); @@ -170,6 +174,12 @@ char* strsFormatArg(Args* out_buffs, char* fmt, Arg* arg); #define tuple_deinit(self) (list_deinit((&((self)->super)))) #define tuple_getArg(self, index) (list_getArg((&((self)->super)), (index))) #define tuple_getSize(self) (list_getSize((&((self)->super)))) +#define tuple_getInt(self, index) (list_getInt((&((self)->super)), (index))) +#define tuple_getFloat(self, index) \ + (list_getFloat((&((self)->super)), (index))) +#define tuple_getStr(self, index) (list_getStr((&((self)->super)), (index))) +#define tuple_getPtr(self, index) (list_getPtr((&((self)->super)), (index))) +#define tuple_getType(self, index) (list_getType((&((self)->super)), (index))) PikaList* New_list(void); PikaTuple* New_tuple(void);