mirror of
https://github.com/samba-team/samba.git
synced 2025-01-25 06:04:04 +03:00
r6159: Move some more general ndr stuff (alignment calculations) to ndr.pm
This commit is contained in:
parent
61e1eea0fd
commit
f4d550c348
@ -8,10 +8,17 @@
|
|||||||
package Ndr;
|
package Ndr;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
|
use typelist;
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
# return a table describing the order in which the parts of an element
|
# return a table describing the order in which the parts of an element
|
||||||
# should be parsed
|
# should be parsed
|
||||||
|
# Possible level types:
|
||||||
|
# - POINTER
|
||||||
|
# - ARRAY
|
||||||
|
# - SUBCONTEXT
|
||||||
|
# - SWITCH
|
||||||
|
# - DATA
|
||||||
sub GetElementLevelTable($)
|
sub GetElementLevelTable($)
|
||||||
{
|
{
|
||||||
my $e = shift;
|
my $e = shift;
|
||||||
@ -20,6 +27,8 @@ sub GetElementLevelTable($)
|
|||||||
|
|
||||||
my $order = [];
|
my $order = [];
|
||||||
my $is_deferred = 0;
|
my $is_deferred = 0;
|
||||||
|
|
||||||
|
# FIXME: Process {ARRAY_SIZE} kinds of arrays
|
||||||
|
|
||||||
# First, all the pointers
|
# First, all the pointers
|
||||||
foreach my $i (1..need_wire_pointer($e)) {
|
foreach my $i (1..need_wire_pointer($e)) {
|
||||||
@ -31,6 +40,7 @@ sub GetElementLevelTable($)
|
|||||||
});
|
});
|
||||||
# everything that follows will be deferred
|
# everything that follows will be deferred
|
||||||
$is_deferred = 1;
|
$is_deferred = 1;
|
||||||
|
# FIXME: Process array here possibly (in case of multi-dimensional arrays, etc)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defined($e->{ARRAY_LEN})) {
|
if (defined($e->{ARRAY_LEN})) {
|
||||||
@ -47,7 +57,8 @@ sub GetElementLevelTable($)
|
|||||||
push (@$order, {
|
push (@$order, {
|
||||||
TYPE => "SUBCONTEXT",
|
TYPE => "SUBCONTEXT",
|
||||||
SUBCONTEXT_SIZE => $sub_size,
|
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, {
|
push (@$order, {
|
||||||
TYPE => "DATA",
|
TYPE => "DATA",
|
||||||
|
DATA_TYPE => $e->{TYPE},
|
||||||
NAME => $e->{NAME},
|
NAME => $e->{NAME},
|
||||||
IS_DEFERRED => $is_deferred,
|
IS_DEFERRED => $is_deferred,
|
||||||
CONTAINS_DEFERRED => can_contain_deferred($e)
|
CONTAINS_DEFERRED => can_contain_deferred($e)
|
||||||
@ -204,6 +216,61 @@ sub find_largest_alignment($)
|
|||||||
return $align;
|
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
|
# determine if an element needs a reference pointer on the wire
|
||||||
# in its NDR representation
|
# in its NDR representation
|
||||||
@ -329,7 +396,10 @@ sub ParseTypedef($$)
|
|||||||
die("Unknown data type '$d->{DATA}->{TYPE}'");
|
die("Unknown data type '$d->{DATA}->{TYPE}'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$data->{ALIGN} = align_type($d->{NAME});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
NAME => $d->{NAME},
|
||||||
TYPE => "TYPEDEF",
|
TYPE => "TYPEDEF",
|
||||||
PROPERTIES => $d->{PROPERTIES},
|
PROPERTIES => $d->{PROPERTIES},
|
||||||
DATA => $data
|
DATA => $data
|
||||||
@ -347,16 +417,17 @@ sub ParseFunction($$)
|
|||||||
$ndr->{PROPERTIES}->{pointer_default} # MIDL defaults to "ref"
|
$ndr->{PROPERTIES}->{pointer_default} # MIDL defaults to "ref"
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach my $x ($d->{ELEMENTS}) {
|
foreach my $x (@{$d->{ELEMENTS}}) {
|
||||||
if (util::has_property($x, "in")) {
|
if (util::has_property($x, "in")) {
|
||||||
push @in, ParseElement($x);
|
push (@in, ParseElement($x));
|
||||||
}
|
}
|
||||||
if (util::has_property($x, "out")) {
|
if (util::has_property($x, "out")) {
|
||||||
push @out, ParseElement($x);
|
push (@out, ParseElement($x));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
NAME => $d->{NAME},
|
||||||
TYPE => "FUNCTION",
|
TYPE => "FUNCTION",
|
||||||
RETURN_TYPE => $d->{RETURN_TYPE},
|
RETURN_TYPE => $d->{RETURN_TYPE},
|
||||||
PROPERTIES => $d->{PROPERTIES},
|
PROPERTIES => $d->{PROPERTIES},
|
||||||
|
@ -21,42 +21,6 @@ sub get_typefamily($)
|
|||||||
return $typefamily{$n};
|
return $typefamily{$n};
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
|
||||||
);
|
|
||||||
|
|
||||||
$typefamily{SCALAR} = {
|
|
||||||
ALIGN => sub {
|
|
||||||
my $t = shift;
|
|
||||||
return $scalar_alignments{$t->{NAME}};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
# determine if an element needs a "buffers" section in NDR
|
# determine if an element needs a "buffers" section in NDR
|
||||||
sub need_buffers_section($)
|
sub need_buffers_section($)
|
||||||
{
|
{
|
||||||
@ -256,46 +220,6 @@ sub end_flags($)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#####################################################################
|
|
||||||
# work out the correct alignment for a structure or union
|
|
||||||
sub find_largest_alignment($)
|
|
||||||
{
|
|
||||||
my $s = shift;
|
|
||||||
|
|
||||||
my $align = 1;
|
|
||||||
for my $e (@{$s->{ELEMENTS}}) {
|
|
||||||
my $a = 1;
|
|
||||||
|
|
||||||
if (Ndr::need_wire_pointer($e)) {
|
|
||||||
$a = 4;
|
|
||||||
} else {
|
|
||||||
$a = align_type($e->{TYPE});
|
|
||||||
}
|
|
||||||
|
|
||||||
$align = $a if ($align < $a);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $align;
|
|
||||||
}
|
|
||||||
|
|
||||||
#####################################################################
|
|
||||||
# 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};
|
|
||||||
|
|
||||||
my $tmp = $typefamily{$dt->{TYPE}}->{ALIGN}->($dt);
|
|
||||||
return $tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
# parse array preceding data - push side
|
# parse array preceding data - push side
|
||||||
sub ParseArrayPushPreceding($$$)
|
sub ParseArrayPushPreceding($$$)
|
||||||
@ -1036,7 +960,7 @@ sub ParseStructPush($)
|
|||||||
|
|
||||||
pidl "NDR_CHECK(ndr_push_struct_start(ndr));";
|
pidl "NDR_CHECK(ndr_push_struct_start(ndr));";
|
||||||
|
|
||||||
my $align = find_largest_alignment($struct);
|
my $align = Ndr::find_largest_alignment($struct);
|
||||||
pidl "NDR_CHECK(ndr_push_align(ndr, $align));";
|
pidl "NDR_CHECK(ndr_push_align(ndr, $align));";
|
||||||
|
|
||||||
foreach my $e (@{$struct->{ELEMENTS}}) {
|
foreach my $e (@{$struct->{ELEMENTS}}) {
|
||||||
@ -1142,7 +1066,6 @@ $typefamily{ENUM} = {
|
|||||||
PULL_FN_ARGS => \&ArgsEnumPull,
|
PULL_FN_ARGS => \&ArgsEnumPull,
|
||||||
PRINT_FN_BODY => \&ParseEnumPrint,
|
PRINT_FN_BODY => \&ParseEnumPrint,
|
||||||
PRINT_FN_ARGS => \&ArgsEnumPrint,
|
PRINT_FN_ARGS => \&ArgsEnumPrint,
|
||||||
ALIGN => sub { return align_type(typelist::enum_type_fn(shift)); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
@ -1244,7 +1167,6 @@ $typefamily{BITMAP} = {
|
|||||||
PULL_FN_ARGS => \&ArgsBitmapPull,
|
PULL_FN_ARGS => \&ArgsBitmapPull,
|
||||||
PRINT_FN_BODY => \&ParseBitmapPrint,
|
PRINT_FN_BODY => \&ParseBitmapPrint,
|
||||||
PRINT_FN_ARGS => \&ArgsBitmapPrint,
|
PRINT_FN_ARGS => \&ArgsBitmapPrint,
|
||||||
ALIGN => sub { return align_type(typelist::bitmap_type_fn(shift)); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
@ -1310,7 +1232,7 @@ sub ParseStructPull($)
|
|||||||
ParseArrayPullPreceding($conform_e, "r->", "NDR_SCALARS");
|
ParseArrayPullPreceding($conform_e, "r->", "NDR_SCALARS");
|
||||||
}
|
}
|
||||||
|
|
||||||
my $align = find_largest_alignment($struct);
|
my $align = Ndr::find_largest_alignment($struct);
|
||||||
pidl "NDR_CHECK(ndr_pull_align(ndr, $align));";
|
pidl "NDR_CHECK(ndr_pull_align(ndr, $align));";
|
||||||
|
|
||||||
foreach my $e (@{$struct->{ELEMENTS}}) {
|
foreach my $e (@{$struct->{ELEMENTS}}) {
|
||||||
@ -1381,7 +1303,6 @@ $typefamily{STRUCT} = {
|
|||||||
PRINT_FN_ARGS => \&ArgsStructPrint,
|
PRINT_FN_ARGS => \&ArgsStructPrint,
|
||||||
SIZE_FN_BODY => \&ParseStructNdrSize,
|
SIZE_FN_BODY => \&ParseStructNdrSize,
|
||||||
SIZE_FN_ARGS => \&ArgsStructNdrSize,
|
SIZE_FN_ARGS => \&ArgsStructNdrSize,
|
||||||
ALIGN => \&find_largest_alignment
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
@ -1638,7 +1559,6 @@ $typefamily{UNION} = {
|
|||||||
PRINT_FN_ARGS => \&ArgsUnionPrint,
|
PRINT_FN_ARGS => \&ArgsUnionPrint,
|
||||||
SIZE_FN_ARGS => \&ArgsUnionNdrSize,
|
SIZE_FN_ARGS => \&ArgsUnionNdrSize,
|
||||||
SIZE_FN_BODY => \&ParseUnionNdrSize,
|
SIZE_FN_BODY => \&ParseUnionNdrSize,
|
||||||
ALIGN => \&find_largest_alignment
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
@ -2110,32 +2030,20 @@ sub ParseInterface($)
|
|||||||
|
|
||||||
# Push functions
|
# Push functions
|
||||||
foreach my $d (@{$data}) {
|
foreach my $d (@{$data}) {
|
||||||
($d->{TYPE} eq "TYPEDEF") &&
|
if ($d->{TYPE} eq "TYPEDEF") {
|
||||||
ParseTypedefPush($d);
|
ParseTypedefPush($d);
|
||||||
($d->{TYPE} eq "FUNCTION") &&
|
|
||||||
ParseFunctionPush($d);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Pull functions
|
|
||||||
foreach my $d (@{$data}) {
|
|
||||||
($d->{TYPE} eq "TYPEDEF") &&
|
|
||||||
ParseTypedefPull($d);
|
ParseTypedefPull($d);
|
||||||
($d->{TYPE} eq "FUNCTION") &&
|
|
||||||
ParseFunctionPull($d);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Print functions
|
|
||||||
foreach my $d (@{$data}) {
|
|
||||||
($d->{TYPE} eq "TYPEDEF") &&
|
|
||||||
ParseTypedefPrint($d);
|
ParseTypedefPrint($d);
|
||||||
($d->{TYPE} eq "FUNCTION") &&
|
ParseTypedefNdrSize($d);
|
||||||
ParseFunctionPrint($d);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Size functions
|
|
||||||
foreach my $d (@{$data}) {
|
foreach my $d (@{$data}) {
|
||||||
($d->{TYPE} eq "TYPEDEF") &&
|
if ($d->{TYPE} eq "FUNCTION") {
|
||||||
ParseTypedefNdrSize($d);
|
ParseFunctionPush($d);
|
||||||
|
ParseFunctionPull($d);
|
||||||
|
ParseFunctionPrint($d);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionTable($interface);
|
FunctionTable($interface);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user