|
|
1.1 ! root 1: /* ringbuf.c */ ! 2: ! 3: /* Synchronet ring buffer routines */ ! 4: ! 5: /* $Id: ringbuf.c,v 1.1.1.1 2000/10/10 11:26:23 rswindell Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This program is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU General Public License for more details: gpl.txt or * ! 18: * http://www.fsf.org/copyleft/gpl.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: /* Pre-define RINGBUF_USE_STD_RTL to use standard C runtime library symbols ! 39: * for malloc, free, and memcpy ! 40: */ ! 41: ! 42: #ifdef VTOOLSD ! 43: #include <vtoolsd.h> ! 44: #include LOCKED_CODE_SEGMENT ! 45: #include LOCKED_DATA_SEGMENT ! 46: #endif ! 47: ! 48: #include "ringbuf.h" ! 49: ! 50: #ifdef RINGBUF_USE_STD_RTL ! 51: ! 52: #ifndef VTOOLSD ! 53: #include <malloc.h> /* malloc prototype */ ! 54: #include <string.h> /* memcpy prototype */ ! 55: #endif ! 56: ! 57: #define os_malloc malloc ! 58: #define rb_malloc malloc ! 59: #define os_free free ! 60: #define rb_free free ! 61: #define os_memcpy memcpy ! 62: #define rb_memcpy memcpy ! 63: ! 64: #else ! 65: ! 66: void (*rb_free)(void *); ! 67: void *(*rb_memcpy)(void *, const void *, size_t); ! 68: ! 69: #endif ! 70: /****************************************************************************/ ! 71: /* Returns 0 on success, non-zero on failure */ ! 72: /****************************************************************************/ ! 73: int RINGBUFCALL RingBufInit( RingBuf* rb, DWORD size ! 74: #ifndef RINGBUF_USE_STD_RTL ! 75: ,void *(os_malloc)(size_t) ! 76: ,void (os_free)(void *) ! 77: ,void *(os_memcpy)(void *, const void *, size_t) ! 78: #endif ! 79: ) ! 80: { ! 81: if((rb->pStart=(BYTE *)os_malloc(size))==NULL) ! 82: return(-1); ! 83: #ifndef RINGBUF_USE_STD_RTL ! 84: rb_free=os_free; ! 85: rb_memcpy=os_memcpy; ! 86: #endif ! 87: rb->pHead=rb->pTail=rb->pStart; ! 88: rb->pEnd=rb->pStart+size-1; ! 89: rb->size=size; ! 90: return(0); ! 91: } ! 92: ! 93: void RINGBUFCALL RingBufDispose( RingBuf* rb) ! 94: { ! 95: if(rb->pStart!=NULL) ! 96: os_free(rb->pStart); ! 97: memset(rb,0,sizeof(RingBuf)); ! 98: } ! 99: ! 100: DWORD RINGBUFCALL RingBufFull( RingBuf* rb ) ! 101: { ! 102: DWORD head,tail,retval; ! 103: ! 104: head = (DWORD) rb->pHead; ! 105: tail = (DWORD) rb->pTail; ! 106: ! 107: if(head >= tail) ! 108: retval = head - tail; ! 109: else ! 110: retval = rb->size - (tail - head); ! 111: ! 112: return(retval); ! 113: } ! 114: ! 115: DWORD RINGBUFCALL RingBufFree( RingBuf* rb ) ! 116: { ! 117: DWORD retval; ! 118: ! 119: retval = (rb->size - RingBufFull( rb ))-1; ! 120: ! 121: return(retval); ! 122: } ! 123: ! 124: DWORD RINGBUFCALL RingBufWrite( RingBuf* rb, BYTE* src, DWORD cnt ) ! 125: { ! 126: DWORD max, first, remain; ! 127: ! 128: if(rb->pStart==NULL) ! 129: return(0); ! 130: ! 131: /* allowed to write at pEnd */ ! 132: max = (((DWORD) rb->pEnd) - ((DWORD) rb->pHead)) + 1; ! 133: ! 134: /* ! 135: * we assume the caller has checked that there is enough room. For this reason ! 136: * we do not have to worry about head wrapping past the tail ! 137: */ ! 138: ! 139: if( max >= cnt ) { ! 140: first = cnt; ! 141: remain = 0; ! 142: } else { ! 143: first = max; ! 144: remain = cnt - first; ! 145: } ! 146: ! 147: rb_memcpy( rb->pHead, src, first ); ! 148: rb->pHead += first; ! 149: src += first; ! 150: ! 151: if(remain) { ! 152: ! 153: rb->pHead = rb->pStart; ! 154: rb_memcpy(rb->pHead, src, remain); ! 155: rb->pHead += remain; ! 156: } ! 157: ! 158: if(rb->pHead > rb->pEnd) ! 159: rb->pHead = rb->pStart; ! 160: ! 161: return(cnt); ! 162: } ! 163: ! 164: /* Pass NULL dst to just foward pointer (after Peek) */ ! 165: DWORD RINGBUFCALL RingBufRead( RingBuf* rb, BYTE* dst, DWORD cnt ) ! 166: { ! 167: DWORD max, first, remain, len; ! 168: ! 169: len = RingBufFull( rb ); ! 170: if( len == 0 ) ! 171: return(0); ! 172: ! 173: if( len < cnt ) ! 174: cnt = len; ! 175: ! 176: /* allowed to read at pEnd */ ! 177: max = (((DWORD) rb->pEnd) - ((DWORD) rb->pTail)) + 1; ! 178: ! 179: if( max >= cnt ) { ! 180: first = cnt; ! 181: remain = 0; ! 182: } else { ! 183: first = max; ! 184: remain = cnt - first; ! 185: } ! 186: ! 187: if(dst!=NULL) { ! 188: rb_memcpy( dst, rb->pTail, first ); ! 189: dst += first; ! 190: } ! 191: rb->pTail += first; ! 192: ! 193: if( remain ){ ! 194: ! 195: rb->pTail = rb->pStart; ! 196: if(dst!=NULL) ! 197: rb_memcpy( dst, rb->pTail, remain ); ! 198: rb->pTail += remain; ! 199: } ! 200: ! 201: if(rb->pTail > rb->pEnd) ! 202: rb->pTail = rb->pStart; ! 203: ! 204: return(cnt); ! 205: } ! 206: ! 207: DWORD RINGBUFCALL RingBufPeek( RingBuf* rb, BYTE* dst, DWORD cnt) ! 208: { ! 209: DWORD max, first, remain, len; ! 210: ! 211: len = RingBufFull( rb ); ! 212: if( len == 0 ) ! 213: return(0); ! 214: ! 215: if( len < cnt ) ! 216: cnt = len; ! 217: ! 218: /* allowed to read at pEnd */ ! 219: max = (((DWORD) rb->pEnd) - ((DWORD) rb->pTail)) + 1; ! 220: ! 221: if( max >= cnt ) { ! 222: first = cnt; ! 223: remain = 0; ! 224: } else { ! 225: first = max; ! 226: remain = cnt - first; ! 227: } ! 228: ! 229: rb_memcpy( dst, rb->pTail, first ); ! 230: dst += first; ! 231: ! 232: if(remain) { ! 233: rb_memcpy( dst, rb->pStart, remain ); ! 234: } ! 235: ! 236: return(cnt); ! 237: } ! 238: ! 239: /* Reset head and tail pointers */ ! 240: void RINGBUFCALL RingBufReInit(RingBuf* rb) ! 241: { ! 242: rb->pHead = rb->pTail = rb->pStart; ! 243: } ! 244: ! 245: /* End of RINGBUF.C */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.