/* error code*/ int FMM_HEAD_GetFirstEmpty(int fileDesc) { int i=0; int tempBitfield; /* We don't want to destroy the information in here, so make a copy */ int bitNumber = 0; /* The position of the first bit that is 1 */ int check=128; /* binary value: 10000000 */ if ( FMM_IsValid(fileDesc) == FALSE ){ /* check if fileDesc is valid */ BF_Errno=BFE_FD; return BFE_FD; } while ( file_headers[file_openings[fileDesc].header].header[i] == 255 /* pass by bytes reffered to blocks in use. */ && i < BF_BLOCK_SIZE ) i++; if ( i == BF_BLOCK_SIZE ){ /* all blocks VALID */ BF_Errno=BFE_EOF; return BFE_EOF; } tempBitfield=file_headers[file_openings[fileDesc].header].header[i]; /* first byte cointaining bit indicating invalid block */ while ((~tempBitfield & check) == 0 && bitNumber < 8 ){ /* find bit possition */ check>>=1; bitNumber++; } return ( 8*i + bitNumber ); /* return block number */ }
/* error code, else return BFE_OK. */ int FMM_GetFileInfoByFD(fileInfo_t* finfo) { if ( FMM_IsValid(finfo->fd) == FALSE ){ /* check validy of fd */ BF_Errno= BFE_FD; return BFE_FD ; } finfo->fp=file_openings[finfo->fd].fp; bzero(finfo->filename,MAX_FILE_NAME ); strcpy(finfo->filename,file_headers[file_openings[finfo->fd].header].name); return BFE_OK; }
/* returning true or false. */ BOOLEAN FMM_HEAD_IsValid(int fileDesc, int blockNum) { int tempBitfield; /* We don't want to destroy the information, make a copy */ if ( FMM_IsValid(fileDesc) == FALSE ){ BF_Errno=BFE_FD; return BFE_FD; } tempBitfield=file_headers[file_openings[fileDesc].header].header[blockNum/8]; /* appropriate byte, reffered to blockNum */ tempBitfield = tempBitfield>>(7-blockNum%8); /* bitwise operation */ if ( (tempBitfield & 1 ) == 1 ) return TRUE; else return FALSE; }
/* Otherwise setting errno and returning error code. */ int FMM_HEAD_Set(int fileDesc, int blockNum, BOOLEAN value) { if ( FMM_IsValid(fileDesc) == FALSE ){ /* check validy of fileDesc */ BF_Errno=BFE_FD; return BFE_FD; } else if ( blockNum >= MAX_BLOCKS){ /* check validy of blockNum */ BF_Errno=BFE_INVALIDBLOCK; return BFE_INVALIDBLOCK ; } if ( value == TRUE ) /* set appropriate bit TRUE (1) */ file_headers[file_openings[fileDesc].header].header[blockNum/8] |=1<<(7-blockNum%8); /* blockNums are 0,1,2,...,7 */ else if ( value == FALSE ) /* set appropriate bit FALSE (0) */ file_headers[file_openings[fileDesc].header].header[blockNum/8] &=~(1<<(7-blockNum%8)); /* blockNums are 0,1,2,...,7 */ file_headers[file_openings[fileDesc].header].dirty=1; return BFE_OK; }
/* returning error code. */ int FMM_HEAD_GetNextBlock(int fileDesc, int prev) { int i; int tempBitfield; /* We don't want to destroy the information in here, so make a copy */ int bitNumber; /* The position of the first bit that is 1 */ int check=128; /* binary value: 10000000 */ if ( FMM_IsValid(fileDesc) == FALSE ){ /* check if fileDesc is valid */ BF_Errno=BFE_FD; return BFE_FD; } if ( prev == MAX_BLOCKS-1){ /* check validy of previous blockNum */ BF_Errno=BFE_HEADOVERFLOW; return BFE_HEADOVERFLOW; } i=(prev+1)/8; /* find byte reffering to block after prev */ tempBitfield=file_headers[file_openings[fileDesc].header].header[i]; check>>=(prev+1)%8; bitNumber=(prev+1)%8; while ( bitNumber < 8 ){ if ( (tempBitfield & check) != 0 ) return ( 8*i + bitNumber ); check>>=1; bitNumber++; } i++; bitNumber=0; check=128; while ( file_headers[file_openings[fileDesc].header].header[i] == 0 /* pass by bytes reffered to blocks NOT in use. */ && i < MAX_BLOCKS ) i++; if ( prev == MAX_BLOCKS-1){ /* all blocks INVALID */ BF_Errno=BFE_HEADOVERFLOW; return BFE_HEADOVERFLOW; } tempBitfield=file_headers[file_openings[fileDesc].header].header[i]; while ( bitNumber < 8 ){ if ( (tempBitfield & check) != 0 ) return ( 8*i + bitNumber ); check>>=1; bitNumber++; } return ( 8*i + bitNumber ); }
/* error code, else return BFE_OK. */ int FMM_Close(int fileDesc) { int RetVal; if ( FMM_IsValid(fileDesc) == FALSE ){ /* check validy of fileDesc */ BF_Errno=BFE_FD; return BFE_FD; } file_headers[file_openings[fileDesc].header].openings--; /* decrease counter of file openings reffering to current header */ if ( file_headers[file_openings[fileDesc].header].openings == 0 /* if no file opening reffers to current header and header has */ && file_headers[file_openings[fileDesc].header].dirty == 1 ) /* been changed, write it back to file. */ if ( (RetVal=HDF_WriteBlock(0, file_headers[file_openings[fileDesc].header].header, file_openings[fileDesc].fp)) != BFE_OK ) return RetVal; file_openings[fileDesc].empty=1; /* set current position as empty */ if ( (RetVal=HDF_CloseFile(file_openings[fileDesc].fp)) != BFE_OK ) /* closing, using file pointer */ return RetVal; return BFE_OK; }
int main(void) { int rvalue; FILE *fp; char *buffer; int fd; fileInfo_t finfo; char athlete[ATHLETE_SIZE]; int offset; int blockNumInFile1; int blockNumInHeader1; int blockNumInFile2; int blockNumInHeader2; int firstValid; int secondValid; // ---------------------- HDF epipedo ---------------------- // Elegxos an yparxei to fileName printf("\nChecking if file %s exists...\n\n", fileName); if (HDF_ExistsFile(fileName) == TRUE) { printf("Checkpoint 1:\n"); printf("HDF_ExistsFile returned TRUE!\n\n"); } // Dimiourgia tou arxeiou fileName printf("Creating file %s...\n\n", fileName); if ( (rvalue=HDF_CreateFile(fileName)) != BFE_OK) { printf("Checkpoint 2:\n"); printf("HDF_CreateFile() returned %d!\n\n", rvalue); } // Anoigma tou arxeiou fileName printf("Opening file %s...\n\n", fileName); if ((rvalue = HDF_OpenFile(fileName,&fp)) != BFE_OK) { printf("Checkpoint 3:\n"); printf("HDF_OpenFile() returned %d, should have returned 0!\n\n",rvalue); } // Dimiourgia epikefalidas tou arxeiou sti mnimi buffer = malloc(sizeof(char) * BF_BLOCK_SIZE); memset(buffer, 0, BF_BLOCK_SIZE); // Antigrafi epikefalidas sto block 0 tou arxeiou printf("Writing file header to disk...\n\n"); if ((rvalue = HDF_WriteBlock(0, buffer, fp)) != BFE_OK) { printf("Checkpoint 4:"); printf("HDF_WriteBlock() returned %d!\n\n",rvalue); } // Kleisimo tou arxeiou fileName printf("Closing file %s\n\n", fileName); if ((rvalue = HDF_CloseFile(fp)) != BFE_OK) { printf("Checkpoint 5:\n"); printf("HDF_CloseFile() returned %d!\n\n", rvalue); } // ---------------------- FMM epipedo ---------------------- FMM_Init(); // Anoigma tou arxeiou printf("Opening file %s...\n\n", fileName); if ((fd = FMM_Open(fileName)) < 0) { printf("Checkpoint 6:\n"); printf("FMM_Open() returned %d!\n\n", fd); } // Elegxos an i thesi fd tou pinaka anoixtwn arxeiwn einai pleon egkyri kataxwrisi arxeiou printf("Checking for validity of position %d of open files array...\n\n", fd); if (FMM_IsValid(fd) != TRUE) { printf("Checkpoint 7:\n"); printf("FMM_IsValid() returned FALSE!\n\n"); } // Anaktisi pliroforias gia to arxeio me vasi to onoma strcpy(finfo.filename, fileName); printf("Retrieving file information by name...\n\n"); if ((rvalue = FMM_GetFileInfoByName(&finfo)) != BFE_OK) { printf("Checkpoint 8:\n"); printf("FMM_GetFileInfoByName() returned %d!\n\n", rvalue); } printFileInfo(&finfo); // Anaktisi pliroforias gia to arxeio me vasi to fd finfo.fd = fd; printf("Retrieving file information by file descriptor...\n\n"); if ((rvalue = FMM_GetFileInfoByFD(&finfo)) != BFE_OK) { printf("Checkpoint 9:\n"); printf("FMM_GetFileInfoByFD() returned %d!\n\n", rvalue); } printFileInfo(&finfo); // Dimiourgia enos neou block sti mnimi memset(buffer, 0, BF_BLOCK_SIZE); offset = 0; strcpy(athlete, "Periklis Iakovakis"); memcpy(buffer + offset, athlete, ATHLETE_SIZE); offset += ATHLETE_SIZE; strcpy(athlete, "Pyrros Dimas"); memcpy(buffer + offset, athlete, ATHLETE_SIZE); offset += ATHLETE_SIZE; strcpy(athlete, "Helena Isinbayeva"); memcpy(buffer + offset, athlete, ATHLETE_SIZE); offset += ATHLETE_SIZE; strcpy(athlete, "Blanka Vlasic"); memcpy(buffer + offset, athlete, ATHLETE_SIZE); // Grapsimo aytou tou block sto arxeio sti thesi blockNumInFile fp = finfo.fp; blockNumInFile1 = 5; printf("Writing block to disk...\n\n"); if ((rvalue = HDF_WriteBlock(blockNumInFile1, buffer, fp)) != BFE_OK) { printf("Checkpoint 10:"); printf("HDF_WriteBlock() returned %d!\n\n",rvalue); } // Enimerwsi tis epikefalidas tou arxeiou oti to block ayto einai pleon egkyro blockNumInHeader1 = blockNumInFile1 - 1; // PROSOXH SE AYTO!!! printf("Updating header...\n\n"); if ((rvalue = FMM_HEAD_Set(fd, blockNumInHeader1, TRUE)) != BFE_OK) { printf("Checkpoint 11:"); printf("FMM_HEAD_Set() returned %d!\n\n",rvalue); } // Elegxos an enimerwthike i epikefalida printf("Checking header...\n\n"); if (FMM_HEAD_IsValid(fd, blockNumInHeader1) == FALSE) { printf("Checkpoint 12:"); printf("FMM_HEAD_isValid() returned %d!\n\n",rvalue); } // Anaktisi tou prwtou egkyrou block tou arxeiou printf("Retrieving first valid block...\n\n"); if ((firstValid = FMM_HEAD_GetFirstBlock(fd)) == BFE_EOF) { printf("Checkpoint 13:"); printf("FMM_HEAD_GetFirstBlock returned %d!\n\n",rvalue); } printf("firstValid = %d, it should be equal to %d\n\n", firstValid, blockNumInHeader1); // Dimiourgia enos 2ou neou block sti mnimi memset(buffer, 0, BF_BLOCK_SIZE); offset = 0; strcpy(athlete, "Vasilis Spanoulis"); memcpy(buffer + offset, athlete, ATHLETE_SIZE); offset += ATHLETE_SIZE; strcpy(athlete, "Sofoklis Sxortsianitis"); memcpy(buffer + offset, athlete, ATHLETE_SIZE); // Grapsimo aytou tou block sto arxeio sti thesi blockNumInFile blockNumInFile2 = 3; printf("Writing block to disk...\n\n"); if ((rvalue = HDF_WriteBlock(blockNumInFile2, buffer, fp)) != BFE_OK) { printf("Checkpoint 14:"); printf("HDF_WriteBlock() returned %d!\n\n",rvalue); } // Enimerwsi tis epikefalidas tou arxeiou oti to block ayto einai pleon egkyro blockNumInHeader2 = blockNumInFile2 - 1; // PROSOXH SE AYTO!!! printf("Updating header...\n\n"); if ((rvalue = FMM_HEAD_Set(fd, blockNumInHeader2, TRUE)) != BFE_OK) { printf("Checkpoint 15:"); printf("FMM_HEAD_Set() returned %d!\n\n",rvalue); } // Anaktisi tou prwtou egkyrou block tou arxeiou printf("Retrieving first valid block...\n\n"); if ((firstValid = FMM_HEAD_GetFirstBlock(fd)) == BFE_EOF) { printf("Checkpoint 16:"); printf("FMM_HEAD_GetFirstBlock returned %d!\n\n",rvalue); } printf("firstValid = %d, it should be equal to %d\n\n", firstValid, blockNumInHeader2); // Anaktisi tou prwtou egkyrou block tou arxeiou meta apo to firstValid printf("Retrieving first valid block after block %d...\n\n", firstValid); if ((secondValid = FMM_HEAD_GetNextBlock(fd, firstValid)) == BFE_EOF) { printf("Checkpoint 17:"); printf("FMM_HEAD_GetFirstBlock returned %d!\n\n",rvalue); } printf("secondValid = %d, it should be equal to %d\n\n", secondValid, blockNumInHeader1); // Kleisimo arxeiou printf("Closing file %s...\n\n", fileName); if ((rvalue = FMM_Close(fd)) != BFE_OK) { printf("Checkpoint 19:\n"); printf("FMM_Close() returned %d!\n\n", rvalue); } free(buffer); return 0; }