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

📄 xsfsstream.c

📁 一个操作系统,用C语言实现开发的,我在一个浙江大学的操作系统实验网站找到.大家学习以下
💻 C
字号:
// XSFS Stream IO

#include <memory.h>
#include <knllib.h>
#include "xsfsunits.h"
#include "xsfsstream.h"

// convert byte-based posisition to unit and offset
static inline void cvt_pos(HXSSTREAM strm, _u64 pos, _u32 *unit, _u32 *off)
{
	_u32 o;
	o = strm->xsfs->desc.sector_size*strm->xsfs->desc.n_scale;
	if(unit) *unit = (_u32)(pos/o);
	if(off) *off = (_u32)(pos%o);
}

static inline int read_unit(HXSSTREAM strm, _u32 unit)
{
	return fsioRead(strm->xsfs->handle, i_xsfs_start_sector(strm->xsfs)+unit*strm->xsfs->desc.n_scale, 
			strm->xsfs->buffer, strm->xsfs->desc.n_scale);
}

static inline int write_unit(HXSSTREAM strm, void *buffer, _u32 unit)
{
	return fsioWrite(strm->xsfs->handle, i_xsfs_start_sector(strm->xsfs)+unit*strm->xsfs->desc.n_scale, 
			buffer, strm->xsfs->desc.n_scale);
}

static _u32 new_pri_unit(HXSSTREAM strm, _u32 unit)
{
	_u32 nu;
	if(xsfsAllocUnits(strm->xsfs, i_xsfs_sector_to_unit(strm->xsfs, strm->sector), 
						1, &nu, 0)==0) return 0;
	strm->stream.pri_index[unit] = nu;
	xsfsUpdateStreamDef(strm);
	return nu;
}

static int update_unit(HXSSTREAM strm, _u32 unit, int index, _u32 link)
{
	if(!read_unit(strm, unit)) return 0;

	((_u32*)strm->xsfs->buffer)[index] = link;
	if(!write_unit(strm, strm->xsfs->buffer, unit))
		return 0;

	return 1;
}

static _u32 new_sec_unit(HXSSTREAM strm, _u32 last, int start, int level, _u32 index[])
{
	int i, cnt = level-start+1, n;
	_u32 nus[MAX_SEC_INDEX+1];

	if(xsfsAllocUnits(strm->xsfs, i_xsfs_sector_to_unit(strm->xsfs, strm->sector), 
						cnt, start==-1?nus:&nus[1], XSAM_CLEAN)!=cnt) return 0;
	if(start>=0) nus[0] = last;

	for(i=start==-1?0:start, n=0; i<=level; i++, n++)
		if(!update_unit(strm, nus[n], index[i], nus[n+1]))
		{
			xsfsFreeUnits(strm->xsfs, start==-1?nus:&nus[1], cnt, 0);
			return 0;
		}
	if(start == -1)
	{
		strm->stream.sec_index[level] = nus[0];
		xsfsUpdateStreamDef(strm);
	}
	return nus[start==-1?cnt-1:cnt];
}

static inline int get_unit_level(_u32 sec_count, _u32 unit, _u32 index[])
{
	unit -= MAX_PRI_INDEX;
	if(unit<sec_count){ index[0] = unit; return 0; }
	if(unit<sec_count+sec_count*sec_count)
	{ index[0] = (unit-sec_count)/sec_count; index[1] = (unit-sec_count)%sec_count; return 1; }
	index[0] = (unit-sec_count-sec_count*sec_count)/(sec_count*sec_count);
	index[1] = ((unit-sec_count-sec_count*sec_count)%(sec_count*sec_count))/sec_count;
	index[2] = ((unit-sec_count-sec_count*sec_count)%(sec_count*sec_count))%sec_count;
	return 2;
}

