⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filesystem.c

📁 支持nvram盘
💻 C
📖 第 1 页 / 共 3 页
字号:
			header.seq = last_sequence + 1;
			header.ver = 0;
			header.fs_version = FS_VERSION;
			header.flag = FS_USED;
			header.file = f->name;	
			new_block = fs_block_new(&header, buf, write_size);
			//update table
			fs_blocklist_get(block, &link);
			link.next_block = new_block;
			fs_blocklist_set(block, &link);
			link.name = f->name;
			link.used = 1;
			link.next_block = -1;
			fs_blocklist_set(new_block, &link);
			fs_blocks_used++;
			if(f->name < 128 || f->name > 143)
				fs_nonpriv_blocks_used++;		

		}
		else
		{
			//add to existing block
			if(len > (int)FS_BLOCK_SIZE - header.last_byte)
			{
				write_size = (int)FS_BLOCK_SIZE - header.last_byte;
			}	
			else
			{
				write_size = len;
			}
			new_block = fs_block_append(block, buf, write_size); 					
			if(f->current_block == block)
			{
				f->current_block = new_block;
			}
			if(previous_block == -1)
			{
				f->first_block = new_block;
				fs_filelist_set(f->name, new_block);
			}
			else
			{
				//update next pointer for previous block
				fs_blocklist_get(previous_block, &link);
				link.next_block = new_block;
				fs_blocklist_set(previous_block, &link);
			}
			//unset old block in table
			link.used = 0;
			link.next_block = -1;
			fs_blocklist_set(block, &link);
			//update new block in table 
			link.name = f->name;
			link.used = 1;
			link.next_block = -1;
			fs_blocklist_set(new_block, &link);
		}
		len -= write_size;
		buf += write_size;
		written += write_size;
	}	//end of while(len)
	return written;
}			

/*** BeginHeader fshift */
int fshift(File *f, int count, char *buf);
/*** EndHeader */

/* START FUNCTION DESCRIPTION ********************************************
fshift                         <filesystem.lib>

SYNTAX: int fshift(File *f, int count, char *buffer)

KEYWORDS:      file system

DESCRIPTION:   removes 'count' number of bytes from the beginning of a file.
					These bytes will be copied into the buffer if it is not null

PARAMETER1:    file pointer
PARAMETER2:    number of bytes to shift out
PARAMETER3:    buffer to store shifted bytes. If this is NULL, it will not
					be used.

RETURN VALUE:  number of bytes shifted out
               0 - error

SEE ALSO:

END DESCRIPTION **********************************************************/
		
nodebug int fshift(File *f, int count, char *buf)
{
	auto int shifted, shift_size, block, new_block;
	auto FSHeader header;
	auto FSBlockLink link;
	
	shifted = 0;
	while(count > 0)
	{
		block = fs_filelist_get(f->name);
		if(block < 0)
			return 0; //no starting block listed
		fs_get_header(block, &header);
		if(count >= header.last_byte - header.first_byte)
		{
			//shift out all of the block
			shift_size = header.last_byte - header.first_byte;
			if(buf)
			{
				fs_block_read(block, header.first_byte, buf, shift_size);
				buf += shift_size;
			}
			fs_blocklist_get(block, &link);
			new_block = link.next_block;
			if(new_block == FS_NOBLOCK)
			{
				count = 0; //stop shifting, file is empty
				header.first_byte = header.last_byte;
				header.crc = 0;
				header.ver++;
				new_block = fs_block_update(block, &header);
				fs_blocklist_set(new_block, &link);
			}
			else
			{
				fs_get_header(new_block, &header);
				f->num_blocks--;
				f->first_sequence = header.seq;
				fs_erase_block(block, 0);
				fs_blocks_used--;
				if(f->name < 128 || f->name > 143)
					fs_nonpriv_blocks_used--;
			}		
			if(f->current_block == block)
			{
				f->current_block = new_block;
				f->current_offset = header.first_byte;
			}
		}
		else
		{
			//just shift out some of the block
			shift_size = count;
			if(buf)
			{
				fs_block_read(block, header.first_byte, buf, shift_size);
			}
			header.first_byte += shift_size;
			header.crc = fs_checksum_far(block, header.first_byte,
										header.last_byte - header.first_byte, 0, 0);
			header.ver++;
			fs_blocklist_get(block, &link);
			new_block = fs_block_update(block, &header);
			fs_blocklist_set(new_block, &link);
			if(f->current_block = block)
			{
				f->current_block = new_block;
				if(header.first_byte > f->current_offset)
					f->current_offset = header.first_byte;
			} 
		}
				 		 			
		link.next_block = -1;
		link.used = 0;
		link.name = 0;
		fs_blocklist_set(block, &link);
		fs_filelist_set(f->name, new_block);
		f->first_block = new_block;	
		f->position -= shift_size;
		if(f->position < 0)
			f->position == 0;
		count -= shift_size;
		shifted += shift_size;
	}
	return shifted;
}

