util-src/ringbuffer.c
author Matthew Wild <mwild1@gmail.com>
Wed, 27 Mar 2024 15:35:15 +0000
branch0.12
changeset 13469 54a936345aaa
parent 10957 c3b3ac63f4c3
child 12579 1f6f05a98fcd
permissions -rw-r--r--
prosodyctl check: Warn about invalid domain names in the config file This ensures that domain names of virtual hosts and components are valid in XMPP, and that they are encoded correctly.
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
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
#include <lua.h>
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
#include <lauxlib.h>
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
10925
6eb5d2bb11af util-src: Use the luaL_pushfail API added in Lua 5.4 to highlight all failure conditions
Kim Alvefur <zash@zash.se>
parents: 10905
diff changeset
     9
#if (LUA_VERSION_NUM < 504)
6eb5d2bb11af util-src: Use the luaL_pushfail API added in Lua 5.4 to highlight all failure conditions
Kim Alvefur <zash@zash.se>
parents: 10905
diff changeset
    10
#define luaL_pushfail lua_pushnil
6eb5d2bb11af util-src: Use the luaL_pushfail API added in Lua 5.4 to highlight all failure conditions
Kim Alvefur <zash@zash.se>
parents: 10905
diff changeset
    11
#endif
6eb5d2bb11af util-src: Use the luaL_pushfail API added in Lua 5.4 to highlight all failure conditions
Kim Alvefur <zash@zash.se>
parents: 10905
diff changeset
    12
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    13
typedef struct {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    14
	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
    15
	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
    16
	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
    17
	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
    18
	char buffer[];
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    19
} ringbuffer;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    20
10905
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    21
/* Translate absolute idx to a wrapped index within the buffer,
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    22
   based on current read position */
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    23
static int wrap_pos(const ringbuffer *b, const long idx, long *pos) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    24
	if(idx > (long)b->blen) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    25
		return 0;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    26
	}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    27
	if(idx + (long)b->rpos > (long)b->alen) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    28
		*pos = idx - (b->alen - b->rpos);
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    29
	} else {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    30
		*pos = b->rpos + idx;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    31
	}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    32
	return 1;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    33
}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    34
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    35
static int calc_splice_positions(const ringbuffer *b, long start, long end, long *out_start, long *out_end) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    36
	if(start < 0) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    37
		start = 1 + start + b->blen;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    38
	}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    39
	if(start <= 0) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    40
		start = 1;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    41
	}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    42
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    43
	if(end < 0) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    44
		end = 1 + end + b->blen;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    45
	}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    46
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    47
	if(end > (long)b->blen) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    48
		end = b->blen;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    49
	}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    50
	if(start < 1) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    51
		start = 1;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    52
	}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    53
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    54
	if(start > end) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    55
		return 0;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    56
	}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    57
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    58
	start = start - 1;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    59
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    60
	if(!wrap_pos(b, start, out_start)) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    61
		return 0;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    62
	}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    63
	if(!wrap_pos(b, end, out_end)) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    64
		return 0;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    65
	}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    66
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    67
	return 1;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    68
}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    69
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
    70
static 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
    71
	b->blen++;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    72
	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
    73
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    74
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    75
/* make sure position counters stay within the allocation */
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
    76
static 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
    77
	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
    78
	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
    79
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    80
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
    81
static 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
    82
	size_t i, j;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    83
	int m;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    84
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    85
	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
    86
		return 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    87
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    88
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
    89
	/* 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
    90
	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
    91
		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
    92
			m = 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    93
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
    94
			/* 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
    95
			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
    96
				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
    97
					m = 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    98
					break;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    99
				}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   100
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   101
			if(m) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   102
				return i + l;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   103
			}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   104
		}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   105
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   106
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   107
	return 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   108
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   109
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   110
/*
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   111
 * Find first position of a substring in buffer
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   112
 * (buffer, string) -> number
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   113
 */
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   114
static 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
   115
	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
   116
	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
   117
	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
   118
	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
   119
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   120
	if(m > 0) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   121
		lua_pushinteger(L, m);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   122
		return 1;
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
	return 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   126
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   127
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   128
/*
8547
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
   129
 * 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
   130
 * (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
   131
 */
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   132
static int rb_discard(lua_State *L) {
8547
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
   133
	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
   134
	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
   135
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
   136
	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
   137
		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
   138
		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
   139
	}
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
   140
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
   141
	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
   142
	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
   143
	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
   144
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
   145
	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
   146
	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
   147
}
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
   148
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
   149
