util-src/ringbuffer.c
author Matthew Wild <mwild1@gmail.com>
Thu, 04 Jun 2020 15:19:20 +0100
changeset 10905 5e33926f4b43
parent 10903 8048255ae61e
child 10925 6eb5d2bb11af
permissions -rw-r--r--
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
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
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
typedef struct {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
	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
    11
	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
    12
	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
    13
	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
    14
	char buffer[];
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    15
} ringbuffer;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    16
10905
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    17
/* 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
    18
   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
    19
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
    20
	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
    21
		return 0;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    22
	}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    23
	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
    24
		*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
    25
	} else {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    26
		*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
    27
	}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    28
	return 1;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    29
}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    30
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    31
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
    32
	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
    33
		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
    34
	}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    35
	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
    36
		start = 1;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    37
	}
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(end < 0) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    40
		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
    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 > (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
    44
		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
	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
    47
		start = 1;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    48
	}
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 > end) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    51
		return 0;
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
	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
    55
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    56
	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
    57
		return 0;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    58
	}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    59
	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
    60
		return 0;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    61
	}
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
	return 1;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    64
}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
    65
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
    66
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
    67
	b->blen++;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    68
	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
    69
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    70
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    71
/* 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
    72
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
    73
	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
    74
	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
    75
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    76
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
    77
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
    78
	size_t i, j;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    79
	int m;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    80
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    81
	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
    82
		return 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    83
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    84
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
    85
	/* 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
    86
	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
    87
		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
    88
			m = 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    89
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
    90
			/* 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
    91
			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
    92
				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
    93
					m = 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    94
					break;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    95
				}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    96
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    97
			if(m) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    98
				return i + l;
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
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   102
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   103
	return 0;
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
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   106
/*
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   107
 * Find first position of a substring in buffer
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   108
 * (buffer, string) -> number
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   109
 */
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   110
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
   111
	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
   112
	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
   113
	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
   114
	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
   115
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   116
	if(m > 0) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   117
		lua_pushinteger(L, m);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   118
		return 1;
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
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   121
	return 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   122
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   123
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   124
/*
8547
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
   125
 * 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
   126
 * (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
   127
 */
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   128
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
   129
	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
   130
	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
   131
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
   132
	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
   133
		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
   134
		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
   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
e7214441523b util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents: 8546
diff changeset
   137
	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
   138
	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
   139
	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
   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
	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
   142
	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
   143
}
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
/*
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   146
 * Read bytes from buffer
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   147
 * (buffer, number, boolean?) -> string
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   148
 */
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   149
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
   150
	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
   151
	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
   152
	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
   153
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   154
	if(r > b->blen) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   155
		lua_pushnil(L);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   156
		return 1;
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
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   159
	if((b->rpos + r) > b->alen) {
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   160
		/* 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
   161
		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
   162
		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
   163
		lua_concat(L, 2);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   164
	} else {
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], r);
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
	if(!peek) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   169
		b->blen -= r;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   170
		b->rpos += r;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   171
		modpos(b);
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
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   174
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   175
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   176
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   177
/*
8738
856a40ec4a0a util.ringbuffer: Fix typo in comment [codespell]
Kim Alvefur <zash@zash.se>
parents: 8547
diff changeset
   178
 * Read buffer until first occurrence of a substring
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   179
 * (buffer, string) -> string
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   180
 */
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   181
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
   182
	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
   183
	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
   184
	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
   185
	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
   186
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   187
	if(m > 0) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   188
		lua_settop(L, 1);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   189
		lua_pushinteger(L, m);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   190
		return rb_read(L);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   191
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   192
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   193
	return 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   194
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   195
8546
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   196
/*
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   197
 * Write bytes into the buffer
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   198
 * (buffer, string) -> integer
0e1d8f2f02bf util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents: 7972
diff changeset
   199
 */
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   200
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
   201
	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
   202
	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
   203
	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
   204
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   205
	/* Does `l` bytes fit? */
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   206
	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
   207
		lua_pushnil(L);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   208
		return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   209
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   210
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   211
	while(l-- > 0) {
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   212
		writechar(b, *s++);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   213
		w++;
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
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   216
	modpos(b);
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
	lua_pushinteger(L, w);
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
	return 1;
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
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   223
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
   224
	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
   225
	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
   226
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   227
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   228
10905
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   229
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
   230
	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
   231
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   232
	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
   233
	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
   234
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   235
	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
   236
	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
   237
		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
   238
	} 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
   239
		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
   240
		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
   241
		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
   242
	} else {
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], (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
   244
	}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   245
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   246
	return 1;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   247
}
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
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
   250
	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
   251
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   252
	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
   253
	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
   254
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   255
	long i;
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   256
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   257
	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
   258
	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
   259
		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
   260
			for(i = wrapped_start; i < (long)b->alen; i++) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   261
				lua_pushinteger(L, b->buffer[i]);
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   262
			}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   263
			for(i = 0; i < wrapped_end; i++) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   264
				lua_pushinteger(L, b->buffer[i]);
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   265
			}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   266
			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
   267
		} else {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   268
			for(i = wrapped_start; i < wrapped_end; i++) {
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   269
				lua_pushinteger(L, b->buffer[i]);
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   270
			}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   271
			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
   272
		}
5e33926f4b43 util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents: 10903
diff changeset
   273
	}
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 0;
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
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   278
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
   279
	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
   280
	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
   281
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   282
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   283
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   284
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
   285
	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
   286
	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
   287
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   288
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   289
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   290
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
   291
	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
   292
	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
   293
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   294
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   295
10484
94cacf9fd0ae util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 8738
diff changeset
   296
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
   297
	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
   298
	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
   299
	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
   300
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   301
	b->rpos = 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   302
	b->wpos = 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   303
	b->alen = size;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   304
	b->blen = 0;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   305
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   306
	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
   307
	lua_setmetatable(L, -2);
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   308
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   309
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   310
}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   311
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   312
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
   313
#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
   314
	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
   315
#endif
7892
b8d694646597 util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents: 7891
diff changeset
   316
7120
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   317
	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
   318
		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
   319
		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
   320
		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
   321
		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
   322
7972
1c6a07606309 util-src: Specify size of various tables to be allocated
Kim Alvefur <zash@zash.se>
parents: 7944
diff changeset
   323
		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
   324
		{
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   325
			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
   326
			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
   327
			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
   328
			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
   329
			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
   330
			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
   331
			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
   332
			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
   333
			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
   334
			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
   335
			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
   336
			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
   337
			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
   338
			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
   339
			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
   340
			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
   341
			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
   342
			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
   343
			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
   344
			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
   345
		}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   346
		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
   347
	}
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   348
7972
1c6a07606309 util-src: Specify size of various tables to be allocated
Kim Alvefur <zash@zash.se>
parents: 7944
diff changeset
   349
	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
   350
	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
   351
	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
   352
	return 1;
2b4432cc9c29 Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   353
}