/*** BeginHeader fread */
int fread(File *f, char *buf, int len);
/*** EndHeader */

/* START FUNCTION DESCRIPTION ********************************************
fread                          <filesystem.lib>

SYNTAX: int fread(File *f, char *buf, int len)

KEYWORDS:      file system

DESCRIPTION:   read len bytes from the file starting at the current
               offset in the file into buf.

PARAMETER1:    file pointer
PARAMETER2:    destination buffer
PARAMETER3:    number of bytes to copy

RETURN VALUE:  number of bytes read
               0 - error

SEE ALSO:

END DESCRIPTION **********************************************************/
			
nodebug int fread(File *f, char *buf, int len)
{
	auto int remaining, read_len, bytes_read;
	auto int block;
	auto FSHeader header;
			
	if(f->mode!=FS_WRITE && f->mode!=FS_READ) return 0;

	bytes_read = 0;
	while(len) {
		/* loop through blocks until we read all they requested */

		fs_get_header(f->current_block, &header);
				
		if(len > header.last_byte - f->current_offset) {
			read_len = header.last_byte - f->current_offset;
		} else {
			read_len = len;
		}

#ifdef FS_CHECKSUM_READS
		/* verify the checksum */
		if(header.crc != fs_checksum_far(f->current_block, header.first_byte,
								  			header.last_byte - header.first_byte, 0, 0)) {
			/* ERROR IN CHECKSUM! */
#ifdef FS_DEBUG
			printf("--> Block #%d has a bad checksum!\n",f->current_block);
#endif
			return 0;
		}
#endif

#ifdef FS_DEBUG
		printf("--> reading <%d> bytes from block <%d>, seq = %d\n",read_len,f->current_block, header.seq);
#endif
		fs_block_read(f->current_block, f->current_offset, buf, read_len);
		buf += read_len;
		bytes_read += read_len;
		len -= read_len;
		f->current_offset += read_len;
		f->position += read_len;
			
		if(f->current_offset == header.last_byte)
		{
			/* move to the next block */
			block = fs_get_next_block(f->current_block);
			if(block == FS_NOBLOCK) {
				/* block not found - we hit the end of the file */
				return bytes_read;
			}
			else
			{
				f->current_sequence++;
				f->current_block = block;
				fs_get_header(f->current_block, &header);
				f->current_offset = header.first_byte;
			}			
		}
	}
	return bytes_read;
}

/*** BeginHeader ftell */
long ftell(File *f);
/*** EndHeader */

/* START FUNCTION DESCRIPTION ********************************************
ftell                          <filesystem.lib>

SYNTAX: long ftell(File *f)

KEYWORDS:      file system

DESCRIPTION:   This function returns the current pointer.

PARAMETER1:    file pointer
PARAMETER2:    offset in file

RETURN VALUE:  offset in file
               -1 - failure

SEE ALSO:

END DESCRIPTION **********************************************************/

nodebug long ftell(File *f)
{
	auto int block;
	auto FSSeq i;
	auto long len;
	auto FSHeader header;
	
	if(f->mode!=FS_WRITE && f->mode!=FS_READ) return -1;
	
	block = fs_filelist_get(f->name);
	if(block == FS_NOBLOCK) return -1;
	len = 0;
	while(block >= 0)
	{
		fs_get_header(block, &header);
		if(header.seq == f->current_sequence)
		{
			//current block
			len += f->current_offset - header.first_byte;
			break;
		}
		else
		{
			len += header.last_byte - header.first_byte;
		}
		block = fs_get_next_block(block);
	}
	return len;
}

/*** BeginHeader fseek */
int fseek(File *f, long to, char whence);
/*** EndHeader */

/* START FUNCTION DESCRIPTION ********************************************
fseek                          <filesystem.lib>

SYNTAX: int fseek(File *f, long where, char whence)

KEYWORDS:      file system

DESCRIPTION:   This function places the current read pointer at
               where in the file.

               SEEK_SET - offset is measured from the beginning
               SEEK_CUR - offset is measured from the current offset
               SEEK_END - offset is measured backwards from end.

PARAMETER1:    file pointer
PARAMETER2:    offset in file
PARAMETER3:    where to measure the offset.

RETURN VALUE:  0 - success
               1 - failure

SEE ALSO:

END DESCRIPTION **********************************************************/

