summaryrefslogtreecommitdiff
path: root/pidl
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2010-09-21 01:44:38 +0200
committerStefan Metzmacher <metze@samba.org>2011-03-10 14:31:19 +0100
commitd79fb9098bc3ce37daa8ab6d51dc62ad0bc2ad26 (patch)
tree750342a79c398407fa1ea924aaad2c734be29c10 /pidl
parentf43e757096750dc2844af49363981fd0246d9f48 (diff)
downloadsamba-d79fb9098bc3ce37daa8ab6d51dc62ad0bc2ad26.tar.gz
pidl: add support for 'pipe' at the NDR layer
metze
Diffstat (limited to 'pidl')
-rw-r--r--pidl/lib/Parse/Pidl/NDR.pm133
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/Header.pm26
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm14
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm213
-rw-r--r--pidl/lib/Parse/Pidl/Typelist.pm12
5 files changed, 380 insertions, 18 deletions
diff --git a/pidl/lib/Parse/Pidl/NDR.pm b/pidl/lib/Parse/Pidl/NDR.pm
index 7b1e007831..d91c324b53 100644
--- a/pidl/lib/Parse/Pidl/NDR.pm
+++ b/pidl/lib/Parse/Pidl/NDR.pm
@@ -39,7 +39,7 @@ $VERSION = '0.01';
use strict;
use Parse::Pidl qw(warning fatal);
-use Parse::Pidl::Typelist qw(hasType getType expandAlias mapScalarType);
+use Parse::Pidl::Typelist qw(hasType getType typeIs expandAlias mapScalarType is_fixed_size_scalar);
use Parse::Pidl::Util qw(has_property property_matches);
# Alignment of the built-in scalar types
@@ -115,6 +115,51 @@ sub GetElementLevelTable($$$)
warning($e, "[out] argument `$e->{NAME}' not a pointer") if ($needptrs > $e->{POINTERS});
}
+ my $allow_pipe = ($e->{PARENT}->{TYPE} eq "FUNCTION");
+ my $is_pipe = typeIs($e->{TYPE}, "PIPE");
+
+ if ($is_pipe) {
+ if (not $allow_pipe) {
+ fatal($e, "argument `$e->{NAME}' is a pipe and not allowed on $e->{PARENT}->{TYPE}");
+ }
+
+ if ($e->{POINTERS} > 1) {
+ fatal($e, "$e->{POINTERS} are not allowed on pipe element $e->{NAME}");
+ }
+
+ if ($e->{POINTERS} < 0) {
+ fatal($e, "pipe element $e->{NAME} needs pointer");
+ }
+
+ if ($e->{POINTERS} == 1 and pointer_type($e) ne "ref") {
+ fatal($e, "pointer should be 'ref' on pipe element $e->{NAME}");
+ }
+
+ if (scalar(@size_is) > 0) {
+ fatal($e, "size_is() on pipe element");
+ }
+
+ if (scalar(@length_is) > 0) {
+ fatal($e, "length_is() on pipe element");
+ }
+
+ if (scalar(@bracket_array) > 0) {
+ fatal($e, "brackets on pipe element");
+ }
+
+ if (defined(has_property($e, "subcontext"))) {
+ fatal($e, "subcontext on pipe element");
+ }
+
+ if (has_property($e, "switch_is")) {
+ fatal($e, "switch_is on pipe element");
+ }
+
+ if (can_contain_deferred($e->{TYPE})) {
+ fatal($e, "$e->{TYPE} can_contain_deferred - not allowed on pipe element");
+ }
+ }
+
# Parse the [][][][] style array stuff
for my $i (0 .. $#bracket_array) {
my $d = $bracket_array[$#bracket_array - $i];
@@ -259,6 +304,19 @@ sub GetElementLevelTable($$$)
}
}
+ if ($is_pipe) {
+ push (@$order, {
+ TYPE => "PIPE",
+ IS_DEFERRED => 0,
+ CONTAINS_DEFERRED => 0,
+ });
+
+ my $i = 0;
+ foreach (@$order) { $_->{LEVEL_INDEX} = $i; $i+=1; }
+
+ return $order;
+ }
+
if (defined(has_property($e, "subcontext"))) {
my $hdr_size = has_property($e, "subcontext");
my $subsize = has_property($e, "subcontext_size");
@@ -429,6 +487,8 @@ sub align_type($)
# Struct/union without body: assume 4
return 4 unless (defined($dt->{ELEMENTS}));
return find_largest_alignment($dt);
+ } elsif (($dt->{TYPE} eq "PIPE")) {
+ return 5;
}
die("Unknown data type type $dt->{TYPE}");
@@ -600,6 +660,57 @@ sub ParseBitmap($$$)
};
}
+sub ParsePipe($$$)
+{
+ my ($pipe, $pointer_default, $ms_union) = @_;
+
+ my $pname = $pipe->{NAME};
+ $pname = $pipe->{PARENT}->{NAME} unless defined $pname;
+
+ if (not defined($pipe->{PROPERTIES})
+ and defined($pipe->{PARENT}->{PROPERTIES})) {
+ $pipe->{PROPERTIES} = $pipe->{PARENT}->{PROPERTIES};
+ }
+
+ if (ref($pipe->{DATA}) eq "HASH") {
+ if (not defined($pipe->{DATA}->{PROPERTIES})
+ and defined($pipe->{PROPERTIES})) {
+ $pipe->{DATA}->{PROPERTIES} = $pipe->{PROPERTIES};
+ }
+ }
+
+ my $struct = ParseStruct($pipe->{DATA}, $pointer_default, $ms_union);
+ $struct->{ALIGN} = 5;
+ $struct->{NAME} = "$pname\_chunk";
+
+ # 'count' is element [0] and 'array' [1]
+ my $e = $struct->{ELEMENTS}[1];
+ # level [0] is of type "ARRAY"
+ my $l = $e->{LEVELS}[1];
+
+ # here we check that pipe elements have a fixed size type
+ while (defined($l)) {
+ my $cl = $l;
+ $l = GetNextLevel($e, $cl);
+ if ($cl->{TYPE} ne "DATA") {
+ fatal($pipe, el_name($pipe) . ": pipe contains non DATA level");
+ }
+
+ # for now we only support scalars
+ next if is_fixed_size_scalar($cl->{DATA_TYPE});
+
+ fatal($pipe, el_name($pipe) . ": pipe contains non fixed size type[$cl->{DATA_TYPE}]");
+ }
+
+ return {
+ TYPE => "PIPE",
+ NAME => $pipe->{NAME},
+ DATA => $struct,
+ PROPERTIES => $pipe->{PROPERTIES},
+ ORIGINAL => $pipe,
+ };
+}
+
sub ParseType($$$)
{
my ($d, $pointer_default, $ms_union) = @_;
@@ -610,6 +721,7 @@ sub ParseType($$$)
ENUM => \&ParseEnum,
BITMAP => \&ParseBitmap,
TYPEDEF => \&ParseTypedef,
+ PIPE => \&ParsePipe,
}->{$d->{TYPE}}->($d, $pointer_default, $ms_union);
return $data;
@@ -942,14 +1054,14 @@ my %property_list = (
"gensize" => ["TYPEDEF", "STRUCT", "UNION"],
"value" => ["ELEMENT"],
- "flag" => ["ELEMENT", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
+ "flag" => ["ELEMENT", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "PIPE"],
# generic
- "public" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
- "nopush" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
- "nopull" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
+ "public" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "PIPE"],
+ "nopush" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "PIPE"],
+ "nopull" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "PIPE"],
"nosize" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
- "noprint" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "ELEMENT"],
+ "noprint" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP", "ELEMENT", "PIPE"],
"nopython" => ["FUNCTION", "TYPEDEF", "STRUCT", "UNION", "ENUM", "BITMAP"],
"todo" => ["FUNCTION"],
@@ -1178,11 +1290,16 @@ sub ValidUnion($)
sub ValidPipe($)
{
my ($pipe) = @_;
- my $data = $pipe->{DATA};
+ my $struct = $pipe->{DATA};
ValidProperties($pipe, "PIPE");
- fatal($pipe, $pipe->{NAME} . ": 'pipe' is not yet supported by pidl");
+ $struct->{PARENT} = $pipe;
+
+ $struct->{FILE} = $pipe->{FILE} unless defined($struct->{FILE});
+ $struct->{LINE} = $pipe->{LINE} unless defined($struct->{LINE});
+
+ ValidType($struct);
}
#####################################################################
diff --git a/pidl/lib/Parse/Pidl/Samba4/Header.pm b/pidl/lib/Parse/Pidl/Samba4/Header.pm
index 9788b2c123..3736315120 100644
--- a/pidl/lib/Parse/Pidl/Samba4/Header.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/Header.pm
@@ -216,6 +216,30 @@ sub HeaderUnion($$;$)
}
#####################################################################
+# parse a pipe
+sub HeaderPipe($$;$)
+{
+ my($pipe,$name,$tail) = @_;
+
+ my $struct = $pipe->{DATA};
+ my $e = $struct->{ELEMENTS}[1];
+
+ pidl "struct $name;\n";
+ pidl "struct $struct->{NAME} {\n";
+ $tab_depth++;
+ pidl tabs()."uint32_t count;\n";
+ pidl tabs().mapTypeName($e->{TYPE})." *array;\n";
+ $tab_depth--;
+ pidl "}";
+
+ if (defined $struct->{PROPERTIES}) {
+ HeaderProperties($struct->{PROPERTIES}, []);
+ }
+
+ pidl $tail if defined($tail);
+}
+
+#####################################################################
# parse a type
sub HeaderType($$$;$)
{
@@ -225,6 +249,7 @@ sub HeaderType($$$;$)
($data->{TYPE} eq "BITMAP") && HeaderBitmap($data, $name);
($data->{TYPE} eq "STRUCT") && HeaderStruct($data, $name, $tail);
($data->{TYPE} eq "UNION") && HeaderUnion($data, $name, $tail);
+ ($data->{TYPE} eq "PIPE") && HeaderPipe($data, $name, $tail);
return;
}
@@ -385,6 +410,7 @@ sub HeaderInterface($)
HeaderUnion($t, $t->{NAME}, ";\n\n") if ($t->{TYPE} eq "UNION");
HeaderEnum($t, $t->{NAME}, ";\n\n") if ($t->{TYPE} eq "ENUM");
HeaderBitmap($t, $t->{NAME}) if ($t->{TYPE} eq "BITMAP");
+ HeaderPipe($t, $t->{NAME}, "\n\n") if ($t->{TYPE} eq "PIPE");
}
foreach my $fn (@{$interface->{FUNCTIONS}}) {
diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm
index 8f43702ad5..ab4f524b9f 100644
--- a/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Client.pm
@@ -101,10 +101,11 @@ sub ParseFunction_r_Send($$$$)
$self->pidl("");
my $out_params = 0;
- foreach (@{$fn->{ELEMENTS}}) {
- if (grep(/out/, @{$_->{DIRECTION}})) {
- $out_params++;
- }
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ next unless grep(/out/, @{$e->{DIRECTION}});
+ next if ContainsPipe($e, $e->{LEVELS}[0]);
+ $out_params++;
+
}
my $submem;
@@ -490,6 +491,9 @@ sub ParseFunction_Send($$$$)
next unless grep(/out/, @{$e->{DIRECTION}});
$self->ParseCopyArgument($fn, $e, "state->orig.out.", "_");
+
+ next if ContainsPipe($e, $e->{LEVELS}[0]);
+
$out_params++;
}
$self->pidl("");
@@ -569,6 +573,7 @@ sub ParseFunction_Done($$$$)
$self->pidl("/* Copy out parameters */");
foreach my $e (@{$fn->{ELEMENTS}}) {
+ next if ContainsPipe($e, $e->{LEVELS}[0]);
next unless (grep(/out/, @{$e->{DIRECTION}}));
$self->ParseOutputArgument($fn, $e,
@@ -698,6 +703,7 @@ sub ParseFunction_Sync($$$$)
$self->pidl("/* Return variables */");
foreach my $e (@{$fn->{ELEMENTS}}) {
+ next if ContainsPipe($e, $e->{LEVELS}[0]);
next unless (grep(/out/, @{$e->{DIRECTION}}));
$self->ParseOutputArgument($fn, $e, "r.", "_", "sync");
diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
index 075ad8516e..f84610d6c8 100644
--- a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
@@ -15,7 +15,7 @@ use strict;
use Parse::Pidl::Typelist qw(hasType getType mapTypeName typeHasBody);
use Parse::Pidl::Util qw(has_property ParseExpr ParseExprExt print_uuid unmake_str);
use Parse::Pidl::CUtil qw(get_pointer_to get_value_of get_array_element);
-use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred is_charset_array);
+use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel ContainsDeferred ContainsPipe is_charset_array);
use Parse::Pidl::Samba4 qw(is_intree choose_header ArrayDynamicallyAllocated);
use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv EnvSubstituteValue GenerateStructEnv);
use Parse::Pidl qw(warning);
@@ -630,6 +630,8 @@ sub ParseElementPush($$$$$$)
my $var_name = $env->{$e->{NAME}};
+ return if ContainsPipe($e, $e->{LEVELS}[0]);
+
return unless $primitives or ($deferred and ContainsDeferred($e, $e->{LEVELS}[0]));
# Representation type is different from transmit_as
@@ -945,6 +947,7 @@ sub ParseMemCtxPullFlags($$$$)
if (($l->{TYPE} eq "POINTER") and ($l->{POINTER_TYPE} eq "ref")) {
my $nl = GetNextLevel($e, $l);
+ return undef if ($nl->{TYPE} eq "PIPE");
return undef if ($nl->{TYPE} eq "ARRAY");
return undef if (($nl->{TYPE} eq "DATA") and ($nl->{DATA_TYPE} eq "string"));
@@ -1149,6 +1152,8 @@ sub ParseElementPull($$$$$$)
my $represent_name;
my $transmit_name;
+ return if ContainsPipe($e, $e->{LEVELS}[0]);
+
return unless $primitives or ($deferred and ContainsDeferred($e, $e->{LEVELS}[0]));
if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) {
@@ -2062,6 +2067,99 @@ $typefamily{TYPEDEF} = {
SIZE_FN_BODY => \&ParseTypedefNdrSize,
};
+sub ParsePipePushChunk($$)
+{
+ my ($self, $t) = @_;
+
+ my $pipe = $t;
+ $pipe = $t->{DATA} if ($t->{TYPE} eq "TYPEDEF");
+ my $struct = $pipe->{DATA};
+
+ my $name = "$struct->{NAME}";
+ my $ndr = "ndr";
+ my $varname = "r";
+
+ my $args = $typefamily{$struct->{TYPE}}->{DECL}->($struct, "push", $name, $varname);
+
+ $self->fn_declare("push", $struct, "enum ndr_err_code ndr_push_$name(struct ndr_push *$ndr, int ndr_flags, $args)") or return;
+
+ return if has_property($t, "nopush");
+
+ $self->pidl("{");
+ $self->indent;
+
+ $self->ParseStructPush($struct, $ndr, $varname);
+ $self->pidl("");
+
+ $self->pidl("NDR_CHECK(ndr_push_pipe_chunk_trailer(ndr, ndr_flags, $varname->count));");
+ $self->pidl("");
+
+ $self->pidl("return NDR_ERR_SUCCESS;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub ParsePipePullChunk($$)
+{
+ my ($self, $t) = @_;
+
+ my $pipe = $t;
+ $pipe = $t->{DATA} if ($t->{TYPE} eq "TYPEDEF");
+ my $struct = $pipe->{DATA};
+
+ my $name = "$struct->{NAME}";
+ my $ndr = "ndr";
+ my $varname = "r";
+
+ my $args = $typefamily{$struct->{TYPE}}->{DECL}->($struct, "pull", $name, $varname);
+
+ $self->fn_declare("pull", $struct, "enum ndr_err_code ndr_pull_$name(struct ndr_pull *$ndr, int ndr_flags, $args)") or return;
+
+ return if has_property($struct, "nopull");
+
+ $self->pidl("{");
+ $self->indent;
+
+ $self->ParseStructPull($struct, $ndr, $varname);
+ $self->pidl("");
+
+ $self->pidl("NDR_CHECK(ndr_check_pipe_chunk_trailer($ndr, ndr_flags, $varname->count));");
+ $self->pidl("");
+
+ $self->pidl("return NDR_ERR_SUCCESS;");
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
+sub ParsePipePrintChunk($$)
+{
+ my ($self, $t) = @_;
+
+ my $pipe = $t;
+ $pipe = $t->{DATA} if ($t->{TYPE} eq "TYPEDEF");
+ my $struct = $pipe->{DATA};
+
+ my $name = "$struct->{NAME}";
+ my $ndr = "ndr";
+ my $varname = "r";
+
+ my $args = $typefamily{$struct->{TYPE}}->{DECL}->($struct, "print", $name, $varname);
+
+ $self->pidl_hdr("void ndr_print_$name(struct ndr_print *ndr, const char *name, $args);");
+
+ return if (has_property($t, "noprint"));
+
+ $self->pidl("_PUBLIC_ void ndr_print_$name(struct ndr_print *$ndr, const char *name, $args)");
+ $self->pidl("{");
+ $self->indent;
+ $self->ParseTypePrint($struct, $ndr, $varname);
+ $self->deindent;
+ $self->pidl("}");
+ $self->pidl("");
+}
+
#####################################################################
# parse a function - print side
sub ParseFunctionPrint($$)
@@ -2264,6 +2362,7 @@ sub ParseFunctionPull($$)
$e->{LEVELS}[0]->{POINTER_TYPE} eq "ref");
next if (($e->{LEVELS}[1]->{TYPE} eq "DATA") and
($e->{LEVELS}[1]->{DATA_TYPE} eq "string"));
+ next if ($e->{LEVELS}[1]->{TYPE} eq "PIPE");
next if (($e->{LEVELS}[1]->{TYPE} eq "ARRAY")
and $e->{LEVELS}[1]->{IS_ZERO_TERMINATED});
@@ -2279,6 +2378,12 @@ sub ParseFunctionPull($$)
} else {
$self->pidl("memset(r->out.$e->{NAME}, 0, ($size) * sizeof(*r->out.$e->{NAME}));");
}
+ } elsif ($e->{LEVELS}[1]->{TYPE} eq "ARRAY") {
+ if (grep(/in/, @{$e->{DIRECTION}})) {
+ $self->pidl("r->out.$e->{NAME} = r->in.$e->{NAME};");
+ } else {
+ $self->pidl("r->out.$e->{NAME} = NULL;");
+ }
} else {
$self->pidl("NDR_PULL_ALLOC($ndr, r->out.$e->{NAME});");
@@ -2337,16 +2442,102 @@ sub AuthServiceStruct($$$)
$self->pidl("");
}
+sub ParseGeneratePipeArray($$$)
+{
+ my ($self, $fn, $direction) = @_;
+
+ $self->pidl("static const struct ndr_interface_call_pipe $fn->{NAME}\_$direction\_pipes[] = {");
+ $self->indent;
+
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ next unless ContainsPipe($e, $e->{LEVELS}[0]);
+ next unless (grep(/$direction/, @{$e->{DIRECTION}}));
+
+ my $cname = "$e->{TYPE}_chunk";
+
+ $self->pidl("{");
+ $self->indent;
+ $self->pidl("\"$direction.$e->{NAME}\",");
+ $self->pidl("\"$cname\",");
+ $self->pidl("sizeof(struct $cname),");
+ $self->pidl("(ndr_push_flags_fn_t) ndr_push_$cname,");
+ $self->pidl("(ndr_pull_flags_fn_t) ndr_pull_$cname,");
+ $self->pidl("(ndr_print_fn_t) ndr_print_$cname,");
+ $self->deindent;
+ $self->pidl("},");
+ }
+ $self->pidl("{ NULL, NULL, 0, NULL, NULL, NULL, NULL }");
+ $self->deindent;
+ $self->pidl("};");
+ $self->pidl("");
+}
+
+sub FunctionCallPipes($$)
+{
+ my ($self, $d) = @_;
+ return if not defined($d->{OPNUM});
+
+ my $in_pipes = 0;
+ my $out_pipes = 0;
+
+ foreach my $e (@{$d->{ELEMENTS}}) {
+ next unless ContainsPipe($e, $e->{LEVELS}[0]);
+
+ if (grep(/in/, @{$e->{DIRECTION}})) {
+ $in_pipes++;
+ }
+ if (grep(/out/, @{$e->{DIRECTION}})) {
+ $out_pipes++;
+ }
+ }
+
+ if ($in_pipes) {
+ $self->ParseGeneratePipeArray($d, "in");
+ }
+
+ if ($out_pipes) {
+ $self->ParseGeneratePipeArray($d, "out");
+ }
+}
+
sub FunctionCallEntry($$)
{
my ($self, $d) = @_;
return 0 if not defined($d->{OPNUM});
+
+ my $in_pipes = 0;
+ my $out_pipes = 0;
+
+ foreach my $e (@{$d->{ELEMENTS}}) {
+ next unless ContainsPipe($e, $e->{LEVELS}[0]);
+
+ if (grep(/in/, @{$e->{DIRECTION}})) {
+ $in_pipes++;
+ }
+ if (grep(/out/, @{$e->{DIRECTION}})) {
+ $out_pipes++;
+ }
+ }
+
+ my $in_pipes_ptr = "NULL";
+ my $out_pipes_ptr = "NULL";
+
+ if ($in_pipes) {
+ $in_pipes_ptr = "\&$d->{NAME}_in_pipes";
+ }
+
+ if ($out_pipes) {
+ $out_pipes_ptr = "\&$d->{NAME}_out_pipes";
+ }
+
$self->pidl("\t{");
$self->pidl("\t\t\"$d->{NAME}\",");
$self->pidl("\t\tsizeof(struct $d->{NAME}),");
$self->pidl("\t\t(ndr_push_flags_fn_t) ndr_push_$d->{NAME},");
$self->pidl("\t\t(ndr_pull_flags_fn_t) ndr_pull_$d->{NAME},");
$self->pidl("\t\t(ndr_print_function_t) ndr_print_$d->{NAME},");
+ $self->pidl("\t\t{ $in_pipes, $in_pipes_ptr },");
+ $self->pidl("\t\t{ $out_pipes, $out_pipes_ptr },");
$self->pidl("\t},");
return 1;
}
@@ -2362,6 +2553,10 @@ sub FunctionTable($$)
return if ($#{$interface->{FUNCTIONS}}+1 == 0);
return unless defined ($interface->{PROPERTIES}->{uuid});
+ foreach my $d (@{$interface->{INHERITED_FUNCTIONS}},@{$interface->{FUNCTIONS}}) {
+ $self->FunctionCallPipes($d);
+ }
+
$self->pidl("static const struct ndr_interface_call $interface->{NAME}\_calls[] = {");
foreach my $d (@{$interface->{INHERITED_FUNCTIONS}},@{$interface->{FUNCTIONS}}) {
@@ -2615,6 +2810,20 @@ sub ParseInterface($$$)
# Typedefs
foreach my $d (@{$interface->{TYPES}}) {
+ if (Parse::Pidl::Typelist::typeIs($d, "PIPE")) {
+ ($needed->{TypeFunctionName("ndr_push", $d)}) &&
+ $self->ParsePipePushChunk($d);
+ ($needed->{TypeFunctionName("ndr_pull", $d)}) &&
+ $self->ParsePipePullChunk($d);
+ ($needed->{TypeFunctionName("ndr_print", $d)}) &&
+ $self->ParsePipePrintChunk($d);
+
+ $needed->{TypeFunctionName("ndr_pull", $d)} = 0;
+ $needed->{TypeFunctionName("ndr_push", $d)} = 0;
+ $needed->{TypeFunctionName("ndr_print", $d)} = 0;
+ next;
+ }
+
next unless(typeHasBody($d));
($needed->{TypeFunctionName("ndr_push", $d)}) && $self->ParseTypePushFunction($d, "r");
@@ -2756,6 +2965,7 @@ sub NeededType($$$)
my ($t,$needed,$req) = @_;
NeededType($t->{DATA}, $needed, $req) if ($t->{TYPE} eq "TYPEDEF");
+ NeededType($t->{DATA}, $needed, $req) if ($t->{TYPE} eq "PIPE");
if ($t->{TYPE} eq "STRUCT" or $t->{TYPE} eq "UNION") {
return unless defined($t->{ELEMENTS});
@@ -2777,6 +2987,7 @@ sub NeededInterface($$)
my ($interface,$needed) = @_;
NeededFunction($_, $needed) foreach (@{$interface->{FUNCTIONS}});
foreach (reverse @{$interface->{TYPES}}) {
+
if (has_property($_, "public")) {
$needed->{TypeFunctionName("ndr_pull", $_)} = $needed->{TypeFunctionName("ndr_push", $_)} =
$needed->{TypeFunctionName("ndr_print", $_)} = 1;
diff --git a/pidl/lib/Parse/Pidl/Typelist.pm b/pidl/lib/Parse/Pidl/Typelist.pm
index bf78717b12..4f26a92ed2 100644
--- a/pidl/lib/Parse/Pidl/Typelist.pm
+++ b/pidl/lib/Parse/Pidl/Typelist.pm
@@ -291,6 +291,7 @@ sub mapType($$)
return "struct $n" if ($t->{TYPE} eq "STRUCT" or $t->{TYPE} eq "INTERFACE");
return "union $n" if ($t->{TYPE} eq "UNION");
return mapScalarType(bitmap_type_fn($t)) if ($t->{TYPE} eq "BITMAP");
+ return "struct $n" if ($t->{TYPE} eq "PIPE");
die("Unknown type $t->{TYPE}");
}
@@ -329,11 +330,12 @@ sub LoadIdl($;$)
}) if (has_property($x, "object"));
foreach my $y (@{$x->{DATA}}) {
- if ($y->{TYPE} eq "TYPEDEF"
- or $y->{TYPE} eq "UNION"
- or $y->{TYPE} eq "STRUCT"
- or $y->{TYPE} eq "ENUM"
- or $y->{TYPE} eq "BITMAP") {
+ if ($y->{TYPE} eq "TYPEDEF"
+ or $y->{TYPE} eq "UNION"
+ or $y->{TYPE} eq "STRUCT"
+ or $y->{TYPE} eq "ENUM"
+ or $y->{TYPE} eq "BITMAP"
+ or $y->{TYPE} eq "PIPE") {
$y->{BASEFILE} = $basename;
addType($y);
}