static _u32 find_unit(HXSSTREAM strm, _u32 unit, int auto_grow)
{
	_u32 sec_count, i, j;
	_u32 index[MAX_SEC_INDEX];
	int level, a;

	// find pri_index
	if(unit<MAX_PRI_INDEX)
	{
		i = strm->stream.pri_index[unit];
		if(!i && auto_grow) new_pri_unit(strm, unit);
		return strm->stream.pri_index[unit];
	}

	// find sec_index
	sec_count = strm->xsfs->desc.n_scale*strm->xsfs->desc.sector_size/sizeof(_u32);
	level = get_unit_level(sec_count, unit, index);

	if((i=strm->stream.sec_index[level])==0)
		return auto_grow ? new_sec_unit(strm, 0, -1, level, index) : 0;
	
	for(a=0; a<=level; a++)
	{
		if(!read_unit(strm, i)) return 0;
		j = i;
		i = ((_u32*)strm->xsfs->buffer)[index[a]];
		if(!i) return auto_grow ? new_sec_unit(strm, j, a, level, index) : 0;
	}
	return i;
}

static inline int read_unit_instream(HXSSTREAM strm, _u32 unit)
{
	unit = find_unit(strm, unit, 0);			
	if(!unit) return 0;
	return read_unit(strm, unit);
}

static inline int write_unit_instream(HXSSTREAM strm, void *buffer, _u32 unit)
{
	unit = find_unit(strm, unit, 1);
	if(!unit) return 0;
	return write_unit(strm, buffer, unit);
}

int xsfsReadStream(HXSSTREAM strm, _u64 pos, void *buf, int len)
{
	_u32 unit, off;
	int cnt = 0, l;
	char *p = (char*) buf;

	cvt_pos(strm, pos, &unit, &off);
	while(len)
	{
		if(!read_unit_instream(strm, unit)) break;			
		l = min((int)(i_xsfs_unit_size(strm->xsfs)-off), len);
		memcpy(p, (char*)strm->xsfs->buffer + off, l);
		p += l; len -= l; off = 0; unit ++; cnt += l;
	}
	return cnt;
}

int xsfsWriteStream(HXSSTREAM strm, _u64 pos, void *buf, int len)
{
	_u32 unit, off;
	int cnt = 0, l;
	char *p = (char*) buf;

	cvt_pos(strm, pos, &unit, &off);
	while(len)
	{
		l = min((int)(i_xsfs_unit_size(strm->xsfs)-off), len);
		if(off || l<(int)(i_xsfs_unit_size(strm->xsfs)-off))
		{
			_u32 u1 = find_unit(strm, unit, 1);
			if(!read_unit(strm, u1)) break;
			memcpy((char*)strm->xsfs->buffer + off, p, l);
			if(!write_unit(strm, strm->xsfs->buffer, u1)) break;
		}
		else
		{
			if(!write_unit_instream(strm, p, unit)) break;
		}
		p += l; len -= l; off = 0; unit ++; cnt += l;
	}
	return cnt;
}

_u32 xsfsLocate(HXSSTREAM strm, _u64 pos, _u32 *off)
{
	_u32 u, o;
	cvt_pos(strm, pos, &u, &o);
	u = find_unit(strm, u, 0);
	if(u && off) *off = o;
	return u;
}

void xsfsUpdateStreamDef(HXSSTREAM strm)
{
	if(fsioRead(strm->xsfs->handle, strm->sector, strm->xsfs->buffer, 1)==0) return;
	memcpy((char*)strm->xsfs->buffer + strm->offset, &strm->stream, sizeof(XSFSSTREAM));
	fsioWrite(strm->xsfs->handle, strm->sector, strm->xsfs->buffer, 1);
}

int xsfsLoadSysStream(XSSTREAM *strm, int index)
{
	int cnt = strm->xsfs->desc.sector_size/sizeof(XSFSSTREAM);
	int n = index/cnt;
	int i = index%cnt;
	XSFSSTREAM *p;

	if(!fsioRead(strm->xsfs->handle, strm->xsfs->desc.n_reserved+n, strm->xsfs->buffer, 1))
		return 0;
	p = (XSFSSTREAM*)strm->xsfs->buffer;
	memcpy(&strm->stream, &p[i], sizeof(XSFSSTREAM));
	strm->sector = strm->xsfs->desc.n_reserved+n;
	strm->offset = i * sizeof(XSFSSTREAM);
	return 1;
}

⌨️ 快捷键说明

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