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

📄 sfseek.c

📁 su 的源代码库
💻 C
字号:
/* Copyright (c) Colorado School of Mines, 2006.*//* All rights reserved.                       */#include	"sfhdr.h"/*	Set the IO pointer to a specific location in the stream****	Written by Kiem-Phong Vo.*/#if __STD_Cstatic void newpos(Sfio_t* f, Sfoff_t p)#elsestatic void newpos(f, p)Sfio_t*	f;Sfoff_t p;#endif{#ifdef MAP_TYPE	if((f->bits&SF_MMAP) && f->data)	{	SFMUNMAP(f, f->data, f->endb-f->data);		f->data = NIL(uchar*);	}#endif	f->next = f->endr = f->endw = f->data;	f->endb = (f->mode&SF_WRITE) ? f->data+f->size : f->data;	if((f->here = p) < 0)	{	f->extent = -1;		f->here = 0;	}}#if __STD_CSfoff_t sfseek(Sfio_t* f, Sfoff_t p, int type)#elseSfoff_t sfseek(f,p,type)Sfio_t*	f;	/* seek to a new location in this stream */Sfoff_t	p;	/* place to seek to */int	type;	/* 0: from org, 1: from here, 2: from end */#endif{	Sfoff_t	r, s;	int	mode, local, hardseek, mustsync;	SFMTXSTART(f, (Sfoff_t)(-1));	GETLOCAL(f,local);	hardseek = (type|f->flags)&(SF_SHARE|SF_PUBLIC);	if(hardseek && f->mode == (SF_READ|SF_SYNCED) )	{	newpos(f,f->here);		f->mode = SF_READ;	}	/* set and initialize the stream to a definite mode */	if((int)SFMODE(f,local) != (mode = f->mode&SF_RDWR))	{	int	flags = f->flags;		if(hardseek&SF_PUBLIC) /* seek ptr must follow file descriptor */			f->flags |= SF_SHARE|SF_PUBLIC;		mode = _sfmode(f,mode,local);		if(hardseek&SF_PUBLIC)			f->flags = flags;		if(mode < 0)			SFMTXRETURN(f, (Sfoff_t)(-1));	}	mustsync = (type&SF_SHARE) && !(type&SF_PUBLIC) &&		   (f->mode&SF_READ) && !(f->flags&SF_STRING);	/* Xopen-compliant */	if((type &= (SEEK_SET|SEEK_CUR|SEEK_END)) != SEEK_SET &&	   type != SEEK_CUR && type != SEEK_END )	{	errno = EINVAL;		SFMTXRETURN(f, (Sfoff_t)(-1));	}	if(f->extent < 0)	{	/* let system call set errno */		(void)SFSK(f,(Sfoff_t)0,SEEK_CUR,f->disc);		SFMTXRETURN(f, (Sfoff_t)(-1));	}	/* throw away ungetc data */	if(f->disc == _Sfudisc)		(void)sfclose((*_Sfstack)(f,NIL(Sfio_t*)));	/* lock the stream for internal manipulations */	SFLOCK(f,local);	/* clear error and eof bits */	f->flags &= ~(SF_EOF|SF_ERROR);	while(f->flags&SF_STRING)	{	SFSTRSIZE(f);		if(type == SEEK_CUR)			r = p + (f->next - f->data);		else if(type == SEEK_END)			r = p + f->extent;		else	r = p;		if(r >= 0 && r <= f->size)		{	p = r;			f->next = f->data+p;			f->here = p;			if(p > f->extent)				memclear((char*)(f->data+f->extent),(int)(p-f->extent));			goto done;		}		/* check exception handler, note that this may pop stream */		if(SFSK(f,r,SEEK_SET,f->disc) != r)		{	p = -1;			goto done;		}		else if(!(f->flags&SF_STRING))		{	p = r;			goto done;		}	}	if(f->mode&SF_WRITE)	{	/* see if we can avoid flushing buffer */		if(!hardseek && type < SEEK_END && !(f->flags&SF_APPENDWR) )		{	s = f->here + (f->next - f->data);			r = p + (type == SEEK_SET ? 0 : s);			if(r == s)			{	p = r;				goto done;			}		}		if(f->next > f->data && SFSYNC(f) < 0)		{	p = -1;			goto done;		}	}	if(type == SEEK_END || (f->mode&SF_WRITE) )	{	if((hardseek&SF_PUBLIC) || type == SEEK_END)			p = SFSK(f, p, type, f->disc);		else		{	r = p + (type == SEEK_CUR ? f->here : 0);			p = (hardseek || r != f->here) ? SFSK(f,r,SEEK_SET,f->disc) : r;		}		if(p >= 0)			newpos(f,p);		goto done;	}	/* if get here, must be a read stream */	s = f->here - (f->endb - f->next);	r = p + (type == SEEK_CUR ? s : 0);	if(r <= f->here && r >= (f->here - (f->endb-f->data)) )	{	if((hardseek || (type == SEEK_CUR && p == 0)) )		{	if((s = SFSK(f, (Sfoff_t)0, SEEK_CUR, f->disc)) == f->here ||			   (s >= 0 && !(hardseek&SF_PUBLIC) &&			    (s = SFSK(f, f->here, SEEK_SET, f->disc)) == f->here) )				goto near_done;			else if(s < 0)			{	p = -1;				goto done;			}			else			{	newpos(f,s);				hardseek = 0;			}		}		else		{ near_done:			f->next = f->endb - (f->here - r);			p = r;			goto done;		}	}	/* desired position */	if((p += type == SEEK_CUR ? s : 0) < 0)		goto done;#ifdef MAP_TYPE	if(f->bits&SF_MMAP)	{	/* if mmap is not great, stop mmaping if moving around too much */#if _mmap_worthy < 2		if((f->next - f->data) < ((f->endb - f->data)/4) )		{	SFSETBUF(f,(Void_t*)f->tiny,(size_t)SF_UNBOUND);			hardseek = 1; /* this forces a hard seek below */		}		else#endif		{	/* for mmap, f->here can be virtual except for hardseek */			newpos(f,p);			if(!hardseek)				goto done;		}	}#endif	if(f->endb > f->next)	{	/* reduce wastage in future buffer fillings */		f->iosz = (f->next - f->data) + (f->endb - f->next)/2;		f->iosz = ((f->iosz + f->blksz-1)/f->blksz)*f->blksz;	}	if(f->iosz >= f->size)		f->iosz = 0;	/* buffer is now considered empty */	f->next = f->endr = f->endb = f->data;	/* small backseeks often come in bunches, so seek back as far as possible */	if(p < f->lpos && f->size > f->blksz && (p + f->blksz) > s)	{	if((r = s - f->size) < 0)			r = 0;	}	/* try to align buffer to block boundary to enhance I/O speed */	else if(f->blksz > 0 && f->size >= 2*f->blksz)		r = p - (p%f->blksz);	else	{	r = p;		/* seeking around and wasting data, be conservative */		if(f->iosz > 0 && (p > f->lpos || p < f->lpos-f->size) )			f->bits |= SF_JUSTSEEK;	}	if((hardseek || r != f->here) && (f->here = SFSK(f,r,SEEK_SET,f->disc)) != r)	{	if(r < p) /* now try to just get to p */			f->here = SFSK(f,p,SEEK_SET,f->disc);		if(f->here != p)			p = -1;		goto done;	}	if(r < p) /* read to cover p */	{	(void)SFRD(f, f->data, f->size, f->disc);		if(p <= f->here && p >= (f->here - (f->endb - f->data)) )			f->next = f->endb - (size_t)(f->here-p);		else /* recover from read failure by just seeking to p */		{	f->next = f->endb = f->data;			if((f->here = SFSK(f,p,SEEK_SET,f->disc)) != p)				p = -1;		}	}done :	if(f->here < 0) /* hasn't been the best of time */	{	f->extent = -1;		f->here = 0;	}	f->lpos = p;	SFOPEN(f,local);	if(mustsync)		sfsync(f);	SFMTXRETURN(f, p);}

⌨️ 快捷键说明

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