Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / cls / lua / lua_bufferlist.cc
1 /*
2  * Lua module wrapping librados::bufferlist
3  */
4 #include <errno.h>
5 #include <string>
6 #include <sstream>
7 #include <math.h>
8 #include <lua.hpp>
9 #include "include/types.h"
10 #include "include/buffer.h"
11 #include "objclass/objclass.h"
12 #include "cls/lua/cls_lua.h"
13
14 #define LUA_BUFFERLIST "ClsLua.Bufferlist"
15
16 struct bufferlist_wrap {
17   bufferlist *bl;
18   int gc; /* do garbage collect? */
19 };
20
21 static inline struct bufferlist_wrap *to_blwrap(lua_State *L, int pos = 1)
22 {
23   return (bufferlist_wrap *)luaL_checkudata(L, pos, LUA_BUFFERLIST);
24 }
25
26 bufferlist *clslua_checkbufferlist(lua_State *L, int pos)
27 {
28   struct bufferlist_wrap *blw = to_blwrap(L, pos);
29   return blw->bl;
30 }
31
32 /*
33  * Pushes a new bufferlist userdata object onto the stack. If @set is non-null
34  * it is assumed to be a bufferlist that should not be garbage collected.
35  */
36 bufferlist *clslua_pushbufferlist(lua_State *L, bufferlist *set)
37 {
38   bufferlist_wrap *blw = static_cast<bufferlist_wrap *>(lua_newuserdata(L, sizeof(*blw)));
39   blw->bl = set ? set : new bufferlist();
40   blw->gc = set ? 0 : 1;
41   luaL_getmetatable(L, LUA_BUFFERLIST);
42   lua_setmetatable(L, -2);
43   return blw->bl;
44 }
45
46 /*
47  * Create a new bufferlist
48  */
49 static int bl_new(lua_State *L)
50 {
51   clslua_pushbufferlist(L, NULL);
52   return 1;
53 }
54
55 /*
56  * Convert bufferlist to Lua string
57  */
58 static int bl_str(lua_State *L)
59 {
60   bufferlist *bl = clslua_checkbufferlist(L);
61   lua_pushlstring(L, bl->c_str(), bl->length());
62   return 1;
63 }
64
65 /*
66  * Append a Lua string to bufferlist
67  */
68 static int bl_append(lua_State *L)
69 {
70   bufferlist *bl = clslua_checkbufferlist(L);
71   luaL_checktype(L, 2, LUA_TSTRING);
72
73   size_t len;
74   const char *data = lua_tolstring(L, 2, &len);
75   bl->append(data, len);
76
77   return 0;
78 }
79
80 /*
81  * Return the length in bytes of bufferlist
82  */
83 static int bl_len(lua_State *L)
84 {
85   bufferlist *bl = clslua_checkbufferlist(L);
86   lua_pushinteger(L, bl->length());
87   return 1;
88 }
89
90 /*
91  * Perform byte-for-byte bufferlist equality test
92  */
93 static int bl_eq(lua_State *L)
94 {
95   bufferlist *bl1 = clslua_checkbufferlist(L, 1);
96   bufferlist *bl2 = clslua_checkbufferlist(L, 2);
97   lua_pushboolean(L, *bl1 == *bl2 ? 1 : 0);
98   return 1;
99 }
100
101 /*
102  * Bufferlist < operator
103  */
104 static int bl_lt(lua_State *L)
105 {
106   bufferlist *bl1 = clslua_checkbufferlist(L, 1);
107   bufferlist *bl2 = clslua_checkbufferlist(L, 2);
108   lua_pushboolean(L, *bl1 < *bl2 ? 1 : 0);
109   return 1;
110 }
111
112 /*
113  * Bufferlist <= operator
114  */
115 static int bl_le(lua_State *L)
116 {
117   bufferlist *bl1 = clslua_checkbufferlist(L, 1);
118   bufferlist *bl2 = clslua_checkbufferlist(L, 2);
119   lua_pushboolean(L, *bl1 <= *bl2 ? 1 : 0);
120   return 1;
121 }
122
123 /*
124  * Bufferlist concatentation
125  */
126 static int bl_concat(lua_State *L)
127 {
128   bufferlist *bl1 = clslua_checkbufferlist(L, 1);
129   bufferlist *bl2 = clslua_checkbufferlist(L, 2);
130   bufferlist *ret = clslua_pushbufferlist(L, NULL);
131   ret->append(bl1->c_str(), bl1->length());
132   ret->append(bl2->c_str(), bl2->length());
133   return 1;
134 }
135
136 /*
137  * Garbage collect bufferlist
138  */
139 static int bl_gc(lua_State *L)
140 {
141   struct bufferlist_wrap *blw = to_blwrap(L);
142   assert(blw);
143   assert(blw->bl);
144   if (blw->gc)
145     delete blw->bl;
146   return 0;
147 }
148
149 static const struct luaL_Reg bufferlist_methods[] = {
150   {"str", bl_str},
151   {"append", bl_append},
152   {"__concat", bl_concat},
153   {"__len", bl_len},
154   {"__lt", bl_lt},
155   {"__le", bl_le},
156   {"__gc", bl_gc},
157   {"__eq", bl_eq},
158   {NULL, NULL}
159 };
160
161 static const struct luaL_Reg bllib_f[] = {
162   {"new", bl_new},
163   {NULL, NULL}
164 };
165
166 LUALIB_API int luaopen_bufferlist(lua_State *L)
167 {
168   /* Setup bufferlist user-data type */
169   luaL_newmetatable(L, LUA_BUFFERLIST);
170   lua_pushvalue(L, -1);
171   lua_setfield(L, -2, "__index");
172
173   luaL_setfuncs(L, bufferlist_methods, 0);
174   lua_pop(L, 1);
175
176   lua_newtable(L);
177   luaL_setfuncs(L, bllib_f, 0);
178
179   return 1;
180 }