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 + -
显示快捷键?