From 9af628a488d2b628e6c33917be7030602eeb5fde Mon Sep 17 00:00:00 2001 From: Douglas Bagnall Date: Fri, 26 Feb 2016 17:01:37 +1300 Subject: [PATCH] ndr: avoid unnecessary searches of token list When pulling complex structures like nt-acls, a long list of tokens may be produced. This change means the token list won't be walked in the buffers case if the switch value is not needed. Signed-off-by: Douglas Bagnall Reviewed-by: Andrew Bartlett Reviewed-by: Garming Sam --- pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm | 49 +++++++++++++++++------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm index f52d4b10f6d..c53ec4a8690 100644 --- a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm +++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm @@ -321,6 +321,25 @@ sub check_null_pointer($$$$) } } +sub is_deferred_switch_non_empty($) +{ + # 1 if there needs to be a deferred branch in an ndr_pull/push, + # 0 otherwise. + my ($e) = @_; + my $have_default = 0; + foreach my $el (@{$e->{ELEMENTS}}) { + if ($el->{CASE} eq "default") { + $have_default = 1; + } + if ($el->{TYPE} ne "EMPTY") { + if (ContainsDeferred($el, $el->{LEVELS}[0])) { + return 1; + } + } + } + return ! $have_default; +} + sub ParseArrayPullGetSize($$$$$$) { my ($self,$e,$l,$ndr,$var_name,$env) = @_; @@ -1923,11 +1942,13 @@ sub ParseUnionPush($$$$) $self->ParseUnionPushPrimitives($e, $ndr, $varname); $self->deindent; $self->pidl("}"); - $self->pidl("if (ndr_flags & NDR_BUFFERS) {"); - $self->indent; - $self->ParseUnionPushDeferred($e, $ndr, $varname); - $self->deindent; - $self->pidl("}"); + if (is_deferred_switch_non_empty($e)) { + $self->pidl("if (ndr_flags & NDR_BUFFERS) {"); + $self->indent; + $self->ParseUnionPushDeferred($e, $ndr, $varname); + $self->deindent; + $self->pidl("}"); + } $self->end_flags($e, $ndr); } @@ -2093,21 +2114,21 @@ sub ParseUnionPull($$$$) $self->start_flags($e, $ndr); - $self->pidl("level = ndr_pull_get_switch_value($ndr, $varname);"); - $self->pidl("NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);"); $self->pidl("if (ndr_flags & NDR_SCALARS) {"); $self->indent; + $self->pidl("level = ndr_pull_get_switch_value($ndr, $varname);"); $self->ParseUnionPullPrimitives($e,$ndr,$varname,$switch_type); $self->deindent; $self->pidl("}"); - - $self->pidl("if (ndr_flags & NDR_BUFFERS) {"); - $self->indent; - $self->ParseUnionPullDeferred($e,$ndr,$varname); - $self->deindent; - $self->pidl("}"); - + if (is_deferred_switch_non_empty($e)) { + $self->pidl("if (ndr_flags & NDR_BUFFERS) {"); + $self->indent; + $self->pidl("level = ndr_pull_get_switch_value($ndr, $varname);"); + $self->ParseUnionPullDeferred($e,$ndr,$varname); + $self->deindent; + $self->pidl("}"); + } $self->add_deferred(); $self->end_flags($e, $ndr); -- 2.34.1