parser.pm
来自「samba最新软件」· PM 代码 · 共 2,327 行 · 第 1/5 页
PM
2,327 行
$self->end_flags($bitmap);}sub DeclBitmap($$$$){ my ($e,$t,$name,$varname) = @_; return mapTypeName(Parse::Pidl::Typelist::bitmap_type_fn($e)) . ($t eq "pull"?" *":" ") . $varname;}$typefamily{BITMAP} = { DECL => \&DeclBitmap, PUSH_FN_BODY => \&ParseBitmapPush, PULL_FN_BODY => \&ParseBitmapPull, PRINT_FN_BODY => \&ParseBitmapPrint,};###################################################################### generate a struct print functionsub ParseStructPrint($$$$){ my($self,$struct,$name,$varname) = @_; return unless defined $struct->{ELEMENTS}; my $env = GenerateStructEnv($struct, $varname); $self->DeclareArrayVariables($_) foreach (@{$struct->{ELEMENTS}}); $self->pidl("ndr_print_struct(ndr, name, \"$name\");"); $self->start_flags($struct); $self->pidl("ndr->depth++;"); $self->ParseElementPrint($_, $env->{$_->{NAME}}, $env) foreach (@{$struct->{ELEMENTS}}); $self->pidl("ndr->depth--;"); $self->end_flags($struct);}sub DeclarePtrVariables($$){ my ($self,$e) = @_; foreach my $l (@{$e->{LEVELS}}) { if ($l->{TYPE} eq "POINTER" and not ($l->{POINTER_TYPE} eq "ref" and $l->{LEVEL} eq "TOP")) { $self->pidl("uint32_t _ptr_$e->{NAME};"); last; } }}sub DeclareArrayVariables($$){ my ($self,$e) = @_; foreach my $l (@{$e->{LEVELS}}) { next if has_fast_array($e,$l); next if is_charset_array($e,$l); if ($l->{TYPE} eq "ARRAY") { $self->pidl("uint32_t cntr_$e->{NAME}_$l->{LEVEL_INDEX};"); } }}sub DeclareMemCtxVariables($$){ my ($self,$e) = @_; foreach my $l (@{$e->{LEVELS}}) { my $mem_flags = $self->ParseMemCtxPullFlags($e, $l); if (defined($mem_flags)) { $self->pidl("TALLOC_CTX *_mem_save_$e->{NAME}_$l->{LEVEL_INDEX};"); } }}sub ParseStructPullPrimitives($$$$){ my($self,$struct,$varname,$env) = @_; if (defined $struct->{SURROUNDING_ELEMENT}) { $self->pidl("NDR_CHECK(ndr_pull_array_size(ndr, &$varname->$struct->{SURROUNDING_ELEMENT}->{NAME}));"); } $self->pidl("NDR_CHECK(ndr_pull_align(ndr, $struct->{ALIGN}));"); if (defined($struct->{PROPERTIES}{relative_base})) { # set the current offset as base for relative pointers # and store it based on the toplevel struct/union $self->pidl("NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, $varname, ndr->offset));"); } $self->ParseElementPull($_, "ndr", $env, 1, 0) foreach (@{$struct->{ELEMENTS}}); $self->add_deferred();}sub ParseStructPullDeferred($$$$){ my ($self,$struct,$varname,$env) = @_; if (defined($struct->{PROPERTIES}{relative_base})) { # retrieve the current offset as base for relative pointers # based on the toplevel struct/union $self->pidl("NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, $varname));"); } foreach my $e (@{$struct->{ELEMENTS}}) { $self->ParseElementPull($e, "ndr", $env, 0, 1); } $self->add_deferred();}###################################################################### parse a struct - pull sidesub ParseStructPull($$$){ my($self,$struct,$varname) = @_; return unless defined $struct->{ELEMENTS}; # declare any internal pointers we need foreach my $e (@{$struct->{ELEMENTS}}) { $self->DeclarePtrVariables($e); $self->DeclareArrayVariables($e); $self->DeclareMemCtxVariables($e); } $self->start_flags($struct); my $env = GenerateStructEnv($struct, $varname); $self->pidl("if (ndr_flags & NDR_SCALARS) {"); $self->indent; $self->ParseStructPullPrimitives($struct,$varname,$env); $self->deindent; $self->pidl("}"); $self->pidl("if (ndr_flags & NDR_BUFFERS) {"); $self->indent; $self->ParseStructPullDeferred($struct,$varname,$env); $self->deindent; $self->pidl("}"); $self->end_flags($struct);}###################################################################### calculate size of ndr structsub ParseStructNdrSize($$$$){ my ($self,$t, $name, $varname) = @_; my $sizevar; if (my $flags = has_property($t, "flag")) { $self->pidl("flags |= $flags;"); } $self->pidl("return ndr_size_struct($varname, flags, (ndr_push_flags_fn_t)ndr_push_$name);");}sub DeclStruct($$$$){ my ($e,$t,$name,$varname) = @_; return ($t ne "pull"?"const ":"") . "struct $name *$varname";}sub ArgsStructNdrSize($$$){ my ($d, $name, $varname) = @_; return "const struct $name *$varname, int flags";}$typefamily{STRUCT} = { PUSH_FN_BODY => \&ParseStructPush, DECL => \&DeclStruct, PULL_FN_BODY => \&ParseStructPull, PRINT_FN_BODY => \&ParseStructPrint, SIZE_FN_BODY => \&ParseStructNdrSize, SIZE_FN_ARGS => \&ArgsStructNdrSize,};###################################################################### calculate size of ndr structsub ParseUnionNdrSize($$$){ my ($self, $t, $name, $varname) = @_; my $sizevar; if (my $flags = has_property($t, "flag")) { $self->pidl("flags |= $flags;"); } $self->pidl("return ndr_size_union($varname, flags, level, (ndr_push_flags_fn_t)ndr_push_$name);");}sub ParseUnionPushPrimitives($$$){ my ($self, $e, $varname) = @_; my $have_default = 0; $self->pidl("int level = ndr_push_get_switch_value(ndr, $varname);"); if (defined($e->{SWITCH_TYPE})) { $self->pidl("NDR_CHECK(ndr_push_$e->{SWITCH_TYPE}(ndr, NDR_SCALARS, level));"); } $self->pidl("switch (level) {"); $self->indent; foreach my $el (@{$e->{ELEMENTS}}) { if ($el->{CASE} eq "default") { $have_default = 1; } $self->pidl("$el->{CASE}: {"); if ($el->{TYPE} ne "EMPTY") { $self->indent; if (defined($e->{PROPERTIES}{relative_base})) { $self->pidl("NDR_CHECK(ndr_push_align(ndr, $el->{ALIGN}));"); # set the current offset as base for relative pointers # and store it based on the toplevel struct/union $self->pidl("NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, $varname, ndr->offset));"); } $self->DeclareArrayVariables($el); $self->ParseElementPush($el, "ndr", {$el->{NAME} => "$varname->$el->{NAME}"}, 1, 0); $self->deindent; } $self->pidl("break; }"); $self->pidl(""); } if (! $have_default) { $self->pidl("default:"); $self->pidl("\treturn ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);"); } $self->deindent; $self->pidl("}");}sub ParseUnionPushDeferred($$$){ my ($self,$e,$varname) = @_; my $have_default = 0; $self->pidl("int level = ndr_push_get_switch_value(ndr, $varname);"); if (defined($e->{PROPERTIES}{relative_base})) { # retrieve the current offset as base for relative pointers # based on the toplevel struct/union $self->pidl("NDR_CHECK(ndr_push_setup_relative_base_offset2(ndr, $varname));"); } $self->pidl("switch (level) {"); $self->indent; foreach my $el (@{$e->{ELEMENTS}}) { if ($el->{CASE} eq "default") { $have_default = 1; } $self->pidl("$el->{CASE}:"); if ($el->{TYPE} ne "EMPTY") { $self->indent; $self->ParseElementPush($el, "ndr", {$el->{NAME} => "$varname->$el->{NAME}"}, 0, 1); $self->deindent; } $self->pidl("break;"); $self->pidl(""); } if (! $have_default) { $self->pidl("default:"); $self->pidl("\treturn ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);"); } $self->deindent; $self->pidl("}");}###################################################################### parse a union - push sidesub ParseUnionPush($$$){ my ($self,$e,$varname) = @_; my $have_default = 0; $self->start_flags($e); $self->pidl("if (ndr_flags & NDR_SCALARS) {"); $self->indent; $self->ParseUnionPushPrimitives($e, $varname); $self->deindent; $self->pidl("}"); $self->pidl("if (ndr_flags & NDR_BUFFERS) {"); $self->indent; $self->ParseUnionPushDeferred($e, $varname); $self->deindent; $self->pidl("}"); $self->end_flags($e);}###################################################################### print a unionsub ParseUnionPrint($$$$){ my ($self,$e,$name,$varname) = @_; my $have_default = 0; $self->pidl("int level;"); foreach my $el (@{$e->{ELEMENTS}}) { $self->DeclareArrayVariables($el); } $self->start_flags($e); $self->pidl("level = ndr_print_get_switch_value(ndr, $varname);"); $self->pidl("ndr_print_union(ndr, name, level, \"$name\");"); $self->pidl("switch (level) {"); $self->indent; foreach my $el (@{$e->{ELEMENTS}}) { if ($el->{CASE} eq "default") { $have_default = 1; } $self->pidl("$el->{CASE}:"); if ($el->{TYPE} ne "EMPTY") { $self->indent; $self->ParseElementPrint($el, "$varname->$el->{NAME}", {}); $self->deindent; } $self->pidl("break;"); $self->pidl(""); } if (! $have_default) { $self->pidl("default:"); $self->pidl("\tndr_print_bad_level(ndr, name, level);"); } $self->deindent; $self->pidl("}"); $self->end_flags($e);}sub ParseUnionPullPrimitives($$$$){ my ($self,$e,$varname,$switch_type) = @_; my $have_default = 0; if (defined($switch_type)) { $self->pidl("NDR_CHECK(ndr_pull_$switch_type(ndr, NDR_SCALARS, &_level));"); $self->pidl("if (_level != level) {"); $self->pidl("\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %u for $varname\", _level);"); $self->pidl("}"); } $self->pidl("switch (level) {"); $self->indent; foreach my $el (@{$e->{ELEMENTS}}) { if ($el->{CASE} eq "default") { $have_default = 1; } $self->pidl("$el->{CASE}: {"); if ($el->{TYPE} ne "EMPTY") { $self->indent; $self->DeclarePtrVariables($el); $self->DeclareArrayVariables($el); if (defined($e->{PROPERTIES}{relative_base})) { $self->pidl("NDR_CHECK(ndr_pull_align(ndr, $el->{ALIGN}));"); # set the current offset as base for relative pointers # and store it based on the toplevel struct/union $self->pidl("NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, $varname, ndr->offset));"); } $self->ParseElementPull($el, "ndr", {$el->{NAME} => "$varname->$el->{NAME}"}, 1, 0); $self->deindent; } $self->pidl("break; }"); $self->pidl(""); } if (! $have_default) { $self->pidl("default:"); $self->pidl("\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);"); } $self->deindent; $self->pidl("}");}sub ParseUnionPullDeferred($$$){ my ($self,$e,$varname) = @_; my $have_default = 0; if (defined($e->{PROPERTIES}{relative_base})) { # retrieve the current offset as base for relative pointers # based on the toplevel struct/union $self->pidl("NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, $varname));"); } $self->pidl("switch (level) {"); $self->indent; foreach my $el (@{$e->{ELEMENTS}}) { if ($el->{CASE} eq "default") { $have_default = 1; } $self->pidl("$el->{CASE}:"); if ($el->{TYPE} ne "EMPTY") { $self->indent; $self->ParseElementPull($el, "ndr", {$el->{NAME} => "$varname->$el->{NAME}"}, 0, 1); $self->deindent; } $self->pidl("break;"); $self->pidl(""); } if (! $have_default) { $self->pidl("default:"); $self->pidl("\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);"); } $self->deindent; $self->pidl("}");}###################################################################### parse a union - pull sidesub ParseUnionPull($$$){ my ($self,$e,$varname) = @_; my $switch_type = $e->{SWITCH_TYPE}; $self->pidl("int level;"); if (defined($switch_type)) { if (Parse::Pidl::Typelist::typeIs($switch_type, "ENUM")) { $switch_type = Parse::Pidl::Typelist::enum_type_fn(getType($switch_type)->{DATA}); } $self->pidl(mapTypeName($switch_type) . " _level;"); } my %double_cases = (); foreach my $el (@{$e->{ELEMENTS}}) { next if ($el->{TYPE} eq "EMPTY"); next if ($double_cases{"$el->{NAME}"}); $self->DeclareMemCtxVariables($el); $double_cases{"$el->{NAME}"} = 1; } $self->start_flags($e); $self->pidl("level = ndr_pull_get_switch_value(ndr, $varname);"); $self->pidl("if (ndr_flags & NDR_SCALARS) {"); $self->indent; $self->ParseUnionPullPrimitives($e,$varname,$switch_type); $self->deindent; $self->pidl("}"); $self->pidl("if (ndr_flags & NDR_BUFFERS) {"); $self->indent; $self->ParseUnionPullDeferred($e,$varname); $self->deindent; $self->pidl("}"); $self->add_deferred(); $self->end_flags($e);}sub DeclUnion($$$$){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?