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

📄 ring.cc

📁 这是关于远程登陆TELNET 的源代码 已经测试过的。
💻 CC
字号:
/* * Copyright (c) 1988 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//* * From: @(#)ring.c	5.2 (Berkeley) 3/1/91 */char ring_rcsid[] =  "$Id: ring.cc,v 1.23 2000/07/23 03:25:09 dholland Exp $";/* * This defines a structure for a ring buffer.  */#include <stdio.h>#include <stdarg.h>#include <assert.h>#include "ring.h"class devnull : public datasink {    virtual int write(const char *, int n) { return n; }    virtual int writeurg(const char *, int n) { return n; }};static devnull nullsink_obj;datasink *nullsink = &nullsink_obj;int ringbuf::init(int sz, datasink *sink, source *src) {    buf = new char[sz];    size = sz;    head = tail = 0;    count = 0;    marked = -1;    binding = sink;    srcbinding = src;    return 1;}/////////////////////////////////////////////////// consume //////////////int ringbuf::gets(char *rbuf, int max) {    int i=0, ch;    assert(max>0);    while (getch(&ch)>0 && i<max-1) rbuf[i++] = ch;    rbuf[i]=0;    return i;}int ringbuf::getch(int *ch) {    int rv = 0;    if (count > 0) {	if (tail==marked) {	    rv = 2;	    marked = -1;	}	else rv = 1;	*ch = (unsigned char) buf[tail++];	if (tail>=size) tail -= size;	count--;    }    return rv;   /* 0 = no more chars available */}void ringbuf::ungetch(int ch) {    int x = tail;    x--;    if (x<0) x += size;    int och = buf[x];   /* avoid sign-extension and other such problems */    if ((och&0xff) == (ch&0xff)) {	tail = x;	count++;    }    else {	//assert(!"Bad ungetch");	tail = x;	count++;    }}/* * Return value: *   -2: Significant error occurred. *   -1: No useful work done, data waiting to go out. *    0: No data was waiting, so nothing was done. *    1: All waiting data was written out. *    n: Some data written, n-1 bytes left. */int ringbuf::flush() {    assert(binding);    assert(count>=0);    if (count==0) return 0;        static int busy=0;    if (busy) {	return -1;    }    busy=1;    /* should always be true */    /* assert(((size+head-tail)%size)==count); */    /* Nope! The above fails if the buffer is full; then:     * head == tail (so LHS is 0), but count == size.     * The following formula should be better. --okir */    assert(((head - tail - count) % size) == 0);    while (count > 0) {	int bot = tail;	int top = head;	if (top < bot) top = size;	if (marked > bot) top = marked;	assert(top-bot > 0 && top-bot <= count);	int n;	if (marked==bot) n = binding->writeurg(buf+bot, top-bot);	else n = binding->write(buf+bot, top-bot);	if (n < 0) { busy=0; return -2; }	else if (n==0) { busy=0; return -1; }		if (marked==bot) marked = -1;	tail += n;	if (tail >= size) tail -= size;	count -= n;	assert(((size+head-tail)%size)==count);		if (n > 0 && n < top-bot) { busy=0; return n+1; }	/* otherwise (if we wrote all data) loop */    }    assert(((size+head-tail)%size)==count);    busy=0;    return 1;}/////////////////////////////////////////////////// supply //////////////void ringbuf::printf(const char *format, ...) {    char xbuf[256];    va_list ap;    va_start(ap, format);    int l = vsnprintf(xbuf, sizeof(xbuf), format, ap);    va_end(ap);    write(xbuf, l);}void ringbuf::write(const char *buffer, int ct) {    if (ct > size - count) {	// Oops. We're about to overflow our buffer.	// In practice this shouldn't ever actually happen.	// We could return a short count, but then we'd have to check	// and retry every call, which ranges somewhere between painful	// and impossible.	// Instead, we drop the data on the floor. This should only happen 	// if (1) the tty hangs, (2) the network hangs while we're trying 	// to send large volumes of data, or (3) massive internal logic errors.	fprintf(stderr, "\n\ntelnet: buffer overflow, losing data, sorry\n");	ct = size - count;    }    for (int i=0; i<ct; i++) {	buf[head++] = buffer[i];	if (head>=size) head -= size;	count++;    }}int ringbuf::read_source() {    int bot = head;    int top = tail-1; /* leave room for an ungetc */    if (top<0) top += size;    if (top < bot) top = size;    if (top==bot) return 0;    int l = srcbinding->read(buf+bot, top-bot);    if (l>=0) {	head += l;	if (head>=size) head -= size;	count += l;    }    if (l==0) l = -1;    return l;}

⌨️ 快捷键说明

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