static void test_Clone_and_Reopen(TestBatchRunner *runner) { String *foo = SSTR_WRAP_C("foo"); String *bar = SSTR_WRAP_C("bar"); RAMFile *file = RAMFile_new(NULL, false); OutStream *outstream = OutStream_open((Obj*)file); RAMFileHandle *fh; InStream *instream; InStream *clone; InStream *reopened; for (uint8_t i = 0; i < 26; i++) { OutStream_Write_U8(outstream, 'a' + i); } OutStream_Close(outstream); fh = RAMFH_open(foo, FH_READ_ONLY, file); instream = InStream_open((Obj*)fh); InStream_Seek(instream, 1); TEST_TRUE(runner, Str_Equals(InStream_Get_Filename(instream), (Obj*)foo), "Get_Filename"); clone = InStream_Clone(instream); TEST_TRUE(runner, Str_Equals(InStream_Get_Filename(clone), (Obj*)foo), "Clones have same filename"); TEST_TRUE(runner, InStream_Length(instream) == InStream_Length(clone), "Clones have same length"); TEST_TRUE(runner, InStream_Read_U8(instream) == InStream_Read_U8(clone), "Clones start at same file position"); reopened = InStream_Reopen(instream, bar, 25, 1); TEST_TRUE(runner, Str_Equals(InStream_Get_Filename(reopened), (Obj*)bar), "Reopened InStreams take new filename"); TEST_TRUE(runner, InStream_Read_U8(reopened) == 'z', "Reopened stream starts at supplied offset"); TEST_TRUE(runner, InStream_Length(reopened) == 1, "Reopened stream uses supplied length"); TEST_TRUE(runner, InStream_Tell(reopened) == 1, "Tell() uses supplied offset for reopened stream"); InStream_Seek(reopened, 0); TEST_TRUE(runner, InStream_Read_U8(reopened) == 'z', "Seek() uses supplied offset for reopened stream"); DECREF(reopened); DECREF(clone); DECREF(instream); DECREF(outstream); DECREF(fh); DECREF(file); }
InStream* InStream_do_open(InStream *self, Obj *file) { InStreamIVARS *const ivars = InStream_IVARS(self); // Init. ivars->buf = NULL; ivars->limit = NULL; ivars->offset = 0; ivars->window = FileWindow_new(); // Obtain a FileHandle. if (Obj_Is_A(file, FILEHANDLE)) { ivars->file_handle = (FileHandle*)INCREF(file); } else if (Obj_Is_A(file, RAMFILE)) { ivars->file_handle = (FileHandle*)RAMFH_open(NULL, FH_READ_ONLY, (RAMFile*)file); } else if (Obj_Is_A(file, CHARBUF)) { ivars->file_handle = (FileHandle*)FSFH_open((CharBuf*)file, FH_READ_ONLY); } else { Err_set_error(Err_new(CB_newf("Invalid type for param 'file': '%o'", Obj_Get_Class_Name(file)))); DECREF(self); return NULL; } if (!ivars->file_handle) { ERR_ADD_FRAME(Err_get_error()); DECREF(self); return NULL; } // Get length and filename from the FileHandle. ivars->filename = CB_Clone(FH_Get_Path(ivars->file_handle)); ivars->len = FH_Length(ivars->file_handle); if (ivars->len == -1) { ERR_ADD_FRAME(Err_get_error()); DECREF(self); return NULL; } return self; }
FileHandle* RAMFolder_local_open_filehandle(RAMFolder *self, const CharBuf *name, uint32_t flags) { RAMFileHandle *fh; CharBuf *fullpath = S_fullpath(self, name); RAMFile *file = (RAMFile*)Hash_Fetch(self->entries, (Obj*)name); bool_t can_create = (flags & (FH_WRITE_ONLY | FH_CREATE)) == (FH_WRITE_ONLY | FH_CREATE) ? true : false; // Make sure the filepath isn't a directory, and that it either exists // or we have permission to create it. if (file) { if (!RAMFile_Is_A(file, RAMFILE)) { Err_set_error(Err_new(CB_newf("Not a file: '%o'", fullpath))); DECREF(fullpath); return NULL; } } else if (!can_create) { Err_set_error(Err_new(CB_newf("File not found: '%o'", fullpath))); DECREF(fullpath); return NULL; } // Open the file and store it if it was just created. fh = RAMFH_open(fullpath, flags, file); if (fh) { if (!file) { file = RAMFH_Get_File(fh); Hash_Store(self->entries, (Obj*)name, INCREF(file)); } } else { Err *error = Err_get_error(); ERR_ADD_FRAME(error); } DECREF(fullpath); return (FileHandle*)fh; }
OutStream* OutStream_do_open(OutStream *self, Obj *file) { OutStreamIVARS *const ivars = OutStream_IVARS(self); // Init. ivars->buf = (char*)MALLOCATE(IO_STREAM_BUF_SIZE); ivars->buf_start = 0; ivars->buf_pos = 0; // Obtain a FileHandle. if (Obj_is_a(file, FILEHANDLE)) { ivars->file_handle = (FileHandle*)INCREF(file); } else if (Obj_is_a(file, RAMFILE)) { ivars->file_handle = (FileHandle*)RAMFH_open(NULL, FH_WRITE_ONLY, (RAMFile*)file); } else if (Obj_is_a(file, STRING)) { ivars->file_handle = (FileHandle*)FSFH_open((String*)file, FH_WRITE_ONLY | FH_CREATE | FH_EXCLUSIVE); } else { Err_set_error(Err_new(Str_newf("Invalid type for param 'file': '%o'", Obj_get_class_name(file)))); DECREF(self); return NULL; } if (!ivars->file_handle) { ERR_ADD_FRAME(Err_get_error()); DECREF(self); return NULL; } // Derive filepath from FileHandle. ivars->path = Str_Clone(FH_Get_Path(ivars->file_handle)); return self; }