summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pttbbs/common/sys/vbuf.c101
-rw-r--r--pttbbs/include/cmsys.h18
-rw-r--r--pttbbs/include/vtuikit.h4
-rw-r--r--pttbbs/mbbsd/vtuikit.c16
4 files changed, 115 insertions, 24 deletions
diff --git a/pttbbs/common/sys/vbuf.c b/pttbbs/common/sys/vbuf.c
index d141ce98..e4c2f30a 100644
--- a/pttbbs/common/sys/vbuf.c
+++ b/pttbbs/common/sys/vbuf.c
@@ -67,6 +67,14 @@ vbuf_space(VBUF *v)
return v->capacity - vbuf_size(v);
}
+VBUFPROTO int
+vbuf_peek(VBUF *v)
+{
+ if (vbuf_is_empty(v))
+ return EOF;
+ return (unsigned char)(*v->tail);
+}
+
#endif
VBUFPROTO void
@@ -110,11 +118,18 @@ vbuf_clear(VBUF *v)
}
VBUFPROTO int
-vbuf_peek(VBUF *v)
+vbuf_peekat(VBUF *v, int i)
{
- if (vbuf_is_empty(v))
- return -1;
- return (unsigned char)(*v->tail);
+ const char *s = v->tail + i;
+ if (vbuf_is_empty(v) || i >= vbuf_capacity(v))
+ return EOF;
+ if (s < v->head)
+ return (unsigned char)*s;
+ if (s >= v->buf_end)
+ s -= v->buf_end - v->buf;
+ if (s < v->head)
+ return (unsigned char)*s;
+ return EOF;
}
VBUFPROTO int
@@ -127,7 +142,7 @@ vbuf_pop(VBUF *v)
}
VBUFPROTO int
-vbuf_push(VBUF *v, char c)
+vbuf_add(VBUF *v, char c)
{
if (vbuf_is_full(v))
return 0;
@@ -143,7 +158,7 @@ vbuf_strchr(VBUF *v, char c)
const char *s = v->tail, *d = v->head;
if (vbuf_is_empty(v))
- return -1;
+ return EOF;
if (d < s)
d = v->buf_end;
@@ -153,7 +168,7 @@ vbuf_strchr(VBUF *v, char c)
return s - v->tail -1;
if (v->head > v->tail)
- return -1;
+ return EOF;
s = v->buf; d = v->head;
@@ -161,17 +176,18 @@ vbuf_strchr(VBUF *v, char c)
if (*s++ == c)
return (v->buf_end - v->tail) + s - v->buf -1;
- return -1;
+ return EOF;
}
#define VBUF_TAIL_SZ(v) ((v->head >= v->tail) ? v->head - v->tail : v->buf_end - v->tail)
-#define VBUF_HEAD_SZ(v) ((v->head >= v->tail) ? v->buf_end - v->head : v->tail - v->head)
+#define VBUF_HEAD_SZ(v) ((v->tail > v->head) ? v->tail - v->head : v->buf_end - v->head)
// get data from vbuf
VBUFPROTO int
-vbuf_get(VBUF *v, char *s, size_t sz)
+vbuf_getblk(VBUF *v, void *p, size_t sz)
{
size_t rw, i;
+ char *s = p;
if (!sz || vbuf_size(v) < sz)
return 0;
@@ -179,6 +195,7 @@ vbuf_get(VBUF *v, char *s, size_t sz)
for (i = 0; sz && i < 2; i++)
{
rw = VBUF_TAIL_SZ(v);
+ assert(rw >= 0 && rw <= v->capacity+1);
if (rw > sz) rw = sz;
memcpy(s, v->tail, rw);
v->tail += rw; s += rw; sz -= rw;
@@ -191,9 +208,10 @@ vbuf_get(VBUF *v, char *s, size_t sz)
// put data into vbuf
VBUFPROTO int
-vbuf_put(VBUF *v, const char *s, size_t sz)
+vbuf_putblk(VBUF *v, const void *p, size_t sz)
{
size_t rw, i;
+ const char *s = p;
if (!sz || vbuf_space(v) < sz)
return 0;
@@ -201,6 +219,7 @@ vbuf_put(VBUF *v, const char *s, size_t sz)
for (i = 0; sz && i < 2; i++)
{
rw = VBUF_HEAD_SZ(v);
+ assert(rw >= 0 && rw <= v->capacity+1);
if (rw > sz) rw = sz;
memcpy(v->head, s, rw);
v->head += rw; s += rw; sz -= rw;
@@ -211,6 +230,35 @@ vbuf_put(VBUF *v, const char *s, size_t sz)
return 1;
}
+char *
+vbuf_getstr (VBUF *v, char *s, size_t sz)
+{
+ char *sbase = s;
+ assert(sz > 0);
+ if (vbuf_is_empty(v))
+ return NULL;
+
+ while (sz-- > 0 && !vbuf_is_empty(v))
+ {
+ if ('\0' == (*s++ = vbuf_pop(v)))
+ return sbase;
+ }
+
+ // need to pad NUL.
+ s[ sz == 0 ? 0 : -1] = '\0';
+ return sbase;
+}
+
+int
+vbuf_putstr (VBUF *v, char *s)
+{
+ int len = strlen(s) + 1;
+ if (vbuf_space(v) < len)
+ return 0;
+ vbuf_putblk(v, s, len);
+ return 1;
+}
+
/* read/write callbacks */
static ssize_t
@@ -326,7 +374,7 @@ vbuf_general_write(VBUF *v, ssize_t sz, void *ctx,
if (rw < 0)
return copied > 0 ? copied : -1;
- assert(rw < VBUF_HEAD_SZ(v));
+ assert(rw <= sz);
v->tail += rw; sz -= rw;
if (v->tail >= v->buf_end)
v->tail -= v->buf_end - v->buf;
@@ -371,7 +419,7 @@ vbuf_general_read(VBUF *v, ssize_t sz, void *ctx,
if (rw < 0)
return copied > 0 ? copied : -1;
- assert(rw < VBUF_HEAD_SZ(v));
+ assert(rw <= sz);
v->head += rw; sz -= rw;
if (v->head >= v->buf_end)
v->head -= v->buf_end - v->buf;
@@ -402,13 +450,13 @@ int main()
vbuf_new(v, 50);
for (i = 0; i < 10; i++)
{
- vbuf_put(v, "blah", sizeof("blah"));
+ vbuf_putblk(v, "blah", sizeof("blah"));
vbuf_rpt(v);
}
for (i = 0; i < 10; i++)
{
char buf[64] = "";
- vbuf_get(v, buf, 5);
+ vbuf_getblk(v, buf, 5);
printf("[got: %s] ", buf);
vbuf_rpt(v);
}
@@ -416,8 +464,8 @@ int main()
for (i = 0; i < 10; i++)
{
char buf[64] = "";
- vbuf_put(v, "blah", sizeof("blah"));
- vbuf_get(v, buf, 5);
+ vbuf_putblk(v, "blah", sizeof("blah"));
+ vbuf_getblk(v, buf, 5);
printf("[got: %s] ", buf);
vbuf_rpt(v);
}
@@ -429,11 +477,28 @@ int main()
printf("index of 't' = %d\n", vbuf_strchr(v, 't'));
vbuf_rpt(v);
printf("give me 4 chars: "); fflush(stdout);
- vbuf_read(v, 0, 5);
+ vbuf_read(v, 0, 4);
vbuf_rpt(v);
printf("\n flushing vbuf: ["); fflush(stdout);
vbuf_write(v, 1, VBUF_RWSZ_ALL);
printf("]\n");
+ vbuf_putblk(v, "peek test\n", sizeof("peek test\n"));
+ while (EOF != (i = vbuf_pop(v)))
+ putchar(i);
+
+ vbuf_clear(v);
+ vbuf_putstr(v, "string test(1)");
+ vbuf_putstr(v, "string test(2)");
+ vbuf_putstr(v, "string test(3)");
+
+ for (i = 0; i < 4; i++)
+ {
+ char xbuf[256];
+ char *s = vbuf_getstr(v, xbuf, sizeof(xbuf));
+ printf("put/getstr(%d): %s\n", i+1,
+ s ? s : "(NULL)");
+ }
+
getchar();
return 0;
}
diff --git a/pttbbs/include/cmsys.h b/pttbbs/include/cmsys.h
index 04cde60a..4bc239f1 100644
--- a/pttbbs/include/cmsys.h
+++ b/pttbbs/include/cmsys.h
@@ -190,11 +190,13 @@ typedef struct VBUF {
size_t capacity;
} VBUF;
+// speedy macros
#define vbuf_is_empty(v) ((v)->head == (v)->tail)
#define vbuf_is_full(v) (!vbuf_space(v))
#define vbuf_capacity(v) ((v)->capacity)
#define vbuf_size(v) ((size_t)((v)->head >= (v)->tail ? (v)->head - (v)->tail : (v)->buf_end - (v)->tail + (v)->head - (v)->buf))
#define vbuf_space(v) ((size_t)((v)->capacity - vbuf_size(v)))
+#define vbuf_peek(v) (vbuf_is_empty(v) ? EOF : (unsigned char)(*v->tail))
// buffer management
extern void vbuf_new (VBUF *v, size_t szbuf);
extern void vbuf_delete(VBUF *v);
@@ -202,13 +204,17 @@ extern void vbuf_attach(VBUF *v, char *buf, size_t szbuf);
extern void vbuf_detach(VBUF *v);
extern void vbuf_clear (VBUF *v);
// data accessing
-extern int vbuf_get (VBUF *v, char *s, size_t sz); // get data from vbuf, return true/false
-extern int vbuf_put (VBUF *v, const char *s, size_t sz); // put data into vbuf, return true/false
-extern int vbuf_peek (VBUF *v); // peek one byte from vbuf, -1 if buffer empty
-extern int vbuf_pop (VBUF *v); // pop one byte from vbuf, -1 if buffer empty
-extern int vbuf_push (VBUF *v, char c); // push one byte into vbuf, return true/false
+extern int vbuf_getblk(VBUF *v, void *p, size_t sz); // get data from vbuf, return true/false
+extern int vbuf_putblk(VBUF *v, const void *p, size_t sz); // put data into vbuf, return true/false
+extern int vbuf_peekat(VBUF *v, int i); // peek at given index, EOF(-1) if invalid index
+extern int vbuf_pop (VBUF *v); // pop one byte from vbuf, EOF(-1) if buffer empty
+extern int vbuf_add (VBUF *v, char c); // append one byte into vbuf, return true/false
// search and test
-extern int vbuf_strchr(VBUF *v, char c); // index of first location of c, otherwise -1
+extern int vbuf_strchr(VBUF *v, char c); // index of first location of c, otherwise EOF(-1)
+
+// vector of C-style NULL terminated strings
+extern char* vbuf_getstr(VBUF *v, char *s, size_t sz); // get a string from vbuf, return NULL if empty
+extern int vbuf_putstr(VBUF *v, char *s); // put a string to vbuf (with NUL), return true/false
#define VBUF_RWSZ_ALL (0) // r/w until buffer full
#define VBUF_RWSZ_MIN (-1) // r/w for minimal try (do not block for more)
diff --git a/pttbbs/include/vtuikit.h b/pttbbs/include/vtuikit.h
index 63694bc3..2c6c8b22 100644
--- a/pttbbs/include/vtuikit.h
+++ b/pttbbs/include/vtuikit.h
@@ -112,6 +112,10 @@ void prints(const char *fmt, ...) GCC_CHECK_FORMAT(1,2);
void mvprints(int y, int x, const char *fmt, ...) GCC_CHECK_FORMAT(3,4);
void mvouts(int y, int x, const char *str);
+// vbuf rendering
+void outs_vbuf (VBUF *v);
+void outns_vbuf(VBUF *v, int n);
+
// input history
int InputHistoryAdd (const char *s);
int InputHistoryExists (const char *s);
diff --git a/pttbbs/mbbsd/vtuikit.c b/pttbbs/mbbsd/vtuikit.c
index 7e14fdcb..6847d82e 100644
--- a/pttbbs/mbbsd/vtuikit.c
+++ b/pttbbs/mbbsd/vtuikit.c
@@ -184,6 +184,22 @@ mvouts(int y, int x, const char *str)
outs(str);
}
+void
+outs_vbuf(VBUF *v)
+{
+ int c;
+ while (EOF != (c = vbuf_pop(v)))
+ outc(c);
+}
+
+void
+outns_vbuf(VBUF *v, int n)
+{
+ int c;
+ while (EOF != (c = vbuf_pop(v)) && n-- > 0)
+ outc(c);
+}
+
/**
* vfill(n, flags, s): 印出並填滿 n 個字元的空間
*