util-src/ringbuffer.c
author Kim Alvefur <zash@zash.se>
Thu, 04 Nov 2021 01:00:06 +0100
branch0.11
changeset 12093 76b4e3f12b53
parent 8738 856a40ec4a0a
child 10484 94cacf9fd0ae
permissions -rw-r--r--
mod_pep: Wipe pubsub service on user deletion Data is already wiped from storage, but this ensures everything is properly unsubscribed, possibly with notifications etc. Clears recipient cache as well, since it is no longer relevant.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
#include <stdlib.h>
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
#include <unistd.h>
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     4
#include <string.h>
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
#include <stdio.h>
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
#include <lua.h>
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
#include <lauxlib.h>
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
typedef struct {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    11
	size_t rpos; /* read position */
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    12
	size_t wpos; /* write position */
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    13
	size_t alen; /* allocated size */
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    14
	size_t blen; /* current content size */
7831
b4a08a514ebc util.ringbuffer: Allocate buffer itself as part of userdata (simpler, single allocation, no need for __gc)
Kim Alvefur <zash@zash.se>
parents: 7830
diff changeset
    15
	char buffer[];
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    16
} ringbuffer;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    17
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
    18
char readchar(ringbuffer *b) {
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    19
	b->blen--;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    20
	return b->buffer[(b->rpos++) % b->alen];
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    21
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    22
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
    23
void writechar(ringbuffer *b, char c) {
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    24
	b->blen++;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    25
	b->buffer[(b->wpos++) % b->alen] = c;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    26
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    27
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    28
/* make sure position counters stay within the allocation */
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
    29
void modpos(ringbuffer *b) {
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    30
	b->rpos = b->rpos % b->alen;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    31
	b->wpos = b->wpos % b->alen;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    32
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    33
7944
8067828e7e40 util.ringbuffer: Change types of length related variables to size_t [-Wsign-compare]
Kim Alvefur <zash@zash.se>
parents: 7892
diff changeset
    34
int find(ringbuffer *b, const char *s, size_t l) {
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    35
	size_t i, j;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    36
	int m;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    37
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    38
	if(b->rpos == b->wpos) { /* empty */
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    39
		return 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    40
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    41
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
    42
	/* look for a matching first byte */
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    43
	for(i = 0; i <= b->blen - l; i++) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    44
		if(b->buffer[(b->rpos + i) % b->alen] == *s) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    45
			m = 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    46
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
    47
			/* check if the following byte also match */
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    48
			for(j = 1; j < l; j++)
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    49
				if(b->buffer[(b->rpos + i + j) % b->alen] != s[j]) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    50
					m = 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    51
					break;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    52
				}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    53
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    54
			if(m) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    55
				return i + l;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    56
			}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    57
		}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    58
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    59
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    60
	return 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    61
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    62
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
    63
/*
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
    64
 * Find first position of a substring in buffer
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
    65
 * (buffer, string) -> number
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
    66
 */
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
    67
int rb_find(lua_State *L) {
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    68
	size_t l, m;
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
    69
	ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
    70
	const char *s = luaL_checklstring(L, 2, &l);
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    71
	m = find(b, s, l);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    72
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    73
	if(m > 0) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    74
		lua_pushinteger(L, m);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    75
		return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    76
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    77
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    78
	return 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    79
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    80
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
    81
/*
8547
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
    82
 * Move read position forward without returning the data
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
    83
 * (buffer, number) -> boolean
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
    84
 */
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
    85
int rb_discard(lua_State *L) {
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
    86
	ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
    87
	size_t r = luaL_checkinteger(L, 2);
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
    88
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
    89
	if(r > b->blen) {
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
    90
		lua_pushboolean(L, 0);
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
    91
		return 1;
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
    92
	}
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
    93
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
    94
	b->blen -= r;
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
    95
	b->rpos += r;
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
    96
	modpos(b);
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
    97
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
    98
	lua_pushboolean(L, 1);
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
    99
	return 1;
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
   100
}
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
   101
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
   102
/*
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   103
 * Read bytes from buffer
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   104
 * (buffer, number, boolean?) -> string
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   105
 */
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   106
int rb_read(lua_State *L) {
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   107
	ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
7944
8067828e7e40 util.ringbuffer: Change types of length related variables to size_t [-Wsign-compare]
Kim Alvefur <zash@zash.se>
parents: 7892
diff changeset
   108
	size_t r = luaL_checkinteger(L, 2);
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   109
	int peek = lua_toboolean(L, 3);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   110
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   111
	if(r > b->blen) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   112
		lua_pushnil(L);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   113
		return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   114
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   115
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   116
	if((b->rpos + r) > b->alen) {
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   117
		/* Substring wraps around to the beginning of the buffer */
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   118
		lua_pushlstring(L, &b->buffer[b->rpos], b->alen - b->rpos);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   119
		lua_pushlstring(L, b->buffer, r - (b->alen - b->rpos));
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   120
		lua_concat(L, 2);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   121
	} else {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   122
		lua_pushlstring(L, &b->buffer[b->rpos], r);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   123
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   124
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   125
	if(!peek) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   126
		b->blen -= r;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   127
		b->rpos += r;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   128
		modpos(b);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   129
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   130
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   131
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   132
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   133
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   134
/*
8738
856a40ec4a0a util.ringbuffer: Fix typo in comment [codespell]
Kim Alvefur <zash@zash.se>
parents: 8547
diff changeset
   135
 * Read buffer until first occurrence of a substring
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   136
 * (buffer, string) -> string
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   137
 */
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   138
int rb_readuntil(lua_State *L) {
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   139
	size_t l, m;
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   140
	ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   141
	const char *s = luaL_checklstring(L, 2, &l);
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   142
	m = find(b, s, l);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   143
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   144
	if(m > 0) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   145
		lua_settop(L, 1);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   146
		lua_pushinteger(L, m);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   147
		return rb_read(L);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   148
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   149
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   150
	return 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   151
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   152
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   153
/*
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   154
 * Write bytes into the buffer
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   155
 * (buffer, string) -> integer
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   156
 */
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   157
int rb_write(lua_State *L) {
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   158
	size_t l, w = 0;
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   159
	ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   160
	const char *s = luaL_checklstring(L, 2, &l);
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   161
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   162
	/* Does `l` bytes fit? */
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   163
	if((l + b->blen) > b->alen) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   164
		lua_pushnil(L);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   165
		return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   166
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   167
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   168
	while(l-- > 0) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   169
		writechar(b, *s++);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   170
		w++;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   171
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   172
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   173
	modpos(b);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   174
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   175
	lua_pushinteger(L, w);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   176
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   177
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   178
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   179
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   180
int rb_tostring(lua_State *L) {
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   181
	ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
7891
74187ee6ed55 util.ringbuffer: Remove address of buffer itself from __tostring since is now in the same struct
Kim Alvefur <zash@zash.se>
parents: 7838
diff changeset
   182
	lua_pushfstring(L, "ringbuffer: %p %d/%d", b, b->blen, b->alen);
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   183
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   184
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   185
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   186
int rb_length(lua_State *L) {
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   187
	ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   188
	lua_pushinteger(L, b->blen);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   189
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   190
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   191
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   192
int rb_size(lua_State *L) {
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   193
	ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   194
	lua_pushinteger(L, b->alen);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   195
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   196
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   197
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   198
int rb_free(lua_State *L) {
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   199
	ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   200
	lua_pushinteger(L, b->alen - b->blen);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   201
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   202
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   203
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   204
int rb_new(lua_State *L) {
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   205
	size_t size = luaL_optinteger(L, 1, sysconf(_SC_PAGESIZE));
7831
b4a08a514ebc util.ringbuffer: Allocate buffer itself as part of userdata (simpler, single allocation, no need for __gc)
Kim Alvefur <zash@zash.se>
parents: 7830
diff changeset
   206
	ringbuffer *b = lua_newuserdata(L, sizeof(ringbuffer) + size);
b4a08a514ebc util.ringbuffer: Allocate buffer itself as part of userdata (simpler, single allocation, no need for __gc)
Kim Alvefur <zash@zash.se>
parents: 7830
diff changeset
   207
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   208
	b->rpos = 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   209
	b->wpos = 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   210
	b->alen = size;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   211
	b->blen = 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   212
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   213
	luaL_getmetatable(L, "ringbuffer_mt");
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   214
	lua_setmetatable(L, -2);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   215
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   216
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   217
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   218
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   219
int luaopen_util_ringbuffer(lua_State *L) {
7821
54669df178c2 util-src: Make C modules assert that the Lua runtime matches what it was compiled for
Kim Alvefur <zash@zash.se>
parents: 7120
diff changeset
   220
#if (LUA_VERSION_NUM > 501)
54669df178c2 util-src: Make C modules assert that the Lua runtime matches what it was compiled for
Kim Alvefur <zash@zash.se>
parents: 7120
diff changeset
   221
	luaL_checkversion(L);
54669df178c2 util-src: Make C modules assert that the Lua runtime matches what it was compiled for
Kim Alvefur <zash@zash.se>
parents: 7120
diff changeset
   222
#endif
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   223
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   224
	if(luaL_newmetatable(L, "ringbuffer_mt")) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   225
		lua_pushcfunction(L, rb_tostring);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   226
		lua_setfield(L, -2, "__tostring");
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   227
		lua_pushcfunction(L, rb_length);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   228
		lua_setfield(L, -2, "__len");
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   229
7972
1c6a07606309 util-src: Specify size of various tables to be allocated
Kim Alvefur <zash@zash.se>
parents: 7944
diff changeset
   230
		lua_createtable(L, 0, 7); /* __index */
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   231
		{
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   232
			lua_pushcfunction(L, rb_find);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   233
			lua_setfield(L, -2, "find");
8547
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
   234
			lua_pushcfunction(L, rb_discard);
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
   235
			lua_setfield(L, -2, "discard");
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   236
			lua_pushcfunction(L, rb_read);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   237
			lua_setfield(L, -2, "read");
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   238
			lua_pushcfunction(L, rb_readuntil);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   239
			lua_setfield(L, -2, "readuntil");
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   240
			lua_pushcfunction(L, rb_write);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   241
			lua_setfield(L, -2, "write");
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   242
			lua_pushcfunction(L, rb_size);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   243
			lua_setfield(L, -2, "size");
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   244
			lua_pushcfunction(L, rb_length);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   245
			lua_setfield(L, -2, "length");
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   246
			lua_pushcfunction(L, rb_free);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   247
			lua_setfield(L, -2, "free");
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   248
		}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   249
		lua_setfield(L, -2, "__index");
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   250
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   251
7972
1c6a07606309 util-src: Specify size of various tables to be allocated
Kim Alvefur <zash@zash.se>
parents: 7944
diff changeset
   252
	lua_createtable(L, 0, 1);
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   253
	lua_pushcfunction(L, rb_new);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   254
	lua_setfield(L, -2, "new");
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   255
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   256
}