InStream* InStream_Reopen_IMP(InStream *self, String *filename, int64_t offset, int64_t len) { InStreamIVARS *const ivars = InStream_IVARS(self); if (!ivars->file_handle) { THROW(ERR, "Can't Reopen() closed InStream %o", ivars->filename); } if (offset + len > FH_Length(ivars->file_handle)) { THROW(ERR, "Offset + length too large (%i64 + %i64 > %i64)", offset, len, FH_Length(ivars->file_handle)); } Class *klass = InStream_get_class(self); InStream *other = (InStream*)Class_Make_Obj(klass); InStreamIVARS *const ovars = InStream_IVARS(other); InStream_do_open(other, (Obj*)ivars->file_handle); if (filename != NULL) { String *temp = ovars->filename; ovars->filename = Str_Clone(filename); DECREF(temp); } ovars->offset = offset; ovars->len = len; InStream_Seek(other, 0); return other; }
InStream* InStream_reopen(InStream *self, const CharBuf *filename, int64_t offset, int64_t len) { if (!self->file_handle) { THROW(ERR, "Can't Reopen() closed InStream %o", self->filename); } if (offset + len > FH_Length(self->file_handle)) { THROW(ERR, "Offset + length too large (%i64 + %i64 > %i64)", offset, len, FH_Length(self->file_handle)); } InStream *twin = (InStream*)VTable_Make_Obj(self->vtable); InStream_do_open(twin, (Obj*)self->file_handle); if (filename != NULL) { CB_Mimic(twin->filename, (Obj*)filename); } twin->offset = offset; twin->len = len; InStream_Seek(twin, 0); return twin; }
InStream* InStream_reopen(InStream *self, const CharBuf *filename, int64_t offset, int64_t len) { InStreamIVARS *const ivars = InStream_IVARS(self); if (!ivars->file_handle) { THROW(ERR, "Can't Reopen() closed InStream %o", ivars->filename); } if (offset + len > FH_Length(ivars->file_handle)) { THROW(ERR, "Offset + length too large (%i64 + %i64 > %i64)", offset, len, FH_Length(ivars->file_handle)); } VTable *vtable = InStream_Get_VTable(self); InStream *other = (InStream*)VTable_Make_Obj(vtable); InStreamIVARS *const ovars = InStream_IVARS(other); InStream_do_open(other, (Obj*)ivars->file_handle); if (filename != NULL) { CB_Mimic(ovars->filename, (Obj*)filename); } ovars->offset = offset; ovars->len = len; InStream_Seek(other, 0); return other; }
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; }