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

📄 es_util.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
#ifndef lint#ifdef sccsstatic  char sccsid[] = "@(#)es_util.c 1.1 92/07/30";#endif#endif/* * Copyright (c) 1986, 1987 by Sun Microsystems, Inc. *//* * Utilities for use with entity streams. */#include <suntool/primal.h>#include <suntool/entity_stream.h>extern Es_indexes_bounds_of_gap(esh, around, last_plus_one, flags)	register Es_handle	 esh;	Es_index		 around;	Es_index		*last_plus_one;	int			 flags;/* If there is no gap, then around == return value == *last_plus_one. * Else, if not looking for the start of the gap (flags & 0x1 == 0), *   around < return value == *last_plus_one. * Else, if looking for the start of the gap, *   return value <= around <= *last_plus_one *   (return value will be ES_CANNOT_SET if gap extends from 0 on). */{#define BUFSIZE 32	char			buf[BUFSIZE+4];	int			count_read;	register Es_index	new_pos, low, high, probe;	low = es_set_position(esh, around);	new_pos = es_read(esh, 1, buf, &count_read);	if (count_read == 0) {	    low = new_pos;	}	if (last_plus_one)	    *last_plus_one = low;	if ((low != around) && (flags & 0x1) &&	    !READ_AT_EOF(around, new_pos, count_read)) {	    /* Try binary search to locate the start of the gap.	     * Invariants for loop:	     *   0 <= low <= start of gap <= high <= around	     *   low < probe = (high + low) / 2 < high	     * Essentially, choose a probe point and try to read. 3 cases:	     *   1) new_pos < around: null, partial or full read	     *      => low = new_pos;	     *         if low >=high, gap starts at probe+count_read	     *   2) new_pos > around: null read	     *      => high = probe	     *   3) new_pos > around: partial read	     *      => gap starts at probe+count_read	     *   "new_pos == around || (new_pos > around: full read)"	     *      impossible as there is gap	     */	    low = 0;	    high = around;	    while (low+1 < high) {		probe = es_set_position(esh, (high+low)/2);		new_pos = es_read(esh, BUFSIZE, buf, &count_read);		if (new_pos < around) {		    if (new_pos >= high) {			low = probe+count_read;			break;		    } else {			low = new_pos;		    }		} else if (count_read == 0) {		    high = probe;		} else {		    low = probe+count_read;		    break;		}	    }	    if (low == 0) {		probe = es_set_position(esh, 0);		new_pos = es_read(esh, BUFSIZE, buf, &count_read);		if (count_read == 0)		    low == ES_CANNOT_SET;	    }	}	return(low);#undef BUFSIZE}/* Caller must make sure that esbuf->last_plus_one is the current position *   in the entity stream. */extern intes_advance_buf(esbuf)	Es_buf_handle	esbuf;{	int			read = 0;	register Es_index	next = esbuf->last_plus_one;	while (read == 0) {	    esbuf->first = next;	    next = es_read(esbuf->esh, esbuf->sizeof_buf, esbuf->buf, &read);	    esbuf->last_plus_one = esbuf->first + read;	    if READ_AT_EOF(esbuf->first, next, read) {		return(1);	    }	}	return(0);}extern Es_indexes_backup_buf(esbuf)	Es_buf_handle	esbuf;{/* Move buffer back in stream (i.e., change so that esbuf->first is smaller). * Backing the buffer up is complicated by possible gap before the current *   beginning of the buffer. * This routine moves over such a gap. */	register Es_index	prev;	register Es_index	esi = esbuf->first-1;Retry:	switch (es_make_buf_include_index(esbuf, esi, esbuf->sizeof_buf-1)) {	  case 0:	    break;	  case 2:	    prev = esi;	    esi = es_bounds_of_gap(esbuf->esh, prev, 0, 0x1);	    if (esi != ES_CANNOT_SET && esi < prev) {		goto Retry;	    }	    /* else gap extends back to 0 OR unexpected error	     *  => fall through.	     */	  case 1:	  default:		    /* Conservative in face of new cases */	    esi = ES_CANNOT_SET;	    break;	}	return(esi);}/* esbuf->first and ->last_plus_one are only adjusted when entities are *   actually read.  This makes it easier for callers to figure out how to *   correct after failure to re-position a buffer. * Returns: *  0	iff it managed to align the buffer as requested, *  1	if read at end of stream while trying to align, *  2	if desired entity is in a "hole" in the stream. */extern intes_make_buf_include_index(esbuf, index, desired_prior_count)	register Es_buf_handle	esbuf;	Es_index		index;	int			desired_prior_count;{	register Es_index	last_plus_one, next;	int			read;	last_plus_one = (desired_prior_count > index) ? 0			: index - desired_prior_count;	es_set_position(esbuf->esh, last_plus_one);	FOREVER {	    next = es_read(esbuf->esh, esbuf->sizeof_buf, esbuf->buf, &read);	    if READ_AT_EOF(last_plus_one, next, read)		return(1);	    esbuf->first = last_plus_one;	    esbuf->last_plus_one = last_plus_one+read;	    if (next > index) {		if (esbuf->last_plus_one < index) {		    return(2);		} else		    return(0);	    }	    last_plus_one = next;	}}extern Es_statuses_copy(from, to, newline_must_terminate)	register Es_handle	from, to;	int			newline_must_terminate;{#define BUFSIZE 2096	char			buf[BUFSIZE+4];	register Es_status	result;	int			read, write;	Es_index		new_pos, pos, to_pos;	/* Find start of "from" (it need not actually be 0, e.g. secondary	 * pieces that compose a selection)	 */	pos = es_set_position(from, 0);	write = 0;	/* Cannot just "es_replace(to, ES_INFINITY, ...)" in case not copying	 * at the end of "to", so get (and maintain) current position in "to".	 */	to_pos = es_get_position(to);	FOREVER {	    new_pos = es_read(from, BUFSIZE, buf, &read);	    if (read > 0) {		to_pos = es_replace(to, to_pos, read, buf, &write);		if (write < read) {		    result = ES_SHORT_WRITE;		    return(result);		}	    } else if (pos == new_pos)		break;	    pos = new_pos;	}	if (newline_must_terminate && (	    (write <= 0) || (write > sizeof(buf)) ||	    (buf[write-1] != '\n') )) {	    buf[0] = '\n';	    (void) es_replace(to, ES_INFINITY, 1, buf, &write);	    if (write < 1) {		result = ES_SHORT_WRITE;		return(result);	    }	}	result = es_commit(to);	return(result);#undef BUFSIZE}

⌨️ 快捷键说明

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