summaryrefslogtreecommitdiff
path: root/source4/build
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2005-08-18 01:24:08 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:33:29 -0500
commitec96a742f7b6ce4cbb4f649dd8aba92ef80f0ff0 (patch)
tree79de41fa761ca1854c1054161173bec374d371eb /source4/build
parenta8d31eac00cf13c20343374f11224778e470e849 (diff)
downloadsamba-ec96a742f7b6ce4cbb4f649dd8aba92ef80f0ff0.tar.gz
samba-ec96a742f7b6ce4cbb4f649dd8aba92ef80f0ff0.tar.bz2
samba-ec96a742f7b6ce4cbb4f649dd8aba92ef80f0ff0.zip
r9373: - create a hierachical memory tree with recursiv ndr_pull_* functions
- with this it's also possible to talloc_free() the ndr_pull structure and talloc_steal(ndr->current_mem_ctx); to fetch the whole data of the hierachical tree - if the toplevel struct is a valid talloc pointer it's also possible to use NDR_PULL_SET_MEM_CTX(ndr, mem_ctx); to the the toplevel pointer with the struct pointer (NOTE: no callers are using this yet, but they shortly will) metze (This used to be commit 1a2b8369586642cc9bc15d015c1e4256c3a92732)
Diffstat (limited to 'source4/build')
-rw-r--r--source4/build/pidl/Parse/Pidl/Samba/NDR/Parser.pm137
1 files changed, 126 insertions, 11 deletions
diff --git a/source4/build/pidl/Parse/Pidl/Samba/NDR/Parser.pm b/source4/build/pidl/Parse/Pidl/Samba/NDR/Parser.pm
index 8692fbb0f4..d456bd5898 100644
--- a/source4/build/pidl/Parse/Pidl/Samba/NDR/Parser.pm
+++ b/source4/build/pidl/Parse/Pidl/Samba/NDR/Parser.pm
@@ -836,6 +836,59 @@ sub CalcNdrFlags($$$)
return undef;
}
+sub ParseMemCtxPullStart($$$)
+{
+ my $e = shift;
+ my $l = shift;
+ my $ptr_name = shift;
+
+ my $mem_r_ctx = "_mem_save_$e->{NAME}_$l->{LEVEL_INDEX}";
+ my $mem_c_ctx = $ptr_name;
+ my $mem_c_flags = "0";
+
+ return if ($l->{TYPE} eq "ARRAY" and $l->{IS_FIXED});
+
+ if (($l->{TYPE} eq "POINTER") and ($l->{POINTER_TYPE} eq "ref")) {
+ my $nl = GetNextLevel($e, $l);
+ my $next_is_array = ($nl->{TYPE} eq "ARRAY");
+ my $next_is_string = (($nl->{TYPE} eq "DATA") and
+ ($nl->{DATA_TYPE} eq "string"));
+ if ($next_is_array or $next_is_string) {
+ return;
+ } else {
+ $mem_c_flags = "LIBNDR_FLAG_REF_ALLOC";
+ }
+ }
+
+ pidl "$mem_r_ctx = NDR_PULL_GET_MEM_CTX(ndr);";
+ pidl "NDR_PULL_SET_MEM_CTX(ndr, $mem_c_ctx, $mem_c_flags);";
+}
+
+sub ParseMemCtxPullEnd($$)
+{
+ my $e = shift;
+ my $l = shift;
+
+ my $mem_r_ctx = "_mem_save_$e->{NAME}_$l->{LEVEL_INDEX}";
+ my $mem_r_flags = "0";
+
+ return if ($l->{TYPE} eq "ARRAY" and $l->{IS_FIXED});
+
+ if (($l->{TYPE} eq "POINTER") and ($l->{POINTER_TYPE} eq "ref")) {
+ my $nl = GetNextLevel($e, $l);
+ my $next_is_array = ($nl->{TYPE} eq "ARRAY");
+ my $next_is_string = (($nl->{TYPE} eq "DATA") and
+ ($nl->{DATA_TYPE} eq "string"));
+ if ($next_is_array or $next_is_string) {
+ return;
+ } else {
+ $mem_r_flags = "LIBNDR_FLAG_REF_ALLOC";
+ }
+ }
+
+ pidl "NDR_PULL_SET_MEM_CTX(ndr, $mem_r_ctx, $mem_r_flags);";
+}
+
sub ParseElementPullLevel
{
my($e,$l,$ndr,$var_name,$env,$primitives,$deferred) = @_;
@@ -890,9 +943,13 @@ sub ParseElementPullLevel
}
}
+ ParseMemCtxPullStart($e,$l, $var_name);
+
$var_name = get_value_of($var_name);
ParseElementPullLevel($e,GetNextLevel($e,$l), $ndr, $var_name, $env, 1, 1);
+ ParseMemCtxPullEnd($e,$l);
+
if ($l->{POINTER_TYPE} ne "ref") {
if ($l->{POINTER_TYPE} eq "relative") {
pidl "ndr_pull_restore(ndr, &_relative_save);";
@@ -904,9 +961,12 @@ sub ParseElementPullLevel
not has_fast_array($e,$l) and not has_property($e, "charset")) {
my $length = ParseExpr($l->{LENGTH_IS}, $env);
my $counter = "cntr_$e->{NAME}_$l->{LEVEL_INDEX}";
+ my $array_name = $var_name;
$var_name = $var_name . "[$counter]";
+ ParseMemCtxPullStart($e,$l, $array_name);
+
if (($primitives and not $l->{IS_DEFERRED}) or ($deferred and $l->{IS_DEFERRED})) {
pidl "for ($counter = 0; $counter < $length; $counter++) {";
indent;
@@ -927,6 +987,9 @@ sub ParseElementPullLevel
deindent;
pidl "}";
}
+
+ ParseMemCtxPullEnd($e,$l);
+
} elsif ($l->{TYPE} eq "SWITCH") {
ParseElementPullLevel($e,GetNextLevel($e,$l), $ndr, $var_name, $env, $primitives, $deferred);
}
@@ -969,7 +1032,7 @@ sub ParsePtrPull($$$$)
unless ($next_is_array or $next_is_string) {
pidl "if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {";
- pidl "\tNDR_ALLOC($ndr, $var_name);";
+ pidl "\tNDR_PULL_ALLOC($ndr, $var_name);";
pidl "}";
}
@@ -987,9 +1050,13 @@ sub ParsePtrPull($$$$)
# Don't do this for arrays, they're allocated at the actual level
# of the array
unless ($next_is_array or $next_is_string) {
- pidl "NDR_ALLOC($ndr, $var_name);";
+ pidl "NDR_PULL_ALLOC($ndr, $var_name);";
} else {
- pidl "NDR_ALLOC_SIZE($ndr, $var_name, 1);"; # FIXME: Yes, this is nasty. We allocate an array twice - once just to indicate that it's there, then the real allocation...
+ # FIXME: Yes, this is nasty.
+ # We allocate an array twice
+ # - once just to indicate that it's there,
+ # - then the real allocation...
+ pidl "NDR_PULL_ALLOC_SIZE($ndr, $var_name, 1);";
}
#pidl "memset($var_name, 0, sizeof($var_name));";
@@ -1285,6 +1352,37 @@ sub DeclareArrayVariables($)
}
}
+sub need_decl_mem_ctx($$)
+{
+ my $e = shift;
+ my $l = shift;
+
+ return 0 if has_fast_array($e,$l);
+ return 0 if (has_property($e, "charset") and ($l->{TYPE} ne "POINTER"));
+ return 1 if (($l->{TYPE} eq "ARRAY") and not $l->{IS_FIXED});
+
+ if (($l->{TYPE} eq "POINTER") and ($l->{POINTER_TYPE} eq "ref")) {
+ my $nl = GetNextLevel($e, $l);
+ my $next_is_array = ($nl->{TYPE} eq "ARRAY");
+ my $next_is_string = (($nl->{TYPE} eq "DATA") and
+ ($nl->{DATA_TYPE} eq "string"));
+ return 0 if ($next_is_array or $next_is_string);
+ }
+ return 1 if ($l->{TYPE} eq "POINTER");
+
+ return 0;
+}
+
+sub DeclareMemCtxVariables($)
+{
+ my $e = shift;
+ foreach my $l (@{$e->{LEVELS}}) {
+ if (need_decl_mem_ctx($e, $l)) {
+ pidl "TALLOC_CTX *_mem_save_$e->{NAME}_$l->{LEVEL_INDEX};";
+ }
+ }
+}
+
#####################################################################
# parse a struct - pull side
sub ParseStructPull($$)
@@ -1299,6 +1397,7 @@ sub ParseStructPull($$)
foreach my $e (@{$struct->{ELEMENTS}}) {
DeclarePtrVariables($e);
DeclareArrayVariables($e);
+ DeclareMemCtxVariables($e);
}
# save the old relative_base_offset
@@ -1543,6 +1642,14 @@ sub ParseUnionPull($$)
pidl Parse::Pidl::Typelist::mapType($switch_type) . " _level;";
}
+ my %double_cases = ();
+ foreach my $el (@{$e->{ELEMENTS}}) {
+ next if ($el->{TYPE} eq "EMPTY");
+ next if ($double_cases{"$el->{NAME}"});
+ DeclareMemCtxVariables($el);
+ $double_cases{"$el->{NAME}"} = 1;
+ }
+
start_flags($e);
pidl "level = ndr_pull_get_switch_value(ndr, r);";
@@ -1846,12 +1953,12 @@ sub AllocateArrayLevel($$$$$)
if (defined($pl) and
$pl->{TYPE} eq "POINTER" and
$pl->{POINTER_TYPE} eq "ref"
- and not $l->{IS_ZERO_TERMINATED}) {
- pidl "if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {";
- pidl "\tNDR_ALLOC_N($ndr, $var, $size);";
- pidl "}";
+ and not $l->{IS_ZERO_TERMINATED}) {
+ pidl "if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {";
+ pidl "\tNDR_PULL_ALLOC_N($ndr, $var, $size);";
+ pidl "}";
} else {
- pidl "NDR_ALLOC_N($ndr, $var, $size);";
+ pidl "NDR_PULL_ALLOC_N($ndr, $var, $size);";
}
if (grep(/in/,@{$e->{DIRECTION}}) and
@@ -1876,10 +1983,18 @@ sub ParseFunctionPull($)
# declare any internal pointers we need
foreach my $e (@{$fn->{ELEMENTS}}) {
- DeclarePtrVariables($e);
+ DeclarePtrVariables($e);
DeclareArrayVariables($e);
}
+ my %double_cases = ();
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ next if ($e->{TYPE} eq "EMPTY");
+ next if ($double_cases{"$e->{NAME}"});
+ DeclareMemCtxVariables($e);
+ $double_cases{"$e->{NAME}"} = 1;
+ }
+
pidl "if (flags & NDR_IN) {";
indent;
@@ -1917,7 +2032,7 @@ sub ParseFunctionPull($)
my $size = ParseExpr($e->{LEVELS}[1]->{SIZE_IS}, $env);
check_null_pointer($size);
- pidl "NDR_ALLOC_N(ndr, r->out.$e->{NAME}, $size);";
+ pidl "NDR_PULL_ALLOC_N(ndr, r->out.$e->{NAME}, $size);";
if (grep(/in/, @{$e->{DIRECTION}})) {
pidl "memcpy(r->out.$e->{NAME}, r->in.$e->{NAME}, $size * sizeof(*r->in.$e->{NAME}));";
@@ -1925,7 +2040,7 @@ sub ParseFunctionPull($)
pidl "memset(r->out.$e->{NAME}, 0, $size * sizeof(*r->out.$e->{NAME}));";
}
} else {
- pidl "NDR_ALLOC(ndr, r->out.$e->{NAME});";
+ pidl "NDR_PULL_ALLOC(ndr, r->out.$e->{NAME});";
if (grep(/in/, @{$e->{DIRECTION}})) {
pidl "*r->out.$e->{NAME} = *r->in.$e->{NAME};";