blob: c5385f7cdf2b70f5ef1f5ccea193b49598bd4ffb [file] [log] [blame] [raw]
/*
* buf.c
*
* Copyright (c) 2000 Dug Song <dugsong@monkey.org>
*
* $Id: buf.c,v 1.7 2001/03/15 08:32:59 dugsong Exp $
*/
#include "config.h"
#include <sys/param.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <err.h>
#include "buf.h"
void
buf_init(buf_t buf, u_char *data, int len)
{
buf->base = data;
buf->end = buf->size = len;
buf->offset = 0;
}
buf_t
buf_new(int size)
{
buf_t buf;
if ((buf = malloc(sizeof(*buf))) == NULL)
return (NULL);
if ((buf->base = malloc(size)) == NULL) {
free(buf);
return (NULL);
}
buf->size = size;
buf->offset = 0;
buf->end = 0;
return (buf);
}
void
buf_free(buf_t buf)
{
if (buf->base != NULL) {
free(buf->base);
}
free(buf);
}
int
buf_seek(buf_t buf, int off, int whence)
{
if ((whence == SEEK_SET) && (off <= buf->size)) {
buf->offset = off;
}
else if ((whence == SEEK_CUR) && ((buf->offset + off) <= buf->size)) {
buf->offset += off;
}
else return (-1);
return (buf->offset);
}
int
buf_get(buf_t buf, void *dst, int len)
{
u_char *p;
int i;
p = dst;
if (buf_len(buf) < len) {
return (-1);
}
for (i = 0; i < len; i++)
p[i] = buf->base[buf->offset + i];
buf->offset += len;
return (len);
}
int
buf_put(buf_t buf, void *src, int len)
{
if (buf->offset + len > buf->size) {
return (-1);
}
memcpy(buf_ptr(buf), src, len);
buf->offset += len;
return (len);
}
int
buf_putf(buf_t buf, const char *fmt, ...)
{
va_list ap;
int i;
va_start(ap, fmt);
i = vsnprintf((char *)buf_ptr(buf), buf_len(buf), fmt, ap);
va_end(ap);
buf_skip(buf, i);
return (i);
}
void
buf_end(buf_t buf)
{
buf->end = buf->offset;
buf->offset = 0;
}
int
buf_index(buf_t buf, void *ptr, int len)
{
u_char *p, *q;
p = buf_ptr(buf);
q = buf->base + buf->end;
for (; q - p >= len; p++) {
if (memcmp(p, ptr, len) == 0)
return (p - buf_ptr(buf));
}
return (-1);
}
int
buf_rindex(buf_t buf, void *ptr, int len)
{
u_char *p, *q;
p = buf->base + buf->end - len;
q = buf_ptr(buf);
for (; p > q; p--) {
if (memcmp(p, ptr, len) == 0)
return (p - q);
}
return (-1);
}
int
buf_cmp(buf_t buf, void *ptr, int len)
{
if (buf_len(buf) < len)
return (-1);
return (memcmp(buf_ptr(buf), ptr, len));
}
buf_t
buf_tok(buf_t buf, void *sep, int len)
{
static struct buf *savebuf, tokbuf;
int off;
if (buf != NULL)
savebuf = buf;
if (sep == NULL && buf_len(savebuf) >= len) {
tokbuf.base = buf_ptr(savebuf);
tokbuf.offset = 0;
tokbuf.size = tokbuf.end = len;
buf_skip(savebuf, len);
}
else if ((off = buf_index(savebuf, sep, len)) != -1) {
tokbuf.base = buf_ptr(savebuf);
tokbuf.offset = 0;
tokbuf.size = tokbuf.end = off;
buf_skip(savebuf, off + len);
}
else if (buf_len(savebuf) > 0) {
tokbuf.base = buf_ptr(savebuf);
tokbuf.offset = 0;
tokbuf.size = tokbuf.end = buf_len(savebuf);
savebuf->offset = savebuf->end;
}
else return (NULL);
return (&tokbuf);
}
buf_t
buf_getbuf(buf_t buf, int offset, int len)
{
buf_t b;
if (buf->offset + offset + len > buf->end)
return (NULL);
buf_skip(buf, offset);
if ((b = buf_new(len)) != NULL) {
buf_put(b, buf_ptr(buf), len);
buf_end(b);
}
buf_skip(buf, len);
return (b);
}
buf_t
buf_getword(buf_t buf, void *sep, int len)
{
buf_t b;
int off;
if ((off = buf_index(buf, sep, len)) < 0)
return (NULL);
if ((b = buf_new(off)) != NULL) {
buf_put(b, buf_ptr(buf), off);
buf_end(b);
buf_skip(buf, off + len);
}
return (b);
}
char *
buf_strdup(buf_t buf)
{
char *p;
int i;
i = buf_len(buf);
if ((p = malloc(i + 1)) == NULL)
err(1, "malloc");
memcpy(p, buf_ptr(buf), i);
p[i] = '\0';
return (p);
}
int
buf_isascii(buf_t buf)
{
u_char *p, *q;
p = buf_ptr(buf);
q = buf->base + buf->end;
for (; p < q; p++)
if (!isascii(*p)) return (0);
return (1);
}