/* File Write function: * This writes 'count' number of 'value'(s) to the file indicated by index. * Writing should start from the point pointed by current position of the file. * Current position should be updated accordingly. * Parameter(s): * index: File index which indicates the file to be read. * value: a character to be written. * count: Number of repetition. * Return: * >0 for successful write * -1 value for error case "File hasn't been open" * -2 for error case "Maximum file size reached" (not implemented.) */ int FileSystem53::write(int index, char value, int count) { if ( index < 0 || index > MAX_FILE_NO+1 ) { cout << "[email protected](): Index out of boundary" << endl; return -1; } if ( oft[index][0] == 0 ) { cout << "[email protected](): File has not been opened" << endl; return -1; } // set the first block with the found index; int file_block_index = find_empty_block(); if ( file_block_index == -1 ) { cout << "[email protected](): no more empty block" << endl; return -1; } // update bytemap desc_table[0][file_block_index] = 1; int current_block = (count + oft[index][1]) / 64; oft[index][2+current_block] = file_block_index; // previous design int cursor = oft[index][OFT_CURRENT_POSITION_INDEX]; int length = oft[index][1]; if ( cursor > (length+6) || cursor < 6 || cursor > OFT_ENTRY_SIZE ) { cout << "[email protected](): Cursor out of boundary" << endl; return -2; } /////////////////////////////////////////// int write_count = 0; for (; write_count < count; write_count++) { if ( feof(index) ) { cout << "[email protected](): EOF of writing buffer" << endl; return -1; } int tmp = fputc((int)value, index); if ( tmp == -2 ) { cout << "[email protected](): error in writing buffer" << endl; return -1; } } char buffer[DESCR_SIZE]; for (int i = 0; i < DESCR_SIZE; ++i) { buffer[i] = oft[index][i+1]; } write_descriptor(oft[index][0], buffer); return write_count; }
/*! adds blocks of memory @param[in] ph - pointer to root phmem_root structure @param[in] addr - address of memory block to be added @patam[in] size - size of memory block in bytes @result function adds information about specified block into an internal list of free memory blocks. */ void free_pages(phmem ** ph, uint32_t addr, int32_t size) { // check if no blocks yet if((*ph)->root.next_mem == 0 ) { phmem * frame = find_empty_block(ph); frame->frame.addr = addr; frame->frame.size = size; frame->frame.next = 0; // no next frame yet // update root //ph->root.next_free = free - ph; (*ph)->root.next_mem = frame - (*ph); //add_first_block(ph, addr, size); return; } else { // find block where new block to be inserted phmem * frame = (*ph) + (*ph)->root.next_mem; phmem * prev_frame = frame; while(frame->frame.addr < addr) { prev_frame = frame; if (frame->frame.next == 0) { break; } frame = (*ph) + frame->frame.next; } // we have found frame with frame.addr > addr // or frame is only frame so prev = frame... if(prev_frame->frame.addr < addr) { if (frame->frame.addr < addr) { // prev < addr && frame < addr if(prev_frame->frame.addr + prev_frame->frame.size == addr) { // update prev_frame prev_frame->frame.size += size; return; } else { // add frame after prev phmem * update = find_empty_block(ph); update->frame.addr = addr; update->frame.size = size; update->frame.next = prev_frame->frame.next; prev_frame->frame.next = update - (*ph); return; } } else { // frame->frame.addr > addr // block between prev_frame and frame if(prev_frame->frame.addr + prev_frame->frame.size == addr) { // update size of prev frame prev_frame->frame.size += size; if (prev_frame->frame.addr + prev_frame->frame.size == frame->frame.addr) { // link prev frame and frame prev_frame->frame.size += frame->frame.size; prev_frame->frame.next = frame->frame.next; // place frame element in a list of free elements frame->free.next_free = (*ph)->root.next_free; (*ph)->root.next_free = frame - (*ph); frame->free.count = 1; } return; } else { // insert frame between prev and frame phmem * update = find_empty_block(ph); update->frame.addr = addr; update->frame.size = size; update->frame.next = frame - (*ph); prev_frame->frame.next = update - (*ph); return; } } } else { // prev_frame->frame.addr > addr if(prev_frame->frame.addr == addr + size) { // increment size of the prev_frame // update start address of prev frame // update prev_frame prev_frame->frame.addr = addr; prev_frame->frame.size += size; return; } else { // insert before 1st block // update root record phmem * update = find_empty_block(ph); update->frame.addr = addr; update->frame.size = size; update->frame.next = prev_frame - (*ph); (*ph)->root.next_mem = update - (*ph); return; } } } }
/* File creation function: * 1. creates empty file with file size zero. * 2. makes/allocates descriptor. * 3. updates directory file. * Parameter(s): * symbolic_file_name: The name of file to create. * Return: * Return 0 for successful creation. * Return -1 for error (no space in disk) * Return -2 for error (for duplication) */ int FileSystem53::create(string symbolic_file_name) { int desc_index = find_empty_descriptor(); if ( desc_index == -1 ) { //cout << "[email protected](): no empty descriptors left" << endl; return -1; } if ( search_dir(0, symbolic_file_name) != -1 ) { //cout << "[email protected](): filename exists" << endl; return -2; } // clean up the exist descriptior in desc_table for (int i = 0; i < 4; i++) { desc_table[desc_index][i] = 0; } // if directory file uses 3 blocked and no more space for the filename // return -1 int filename_length = symbolic_file_name.size(); if ( oft[0][1] + filename_length > 192 || filename_length > 10 ) { //cout << "[email protected](): filename oversize" << endl; return -1; } // get new empty block for directory to store the content if needed.. int dir_block_index = find_empty_block(); if ( dir_block_index == -1 ) { //cout << "[email protected](): no more empty block" << endl; return -1; } // update bytemap desc_table[0][dir_block_index] = 1; // set the first block with the found index; int current_block = (filename_length + oft[0][1]) / 64; oft[0][2+current_block] = dir_block_index; // write filename to directory file in oft // handling multiply filenames // create new file name entry int start_pos = 0; int filename_buffer_length = 2+filename_length; char filename_buffer[filename_buffer_length]; filename_buffer[0] = desc_index; filename_buffer[1] = filename_length; for (int i = 0; i < filename_length; i++) { filename_buffer[i+2] = symbolic_file_name[i]; } // find empty space in directory file to write the entry for (int i = OFT_CURRENT_POSITION_INDEX; i < OFT_ENTRY_SIZE; i++) { while ( oft[0][i] == 0 && start_pos < filename_buffer_length ) { oft[0][i] = filename_buffer[start_pos]; i++; start_pos++; } } //oft[0][OFT_CURRENT_POSITION_INDEX] = start_pos; // update descriptor in oft oft[0][1] += filename_length+2; // write descriptior to desc_table char desc_buffer[DESCR_SIZE]; for (int i = 0; i < DESCR_SIZE; i++) { desc_buffer[i] = oft[0][i+1]; } write_descriptor(1, desc_buffer); return 0; }