HEX
Server: Apache
System: Linux s198.coreserver.jp 5.15.0-151-generic #161-Ubuntu SMP Tue Jul 22 14:25:40 UTC 2025 x86_64
User: nagasaki (10062)
PHP: 7.1.33
Disabled: NONE
Upload Files
File: //usr/local/qlibs/buffer.c
#include <unistd.h>
#include "buffer.h"
#include "str.h"
#include "byte.h"
#include "error.h"

/**
	@file buffer.c
	@author djb
	@brief input/output routines
*/

void buffer_init(buffer *s,ssize_t (*op)(),int fd,char *buf,size_t len)
{
  s->x = buf;
  s->fd = fd;
  s->op = op;
  s->p = 0;
  s->n = len;
}

ssize_t buffer_0_read(int fd,char *buf,size_t len) 
{
  if (buffer_flush(buffer_1) == -1) return -1;
  return read(fd,buf,len);
}

char buffer_0_space[BUFFER_INSIZE];
static buffer it0 = BUFFER_INIT(buffer_0_read,0,buffer_0_space,sizeof(buffer_0_space));
buffer *buffer_0 = &it0;

char buffer_1_space[BUFFER_OUTSIZE];
static buffer it1 = BUFFER_INIT(write,1,buffer_1_space,sizeof(buffer_1_space));
buffer *buffer_1 = &it1;

char buffer_2_space[BUFFER_OUTSIZE];
static buffer it2 = BUFFER_INIT(write,2,buffer_2_space,sizeof(buffer_2_space));
buffer *buffer_2 = &it2;

char buffer_0_small[BUFFER_SMALL];
static buffer is0 = BUFFER_INIT(buffer_0_read,0,buffer_0_small,sizeof(buffer_0_small));
buffer *buffer_0small = &is0;

char buffer_1_small[BUFFER_SMALL];
static buffer is1 = BUFFER_INIT(write,1,buffer_1_small,sizeof(buffer_1_small));
buffer *buffer_1small = &is1;

char buffer_2_small[BUFFER_SMALL];
static buffer is2 = BUFFER_INIT(write,2,buffer_2_small,sizeof(buffer_2_small));
buffer *buffer_2small = &is2;

ssize_t buffer_unixread(int fd,char *buf,size_t len)
{
  return read(fd,buf,len);
}

ssize_t buffer_unixwrite(int fd,char *buf,size_t len)
{
  return write(fd,buf,len);
}

int buffer_copy(buffer *bout,buffer *bin)
{
  int n;
  char *x;

  for (;;) {
    n = buffer_feed(bin);
    if (n < 0) return -2;
    if (!n) return 0;
    x = buffer_PEEK(bin);
    if (buffer_put(bout,x,n) == -1) return -3;
    buffer_SEEK(bin,n);
  }
}

static int oneread(ssize_t (*op)(),int fd,char *buf,size_t len) 
{
  int r;

  for (;;) {
    r = op(fd,buf,len);
    if (r == -1) if (errno == EINTR) continue;
    return r;
  }
}

static int getthis(buffer *s,char *buf,size_t len) 
{
  if (len > s->p) len = s->p;
  s->p -= len;
  byte_copy(buf,len,s->x + s->n);
  s->n += len;
  return len;
}

int buffer_feed(buffer *s) 
{
  int r;

  if (s->p) return s->p;
  r = oneread(s->op,s->fd,s->x,s->n);
  if (r <= 0) return r;
  s->p = r;
  s->n -= r;
  if (s->n > 0) byte_copyr(s->x + s->n,r,s->x);
  return r;
}

int buffer_bget(buffer *s,char *buf,size_t len)
{
  int r;

  if (s->p > 0) return getthis(s,buf,len);
  if (s->n <= len) return oneread(s->op,s->fd,buf,s->n);
  r = buffer_feed(s); 
	if (r <= 0) return r;
  return getthis(s,buf,len);
}

int buffer_get(buffer *s,char *buf,size_t len) 
{
  int r;

  if (s->p > 0) return getthis(s,buf,len);
  if (s->n <= len) return oneread(s->op,s->fd,buf,len);
  r = buffer_feed(s); 
  if (r <= 0) return r;
  return getthis(s,buf,len);
}

char *buffer_peek(buffer *s) 
{
  return s->x + s->n;
}

void buffer_seek(buffer *s,size_t len) 
{
  s->n += len;
  s->p -= len;
}

static int allwrite(ssize_t (*op)(),int fd,const char *buf,size_t len)
{
  int w;

  while (len) {
    w = op(fd,buf,len);
    if (w == -1) {
      if (errno == EINTR) continue;
      return -1; /* note that some data may have been written */
    }
    if (w == 0) /* luser's fault */
    ;
    buf += w;
    len -= w;
  }
  return 0;
}

int buffer_flush(buffer *s)
{
  int p;

  p = s->p;
  if (!p) return 0;
  s->p = 0;
  return allwrite(s->op,s->fd,s->x,p);
}

int buffer_putalign(buffer *s,const char *buf,size_t len)
{
  unsigned int n;

  while (len > (n = s->n - s->p)) {
    byte_copy(s->x + s->p,n,buf); s->p += n; buf += n; len -= n;
    if (buffer_flush(s) == -1) return -1;
  }
  /* now len <= s->n - s->p */
  byte_copy(s->x + s->p,len,buf);
  s->p += len;
  return 0;
}

int buffer_put(buffer *s,const char *buf,size_t len)
{
  unsigned int n;

  n = s->n;
  if (len > n - s->p) {
    if (buffer_flush(s) == -1) return -1;
    /* now s->p == 0 */
    if (n < BUFFER_OUTSIZE) n = BUFFER_OUTSIZE;
    while (len > s->n) {
      if (n > len) n = len;
      if (allwrite(s->op,s->fd,buf,n) == -1) return -1;
      buf += n;
      len -= n;
    }
  }
  /* now len <= s->n - s->p */
  byte_copy(s->x + s->p,len,buf);
  s->p += len;
  return 0;
}

int buffer_putflush(buffer *s,const char *buf,size_t len)
{
  if (buffer_flush(s) == -1) return -1;
  return allwrite(s->op,s->fd,buf,len);
}

int buffer_putsalign(buffer *s,const char *buf)
{
  return buffer_putalign(s,buf,str_len(buf));
}

int buffer_puts(buffer *s,const char *buf)
{
  return buffer_put(s,buf,str_len(buf));
}

int buffer_putsflush(buffer *s,const char *buf)
{
  return buffer_putflush(s,buf,str_len(buf));
}