1 | /* |
2 | * Copyright 2008-2018 Aerospike, Inc. |
3 | * |
4 | * Portions may be licensed to Aerospike, Inc. under one or more contributor |
5 | * license agreements. |
6 | * |
7 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
8 | * use this file except in compliance with the License. You may obtain a copy of |
9 | * the License at http://www.apache.org/licenses/LICENSE-2.0 |
10 | * |
11 | * Unless required by applicable law or agreed to in writing, software |
12 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
14 | * License for the specific language governing permissions and limitations under |
15 | * the License. |
16 | */ |
17 | #include <aerospike/mod_lua_iterator.h> |
18 | #include <aerospike/as_val.h> |
19 | #include <aerospike/mod_lua_val.h> |
20 | #include <aerospike/mod_lua_reg.h> |
21 | #include <lua.h> |
22 | #include <lauxlib.h> |
23 | #include <lualib.h> |
24 | #include <string.h> |
25 | |
26 | #include "internal.h" |
27 | |
28 | /******************************************************************************* |
29 | * MACROS |
30 | ******************************************************************************/ |
31 | |
32 | #define OBJECT_NAME "iterator" |
33 | #define CLASS_NAME "Iterator" |
34 | |
35 | /******************************************************************************* |
36 | * FUNCTIONS |
37 | ******************************************************************************/ |
38 | |
39 | // |
40 | // NOTE ITERATORS ARE NOT AS_VALS |
41 | // |
42 | |
43 | as_iterator * mod_lua_toiterator(lua_State * l, int index) { |
44 | as_iterator * itr = (as_iterator *) lua_touserdata(l, index); |
45 | return (as_iterator *) itr; |
46 | } |
47 | |
48 | as_iterator * mod_lua_pushiterator(lua_State * l, size_t sz) { |
49 | as_iterator * i = (as_iterator *) lua_newuserdata(l, sz); |
50 | memset(i, 0, sz); |
51 | luaL_getmetatable(l, CLASS_NAME); |
52 | lua_setmetatable(l, -2); |
53 | return i; |
54 | } |
55 | |
56 | static as_iterator * mod_lua_checkiterator(lua_State * l, int index) { |
57 | luaL_checktype(l, index, LUA_TUSERDATA); |
58 | as_iterator * itr = (as_iterator *) luaL_checkudata(l, index, CLASS_NAME); |
59 | if (itr == NULL) luaL_typerror(l, index, CLASS_NAME); |
60 | return itr; |
61 | } |
62 | |
63 | static int mod_lua_iterator_gc(lua_State * l) { |
64 | as_iterator * itr = (as_iterator *) lua_touserdata(l, 1); |
65 | if (itr) as_iterator_destroy(itr); |
66 | return 0; |
67 | } |
68 | |
69 | /** |
70 | * Tests to see if there are any more entries in the iterator |
71 | */ |
72 | static int mod_lua_iterator_has_next(lua_State * l) { |
73 | as_iterator * i = mod_lua_checkiterator(l, 1); |
74 | bool b = as_iterator_has_next(i); |
75 | lua_pushboolean(l, b); |
76 | return 1; |
77 | } |
78 | |
79 | /** |
80 | * Tests to see if there are any more entries in the iterator |
81 | */ |
82 | static int mod_lua_iterator_next(lua_State * l) { |
83 | as_iterator * i = mod_lua_checkiterator(l, 1); |
84 | as_val * v = (as_val *) as_iterator_next(i); |
85 | if ( v != NULL ) { |
86 | mod_lua_pushval(l,v); |
87 | } |
88 | else { |
89 | lua_pushnil(l); |
90 | } |
91 | return 1; |
92 | } |
93 | |
94 | |
95 | /****************************************************************************** |
96 | * OBJECT TABLE |
97 | *****************************************************************************/ |
98 | |
99 | static const luaL_reg object_table[] = { |
100 | {"has_next" , mod_lua_iterator_has_next}, |
101 | {"next" , mod_lua_iterator_next}, |
102 | {0, 0} |
103 | }; |
104 | |
105 | static const luaL_reg object_metatable[] = { |
106 | {"__call" , mod_lua_iterator_next}, |
107 | {0, 0} |
108 | }; |
109 | |
110 | /****************************************************************************** |
111 | * CLASS TABLE |
112 | *****************************************************************************/ |
113 | |
114 | static const luaL_reg class_table[] = { |
115 | {"has_next" , mod_lua_iterator_has_next}, |
116 | {"next" , mod_lua_iterator_next}, |
117 | {0, 0} |
118 | }; |
119 | |
120 | static const luaL_reg class_metatable[] = { |
121 | {"__gc" , mod_lua_iterator_gc}, |
122 | {0, 0} |
123 | }; |
124 | |
125 | /****************************************************************************** |
126 | * REGISTER |
127 | *****************************************************************************/ |
128 | |
129 | int mod_lua_iterator_register(lua_State * l) { |
130 | mod_lua_reg_object(l, OBJECT_NAME, object_table, object_metatable); |
131 | mod_lua_reg_class(l, CLASS_NAME, class_table, class_metatable); |
132 | return 1; |
133 | } |
134 | |
135 | |