2 # (C) 2007 Jelmer Vernooij <jelmer@samba.org>
3 # Published under the GNU General Public License
7 use Test
::More tests
=> 9;
8 use FindBin
qw($RealBin);
11 use Parse::Pidl::Util qw(MyDumper);
12 use Parse
::Pidl
::Samba3
::ClientNDR
qw(ParseFunction ParseOutputArgument);
13 use Parse
::Pidl
::Samba4
::Header
qw(GenerateFunctionInEnv GenerateFunctionOutEnv);
15 # Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work
16 my $fn = { ELEMENTS
=> [ { DIRECTION
=> ["in"], NAME
=> "foo" } ] };
17 is_deeply
({ "foo" => "r.in.foo" }, GenerateFunctionInEnv
($fn, "r."));
18 is_deeply
({ "foo" => "r.in.foo" }, GenerateFunctionOutEnv
($fn, "r."));
20 $fn = { ELEMENTS
=> [ { DIRECTION
=> ["out", "in"], NAME
=> "foo" } ] };
21 is_deeply
({ "foo" => "r.in.foo" }, GenerateFunctionInEnv
($fn, "r."));
22 is_deeply
({ "foo" => "r.out.foo" }, GenerateFunctionOutEnv
($fn, "r."));
24 $fn = { ELEMENTS
=> [ { DIRECTION
=> ["out"], NAME
=> "foo" } ] };
25 is_deeply
({ }, GenerateFunctionInEnv
($fn, "r."));
26 is_deeply
({ "foo" => "r.out.foo" }, GenerateFunctionOutEnv
($fn, "r."));
28 my $x = new Parse
::Pidl
::Samba3
::ClientNDR
();
30 $fn = { NAME
=> "bar", ELEMENTS
=> [ ] };
31 $x->ParseFunction("foo", $fn);
33 "struct rpccli_bar_state {
36 TALLOC_CTX *out_mem_ctx;
37 NTSTATUS (*dispatch_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx);
40 static void rpccli_bar_done(struct tevent_req *subreq);
42 struct tevent_req *rpccli_bar_send(TALLOC_CTX *mem_ctx,
43 struct tevent_context *ev,
44 struct rpc_pipe_client *cli)
46 struct tevent_req *req;
47 struct rpccli_bar_state *state;
48 struct tevent_req *subreq;
50 req = tevent_req_create(mem_ctx, &state,
51 struct rpccli_bar_state);
55 state->out_mem_ctx = NULL;
56 state->dispatch_recv = cli->dispatch_recv;
62 /* make a temporary copy, that we pass to the dispatch function */
63 state->tmp = state->orig;
65 subreq = cli->dispatch_send(state, ev, cli,
69 if (tevent_req_nomem(subreq, req)) {
70 return tevent_req_post(req, ev);
72 tevent_req_set_callback(subreq, rpccli_bar_done, req);
76 static void rpccli_bar_done(struct tevent_req *subreq)
78 struct tevent_req *req = tevent_req_callback_data(
79 subreq, struct tevent_req);
80 struct rpccli_bar_state *state = tevent_req_data(
81 req, struct rpccli_bar_state);
85 if (state->out_mem_ctx) {
86 mem_ctx = state->out_mem_ctx;
91 status = state->dispatch_recv(subreq, mem_ctx);
93 if (!NT_STATUS_IS_OK(status)) {
94 tevent_req_nterror(req, status);
98 /* Copy out parameters */
100 /* Reset temporary structure */
101 ZERO_STRUCT(state->tmp);
103 tevent_req_done(req);
106 NTSTATUS rpccli_bar_recv(struct tevent_req *req,
109 struct rpccli_bar_state *state = tevent_req_data(
110 req, struct rpccli_bar_state);
113 if (tevent_req_is_nterror(req, &status)) {
114 tevent_req_received(req);
118 /* Steal possbile out parameters to the callers context */
119 talloc_steal(mem_ctx, state->out_mem_ctx);
121 tevent_req_received(req);
125 NTSTATUS rpccli_bar(struct rpc_pipe_client *cli,
133 status = cli->dispatch(cli,
139 if (!NT_STATUS_IS_OK(status)) {
143 if (NT_STATUS_IS_ERR(status)) {
147 /* Return variables */
155 $x = new Parse
::Pidl
::Samba3
::ClientNDR
();
157 $fn = { NAME
=> "bar", ELEMENTS
=> [ ], RETURN_TYPE
=> "WERROR" };
158 $x->ParseFunction("foo", $fn);
160 "struct rpccli_bar_state {
163 TALLOC_CTX *out_mem_ctx;
164 NTSTATUS (*dispatch_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx);
167 static void rpccli_bar_done(struct tevent_req *subreq);
169 struct tevent_req *rpccli_bar_send(TALLOC_CTX *mem_ctx,
170 struct tevent_context *ev,
171 struct rpc_pipe_client *cli)
173 struct tevent_req *req;
174 struct rpccli_bar_state *state;
175 struct tevent_req *subreq;
177 req = tevent_req_create(mem_ctx, &state,
178 struct rpccli_bar_state);
182 state->out_mem_ctx = NULL;
183 state->dispatch_recv = cli->dispatch_recv;
190 ZERO_STRUCT(state->orig.out.result);
192 /* make a temporary copy, that we pass to the dispatch function */
193 state->tmp = state->orig;
195 subreq = cli->dispatch_send(state, ev, cli,
199 if (tevent_req_nomem(subreq, req)) {
200 return tevent_req_post(req, ev);
202 tevent_req_set_callback(subreq, rpccli_bar_done, req);
206 static void rpccli_bar_done(struct tevent_req *subreq)
208 struct tevent_req *req = tevent_req_callback_data(
209 subreq, struct tevent_req);
210 struct rpccli_bar_state *state = tevent_req_data(
211 req, struct rpccli_bar_state);
215 if (state->out_mem_ctx) {
216 mem_ctx = state->out_mem_ctx;
221 status = state->dispatch_recv(subreq, mem_ctx);
223 if (!NT_STATUS_IS_OK(status)) {
224 tevent_req_nterror(req, status);
228 /* Copy out parameters */
231 state->orig.out.result = state->tmp.out.result;
233 /* Reset temporary structure */
234 ZERO_STRUCT(state->tmp);
236 tevent_req_done(req);
239 NTSTATUS rpccli_bar_recv(struct tevent_req *req,
243 struct rpccli_bar_state *state = tevent_req_data(
244 req, struct rpccli_bar_state);
247 if (tevent_req_is_nterror(req, &status)) {
248 tevent_req_received(req);
252 /* Steal possbile out parameters to the callers context */
253 talloc_steal(mem_ctx, state->out_mem_ctx);
256 *result = state->orig.out.result;
258 tevent_req_received(req);
262 NTSTATUS rpccli_bar(struct rpc_pipe_client *cli,
271 status = cli->dispatch(cli,
277 if (!NT_STATUS_IS_OK(status)) {
281 if (NT_STATUS_IS_ERR(status)) {
285 /* Return variables */
289 *werror = r.out.result;
292 return werror_to_ntstatus(r.out.result);
297 $x = new Parse
::Pidl
::Samba3
::ClientNDR
();
299 $fn = { NAME
=> "bar", ELEMENTS
=> [ ], RETURN_TYPE
=> "WERROR" };
300 my $e = { NAME
=> "foo", ORIGINAL
=> { FILE
=> "f", LINE
=> -1 },
301 LEVELS
=> [ { TYPE
=> "ARRAY", SIZE_IS
=> "mysize" }, { TYPE
=> "DATA", DATA_TYPE
=> "int" } ]};
303 $x->ParseOutputArgument($fn, $e);
304 is
($x->{res
}, "memcpy(foo, r.out.foo, (mysize) * sizeof(*foo));\n");