📄 parser.pm
字号:
$self->end_flags($bitmap);}###################################################################### generate a pull function for an bitmapsub ParseBitmapPull($$$){ my($self,$bitmap,$varname) = @_; my $type_fn = $bitmap->{BASE_TYPE}; my($type_decl) = mapTypeName($bitmap->{BASE_TYPE}); $self->pidl("$type_decl v;"); $self->start_flags($bitmap); $self->pidl("NDR_CHECK(ndr_pull_$type_fn(ndr, NDR_SCALARS, &v));"); $self->pidl("*$varname = v;"); $self->end_flags($bitmap);}###################################################################### generate a print function for an bitmapsub ParseBitmapPrintElement($$$$$){ my($self,$e,$bitmap,$name,$varname) = @_; my($type_decl) = mapTypeName($bitmap->{BASE_TYPE}); my($type_fn) = $bitmap->{BASE_TYPE}; my($flag); if ($e =~ /^(\w+) .*$/) { $flag = "$1"; } else { die "Bitmap: \"$name\" invalid Flag: \"$e\""; } $self->pidl("ndr_print_bitmap_flag(ndr, sizeof($type_decl), \"$flag\", $flag, $varname);");}###################################################################### generate a print function for an bitmapsub ParseBitmapPrint($$$$){ my($self,$bitmap,$name,$varname) = @_; my($type_decl) = mapTypeName($bitmap->{TYPE}); my($type_fn) = $bitmap->{BASE_TYPE}; $self->start_flags($bitmap); $self->pidl("ndr_print_$type_fn(ndr, name, $varname);"); $self->pidl("ndr->depth++;"); foreach my $e (@{$bitmap->{ELEMENTS}}) { $self->ParseBitmapPrintElement($e, $bitmap, $name, $varname); } $self->pidl("ndr->depth--;"); $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 need_decl_mem_ctx($$){ my ($e,$l) = @_; return 0 if has_fast_array($e,$l); return 0 if is_charset_array($e,$l); 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 ($self,$e) = @_; foreach my $l (@{$e->{LEVELS}}) { if (need_decl_mem_ctx($e, $l)) { $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}}) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -