📄 fcb.cpp
字号:
#include"fcb.h"
#include<string.h>
#include<iostream.h>
ifcb::ifcb()
{
//初始化curfp,iadd[],fcbnum
curfp=NULL;
for(int i=0;i<fcbmax;i++)
{
fcbi[i]=NULL;
}
for(int k=0;k<256;k++)
{
iadd[k]=0;
}
fcbnum=0;
}
ifcb::~ifcb()
{
//存储iadd[]以及fcbi[]中的信息
if(curfp!=NULL)
putiadd(curfp);
for(int f=0;f<16;f++)
{
if(fcbi[f]!=NULL)
iput(fcbi[f]);
}
}
int ifcb::getiadd(fcb *fp)
{
//读出指定fcb的一级间接寻址的信息
if(fp==NULL)
return OK;
if(fp->f_add[8]==0)
{
for(int i=0;i<256;i++)
{
iadd[i]=0;
}
return OK;
}
else
{
char buf[bsize+1];
if(iblock.bread(fp->f_add[8],buf)==BLKREADERR)
{
cout<<"GET IADD ERROR\n";
return BLKREADERR;
}
for(int num=0;num<256;num++)
{
iadd[num]=int((unsigned char)buf[num*2])*256+int((unsigned char)buf[num*2+1]);
}
return OK;
}
}
int ifcb::putiadd(fcb *fp)
{
//存储iadd[]中的内容
if(fp==NULL)
return OK;
if(fp->f_add[8]==0)
return OK;
else
{
char buf[bsize+1];
for(int num=0;num<256;num++)
{
buf[num*2]=char(iadd[num]/256);
buf[num*2+1]=char(iadd[num]%256);
}
buf[512]='\0';
if(iblock.bwrite(fp->f_add[8],buf)==BLKWRITEERR)
{
cout<<"PUT IADD ERROR\n";
return BLKWRITEERR;
}
return OK;
}
}
int ifcb::addblock(fcb *fp,int pblock)
{
//增加空闲块到指定的FCB的空间里
int i=0;
for(;i<263;i++)
{
if(getblock(fp,i)==0)
break;
}
if(i>=263)
{
cout<<"ADD BLOCK ERROR\n";
return ERROR;
}
if(i<8)
{
fp->f_add[i]=pblock;
return OK;
}
else
{
if(i==8)
{
char buf[bsize+1];
for(int j=0;j<512;j++)
{
buf[j]=(char)0;
}
buf[512]='\0';
buf[0]=char(pblock/256);
buf[1]=char(pblock%256);
int blkno=iblock.balloc();
if(blkno==NOSPACE||blkno==BLOCKERR)
{
cout<<"ADD BLOCK ERROR\n";
return blkno;
}
if(iblock.bwrite(blkno,buf)==BLKWRITEERR)
{
cout<<"ADD BLOCK ERROR\n";
return BLKWRITEERR;
}
fp->f_add[8]=blkno;
iadd[0]=pblock;
for(int t=1;t<256;t++)
{
iadd[t]=0;
}
curfp=fp;
return OK;
}
else
{
if(i>8)
{
iadd[i-8]=pblock;
return OK;
}
}
}
}
int ifcb::getblock(fcb *fp,int lblock)
{
//得到指定FCB空间的指定逻辑块对应的物理块
if(lblock<8&&lblock>=0)
return fp->f_add[lblock];
else
{
if(lblock>=8)
{
if(fp->f_add[8]==0)
return 0;
else
{
if(fp!=curfp)
{
if(curfp!=NULL)
putiadd(curfp);
getiadd(fp);
curfp=fp;
}
return iadd[lblock-8];
}
}
}
}
int ifcb::readi(fcb *fp,int offset,int count,char*base)
{
//读指定文件的信息
if(offset/bsize<0||offset/bsize>=263||offset>fp->f_fsize-1)
{
cout<<"FCB READ ERROR\n";
return FCBREADERR;
}
int temp=0;
char buf[bsize+1];
int num;
if((fp->f_fsize-(offset+1)+1)>count)
num=count;
else
num=fp->f_fsize-(offset+1)+1;
for(int i=0;;i++)
{
if(iblock.bread(getblock(fp,(offset/bsize)+i),buf)==BLKREADERR)
{
cout<<"BLOCK READ ERROR\n";
return BLKREADERR;
}
if(i==0)
temp=0;
else
if(i==1)
temp=bsize-offset%bsize;
else
temp=bsize-offset%bsize+bsize*(i-1);
if(num-(bsize-offset%bsize)>=0&&i==0)
{
for(int k=0;k<(bsize-offset%bsize);k++)
base[k]=buf[offset%bsize+k];
base[bsize-offset%bsize]='\0';
}
else
{
if((num-(bsize-offset%bsize)-i*bsize)<0)
{
for(int j=temp;j<num;j++)
{
if(i==0)
base[j]=buf[j-temp+offset%bsize];
else
base[j]=buf[j-temp];
}
base[num]='\0';
fp->f_count++;
return num;
}
else
strcat(base,buf);
}
}
}
int ifcb::writei(fcb *fp,int offset,int count,char*base)
{
if(offset>fp->f_fsize||offset<0)
{
cout<<"FCB WRITE ERROR\n";
return FCBWRITEERR;
}
if((offset+count-1)/bsize>=263)
{
cout<<"NOT ENOUGH SPACE\n";
return NOSPACE;
}
//写信息入指定的文件
int temp=0;
char buf[bsize+1];
int ph=-1;
int blkno;
for(int i=0;;i++)
{
if(i==0)
temp=0;
else
if(i==1)
temp=bsize-offset%bsize;
else
temp=bsize-offset%bsize+bsize*(i-1);
if(ph==0)
{
blkno=iblock.balloc();
if(blkno==NOSPACE||blkno==BLOCKERR)
{
cout<<"FCB WRITE ERROR\n";
return blkno;
}
addblock(fp,blkno);
}
else
{
ph=getblock(fp,offset/bsize+i);
if(ph==0)
{
blkno=iblock.balloc();
if(blkno==NOSPACE||blkno==BLOCKERR)
{
cout<<"FCB WRITE ERROR\n";
return blkno;
}
addblock(fp,blkno);
}
else
{
blkno=ph;
if(i==0)
{
if(iblock.bread(blkno,buf)==BLKREADERR)
{
cout<<"FCB WRITE ERROR\n";
return BLKREADERR;
}
}
}
}
if(count-(bsize-offset%bsize)>0&&i==0)
{
for(int k=0;k<(bsize-offset%bsize);k++)
buf[offset%bsize+k]=base[k];
if(iblock.bwrite(blkno,buf)==BLKWRITEERR)
{
cout<<"FCB WRITE ERROR\n";
return BLKWRITEERR;
}
}
else
{
if((count-(bsize-offset%bsize)-i*bsize)<=0)
{
for(int j=temp;j<count;j++)
{
if(i==0)
buf[offset%bsize+j-temp]=base[j];
else
buf[j-temp]=base[j];
}
if(iblock.bwrite(blkno,buf)==BLKWRITEERR)
{
cout<<"FCB WRITE ERROR\n";
return BLKWRITEERR;
}
if((offset+count-1)/bsize<(fp->f_fsize-1)/bsize)
{
for(int tt=((offset+count-1)/bsize)+1;tt<=(fp->f_fsize-1)/bsize;tt++)
{
iblock.brelse(getblock(fp,tt));
}
}
fp->f_fsize=offset+count;
if(fp->f_flag<FCHG)
fp->f_flag=fp->f_flag|FCHG;
fp->f_count++;
return count;
}
else
{
for(int t=temp;t<temp+bsize;t++)
{
buf[t-temp]=base[t];
}
if(iblock.bwrite(blkno,buf)==BLKWRITEERR)
{
cout<<"FCB WRITE ERROR\n";
return BLKWRITEERR;
}
}
}
}
}
fcb *ifcb::iget(int blkno,int num)
{
//读出指定的文件目录结构的信息,并产生对应的FCB结构
int free=0;
for(;free<16;free++) //寻找FCB系统中空闲的位置
{
if(fcbi[free]==NULL)
break;
}
if(free>=16)
{
cout<<"FCB STRUCT IS FULL\n";
return NULL;
}
char buf[bsize+1];
if(iblock.bread(blkno,buf)==BLKREADERR)
{
cout<<"CREATE FCB ERROR\n";
return NULL;
}
fcbi[free]=new struct fcb;//产生fcb结构并初始化
fcbi[free]->f_mode=int((unsigned char)buf[num*dsize])*256+int((unsigned char)buf[num*dsize+1]);
fcbi[free]->f_uid=buf[num*dsize+2];
fcbi[free]->f_gid=buf[num*dsize+3];
fcbi[free]->f_fsize=int((unsigned char)buf[num*dsize+4])*16777216+int((unsigned char)buf[num*dsize+5])*65537+int((unsigned char)buf[num*dsize+6])*256+int((unsigned char)buf[num*dsize+7]);
for(int n=0;n<8;n++)
{
fcbi[free]->f_name[n]=buf[num*dsize+8+n];
}
for(int a=0;a<8;a++)
{
fcbi[free]->f_add[a]=int((unsigned char)buf[num*dsize+16+a*2])*256+int((unsigned char)buf[num*dsize+16+a*2+1]);
}
fcbi[free]->f_blkno=blkno;
fcbi[free]->f_number=num;
fcbi[free]->f_count=1;
fcbi[free]->f_flag=FLOCK;
fcbnum++;
return fcbi[free];
}
int ifcb::iput(fcb *fp)
{
if(fp->f_flag>=FCHG) //fcb结构信息有改变,则存储该fcb的信息到文件目录结构中
{
char buf[bsize+1];
if(iblock.bread(fp->f_blkno,buf)==BLKREADERR)
{
cout<<"SAVE FCB ERROR\n";
return BLKREADERR;
}
buf[fp->f_number*dsize]=char(fp->f_mode/256);
buf[fp->f_number*dsize+1]=char(fp->f_mode%256);
buf[fp->f_number*dsize+2]=fp->f_uid;
buf[fp->f_number*dsize+3]=fp->f_gid;
buf[fp->f_number*dsize+4]=char(fp->f_fsize/16777216);
buf[fp->f_number*dsize+5]=char((fp->f_fsize%16777216)/65536);
buf[fp->f_number*dsize+6]=char(((fp->f_fsize%16777216)%65536)/256);
buf[fp->f_number*dsize+7]=char(((fp->f_fsize%16777216)%65536)%256);
for(int n=0;n<8;n++)
{
buf[fp->f_number*dsize+8+n]=fp->f_name[n];
}
for(int a=0;a<8;a++)
{
buf[fp->f_number*dsize+16+a*2]=char(fp->f_add[a]/256);
buf[fp->f_number*dsize+16+a*2+1]=char(fp->f_add[a]%256);
}
if(iblock.bwrite(fp->f_blkno,buf)==BLKWRITEERR)
{
cout<<"SAVE FCB ERROR\n";
return BLKWRITEERR;
}
}
//删除FCB系统中对应的fcb
for(int w=0;w<16;w++)
{
if(fp==fcbi[w])
{
fcbi[w]=NULL;
delete fp;
break;
}
}
fcbnum--;
return OK;
}
fcb *ifcb::namei(fcb *fp,char*name,int f_mode)
{
//在FCB系统中查找,fp==NULL是查找根目录
for(int it=0;it<fcbmax;it++)
{
if(fcbi[it]!=NULL)
{
if(strcmp(fcbi[it]->f_name,name)==0)
{
if(fp==NULL&&fcbi[it]->f_blkno==0)
return fcbi[it];
int u;
for(int yy=0;yy<263;yy++)
{
u=getblock(fp,yy);
if(u==0)
break;
else
{
if(u==fcbi[it]->f_blkno)
{
if((fcbi[it]->f_mode==IFDIR&&f_mode==IFDIR)||(fcbi[it]->f_mode>=IFREG&&f_mode>=IFREG))
return fcbi[it];
}
}
}
}
}
}
//在指定的FCB对应的空间中查找
char buf[bsize+1];
char f_name[8];
int d_mode;
if(fp==NULL)
{
iblock.bread(0,buf);
for(int g=0;g<8;g++)
{
f_name[g]=buf[dsize*15+8+g];
}
d_mode=int((unsigned char)buf[dsize*15])*256+int((unsigned char)buf[dsize*15+1]);
if(strcmp(name,f_name)==0)
{
if((d_mode==IFDIR&&f_mode==IFDIR)||(d_mode>=IFREG&&f_mode>=IFREG))
return iget(0,15);
}
return NULL;
}
int blkno;
int blkend;
int dirend;
blkend=(fp->f_fsize-1)/bsize;
dirend=((fp->f_fsize-1)%bsize)/dsize;
for(int i=0;i<263;i++)
{
if(i==(blkend+1))
return NULL;
blkno=getblock(fp,i);
if(blkno==0)
return NULL;
if(iblock.bread(blkno,buf)==BLKREADERR)
return NULL;
for(int d=0;d<16;d++)
{
if(i==blkend&&d==(dirend+1))
return NULL;
for(int n=0;n<8;n++)
{
f_name[n]=buf[dsize*d+8+n];
}
d_mode=int((unsigned char)buf[dsize*d])*256+int((unsigned char)buf[dsize*d+1]);
if(strcmp(f_name,name)==0)
{
if((d_mode==IFDIR&&f_mode==IFDIR)||(d_mode>=IFREG&&f_mode>=IFREG))
return iget(blkno,d);
}
}
}
return NULL;
}
fcb *ifcb::icreate(fcb *fp,char*name)
{
//在指定的fcb下创建fcb,fp==NULL,是创建根目录
int i=0;
for(;i<fcbmax;i++)
{
if(fcbi[i]==NULL)
break;
}
if(i>=fcbmax)
return NULL;
fcb *ft=new struct fcb;
int blkno;
int num;
if(fp==NULL)
{
blkno=0;
num=15;
ft->f_uid='0';
ft->f_gid='0';
}
else
{
if(fp->f_fsize==0||(fp->f_fsize-1)%bsize==511)
{
blkno=iblock.balloc();
addblock(fp,blkno);
num=0;
}
else
{
blkno=getblock(fp,(fp->f_fsize-1)/bsize);
num=(((fp->f_fsize-1)%bsize)/dsize)+1;
}
fp->f_fsize=fp->f_fsize+32;
fp->f_flag=FUPD|FCHG;
}
ft->f_count=1;
ft->f_flag=FCHG;
ft->f_blkno=blkno;
ft->f_number=num;
ft->f_mode=IFMT;
ft->f_fsize=0;
strcpy(ft->f_name,name);
for(int a=0;a<8;a++)
{
ft->f_add[a]=0;
}
fcbi[i]=ft;
fcbnum++;
return ft;
}
int ifcb::idelete(fcb *pfp,fcb *fp)
{
//删除父目录中,该文件目录的信息
for(int yy=0;yy<263;yy++)
{
if(getblock(pfp,yy)==fp->f_blkno)
{
char*base;
if(yy*bsize+fp->f_number*dsize+32>pfp->f_fsize-1)
{
base=new char[pfp->f_fsize-32+1];
readi(pfp,0,pfp->f_fsize-32,base);
writei(pfp,0,pfp->f_fsize-32,base);
}
else
{
base=new char[pfp->f_fsize-1-(yy*bsize+fp->f_number*dsize+32)+1+1];
readi(pfp,yy*bsize+fp->f_number*dsize+32,pfp->f_fsize-1-(yy*bsize+fp->f_number*dsize+32)+1,base);
writei(pfp,yy*bsize+fp->f_number*dsize,pfp->f_fsize-1-(yy*bsize+fp->f_number*dsize+32)+1,base);
}
if(pfp->f_flag<FCHG)
pfp->f_flag=pfp->f_flag|FCHG;
delete[]base;
break;
}
}
//删除该FCB对应的文件,释放空间
int g;
for(int kk=0;kk<263;kk++)
{
g=getblock(fp,kk);
if(g==0)
break;
else
iblock.brelse(g);
}
if(curfp==fp)
curfp=NULL;
for(int ee=0;ee<fcbmax;ee++)
{
if(fcbi[ee]==fp)
{
fcbi[ee]=NULL;
fcbnum--;
delete fp;
}
}
return OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -