ndr: avoid unnecessary searches of token list
[kai/samba-autobuild/.git] / pidl / lib / Parse / Pidl / Samba4 / NDR / Parser.pm
index f52d4b10f6d54b5b0ba7ab2f71ab7f51630e9d07..c53ec4a8690d631b1177733bc3ae6eba0cc510af 100644 (file)
@@ -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);