/* move the cursor of offset positions. */ void seek_ifile(file_desc_t *fd, int offset) { unsigned int old_pos = fd->fds_pos; unsigned int fbloc, vbloc; /* update the position */ fd->fds_pos += offset; /* does the seek imply a jump in another bloc? */ if (bloc_of_pos(fd->fds_pos) != bloc_of_pos(old_pos)) { /* flush */ flush_ifile(fd); /* the bloc index of the new buffer */ fbloc = bloc_of_pos(fd->fds_pos); vbloc = vbloc_of_fbloc(fd->fds_inumber, fbloc, FALSE); if (! vbloc) /* the bloc #0 is full of zeros */ memset(fd->fds_buf, 0, BLOC_SIZE); else /* load the bloc */ read_bloc(current_volume, vbloc, fd->fds_buf); } }
/* return the pos in the file ; RETURN_FAILURE in case of error */ int writec_ifile(file_desc_t *fd, char c) { unsigned int ibloc; /* write the char in the buffer */ fd->fds_buf[ibloc_of_pos(fd->fds_pos)] = c; /* first write in the bloc ? ensure the data bloc allocation */ if (! fd->fds_dirty) { ibloc = vbloc_of_fbloc(fd->fds_inumber, bloc_of_pos(fd->fds_pos), TRUE); if (! ibloc) { return RETURN_FAILURE; } fd->fds_dirty = TRUE; } /* is the buffer full? */ if (ibloc_of_pos(fd->fds_pos) == BLOC_SIZE-1) { /* write the buffer */ ibloc = vbloc_of_fbloc(fd->fds_inumber, bloc_of_pos(fd->fds_pos), FALSE); write_bloc(current_vol, ibloc, fd->fds_buf); /* read the new buffer */ ibloc = vbloc_of_fbloc(fd->fds_inumber, bloc_of_pos(fd->fds_pos+1), FALSE); if (! ibloc) memset(fd->fds_buf, 0, BLOC_SIZE); else read_bloc(current_vol, ibloc, fd->fds_buf); fd->fds_dirty = FALSE; } /* update the file cursor and size */ if (fd->fds_size < fd->fds_pos) fd->fds_size = fd->fds_pos; fd->fds_pos++; /* the position of the written char */ return fd->fds_pos - 1; }
/* note that flush don't need to worry about the bloc allocation; a previous write operation has already done it. */ void flush_ifile(file_desc_t *fd) { unsigned int fbloc; /* bloc index in the file */ unsigned int vbloc; /* bloc index in the volume */ if (fd-> fds_dirty) { /* compute the number of the bloc on the volume associated to the buffer */ fbloc = bloc_of_pos(fd->fds_pos); vbloc = vbloc_of_fbloc(fd-> fds_inumber, fbloc, TRUE); /* write back the buffer */ write_bloc(current_volume, vbloc, fd->fds_buf); /* done */ fd-> fds_dirty = FALSE ; } }