nodebug int fseek(File *f, long to, char whence)
{
	auto long prev, filelength, currentpos, seekpos;
	auto int block, current_mark;
	auto FSSeq i;
	auto FSHeader header;
	
	if(f->mode!=FS_WRITE && f->mode!=FS_READ) return 1;

	prev = 0;

	//calculate file length
	filelength = 0;
	currentpos = 0;
	current_mark = 0; //flag set when current position is hit
	block = fs_filelist_get(f->name);
	if(block == FS_NOBLOCK) return 1;
	while(block >= 0)
	{
		fs_get_header(block, &header);
		filelength += header.last_byte - header.first_byte;
		if(header.seq == f->current_sequence)
		{
			currentpos += f->current_offset - header.first_byte;
			current_mark = 1;
		}
		else if(current_mark == 0)
		{
			currentpos += header.last_byte - header.first_byte;
		}
		block = fs_get_next_block(block);
	}

	switch(whence)
	{
		case SEEK_SET:
			seekpos = to;
			break;
		case SEEK_CUR:
			seekpos = currentpos + to;
			break;
		case SEEK_END:
			seekpos = filelength + to;
			break;
		default:
		/* ERROR - unknown 'whence' value! */
		return 1;
	}
	//check limits
	if(seekpos < 0 || seekpos > filelength)
		return 1;
	f->position = seekpos;
	//set file pointer
	block = fs_filelist_get(f->name);
	while(block >= 0)
	{
		fs_get_header(block, &header);
		if(seekpos > header.last_byte - header.first_byte)
		{
			seekpos -= header.last_byte - header.first_byte;
		}
		else
		{
			//this is our block			
			f->current_block = block;
			f->current_sequence = header.seq;
			f->current_offset = header.first_byte + (int)seekpos;
			return 0;
		}
		block = fs_get_next_block(block);
	}
	return 1;	//end of file, this shouldn't happen					
}

/*** BeginHeader fs_level_wear */
int fs_level_wear(int seconds);
/*** EndHeader */

/* START FUNCTION DESCRIPTION ********************************************
fs_level_wear                  <filesystem.lib>

SYNTAX: int fs_level_wear(int seconds)

KEYWORDS:      file system

DESCRIPTION:   Wear level flash - Unimplemented.

PARAMETER1:    number of seconds to wearlevel

RETURN VALUE:  0 - success
               1 - failure

SEE ALSO:

END DESCRIPTION **********************************************************/

nodebug int fs_level_wear(int seconds)
{
	/* not implemented yet */
}

/*** Beginheader fs_reserve_blocks */
int fs_reserve_blocks(int blocks);
/*** EndHeader */

/* START FUNCTION DESCRIPTION ********************************************
fs_reserve_blocks                  <filesystem.lib>

SYNTAX: int fs_reserve_blocks(int blocks)

KEYWORDS:      file system

DESCRIPTION:   Sets up a number of blocks that will be guarenteed to be
					available for priveleged files (128-143)

PARAMETER1:    number of blocks to reserve

RETURN VALUE:  0 - success
               1 - failure

SEE ALSO:

END DESCRIPTION **********************************************************/

nodebug int fs_reserve_blocks(int blocks)
{
	if(blocks >= 0 && blocks < fs_num_blocks - fs_nonpriv_blocks_used)
	{
		fs_blocks_reserved = blocks;
		return 0;
	}
	else
	{
		return 1; //failed
	}
}	

/*** BeginHeader fsck */
int fsck(int flags);
/*** EndHeader */

/* START FUNCTION DESCRIPTION ********************************************
fsck		                  <filesystem.lib>

SYNTAX: int fsck(int flags)

KEYWORDS:      file system

DESCRIPTION:   Check the filesystem for errors.

PARAMETER1:    A bitmask indicating which checks to NOT perform.
					The following checks are avaliable:
						FSCK_HEADERS	- Block headers
						FSCK_CHECKSUMS - Data checksums
						FSCK_VERSION	- Block versions, from a failed write.

RETURN VALUE:  0 - success
					non 0 - A bitmask indicating which checks failed.

SEE ALSO:

END DESCRIPTION **********************************************************/

nodebug int fsck(int flags)
{
	auto int i;
	auto int retval;
	FSHeader header;
		
	retval = 0;		
	if(!(FSCK_HEADERS&flags)) {
#ifdef FS_DEBUG
		printf("Checking filesystem block headers...\n");
#endif

		for(i=0; i<fs_num_blocks; i++) {
			if(fs_verify_block(i)) {
				/* ERROR IN HEADER */
#ifdef FS_DEBUG
				printf("Error in header for block #%d\n",i);
#endif
				retval |= FSCK_HEADERS;
			}
		}
	}
	
	if(!(FSCK_CHECKSUMS&flags)) {
#ifdef FS_DEBUG
		printf("Checking filesystem checksums...\n");
#endif

		for(i=0; i<fs_num_blocks; i++) {
			fs_get_header(i, &header);
			if(header.flag == FS_USED)
				if(header.crc != fs_checksum_far(i, header.first_byte,
					header.last_byte - header.first_byte, 0, 0)) {

					/* ERROR IN BLOCK! */
#ifdef FS_DEBUG
					printf("Error in checksum on block #%d!\n",i);
#endif
					retval |= FSCK_CHECKSUMS;
			}
		}
	}
	
	if(!(FSCK_VERSION&flags)) {
#ifdef FS_DEBUG
		printf("Checking for duplicate blocks...\n");
#endif

		for(i=0; i<fs_num_blocks; i++) {
			if(fs_verify_version(i)) {
				retval |= FSCK_VERSION;
			}
		}
	}

	return retval;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -