summaryrefslogtreecommitdiff
path: root/source4/build/pidl/ndr.pm
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2005-03-31 22:50:28 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:11:22 -0500
commitb1e46fde3a3b05baa871240ec173a7cfd5af8a02 (patch)
tree38edfd73578b506a373a5e24a7723b60fee9153f /source4/build/pidl/ndr.pm
parent4b96d831479f31ae6e0f2039f4b91c1bed643bea (diff)
downloadsamba-b1e46fde3a3b05baa871240ec173a7cfd5af8a02.tar.gz
samba-b1e46fde3a3b05baa871240ec173a7cfd5af8a02.tar.bz2
samba-b1e46fde3a3b05baa871240ec173a7cfd5af8a02.zip
r6159: Move some more general ndr stuff (alignment calculations) to ndr.pm
(This used to be commit f4d550c348e9604439f07329ddbc3cf65891d578)
Diffstat (limited to 'source4/build/pidl/ndr.pm')
-rw-r--r--source4/build/pidl/ndr.pm79
1 files changed, 75 insertions, 4 deletions
diff --git a/source4/build/pidl/ndr.pm b/source4/build/pidl/ndr.pm
index f7b52dd83d..0804737747 100644
--- a/source4/build/pidl/ndr.pm
+++ b/source4/build/pidl/ndr.pm
@@ -8,10 +8,17 @@
package Ndr;
use strict;
+use typelist;
#####################################################################
# return a table describing the order in which the parts of an element
# should be parsed
+# Possible level types:
+# - POINTER
+# - ARRAY
+# - SUBCONTEXT
+# - SWITCH
+# - DATA
sub GetElementLevelTable($)
{
my $e = shift;
@@ -20,6 +27,8 @@ sub GetElementLevelTable($)
my $order = [];
my $is_deferred = 0;
+
+ # FIXME: Process {ARRAY_SIZE} kinds of arrays
# First, all the pointers
foreach my $i (1..need_wire_pointer($e)) {
@@ -31,6 +40,7 @@ sub GetElementLevelTable($)
});
# everything that follows will be deferred
$is_deferred = 1;
+ # FIXME: Process array here possibly (in case of multi-dimensional arrays, etc)
}
if (defined($e->{ARRAY_LEN})) {
@@ -47,7 +57,8 @@ sub GetElementLevelTable($)
push (@$order, {
TYPE => "SUBCONTEXT",
SUBCONTEXT_SIZE => $sub_size,
- IS_DEFERRED => $is_deferred
+ IS_DEFERRED => $is_deferred,
+ COMPRESSION => util::has_property($e, "compression")
});
}
@@ -61,6 +72,7 @@ sub GetElementLevelTable($)
push (@$order, {
TYPE => "DATA",
+ DATA_TYPE => $e->{TYPE},
NAME => $e->{NAME},
IS_DEFERRED => $is_deferred,
CONTAINS_DEFERRED => can_contain_deferred($e)
@@ -204,6 +216,61 @@ sub find_largest_alignment($)
return $align;
}
+my %scalar_alignments =
+(
+ "char" => 1,
+ "int8" => 1,
+ "uint8" => 1,
+ "short" => 2,
+ "wchar_t" => 2,
+ "int16" => 2,
+ "uint16" => 2,
+ "long" => 4,
+ "int32" => 4,
+ "uint32" => 4,
+ "dlong" => 4,
+ "udlong" => 4,
+ "udlongr" => 4,
+ "NTTIME" => 4,
+ "NTTIME_1sec" => 4,
+ "time_t" => 4,
+ "DATA_BLOB" => 4,
+ "error_status_t" => 4,
+ "WERROR" => 4,
+ "NTSTATUS" => 4,
+ "boolean32" => 4,
+ "unsigned32" => 4,
+ "ipv4address" => 4,
+ "hyper" => 8,
+ "NTTIME_hyper" => 8
+);
+
+#####################################################################
+# align a type
+sub align_type
+{
+ my $e = shift;
+
+ unless (typelist::hasType($e)) {
+ # it must be an external type - all we can do is guess
+ # print "Warning: assuming alignment of unknown type '$e' is 4\n";
+ return 4;
+ }
+
+ my $dt = typelist::getType($e)->{DATA};
+
+ if ($dt->{TYPE} eq "ENUM") {
+ return align_type(typelist::enum_type_fn($dt));
+ } elsif ($dt->{TYPE} eq "BITMAP") {
+ return align_type(typelist::bitmap_type_fn($dt));
+ } elsif (($dt->{TYPE} eq "STRUCT") or ($dt->{TYPE} eq "UNION")) {
+ return find_largest_alignment($dt);
+ } elsif ($dt->{TYPE} eq "SCALAR") {
+ return $scalar_alignments{$dt->{NAME}};
+ } else {
+ die("Unknown data type type $dt->{TYPE}");
+ }
+}
# determine if an element needs a reference pointer on the wire
# in its NDR representation
@@ -329,7 +396,10 @@ sub ParseTypedef($$)
die("Unknown data type '$d->{DATA}->{TYPE}'");
}
+ $data->{ALIGN} = align_type($d->{NAME});
+
return {
+ NAME => $d->{NAME},
TYPE => "TYPEDEF",
PROPERTIES => $d->{PROPERTIES},
DATA => $data
@@ -347,16 +417,17 @@ sub ParseFunction($$)
$ndr->{PROPERTIES}->{pointer_default} # MIDL defaults to "ref"
);
- foreach my $x ($d->{ELEMENTS}) {
+ foreach my $x (@{$d->{ELEMENTS}}) {
if (util::has_property($x, "in")) {
- push @in, ParseElement($x);
+ push (@in, ParseElement($x));
}
if (util::has_property($x, "out")) {
- push @out, ParseElement($x);
+ push (@out, ParseElement($x));
}
}
return {
+ NAME => $d->{NAME},
TYPE => "FUNCTION",
RETURN_TYPE => $d->{RETURN_TYPE},
PROPERTIES => $d->{PROPERTIES},