/*
 * Copyright (c) 2004  Brian S. Dean <bsd@bdmicro.com>
 * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY BRIAN S. DEAN ``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 BRIAN S. DEAN 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.
 * 
 */

#include <inttypes.h>

#include "ringbuf.h"


#if 0
uint8_t ringbuf_find(RINGBUF * r, char ch)
{
  uint8_t count;
  uint8_t * p;

  if (r->bufcnt == 0) {
    return 0;
  }

  count = 0;
  p = r->out;
  while (p != r->in) {
    if (*p == ch)
      return ch;
    count++;
    p++;
    if (count >= r->bufcnt)
      return 0;
    if (p > r->buf + r->buflen) {
      p = r->buf;
    }
  }

  return 0;
}
#endif






uint8_t ringbuf8_get(RINGBUF8 * r)
{
  uint8_t c;

  if (r->bufcnt == 0) {
    return 0;
  }

  c = *r->out++;
  r->bufcnt--;

  if (r->out >= r->buf + r->buflen) {
    /* wrap around to beginning */
    r->out = r->buf;
  }

  return c;
}


void ringbuf8_init(RINGBUF8 * r, 
                          uint8_t * buf, uint16_t buflen)
{
  r->buflen = buflen;
  r->bufcnt = 0;
  r->in     = buf;
  r->out    = buf;
  r->buf    = buf;
}


uint8_t ringbuf8_look(RINGBUF8 * r)
{
  if (r->bufcnt == 0) {
    return 0;
  }

  return *r->out;
}


void ringbuf8_put(RINGBUF8 * r, uint8_t c)
{
  if (r->bufcnt >= r->buflen) {
    return;
  }

  *r->in++ = c;
  r->bufcnt++;

  if (r->in >= r->buf + r->buflen) {
    /* wrap around to beginning */
    r->in = r->buf;
  }
}










uint16_t ringbuf16_get(RINGBUF16 * r)
{
  uint16_t c;

  if (r->bufcnt == 0) {
    return 0;
  }

  c = *r->out++;
  r->bufcnt--;

  if (r->out >= r->buf + r->buflen) {
    /* wrap around to beginning */
    r->out = r->buf;
  }

  return c;
}


void ringbuf16_init(RINGBUF16 * r, 
                          uint16_t * buf, uint16_t buflen)
{
  r->buflen = buflen;
  r->bufcnt = 0;
  r->in     = buf;
  r->out    = buf;
  r->buf    = buf;
}


uint16_t ringbuf16_look(RINGBUF16 * r)
{
  if (r->bufcnt == 0) {
    return 0;
  }

  return *r->out;
}


void ringbuf16_put(RINGBUF16 * r, uint16_t c)
{
  if (r->bufcnt >= r->buflen) {
    return;
  }

  *r->in++ = c;
  r->bufcnt++;

  if (r->in >= r->buf + r->buflen) {
    /* wrap around to beginning */
    r->in = r->buf;
  }
}


