/* cirbuf.cpp
 *
 * Copyright (C) DFS Deutsche Flugsicherung (2004, 2005). 
 * All Rights Reserved.
 *
 * Circular buffers
 *
 * Version 0.2
 */

#include <string.h>
#include <strings.h>

#include "oss.h"
#include "cirbuf.h"
#include "intercomd.h"

CIRBUF::CIRBUF()
{
  bzero(buf, CIRBUFSIZE);
  in = out = len = 0;
}

void CIRBUF::init()
{
  bzero(buf, CIRBUFSIZE);
  in = out = len = 0;
}

int CIRBUF::push(char *from, int size)
{
  memcpy(buf + in, from, size);
  in += size;
  if (in >= CIRBUFSIZE) {
    in -= CIRBUFSIZE;
  }
  len += size;
  if (len > CIRBUFSIZE) {
    int oversize = (((len - CIRBUFSIZE) / FRAGSIZE)) * FRAGSIZE;
    if (oversize < len - CIRBUFSIZE) {
      oversize += FRAGSIZE;
    }
    // delete oldest if overrun
    out += oversize;
    if (out >= CIRBUFSIZE) {
      out -= CIRBUFSIZE;
    }
    len -= oversize;
    return -oversize;
  } else {
    return OKAY;
  }
}

int CIRBUF::pop(char *to, int size)
{
  if (len < size) {
    // play out silence if underrun
    bzero(to, size);
    return ERROR;
  }
  memcpy(to, buf + out, size);
  out += size;
  if (out >= CIRBUFSIZE) {
    out -= CIRBUFSIZE;
  }
  len -= size;
  return OKAY;
}
