?? iobuff.c
字號:
/* iobuff.c -- Intercom I/O buffering routines Copyright (C) 2001-2003 Shane Wegner This file is part of Intercom. Intercom is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. Intercom is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of version 2 of the GNU General Public License along with Intercom; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA To contact the author, please send email to shane@cm.nu. *//* $Id: iobuff.c,v 1.9 2003/02/13 20:22:49 shane Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#define __USE_STRING_INLINES#include <stdlib.h>#include <string.h>#include <math.h>#include <sys/types.h>#ifdef _REENTRANT#include <pthread.h>#endif#include "iobuff.h"#ifdef _REENTRANT#define ioblock(n) pthread_mutex_lock(&n)#define iobunlock(n) pthread_mutex_unlock(&n)#else#define ioblock(n)#define iobunlock(n)#endifvoid iob_init(struct iobuff *iob){#ifdef _REENTRANTpthread_mutex_init(&iob->mutex, NULL);#endifioblock(iob->mutex);iob->page = NULL;iob->minpages = 0;iobunlock(iob->mutex);}void iob_setminbytes(struct iobuff *iob, size_t n){iob->minpages = (int)ceil((float)n / IOB_PAGESIZE);}void iob_flush(struct iobuff *iob){struct iob_page *p, *next;ioblock(iob->mutex);for (p = iob->page; p != NULL; p = next) {next = p->next;free(p);}iob->page = NULL;iobunlock(iob->mutex);}static struct iob_page *iob_newpage(void){struct iob_page *p = malloc(sizeof(struct iob_page));p->len = 0;p->pos = 0;p->next = NULL;return p;}void iob_queue(struct iobuff *iob, const char *buff, size_t n){struct iob_page *ip;size_t fb, btc, buffpos = 0;ioblock(iob->mutex);if (n && iob->page == NULL) {iob->page = iob_newpage();iob->page->prev = NULL;}/* put ip on the last valid page */for (ip = iob->page; ip->next != NULL; ip = ip->next);/* Now reverse to find the last non-empty page */for (; !ip->len && ip->prev != NULL; ip = ip->prev);while(n) {fb = IOB_PAGESIZE - (ip->pos + ip->len);if (!fb) {if (ip->next == NULL) {ip->next = iob_newpage();ip->next->prev = ip;}ip = ip->next;continue;}btc = (fb >= n) ? n : fb;memcpy(&ip->data[ip->pos+ip->len], &buff[buffpos], btc);ip->len += btc;buffpos += btc;n -= btc;} /* while */iobunlock(iob->mutex);}size_t iob_buffsize(struct iobuff *iob){struct iob_page *p;size_t sz = 0;ioblock(iob->mutex);for (p = iob->page; p != NULL; p = p->next)sz += p->len;iobunlock(iob->mutex);return sz;}size_t iob_readkeep(struct iobuff *iob, char *buff, size_t n){struct iob_page *p;size_t buffpos = 0, btc;ioblock(iob->mutex);for (p = iob->page; p != NULL; p = p->next) {btc = (p->len >= n) ? n : p->len;memcpy(&buff[buffpos], &p->data[p->pos], btc);buffpos += btc;n -= btc;if (!n)break;}iobunlock(iob->mutex);return n;}size_t iob_read(struct iobuff *iob, char *buff, size_t n){iob_readkeep(iob, buff, n);iob_delete(iob, n);return n;}void iob_delete(struct iobuff *iob, size_t n){struct iob_page *p, *next;size_t btc, pagecount = 0;ioblock(iob->mutex);for (p = iob->page; p != NULL; p = p->next)pagecount++;for (p = iob->page; p != NULL && n; p = next) {btc = (p->len >= n) ? n : p->len;p->pos += btc;p->len -= btc;n -= btc;next = p->next;if (!p->len)p->pos = 0;if (!p->len && pagecount > iob->minpages) {pagecount--;if (p->prev == NULL) {iob->page = next;iob->page->prev = NULL;} else {p->prev->next = next;if (next != NULL)next->prev = p->prev;}free(p);}}iobunlock(iob->mutex);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -