1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
/* $Id: cbuf.C,v 1.1 1998/12/30 19:45:06 dm Exp $ */
/*
*
* Copyright (C) 1998 David Mazieres (dm@uun.org)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2, 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
*/
#include "cbuf.h"
#include "stllike.h"
void
cbuf::resize (size_t n)
{
int nend = size ();
char *nbuf = (char *) xmalloc (n);
copyout (nbuf, nend);
xfree (buf);
buf = nbuf;
buflen = n;
empty = nend;
start = 0;
end = nend;
}
const iovec *
cbuf::iniov ()
{
inv[0].iov_base = buf + end;
if (empty || start < end) {
inv[0].iov_len = buflen - end;
inv[1].iov_base = buf;
inv[1].iov_len = start;
}
else {
inv[0].iov_len = start - end;
inv[1].iov_base = NULL;
inv[1].iov_len = 0;
}
return inv;
}
void
cbuf::addbytes (size_t n)
{
if (n) {
assert (n <= space ());
empty = false;
end += n;
if (end >= buflen)
end -= buflen;
}
}
int
cbuf::find (char c)
{
if (empty)
return -1;
if (start < end) {
if (char *p = (char *) memchr (buf + start, c, end - start))
return p - (buf + start);
return -1;
}
if (char *p = (char *) memchr (buf + start, c, buflen - start))
return p - (buf + start);
if (char *p = (char *) memchr (buf, c, end))
return p - buf + buflen - start;
return -1;
};
const iovec *
cbuf::outiov ()
{
outv[0].iov_base = buf + start;
if (start >= end && !empty) {
outv[0].iov_len = buflen - start;
outv[1].iov_base = buf;
outv[1].iov_len = end;
}
else {
outv[0].iov_len = end - start;
outv[1].iov_base = NULL;
outv[1].iov_len = 0;
}
return outv;
}
void
cbuf::copyout (void *_dst, size_t len)
{
char *dst = static_cast<char *> (_dst);
assert (len <= size ());
if (empty || start < end)
memcpy (dst, buf + start, min (len, end - start));
else {
size_t n = min (len, buflen - start);
memcpy (dst, buf + start, n);
if (len > n)
memcpy (dst + n, buf, len - n);
}
rembytes (len);
}
|