📄 parser.pm
字号:
if (not $l->{IS_FIXED} and not is_charset_array($e, $l)) { $self->AllocateArrayLevel($e,$l,$ndr,$env,$size); } return $length;}sub compression_alg($$){ my ($e, $l) = @_; my ($alg, $clen, $dlen) = split(/ /, $l->{COMPRESSION}); return $alg;}sub compression_clen($$$){ my ($e, $l, $env) = @_; my ($alg, $clen, $dlen) = split(/ /, $l->{COMPRESSION}); return ParseExpr($clen, $env, $e->{ORIGINAL});}sub compression_dlen($$$){ my ($e,$l,$env) = @_; my ($alg, $clen, $dlen) = split(/ /, $l->{COMPRESSION}); return ParseExpr($dlen, $env, $e->{ORIGINAL});}sub ParseCompressionPushStart($$$$$){ my ($self,$e,$l,$ndr,$env) = @_; my $comndr = "$ndr\_compressed"; my $alg = compression_alg($e, $l); my $dlen = compression_dlen($e, $l, $env); $self->pidl("{"); $self->indent; $self->pidl("struct ndr_push *$comndr;"); $self->pidl("NDR_CHECK(ndr_push_compression_start($ndr, &$comndr, $alg, $dlen));"); return $comndr;}sub ParseCompressionPushEnd($$$$$){ my ($self,$e,$l,$ndr,$env) = @_; my $comndr = "$ndr\_compressed"; my $alg = compression_alg($e, $l); my $dlen = compression_dlen($e, $l, $env); $self->pidl("NDR_CHECK(ndr_push_compression_end($ndr, $comndr, $alg, $dlen));"); $self->deindent; $self->pidl("}");}sub ParseCompressionPullStart($$$$$){ my ($self,$e,$l,$ndr,$env) = @_; my $comndr = "$ndr\_compressed"; my $alg = compression_alg($e, $l); my $dlen = compression_dlen($e, $l, $env); $self->pidl("{"); $self->indent; $self->pidl("struct ndr_pull *$comndr;"); $self->pidl("NDR_CHECK(ndr_pull_compression_start($ndr, &$comndr, $alg, $dlen));"); return $comndr;}sub ParseCompressionPullEnd($$$$$){ my ($self,$e,$l,$ndr,$env) = @_; my $comndr = "$ndr\_compressed"; my $alg = compression_alg($e, $l); my $dlen = compression_dlen($e, $l, $env); $self->pidl("NDR_CHECK(ndr_pull_compression_end($ndr, $comndr, $alg, $dlen));"); $self->deindent; $self->pidl("}");}sub ParseSubcontextPushStart($$$$$){ my ($self,$e,$l,$ndr,$env) = @_; my $subndr = "_ndr_$e->{NAME}"; my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE}, $env, $e->{ORIGINAL}); $self->pidl("{"); $self->indent; $self->pidl("struct ndr_push *$subndr;"); $self->pidl("NDR_CHECK(ndr_push_subcontext_start($ndr, &$subndr, $l->{HEADER_SIZE}, $subcontext_size));"); if (defined $l->{COMPRESSION}) { $subndr = $self->ParseCompressionPushStart($e, $l, $subndr, $env); } return $subndr;}sub ParseSubcontextPushEnd($$$$$){ my ($self,$e,$l,$ndr,$env) = @_; my $subndr = "_ndr_$e->{NAME}"; my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE}, $env, $e->{ORIGINAL}); if (defined $l->{COMPRESSION}) { $self->ParseCompressionPushEnd($e, $l, $subndr, $env); } $self->pidl("NDR_CHECK(ndr_push_subcontext_end($ndr, $subndr, $l->{HEADER_SIZE}, $subcontext_size));"); $self->deindent; $self->pidl("}");}sub ParseSubcontextPullStart($$$$$){ my ($self,$e,$l,$ndr,$env) = @_; my $subndr = "_ndr_$e->{NAME}"; my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE}, $env, $e->{ORIGINAL}); $self->pidl("{"); $self->indent; $self->pidl("struct ndr_pull *$subndr;"); $self->pidl("NDR_CHECK(ndr_pull_subcontext_start($ndr, &$subndr, $l->{HEADER_SIZE}, $subcontext_size));"); if (defined $l->{COMPRESSION}) { $subndr = $self->ParseCompressionPullStart($e, $l, $subndr, $env); } return $subndr;}sub ParseSubcontextPullEnd($$$$$){ my ($self,$e,$l,$ndr,$env) = @_; my $subndr = "_ndr_$e->{NAME}"; my $subcontext_size = ParseExpr($l->{SUBCONTEXT_SIZE}, $env, $e->{ORIGINAL}); if (defined $l->{COMPRESSION}) { $self->ParseCompressionPullEnd($e, $l, $subndr, $env); } $self->pidl("NDR_CHECK(ndr_pull_subcontext_end($ndr, $subndr, $l->{HEADER_SIZE}, $subcontext_size));"); $self->deindent; $self->pidl("}");}sub ParseElementPushLevel{ my ($self,$e,$l,$ndr,$var_name,$env,$primitives,$deferred) = @_; my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred); if ($l->{TYPE} eq "ARRAY" and ($l->{IS_CONFORMANT} or $l->{IS_VARYING})) { $var_name = get_pointer_to($var_name); } if (defined($ndr_flags)) { if ($l->{TYPE} eq "SUBCONTEXT") { my $subndr = $self->ParseSubcontextPushStart($e, $l, $ndr, $env); $self->ParseElementPushLevel($e, GetNextLevel($e, $l), $subndr, $var_name, $env, 1, 1); $self->ParseSubcontextPushEnd($e, $l, $ndr, $env); } elsif ($l->{TYPE} eq "POINTER") { $self->ParsePtrPush($e, $l, $var_name); } elsif ($l->{TYPE} eq "ARRAY") { my $length = $self->ParseArrayPushHeader($e, $l, $ndr, $var_name, $env); my $nl = GetNextLevel($e, $l); # Allow speedups for arrays of scalar types if (is_charset_array($e,$l)) { $self->pidl("NDR_CHECK(ndr_push_charset($ndr, $ndr_flags, $var_name, $length, sizeof(" . mapTypeName($nl->{DATA_TYPE}) . "), CH_$e->{PROPERTIES}->{charset}));"); return; } elsif (has_fast_array($e,$l)) { $self->pidl("NDR_CHECK(ndr_push_array_$nl->{DATA_TYPE}($ndr, $ndr_flags, $var_name, $length));"); return; } } elsif ($l->{TYPE} eq "SWITCH") { $self->ParseSwitchPush($e, $l, $ndr, $var_name, $env); } elsif ($l->{TYPE} eq "DATA") { $self->ParseDataPush($e, $l, $ndr, $var_name, $primitives, $deferred); } } if ($l->{TYPE} eq "POINTER" and $deferred) { if ($l->{POINTER_TYPE} ne "ref") { $self->pidl("if ($var_name) {"); $self->indent; if ($l->{POINTER_TYPE} eq "relative") { $self->pidl("NDR_CHECK(ndr_push_relative_ptr2(ndr, $var_name));"); } } $var_name = get_value_of($var_name); $self->ParseElementPushLevel($e, GetNextLevel($e, $l), $ndr, $var_name, $env, 1, 1); if ($l->{POINTER_TYPE} ne "ref") { $self->deindent; $self->pidl("}"); } } elsif ($l->{TYPE} eq "ARRAY" and not has_fast_array($e,$l) and not is_charset_array($e, $l)) { my $length = ParseExpr($l->{LENGTH_IS}, $env, $e->{ORIGINAL}); my $counter = "cntr_$e->{NAME}_$l->{LEVEL_INDEX}"; $var_name = $var_name . "[$counter]"; if (($primitives and not $l->{IS_DEFERRED}) or ($deferred and $l->{IS_DEFERRED})) { $self->pidl("for ($counter = 0; $counter < $length; $counter++) {"); $self->indent; $self->ParseElementPushLevel($e, GetNextLevel($e, $l), $ndr, $var_name, $env, 1, 0); $self->deindent; $self->pidl("}"); } if ($deferred and ContainsDeferred($e, $l)) { $self->pidl("for ($counter = 0; $counter < $length; $counter++) {"); $self->indent; $self->ParseElementPushLevel($e, GetNextLevel($e, $l), $ndr, $var_name, $env, 0, 1); $self->deindent; $self->pidl("}"); } } elsif ($l->{TYPE} eq "SWITCH") { $self->ParseElementPushLevel($e, GetNextLevel($e, $l), $ndr, $var_name, $env, $primitives, $deferred); }}###################################################################### parse scalars in a structure elementsub ParseElementPush($$$$$$){ my ($self,$e,$ndr,$env,$primitives,$deferred) = @_; my $subndr = undef; my $var_name = $env->{$e->{NAME}}; return unless $primitives or ($deferred and ContainsDeferred($e, $e->{LEVELS}[0])); # Representation type is different from transmit_as if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) { $self->pidl("{"); $self->indent; my $transmit_name = "_transmit_$e->{NAME}"; $self->pidl(mapTypeName($e->{TYPE}) ." $transmit_name;"); $self->pidl("NDR_CHECK(ndr_$e->{REPRESENTATION_TYPE}_to_$e->{TYPE}($var_name, " . get_pointer_to($transmit_name) . "));"); $var_name = $transmit_name; } $var_name = append_prefix($e, $var_name); $self->start_flags($e); if (defined(my $value = has_property($e, "value"))) { $var_name = ParseExpr($value, $env, $e->{ORIGINAL}); } $self->ParseElementPushLevel($e, $e->{LEVELS}[0], $ndr, $var_name, $env, $primitives, $deferred); $self->end_flags($e); if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) { $self->deindent; $self->pidl("}"); }}###################################################################### parse a pointer in a struct element or functionsub ParsePtrPush($$$$){ my ($self,$e,$l,$var_name) = @_; if ($l->{POINTER_TYPE} eq "ref") { $self->pidl("if ($var_name == NULL) {"); $self->indent; $self->pidl("return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, \"NULL [ref] pointer\");"); $self->deindent; $self->pidl("}"); if ($l->{LEVEL} eq "EMBEDDED") { $self->pidl("NDR_CHECK(ndr_push_ref_ptr(ndr));"); } } elsif ($l->{POINTER_TYPE} eq "relative") { $self->pidl("NDR_CHECK(ndr_push_relative_ptr1(ndr, $var_name));"); } elsif ($l->{POINTER_TYPE} eq "unique") { $self->pidl("NDR_CHECK(ndr_push_unique_ptr(ndr, $var_name));"); } elsif ($l->{POINTER_TYPE} eq "full") { $self->pidl("NDR_CHECK(ndr_push_full_ptr(ndr, $var_name));"); } else { die("Unhandled pointer type $l->{POINTER_TYPE}"); }}sub ParseDataPrint($$$$){ my ($self, $e, $l, $var_name) = @_; if (not ref($l->{DATA_TYPE}) or defined($l->{DATA_TYPE}->{NAME})) { my $t; if (ref($l->{DATA_TYPE})) { $t = "$l->{DATA_TYPE}->{TYPE}_$l->{DATA_TYPE}->{NAME}"; } else { $t = $l->{DATA_TYPE}; } if (not Parse::Pidl::Typelist::is_scalar($t) or Parse::Pidl::Typelist::scalar_is_reference($t)) { $var_name = get_pointer_to($var_name); } $self->pidl("ndr_print_$t(ndr, \"$e->{NAME}\", $var_name);"); } else { $self->ParseTypePrint($l->{DATA_TYPE}, $var_name); }}###################################################################### print scalars in a structure elementsub ParseElementPrint($$$$){ my($self, $e, $var_name, $env) = @_; return if (has_property($e, "noprint")); if ($e->{REPRESENTATION_TYPE} ne $e->{TYPE}) { $self->pidl("ndr_print_$e->{REPRESENTATION_TYPE}(ndr, \"$e->{NAME}\", $var_name);"); return; } $var_name = append_prefix($e, $var_name); if (defined(my $value = has_property($e, "value"))) { $var_name = "(ndr->flags & LIBNDR_PRINT_SET_VALUES)?" . ParseExpr($value,$env, $e->{ORIGINAL}) . ":$var_name"; } foreach my $l (@{$e->{LEVELS}}) { if ($l->{TYPE} eq "POINTER") { $self->pidl("ndr_print_ptr(ndr, \"$e->{NAME}\", $var_name);"); $self->pidl("ndr->depth++;"); if ($l->{POINTER_TYPE} ne "ref") { $self->pidl("if ($var_name) {"); $self->indent; } $var_name = get_value_of($var_name); } elsif ($l->{TYPE} eq "ARRAY") { my $length; if ($l->{IS_CONFORMANT} or $l->{IS_VARYING}) { $var_name = get_pointer_to($var_name); } if ($l->{IS_ZERO_TERMINATED}) { $length = "ndr_string_length($var_name, sizeof(*$var_name))"; } else { $length = ParseExprExt($l->{LENGTH_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, sub { $self->pidl(shift); }, "return;"), check_fully_dereferenced($e, $env)); } if (is_charset_array($e,$l)) { $self->pidl("ndr_print_string(ndr, \"$e->{NAME}\", $var_name);"); last; } elsif (has_fast_array($e, $l)) { my $nl = GetNextLevel($e, $l); $self->pidl("ndr_print_array_$nl->{DATA_TYPE}(ndr, \"$e->{NAME}\", $var_name, $length);"); last; } else { my $counter = "cntr_$e->{NAME}_$l->{LEVEL_INDEX}"; $self->pidl("ndr->print(ndr, \"\%s: ARRAY(\%d)\", \"$e->{NAME}\", $length);"); $self->pidl("ndr->depth++;"); $self->pidl("for ($counter=0;$counter<$length;$counter++) {"); $self->indent; $self->pidl("char *idx_$l->{LEVEL_INDEX}=NULL;"); $self->pidl("asprintf(&idx_$l->{LEVEL_INDEX}, \"[\%d]\", $counter);"); $self->pidl("if (idx_$l->{LEVEL_INDEX}) {"); $self->indent; $var_name = $var_name . "[$counter]"; } } elsif ($l->{TYPE} eq "DATA") { $self->ParseDataPrint($e, $l, $var_name); } elsif ($l->{TYPE} eq "SWITCH") { my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, sub { $self->pidl(shift); }, "return;"), check_fully_dereferenced($e, $env)); $self->pidl("ndr_print_set_switch_value(ndr, " . get_pointer_to($var_name) . ", $switch_var);"); } } foreach my $l (reverse @{$e->{LEVELS}}) { if ($l->{TYPE} eq "POINTER") { if ($l->{POINTER_TYPE} ne "ref") { $self->deindent; $self->pidl("}"); } $self->pidl("ndr->depth--;"); } elsif (($l->{TYPE} eq "ARRAY") and not is_charset_array($e,$l) and not has_fast_array($e,$l)) { $self->pidl("free(idx_$l->{LEVEL_INDEX});"); $self->deindent; $self->pidl("}"); $self->deindent; $self->pidl("}"); $self->pidl("ndr->depth--;"); } }}###################################################################### parse scalars in a structure element - pull sizesub ParseSwitchPull($$$$$$){ my($self,$e,$l,$ndr,$var_name,$env) = @_; my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, sub { $self->pidl(shift); }, "return ndr_pull_error(ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for switch_is()\");"), check_fully_dereferenced($e, $env)); $var_name = get_pointer_to($var_name); $self->pidl("NDR_CHECK(ndr_pull_set_switch_value($ndr, $var_name, $switch_var));");}###################################################################### push switch elementsub ParseSwitchPush($$$$$$){ my($self,$e,$l,$ndr,$var_name,$env) = @_; my $switch_var = ParseExprExt($l->{SWITCH_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, sub { $self->pidl(shift); }, "return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for switch_is()\");"), check_fully_dereferenced($e, $env)); $var_name = get_pointer_to($var_name); $self->pidl("NDR_CHECK(ndr_push_set_switch_value($ndr, $var_name, $switch_var));");}sub ParseDataPull($$$$$$$){ my ($self,$e,$l,$ndr,$var_name,$primitives,$deferred) = @_; if (not ref($l->{DATA_TYPE}) or defined($l->{DATA_TYPE}->{NAME})) { my $ndr_flags = CalcNdrFlags($l, $primitives, $deferred); if (Parse::Pidl::Typelist::scalar_is_reference($l->{DATA_TYPE})) { $var_name = get_pointer_to($var_name); } $var_name = get_pointer_to($var_name); $self->pidl("NDR_CHECK(".TypeFunctionName("ndr_pull", $l->{DATA_TYPE})."($ndr, $ndr_flags, $var_name));"); if (my $range = has_property($e, "range")) { $var_name = get_value_of($var_name); my ($low, $high) = split(/ /, $range, 2); $self->pidl("if ($var_name < $low || $var_name > $high) {"); $self->pidl("\treturn ndr_pull_error($ndr, NDR_ERR_RANGE, \"value out of range\");"); $self->pidl("}"); } } else { $self->ParseTypePull($l->{DATA_TYPE}, $var_name, $primitives, $deferred); }}sub ParseDataPush($$$$$$$){ my ($self,$e,$l,$ndr,$var_name,$primitives,$deferred) = @_; if (not ref($l->{DATA_TYPE}) or defined($l->{DATA_TYPE}->{NAME})) { my $t;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -