]> git.proxmox.com Git - ceph.git/blame - ceph/src/jaegertracing/thrift/lib/lua/src/luabpack.c
buildsys: switch source download to quincy
[ceph.git] / ceph / src / jaegertracing / thrift / lib / lua / src / luabpack.c
CommitLineData
f67539c2
TL
1//
2// Licensed to the Apache Software Foundation (ASF) under one
3// or more contributor license agreements. See the NOTICE file
4// distributed with this work for additional information
5// regarding copyright ownership. The ASF licenses this file
6// to you under the Apache License, Version 2.0 (the
7// "License"); you may not use this file except in compliance
8// with the License. You may obtain a copy of the License at
9//
10// http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing,
13// software distributed under the License is distributed on an
14// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15// KIND, either express or implied. See the License for the
16// specific language governing permissions and limitations
17// under the License.
18//
19
20#include <lua.h>
21#include <lauxlib.h>
22#include <string.h>
23#include <inttypes.h>
24#include <netinet/in.h>
25
26extern int64_t lualongnumber_checklong(lua_State *L, int index);
27extern int64_t lualongnumber_pushlong(lua_State *L, int64_t *val);
28
29// host order to network order (64-bit)
30static int64_t T_htonll(uint64_t data) {
31 uint32_t d1 = htonl((uint32_t)data);
32 uint32_t d2 = htonl((uint32_t)(data >> 32));
33 return ((uint64_t)d1 << 32) + (uint64_t)d2;
34}
35
36// network order to host order (64-bit)
37static int64_t T_ntohll(uint64_t data) {
38 uint32_t d1 = ntohl((uint32_t)data);
39 uint32_t d2 = ntohl((uint32_t)(data >> 32));
40 return ((uint64_t)d1 << 32) + (uint64_t)d2;
41}
42
43/**
44 * bpack(type, data)
45 * c - Signed Byte
46 * s - Signed Short
47 * i - Signed Int
48 * l - Signed Long
49 * d - Double
50 */
51static int l_bpack(lua_State *L) {
52 const char *code = luaL_checkstring(L, 1);
53 luaL_argcheck(L, code[1] == '\0', 0, "Format code must be one character.");
54 luaL_Buffer buf;
55 luaL_buffinit(L, &buf);
56
57 switch (code[0]) {
58 case 'c': {
59 int8_t data = luaL_checknumber(L, 2);
60 luaL_addlstring(&buf, (void*)&data, sizeof(data));
61 break;
62 }
63 case 's': {
64 int16_t data = luaL_checknumber(L, 2);
65 data = (int16_t)htons(data);
66 luaL_addlstring(&buf, (void*)&data, sizeof(data));
67 break;
68 }
69 case 'i': {
70 int32_t data = luaL_checkinteger(L, 2);
71 data = (int32_t)htonl(data);
72 luaL_addlstring(&buf, (void*)&data, sizeof(data));
73 break;
74 }
75 case 'l': {
76 int64_t data = lualongnumber_checklong(L, 2);
77 data = (int64_t)T_htonll(data);
78 luaL_addlstring(&buf, (void*)&data, sizeof(data));
79 break;
80 }
81 case 'd': {
82 double data = luaL_checknumber(L, 2);
83 luaL_addlstring(&buf, (void*)&data, sizeof(data));
84 break;
85 }
86 default:
87 luaL_argcheck(L, 0, 0, "Invalid format code.");
88 }
89
90 luaL_pushresult(&buf);
91 return 1;
92}
93
94/**
95 * bunpack(type, data)
96 * c - Signed Byte
97 * C - Unsigned Byte
98 * s - Signed Short
99 * i - Signed Int
100 * l - Signed Long
101 * d - Double
102 */
103static int l_bunpack(lua_State *L) {
104 const char *code = luaL_checkstring(L, 1);
105 luaL_argcheck(L, code[1] == '\0', 0, "Format code must be one character.");
106 const char *data = luaL_checkstring(L, 2);
107#if LUA_VERSION_NUM >= 502
108 size_t len = lua_rawlen(L, 2);
109#else
110 size_t len = lua_objlen(L, 2);
111#endif
112
113 switch (code[0]) {
114 case 'c': {
115 int8_t val;
116 luaL_argcheck(L, len == sizeof(val), 1, "Invalid input string size.");
117 memcpy(&val, data, sizeof(val));
118 lua_pushnumber(L, val);
119 break;
120 }
121 /**
122 * unpack unsigned Byte.
123 */
124 case 'C': {
125 uint8_t val;
126 luaL_argcheck(L, len == sizeof(val), 1, "Invalid input string size.");
127 memcpy(&val, data, sizeof(val));
128 lua_pushnumber(L, val);
129 break;
130 }
131 case 's': {
132 int16_t val;
133 luaL_argcheck(L, len == sizeof(val), 1, "Invalid input string size.");
134 memcpy(&val, data, sizeof(val));
135 val = (int16_t)ntohs(val);
136 lua_pushnumber(L, val);
137 break;
138 }
139 case 'i': {
140 int32_t val;
141 luaL_argcheck(L, len == sizeof(val), 1, "Invalid input string size.");
142 memcpy(&val, data, sizeof(val));
143 val = (int32_t)ntohl(val);
144 lua_pushnumber(L, val);
145 break;
146 }
147 case 'l': {
148 int64_t val;
149 luaL_argcheck(L, len == sizeof(val), 1, "Invalid input string size.");
150 memcpy(&val, data, sizeof(val));
151 val = (int64_t)T_ntohll(val);
152 lualongnumber_pushlong(L, &val);
153 break;
154 }
155 case 'd': {
156 double val;
157 luaL_argcheck(L, len == sizeof(val), 1, "Invalid input string size.");
158 memcpy(&val, data, sizeof(val));
159 lua_pushnumber(L, val);
160 break;
161 }
162 default:
163 luaL_argcheck(L, 0, 0, "Invalid format code.");
164 }
165 return 1;
166}
167
168/**
169 * Convert l into a zigzag long. This allows negative numbers to be
170 * represented compactly as a varint.
171 */
172static int l_i64ToZigzag(lua_State *L) {
173 int64_t n = lualongnumber_checklong(L, 1);
174 int64_t result = (n << 1) ^ (n >> 63);
175 lualongnumber_pushlong(L, &result);
176 return 1;
177}
178/**
179 * Convert n into a zigzag int. This allows negative numbers to be
180 * represented compactly as a varint.
181 */
182static int l_i32ToZigzag(lua_State *L) {
183 int32_t n = luaL_checkinteger(L, 1);
184 uint32_t result = (uint32_t)(n << 1) ^ (n >> 31);
185 lua_pushnumber(L, result);
186 return 1;
187}
188
189/**
190 * Convert from zigzag int to int.
191 */
192static int l_zigzagToI32(lua_State *L) {
193 uint32_t n = luaL_checkinteger(L, 1);
194 int32_t result = (int32_t)(n >> 1) ^ (uint32_t)(-(int32_t)(n & 1));
195 lua_pushnumber(L, result);
196 return 1;
197}
198
199/**
200 * Convert from zigzag long to long.
201 */
202static int l_zigzagToI64(lua_State *L) {
203 int64_t n = lualongnumber_checklong(L, 1);
204 int64_t result = (int64_t)(n >> 1) ^ (uint64_t)(-(int64_t)(n & 1));
205 lualongnumber_pushlong(L, &result);
206 return 1;
207}
208
209/**
210 * Convert an i32 to a varint. Results in 1-5 bytes on the buffer.
211 */
212static int l_toVarint32(lua_State *L) {
213 uint8_t buf[5];
214 uint32_t n = luaL_checkinteger(L, 1);
215 uint32_t wsize = 0;
216
217 while (1) {
218 if ((n & ~0x7F) == 0) {
219 buf[wsize++] = (int8_t)n;
220 break;
221 } else {
222 buf[wsize++] = (int8_t)((n & 0x7F) | 0x80);
223 n >>= 7;
224 }
225 }
226 lua_pushlstring(L, buf, wsize);
227 return 1;
228}
229
230/**
231 * Convert an i64 to a varint. Results in 1-10 bytes on the buffer.
232 */
233static int l_toVarint64(lua_State *L) {
234 uint8_t data[10];
235 uint64_t n = lualongnumber_checklong(L, 1);
236 uint32_t wsize = 0;
237 luaL_Buffer buf;
238 luaL_buffinit(L, &buf);
239
240 while (1) {
241 if ((n & ~0x7FL) == 0) {
242 data[wsize++] = (int8_t)n;
243 break;
244 } else {
245 data[wsize++] = (int8_t)((n & 0x7F) | 0x80);
246 n >>= 7;
247 }
248 }
249
250 luaL_addlstring(&buf, (void*)&data, wsize);
251 luaL_pushresult(&buf);
252 return 1;
253}
254
255/**
256 * Convert a varint to i64.
257 */
258static int l_fromVarint64(lua_State *L) {
259 int64_t result;
260 uint8_t byte = luaL_checknumber(L, 1);
261 int32_t shift = luaL_checknumber(L, 2);
262 uint64_t n = (uint64_t)lualongnumber_checklong(L, 3);
263 n |= (uint64_t)(byte & 0x7f) << shift;
264
265 if (!(byte & 0x80)) {
266 result = (int64_t)(n >> 1) ^ (uint64_t)(-(int64_t)(n & 1));
267 lua_pushnumber(L, 0);
268 } else {
269 result = n;
270 lua_pushnumber(L, 1);
271 }
272 lualongnumber_pushlong(L, &result);
273 return 2;
274}
275
276/**
277 * To pack message type of compact protocol.
278 */
279static int l_packMesgType(lua_State *L) {
280 int32_t version_n = luaL_checkinteger(L, 1);
281 int32_t version_mask = luaL_checkinteger(L, 2);
282 int32_t messagetype = luaL_checkinteger(L, 3);
283 int32_t type_shift_amount = luaL_checkinteger(L, 4);
284 int32_t type_mask = luaL_checkinteger(L, 5);
285 int32_t to_mesg_type = (version_n & version_mask) |
286 (((int32_t)messagetype << type_shift_amount) & type_mask);
287 lua_pushnumber(L, to_mesg_type);
288 return 1;
289}
290
291static const struct luaL_Reg lua_bpack[] = {
292 {"bpack", l_bpack},
293 {"bunpack", l_bunpack},
294 {"i32ToZigzag", l_i32ToZigzag},
295 {"i64ToZigzag", l_i64ToZigzag},
296 {"zigzagToI32", l_zigzagToI32},
297 {"zigzagToI64", l_zigzagToI64},
298 {"toVarint32", l_toVarint32},
299 {"toVarint64", l_toVarint64},
300 {"fromVarint64", l_fromVarint64},
301 {"packMesgType", l_packMesgType},
302 {NULL, NULL}
303};
304
305int luaopen_libluabpack(lua_State *L) {
306 luaL_register(L, "libluabpack", lua_bpack);
307 return 1;
308}