Annotation of sbbs/sbbs3/ringbuf.c, revision 1.1.1.1

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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.