2011년 6월 23일 목요일

General Purpose FIFO for C/C++ Language

/* FIFO

 Copyright 2011 Hoyoung Yi.

 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program 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 Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public License
 along with this program; if not, please visit www.gnu.org.
*/


#ifndef __FIFO_H__
#define __FIFO_H__

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
    int length;
    char *buffer;
int head;
int tail;
} fifo_t;

fifo_t *fifo_create(int bytes);
void fifo_delete(fifo_t *p);
int fifo_full(fifo_t *p);
int fifo_empty(fifo_t *p);
int fifo_filled_bytes(fifo_t *p);
int fifo_fill(fifo_t *q, const void *p, int bytes);
int fifo_copy(void *q, int bytes, fifo_t *p);
int fifo_bring(void *q, int bytes, fifo_t *p);

#ifdef __cplusplus
}
#endif

#endif /* __FIFO_H__ */


/* FIFO

 Copyright 2011 Hoyoung Yi.

 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program 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 Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public License
 along with this program; if not, please visit www.gnu.org.
*/

#include
#include
#include
#include "fifo.h"

fifo_t *fifo_create(int bytes)
{
fifo_t *p;

p = (fifo_t *)malloc(sizeof(*p)+bytes);
assert(p);
if (p == NULL) goto __error_return__;
p->length = bytes;
p->buffer = (char *)p+sizeof(*p);
p->head = 1;
p->tail = 0;
__error_return__:;
return p;
}

void fifo_delete(fifo_t *p)
{
assert(p);
free(p);
}

int fifo_full(fifo_t *p)
{
assert(p);
return (p->head == p->tail);
}

int fifo_empty(fifo_t *p)
{
assert(p);
return (p->head == ((p->tail+1)%p->length));
}

int fifo_fill(fifo_t *q, const void *p, int bytes)
{
int count;
const char *ptr = (const char *)p;

for (count = 0; count < bytes; count++) {
if (q->head == q->tail) break; /* fifo is full ? */
q->buffer[q->head] = *ptr++;
q->head = (q->head+1)%q->length;
}
return count;
}

int fifo_copy(void *q, int bytes, fifo_t *p)
{
int count, tail;

char *ptr = (char *)q;
tail = p->tail;
for (count = 0; count < bytes; count++) {
if (p->head == ((tail+1)%p->length)) break; /* fifo is empty ? */
tail = (tail+1)%p->length;
*ptr++ = p->buffer[tail];
}
return count;
}

int fifo_bring(void *q, int bytes, fifo_t *p)
{
int count;
char *ptr = (char *)q;
for (count = 0; count < bytes; count++) {
if (p->head == ((p->tail+1)%p->length)) break; /* fifo is empty ? */
p->tail = (p->tail+1)%p->length;
*ptr++ = p->buffer[p->tail];
}
return count;
}

int fifo_filled_bytes(fifo_t *p)
{
if (p->head > p->tail) return (p->head-p->tail-1);
if (p->head == p->tail) return p->length;
return ((p->head+p->length)-p->tail-1);
}

댓글 없음:

댓글 쓰기