Software /
code /
prosody
Annotate
util-src/ringbuffer.c @ 12631:9524bb7f3944
mod_storage_sql: Drop archive timestamp precision pending schema update
The "when" column is an INTEGER which will probably be unhappy about
storing higher precision timestamps, so we keep the older behavior for
now.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 14 Aug 2022 17:29:39 +0200 |
parent | 12575:1f6f05a98fcd |
child | 12976:a187600ec7d6 |
rev | line source |
---|---|
7117
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 |
10921
6eb5d2bb11af
util-src: Use the luaL_pushfail API added in Lua 5.4 to highlight all failure conditions
Kim Alvefur <zash@zash.se>
parents:
10901
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:
10901
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:
10901
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:
10901
diff
changeset
|
12 |
7117
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 */ |
7828
b4a08a514ebc
util.ringbuffer: Allocate buffer itself as part of userdata (simpler, single allocation, no need for __gc)
Kim Alvefur <zash@zash.se>
parents:
7827
diff
changeset
|
18 char buffer[]; |
7117
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 |
10901
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
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:
10899
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:
10899
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:
10899
diff
changeset
|
25 return 0; |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
26 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
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:
10899
diff
changeset
|
29 } else { |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
diff
changeset
|
31 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
32 return 1; |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
33 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
34 |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
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:
10899
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:
10899
diff
changeset
|
38 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
diff
changeset
|
40 start = 1; |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
41 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
42 |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
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:
10899
diff
changeset
|
45 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
46 |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
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:
10899
diff
changeset
|
49 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
diff
changeset
|
51 start = 1; |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
52 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
53 |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
diff
changeset
|
55 return 0; |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
56 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
57 |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
diff
changeset
|
59 |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
diff
changeset
|
61 return 0; |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
62 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
diff
changeset
|
64 return 0; |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
65 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
66 |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
67 return 1; |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
68 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
69 |
10480
94cacf9fd0ae
util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8735
diff
changeset
|
70 static void writechar(ringbuffer *b, char c) { |
7117
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 */ |
10480
94cacf9fd0ae
util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8735
diff
changeset
|
76 static void modpos(ringbuffer *b) { |
7117
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 |
10480
94cacf9fd0ae
util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8735
diff
changeset
|
81 static int find(ringbuffer *b, const char *s, size_t l) { |
7117
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 |
8543
0e1d8f2f02bf
util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents:
7969
diff
changeset
|
89 /* look for a matching first byte */ |
7117
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 |
8543
0e1d8f2f02bf
util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents:
7969
diff
changeset
|
94 /* check if the following byte also match */ |
7117
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 |
8543
0e1d8f2f02bf
util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents:
7969
diff
changeset
|
110 /* |
0e1d8f2f02bf
util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents:
7969
diff
changeset
|
111 * Find first position of a substring in buffer |
0e1d8f2f02bf
util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents:
7969
diff
changeset
|
112 * (buffer, string) -> number |
0e1d8f2f02bf
util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents:
7969
diff
changeset
|
113 */ |
10480
94cacf9fd0ae
util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8735
diff
changeset
|
114 static int rb_find(lua_State *L) { |
7117
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; |
7889
b8d694646597
util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents:
7888
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:
7888
diff
changeset
|
117 const char *s = luaL_checklstring(L, 2, &l); |
7117
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 |
8543
0e1d8f2f02bf
util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents:
7969
diff
changeset
|
128 /* |
8544
e7214441523b
util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents:
8543
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:
8543
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:
8543
diff
changeset
|
131 */ |
10480
94cacf9fd0ae
util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8735
diff
changeset
|
132 static int rb_discard(lua_State *L) { |
8544
e7214441523b
util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents:
8543
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:
8543
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:
8543
diff
changeset
|
135 |
e7214441523b
util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents:
8543
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:
8543
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:
8543
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:
8543
diff
changeset
|
139 } |
e7214441523b
util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents:
8543
diff
changeset
|
140 |
e7214441523b
util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents:
8543
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:
8543
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:
8543
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:
8543
diff
changeset
|
144 |
e7214441523b
util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents:
8543
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:
8543
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:
8543
diff
changeset
|
147 } |
e7214441523b
util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents:
8543
diff
changeset
|
148 |
e7214441523b
util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents:
8543
diff
changeset
|
149 /* |
8543
0e1d8f2f02bf
util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents:
7969
diff
changeset
|
150 * Read bytes from buffer |
0e1d8f2f02bf
util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents:
7969
diff
changeset
|
151 * (buffer, number, boolean?) -> string |
0e1d8f2f02bf
util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents:
7969
diff
changeset
|
152 */ |
10480
94cacf9fd0ae
util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8735
diff
changeset
|
153 static int rb_read(lua_State *L) { |
7889
b8d694646597
util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents:
7888
diff
changeset
|
154 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
7941
8067828e7e40
util.ringbuffer: Change types of length related variables to size_t [-Wsign-compare]
Kim Alvefur <zash@zash.se>
parents:
7889
diff
changeset
|
155 size_t r = luaL_checkinteger(L, 2); |
7117
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) { |
10921
6eb5d2bb11af
util-src: Use the luaL_pushfail API added in Lua 5.4 to highlight all failure conditions
Kim Alvefur <zash@zash.se>
parents:
10901
diff
changeset
|
159 luaL_pushfail(L); |
7117
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) { |
8543
0e1d8f2f02bf
util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents:
7969
diff
changeset
|
164 /* Substring wraps around to the beginning of the buffer */ |
7117
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 |
8543
0e1d8f2f02bf
util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents:
7969
diff
changeset
|
181 /* |
8735
856a40ec4a0a
util.ringbuffer: Fix typo in comment [codespell]
Kim Alvefur <zash@zash.se>
parents:
8544
diff
changeset
|
182 * Read buffer until first occurrence of a substring |
8543
0e1d8f2f02bf
util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents:
7969
diff
changeset
|
183 * (buffer, string) -> string |
0e1d8f2f02bf
util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents:
7969
diff
changeset
|
184 */ |
10480
94cacf9fd0ae
util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8735
diff
changeset
|
185 static int rb_readuntil(lua_State *L) { |
7117
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; |
7889
b8d694646597
util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents:
7888
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:
7888
diff
changeset
|
188 const char *s = luaL_checklstring(L, 2, &l); |
7117
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 |
8543
0e1d8f2f02bf
util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents:
7969
diff
changeset
|
200 /* |
0e1d8f2f02bf
util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents:
7969
diff
changeset
|
201 * Write bytes into the buffer |
0e1d8f2f02bf
util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents:
7969
diff
changeset
|
202 * (buffer, string) -> integer |
0e1d8f2f02bf
util.ringbuffer: Add various comments
Kim Alvefur <zash@zash.se>
parents:
7969
diff
changeset
|
203 */ |
10480
94cacf9fd0ae
util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8735
diff
changeset
|
204 static int rb_write(lua_State *L) { |
7117
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; |
7889
b8d694646597
util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents:
7888
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:
7888
diff
changeset
|
207 const char *s = luaL_checklstring(L, 2, &l); |
7117
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) { |
10921
6eb5d2bb11af
util-src: Use the luaL_pushfail API added in Lua 5.4 to highlight all failure conditions
Kim Alvefur <zash@zash.se>
parents:
10901
diff
changeset
|
211 luaL_pushfail(L); |
7117
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 |
10480
94cacf9fd0ae
util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8735
diff
changeset
|
227 static int rb_tostring(lua_State *L) { |
7889
b8d694646597
util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents:
7888
diff
changeset
|
228 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
7888
74187ee6ed55
util.ringbuffer: Remove address of buffer itself from __tostring since is now in the same struct
Kim Alvefur <zash@zash.se>
parents:
7835
diff
changeset
|
229 lua_pushfstring(L, "ringbuffer: %p %d/%d", b, b->blen, b->alen); |
7117
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 |
10901
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
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:
10899
diff
changeset
|
235 |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
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:
10899
diff
changeset
|
238 |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
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:
10899
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:
10899
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:
10899
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:
10899
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:
10899
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:
10899
diff
changeset
|
246 } else { |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
diff
changeset
|
248 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
249 |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
250 return 1; |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
251 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
252 |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
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:
10899
diff
changeset
|
255 |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
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:
10899
diff
changeset
|
258 |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
259 long i; |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
260 |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
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:
10899
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:
10899
diff
changeset
|
264 for(i = wrapped_start; i < (long)b->alen; i++) { |
10953
c3b3ac63f4c3
util.ringbuffer: Ensure unsigned chars are always returned from :byte()
Matthew Wild <mwild1@gmail.com>
parents:
10921
diff
changeset
|
265 lua_pushinteger(L, (unsigned char)b->buffer[i]); |
10901
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
266 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
267 for(i = 0; i < wrapped_end; i++) { |
10953
c3b3ac63f4c3
util.ringbuffer: Ensure unsigned chars are always returned from :byte()
Matthew Wild <mwild1@gmail.com>
parents:
10921
diff
changeset
|
268 lua_pushinteger(L, (unsigned char)b->buffer[i]); |
10901
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
269 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
diff
changeset
|
271 } else { |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
272 for(i = wrapped_start; i < wrapped_end; i++) { |
10953
c3b3ac63f4c3
util.ringbuffer: Ensure unsigned chars are always returned from :byte()
Matthew Wild <mwild1@gmail.com>
parents:
10921
diff
changeset
|
273 lua_pushinteger(L, (unsigned char)b->buffer[i]); |
10901
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
274 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
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:
10899
diff
changeset
|
276 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
277 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
278 |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
279 return 0; |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
280 } |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
281 |
10480
94cacf9fd0ae
util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8735
diff
changeset
|
282 static int rb_length(lua_State *L) { |
7889
b8d694646597
util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents:
7888
diff
changeset
|
283 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
7117
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 |
10480
94cacf9fd0ae
util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8735
diff
changeset
|
288 static int rb_size(lua_State *L) { |
7889
b8d694646597
util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents:
7888
diff
changeset
|
289 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
7117
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 |
10480
94cacf9fd0ae
util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8735
diff
changeset
|
294 static int rb_free(lua_State *L) { |
7889
b8d694646597
util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents:
7888
diff
changeset
|
295 ringbuffer *b = luaL_checkudata(L, 1, "ringbuffer_mt"); |
7117
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 |
10480
94cacf9fd0ae
util.*.c: Add static qualifiers everywhere
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
8735
diff
changeset
|
300 static int rb_new(lua_State *L) { |
10899
8048255ae61e
util.ringbuffer: Prevent creation of buffer with negative size
Kim Alvefur <zash@zash.se>
parents:
10898
diff
changeset
|
301 lua_Integer size = luaL_optinteger(L, 1, sysconf(_SC_PAGESIZE)); |
10898
c6465fb3c839
util.ringbuffer: Prevent creation of zero-size buffer
Kim Alvefur <zash@zash.se>
parents:
10480
diff
changeset
|
302 luaL_argcheck(L, size > 0, 1, "positive integer expected"); |
7828
b4a08a514ebc
util.ringbuffer: Allocate buffer itself as part of userdata (simpler, single allocation, no need for __gc)
Kim Alvefur <zash@zash.se>
parents:
7827
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:
7827
diff
changeset
|
304 |
7117
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 |
7889
b8d694646597
util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents:
7888
diff
changeset
|
316 int luaopen_util_ringbuffer(lua_State *L) { |
7818
54669df178c2
util-src: Make C modules assert that the Lua runtime matches what it was compiled for
Kim Alvefur <zash@zash.se>
parents:
7117
diff
changeset
|
317 luaL_checkversion(L); |
7889
b8d694646597
util-src/*.c: Attach pointer * to name instead of type
Kim Alvefur <zash@zash.se>
parents:
7888
diff
changeset
|
318 |
7117
2b4432cc9c29
Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
319 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
|
320 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
|
321 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
|
322 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
|
323 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
|
324 |
7969
1c6a07606309
util-src: Specify size of various tables to be allocated
Kim Alvefur <zash@zash.se>
parents:
7941
diff
changeset
|
325 lua_createtable(L, 0, 7); /* __index */ |
7117
2b4432cc9c29
Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
326 { |
2b4432cc9c29
Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
327 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
|
328 lua_setfield(L, -2, "find"); |
8544
e7214441523b
util.ringbuffer: Add method for discarding buffered data without returning it to lua
Kim Alvefur <zash@zash.se>
parents:
8543
diff
changeset
|
329 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:
8543
diff
changeset
|
330 lua_setfield(L, -2, "discard"); |
7117
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_read); |
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, "read"); |
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_readuntil); |
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, "readuntil"); |
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_write); |
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, "write"); |
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_size); |
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, "size"); |
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_length); |
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, "length"); |
10901
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
341 lua_pushcfunction(L, rb_sub); |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
342 lua_setfield(L, -2, "sub"); |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
343 lua_pushcfunction(L, rb_byte); |
5e33926f4b43
util.ringbuffer: Add :sub() and :byte() methods equivalent to the string methods
Matthew Wild <mwild1@gmail.com>
parents:
10899
diff
changeset
|
344 lua_setfield(L, -2, "byte"); |
7117
2b4432cc9c29
Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
345 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
|
346 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
|
347 } |
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, "__index"); |
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 |
7969
1c6a07606309
util-src: Specify size of various tables to be allocated
Kim Alvefur <zash@zash.se>
parents:
7941
diff
changeset
|
351 lua_createtable(L, 0, 1); |
7117
2b4432cc9c29
Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
352 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
|
353 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
|
354 return 1; |
2b4432cc9c29
Add util.ringbuffer, a ringbuffer with a file handle like interface
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
355 } |