#include "tape.h" #include "common.h" #include <stdlib.h> #include <memory.h> #include <string.h> tape_t* tape_open(const char* filename, const char* mode) { file_t *file = file_open(filename, mode); printfv(VERBOSITY_VERBOSE, "Opening file %s in mode %s.\n", filename, mode); if (!file) { fprintf(stderr, "Cannot open %s in %s mode.", filename, mode); return NULL; } tape_t* tape = malloc(sizeof(tape_t)); fseek(file->file, 0, SEEK_END); tape->file = file; tape->end = ftell(file->file); return tape; } void tape_close(tape_t* tape) { file_close(tape->file); } void* tape_read(tape_t* tape, offset_t offset, void* record, size_t size) { char buffer[PAGE_SIZE]; page_t page = offset / PAGE_SIZE; offset = offset % PAGE_SIZE; offset_t written = 0; file_read(tape->file, page, buffer, PAGE_SIZE); while (size > PAGE_SIZE - offset) { memcpy(record + written, buffer + offset, PAGE_SIZE - offset); size -= PAGE_SIZE - offset; written += PAGE_SIZE - offset; page++; offset = 0; file_read(tape->file, page, buffer, PAGE_SIZE); } memcpy(record + written, buffer + offset, size); return record; } offset_t tape_write(tape_t* tape, offset_t location, void* record, size_t size) { char buffer[PAGE_SIZE]; page_t page = location / PAGE_SIZE; offset_t offset = location % PAGE_SIZE; offset_t written = 0; size_t original = file_read(tape->file, page, buffer, PAGE_SIZE); while (size > PAGE_SIZE - offset) { memcpy(buffer + offset, record + written, PAGE_SIZE - offset); size -= PAGE_SIZE - offset; written += PAGE_SIZE - offset; file_write(tape->file, page, buffer, PAGE_SIZE); page++; offset = 0; file_read(tape->file, page, buffer, PAGE_SIZE); } memcpy(buffer + offset, record + written, size); file_write(tape->file, page, buffer, offset + size > original ? offset + size : original); written += size; if (location + written > tape->end) { tape->end = location + written; } return location; } offset_t tape_append(tape_t* tape, void* record, size_t size) { return tape_write(tape, tape->end, record, size); }