9 #define BUFFER_ADD_CHECK_INPUT_FIRST 1 |
9 #define BUFFER_ADD_CHECK_INPUT_FIRST 1 |
10 |
10 |
11 static le_buffer* event_buffer_get(lua_State* L, int idx) { |
11 static le_buffer* event_buffer_get(lua_State* L, int idx) { |
12 return (le_buffer*)luaL_checkudata(L, idx, EVENT_BUFFER_MT); |
12 return (le_buffer*)luaL_checkudata(L, idx, EVENT_BUFFER_MT); |
13 } |
13 } |
|
14 static void event_buffer_check(lua_State* L, int idx) { |
|
15 le_buffer* buf = (le_buffer*)luaL_checkudata(L, idx, EVENT_BUFFER_MT); |
|
16 if(!buf->buffer) |
|
17 luaL_argerror(L, idx, "Attempt to use closed event_buffer object"); |
|
18 return buf; |
|
19 } |
14 static int is_event_buffer(lua_State* L, int idx) { |
20 static int is_event_buffer(lua_State* L, int idx) { |
15 int ret; |
21 int ret; |
16 lua_getmetatable(L, idx); |
22 lua_getmetatable(L, idx); |
17 luaL_getmetatable(L, EVENT_BUFFER_MT); |
23 luaL_getmetatable(L, EVENT_BUFFER_MT); |
18 ret = lua_rawequal(L, -2, -1); |
24 ret = lua_rawequal(L, -2, -1); |
19 lua_pop(L, 2); |
25 lua_pop(L, 2); |
20 return ret; |
26 return ret; |
21 } |
27 } |
22 |
28 |
|
29 /* TODO: Use lightuserdata mapping to locate hanging object instances */ |
|
30 static int event_buffer_push(lua_State* L, struct evbuffer* buffer) { |
|
31 le_buffer *buf = (le_buffer*)lua_newuserdata(L, sizeof(le_buffer)); |
|
32 buf->buffer = buffer; |
|
33 luaL_getmetatable(L, EVENT_BUFFER_MT); |
|
34 lua_setmetatable(L, -2); |
|
35 return 1; |
|
36 } |
|
37 |
|
38 static int event_buffer_push_new(lua_State* L) { |
|
39 return event_buffer_push(L, evbuffer_new()); |
|
40 } |
|
41 |
|
42 static int event_buffer_gc(lua_State* L) { |
|
43 le_buffer* buf = event_buffer_get(L, 1); |
|
44 if(buf->buffer) { |
|
45 evbuffer_free(buf->buffer); |
|
46 buf->buffer = NULL; |
|
47 } |
|
48 return 0; |
|
49 } |
|
50 |
23 /* LUA: buffer:add(...) |
51 /* LUA: buffer:add(...) |
24 progressively adds items to the buffer |
52 progressively adds items to the buffer |
25 if arg[*] is string, treat as a string:format call |
53 if arg[*] is string, treat as a string:format call |
26 if arg[*] is a buffer, perform event_add_buffer |
54 if arg[*] is a buffer, perform event_add_buffer |
27 returns number of bytes added |
55 returns number of bytes added |
28 */ |
56 */ |
29 int event_buffer_add(lua_State* L) { |
57 static int event_buffer_add(lua_State* L) { |
30 le_buffer* buf = event_buffer_get(L, 1); |
58 le_buffer* buf = event_buffer_check(L, 1); |
31 struct evbuffer* buffer = buf->buffer; |
59 struct evbuffer* buffer = buf->buffer; |
32 int oldLength = EVBUFFER_LENGTH(buffer); |
60 int oldLength = EVBUFFER_LENGTH(buffer); |
33 int last = lua_top(L); |
61 int last = lua_top(L); |
34 int i; |
62 int i; |
35 for(i = 2; i <= last; i++) { |
63 for(i = 2; i <= last; i++) { |
44 size_t len; |
72 size_t len; |
45 const char* data = lua_tolstring(L, i, &len); |
73 const char* data = lua_tolstring(L, i, &len); |
46 if(0 != evbuffer_add(buffer, data, len)) |
74 if(0 != evbuffer_add(buffer, data, len)) |
47 luaL_error(L, "Failed to add data to the buffer"); |
75 luaL_error(L, "Failed to add data to the buffer"); |
48 } else { |
76 } else { |
49 le_buffer* buf2 = event_buffer_get(L, i); |
77 le_buffer* buf2 = event_buffer_check(L, i); |
50 if(0 != evbuffer_add_buffer(buffer, buf2->buffer)) |
78 if(0 != evbuffer_add_buffer(buffer, buf2->buffer)) |
51 luaL_error(L, "Failed to move buffer-data to the buffer"); |
79 luaL_error(L, "Failed to move buffer-data to the buffer"); |
52 } |
80 } |
53 } |
81 } |
54 lua_pushinteger(L, EVBUFFER_LENGTH(buffer) - oldLength); |
82 lua_pushinteger(L, EVBUFFER_LENGTH(buffer) - oldLength); |
55 return 1; |
83 return 1; |
56 } |
84 } |
57 |
85 |
|
86 static int event_buffer_get_length(lua_State* L) { |
|
87 le_buffer* buf = event_buffer_check(L, 1); |
|
88 lua_pushinteger(L, EVBUFFER_LENGTH(buf->buffer)); |
|
89 return 1; |
|
90 } |
|
91 |
|
92 /* MAYBE: Could add caching */ |
|
93 static int event_buffer_get_data(lua_State* L) { |
|
94 le_buffer* buf = event_buffer_check(L, 1); |
|
95 lua_pushlstring(L, EVBUFFER_DATA(buf->buffer), EVBUFFER_LENGTH(buf->buffer)); |
|
96 return 1; |
|
97 } |
|
98 |
|
99 static int event_buffer_drain(lua_State* L) { |
|
100 le_buffer* buf = event_buffer_check(L, 1); |
|
101 size_t len = luaL_checkinteger(L, 2); |
|
102 evbuffer_drain(buf->buffer, len); |
|
103 return 0; |
|
104 } |
|
105 |
58 static luaL_Reg buffer_funcs[] = { |
106 static luaL_Reg buffer_funcs[] = { |
59 {"add",event_buffer_add}, |
107 {"add",event_buffer_add}, |
|
108 {"length",event_buffer_get_length}, |
|
109 {"get_data",event_buffer_get_data}, |
|
110 {"drain",event_buffer_drain}, |
|
111 {"close",event_buffer_gc}, |
60 {NULL, NULL} |
112 {NULL, NULL} |
61 }; |
113 }; |
62 static luaL_Ref funcs[] = { |
114 static luaL_Ref funcs[] = { |
|
115 {"new",event_buffer_push_new}, |
63 {NULL, NULL} |
116 {NULL, NULL} |
64 }; |
117 }; |
65 |
118 |
66 int event_buffer_register(lua_State* L) { |
119 int event_buffer_register(lua_State* L) { |
67 luaL_newmetatable(L, EVENT_BUFFER_MT); |
120 luaL_newmetatable(L, EVENT_BUFFER_MT); |
|
121 lua_pushcfunction(L, event_buffer_gc); |
|
122 lua_setfield(L, -2, "__gc"); |
68 lua_newtable(L); |
123 lua_newtable(L); |
69 luaL_register(L, NULL, buffer_funcs); |
124 luaL_register(L, NULL, buffer_funcs); |
70 lua_setfield(L, -2, "__index"); |
125 lua_setfield(L, -2, "__index"); |
71 lua_pop(L, 1); |
126 lua_pop(L, 1); |
72 |
127 |