//CSU 480 File System Project
//2/17/06
//Ken Eimer, Brandon Schory, Brian Tobia
//disk.cc

#include "disk.h"

Disk::Disk( FILE* _disk, int _blocksize, int _numblocks ) {
  disk = _disk;
  blocksize = _blocksize;
  numblocks = _numblocks;
  offset = sizeof(int)*2 + numblocks;
  used = new bool[numblocks];
  for ( int i=0; i<numblocks; i++ ) used[i] = false;
}

Disk::Disk( FILE* _disk ) {
  disk = _disk;
  int twoints[2];
  fread( (char*)twoints, sizeof(int), 2, disk );
  blocksize = twoints[0];
  numblocks = twoints[1];
  char* buffer = new char[numblocks];
  fread( buffer, numblocks, 1, disk );
  used = new bool[numblocks];
  for ( int i=0; i<numblocks; i++ ) used[i] = (buffer[i]==(char)1);
  delete buffer;
  offset = sizeof(int)*2+numblocks;
}
  
Disk::~Disk() {
  fseek( disk, 0, SEEK_SET );
  fwrite( (char*)&blocksize, sizeof(int), 1, disk );
  fwrite( (char*)&numblocks, sizeof(int), 1, disk );
  char* buffer = new char[numblocks];
  for ( int i=0; i<numblocks; i++ ) {
    if ( used[i] ) buffer[i] = (char)1;
    else buffer[i] = (char)0;
  }
  fwrite( buffer, numblocks, 1, disk );
  delete buffer;
  fclose( disk );
  delete used;
}

bool Disk::ReadBlock( int blocknumber, char* buffer ) {
  if ( blocknumber < 0 || blocknumber > numblocks ) return false;
  fseek( disk, offset + blocknumber * blocksize, SEEK_SET );
  fread( buffer, blocksize, 1, disk );
  return true;
}

bool Disk::WriteBlock( int blocknumber, char* buffer ) {
  if ( blocknumber < 0 || blocknumber > numblocks ) return false;
  fseek( disk, offset + blocknumber * blocksize, SEEK_SET );
  fwrite( buffer, blocksize, 1, disk );
  return true;
}
   
int Disk::AllocateBlock() {
  int i = 0;
  while ( i<numblocks && used[i] ) i++;
  if ( i == numblocks ) return -1;
  used[i] = true;
  return i;
}

void Disk::FreeBlock( int i ) {
  used[i] = false;
}