/*
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   150
 * Read bytes from buffer
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   151
 * (buffer, number, boolean?) -> string
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   152
 */
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   153
static int rb_read(lua_State *L) {
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   154
	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
   155
	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
   156
	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
   157
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   158
	if(r > b->blen) {
10925
6eb5d2bb11af util-src: Use the luaL_pushfail API added in Lua 5.4 to highlight all failure conditions
Kim Alvefur <zash@zash.se>
parents: 10905
diff changeset
   159
		luaL_pushfail(L);
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   160
		return 1;
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
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   163
	if((b->rpos + r) > b->alen) {
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   164
		/* 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
   165
		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
   166
		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
   167
		lua_concat(L, 2);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   168
	} else {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   169
		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
   170
	}
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
	if(!peek) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   173
		b->blen -= r;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   174
		b->rpos += r;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   175
		modpos(b);
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
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   178
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   179
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   180
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   181
/*
8738
856a40ec4a0a util.ringbuffer: Fix typo in comment [codespell]
Kim Alvefur <zash@zash.se>
parents: 8547
diff changeset
   182
 * Read buffer until first occurrence of a substring
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   183
 * (buffer, string) -> string
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   184
 */
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   185
static 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
   186
	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
   187
	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
   188
	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
   189
	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
   190
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   191
	if(m > 0) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   192
		lua_settop(L, 1);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   193
		lua_pushinteger(L, m);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   194
		return rb_read(L);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   195
	}
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
	return 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   198
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   199
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   200
/*
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   201
 * Write bytes into the buffer
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   202
 * (buffer, string) -> integer
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   203
 */
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   204
static 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
   205
	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
   206
	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
   207
	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
   208
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   209
	/* Does `l` bytes fit? */
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   210
	if((l + b->blen) > b->alen) {
10925
6eb5d2bb11af util-src: Use the luaL_pushfail API added in Lua 5.4 to highlight all failure conditions
Kim Alvefur <zash@zash.se>
parents: 10905
diff changeset
   211
		luaL_pushfail(L);
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   212
		return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   213
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   214
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   215
	while(l-- > 0) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   216
		writechar(b, *s++);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   217
		w++;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   218
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   219
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   220
	modpos(b);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   221
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   222
	lua_pushinteger(L, w);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   223
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   224
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   225
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   226
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   227
static int rb_tostring(lua_State *L) {
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   228
	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
   229
	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
   230
	return 1;
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
10905
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   233
static int rb_sub(lua_State *L) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   234
	ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   235
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   236
	long start = luaL_checkinteger(L, 2);
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   237
	long end = luaL_optinteger(L, 3, -1);
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   238
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   239
	long wrapped_start, wrapped_end;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   240
	if(!calc_splice_positions(b, start, end, &wrapped_start, &wrapped_end)) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   241
		lua_pushstring(L, "");
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   242
	} else if(wrapped_end <= wrapped_start) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   243
		lua_pushlstring(L, &b->buffer[wrapped_start], b->alen - wrapped_start);
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   244
		lua_pushlstring(L, b->buffer, wrapped_end);
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   245
		lua_concat(L, 2);
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   246
	} else {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   247
		lua_pushlstring(L, &b->buffer[wrapped_start], (wrapped_end - wrapped_start));
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   248
	}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   249
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   250
	return 1;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   251
}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   252
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   253
static int rb_byte(lua_State *L) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   254
	ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt");
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   255
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   256
	long start = luaL_optinteger(L, 2, 1);
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   257
	long end = luaL_optinteger(L, 3, start);
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   258
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   259
	long i;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   260
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   261
	long wrapped_start, wrapped_end;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   262
	if(calc_splice_positions(b, start, end, &wrapped_start, &wrapped_end)) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   263
		if(wrapped_end <= wrapped_start) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   264
			for(i = wrapped_start; i < (long)b->alen; i++) {
10957
c3b3ac63f4c3 util.ringbuffer: Ensure unsigned chars are always returned from :byte()
Matthew Wild <mwild1@gmail.com>
parents: 10925
diff changeset
   265
				lua_pushinteger(L, (unsigned char)b->buffer[i]);
10905
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   266
			}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   267
			for(i = 0; i < wrapped_end; i++) {
10957
c3b3ac63f4c3 util.ringbuffer: Ensure unsigned chars are always returned from :byte()
Matthew Wild <mwild1@gmail.com>
parents: 10925
diff changeset
   268
				lua_pushinteger(L, (unsigned char)b->buffer[i]);
10905
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   269
			}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   270
			return wrapped_end + (b->alen - wrapped_start);
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   271
		} else {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   272
			for(i = wrapped_start; i < wrapped_end; i++) {
10957
c3b3ac63f4c3 util.ringbuffer: Ensure unsigned chars are always returned from :byte()
Matthew Wild <mwild1@gmail.com>
parents: 10925
diff changeset
   273
				lua_pushinteger(L, (unsigned char)b->buffer[i]);
10905
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   274
			}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   275
			return wrapped_end - wrapped_start;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   276
		}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   277
	}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   278
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   279
	return 0;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   280
}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   281
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   282
static int rb_length(lua_State *L) {
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   283
	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
   284
	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
   285
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   286
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   287
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   288
static int rb_size(lua_State *L) {
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   289
	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
   290
	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
   291
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   292
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   293
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   294
static int rb_free(lua_State *L) {
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   295
	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
   296
	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
   297
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   298
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   299
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   300
static int rb_new(lua_State *L) {
10903
8048255ae61e util.ringbuffer: Prevent creation of buffer with negative size
Kim Alvefur <zash@zash.se>
parents: 10902
diff changeset
   301
	lua_Integer size = luaL_optinteger(L, 1, sysconf(_SC_PAGESIZE));
10902
c6465fb3c839 util.ringbuffer: Prevent creation of zero-size buffer
Kim Alvefur <zash@zash.se>
parents: 10484
diff changeset
   302
	luaL_argcheck(L, size > 0, 1, "positive integer expected");
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
   303
	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
   304
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   305
	b->rpos = 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   306
	b->wpos = 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   307
	b->alen = size;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   308
	b->blen = 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   309
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   310
	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
   311
	lua_setmetatable(L, -2);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   312
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   313
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   314
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   315
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   316
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
   317
#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
   318
	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
   319
#endif
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   320
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   321
	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
   322
		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
   323
		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
   324
		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
   325
		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
   326
7972
1c6a07606309 util-src: Specify size of various tables to be allocated
Kim Alvefur <zash@zash.se>
parents: 7944
diff changeset
   327
		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
   328
		{
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   329
			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
   330
			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
   331
			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
   332
			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
   333
			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
   334
			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
   335
			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
   336
			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
   337
			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
   338
			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
   339
			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
   340
			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
   341
			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
   342
			lua_setfield(L, -2, "length");
10905
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   343
			lua_pushcfunction(L, rb_sub);
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   344
			lua_setfield(L, -2, "sub");
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   345
			lua_pushcfunction(L, rb_byte);
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   346
			lua_setfield(L, -2, "byte");
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   347
			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
   348
			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
   349
		}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   350
		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
   351
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   352
7972
1c6a07606309 util-src: Specify size of various tables to be allocated
Kim Alvefur <zash@zash.se>
parents: 7944
diff changeset
   353
	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
   354
	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
   355
	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
   356
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   357
}