⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ejs.pm

📁 wireshark 0.99.7 最新源码
💻 PM
📖 第 1 页 / 共 2 页
字号:
#################################################### EJS function wrapper generator# Copyright jelmer@samba.org 2005# Copyright Andrew Tridgell 2005# released under the GNU GPLpackage Parse::Pidl::Samba4::EJS;use Exporter;@ISA = qw(Exporter);@EXPORT_OK = qw(get_pointer_to get_value_of check_null_pointer fn_declare TypeFunctionName);use strict;use Parse::Pidl::Typelist;use Parse::Pidl::Util qw(has_property ParseExpr);use Parse::Pidl::NDR qw(GetPrevLevel GetNextLevel);use Parse::Pidl::Samba4::NDR::Parser qw(GenerateStructEnv GenerateFunctionInEnv                                        GenerateFunctionOutEnv);use vars qw($VERSION);$VERSION = '0.01';sub new($) {	my ($class) = @_;	my $self = { res => "", res_hdr => "", tabs => "", constants => {}};	bless($self, $class);}sub pidl_hdr ($$){	my $self = shift;	$self->{res_hdr} .= shift;}sub pidl($$){	my ($self, $d) = @_;	if ($d) {		$self->{res} .= $self->{tabs};		$self->{res} .= $d;	}	$self->{res} .= "\n";}sub indent($){	my ($self) = @_;	$self->{tabs} .= "\t";}sub deindent($){	my ($self) = @_;	$self->{tabs} = substr($self->{tabs}, 0, -1);}sub get_pointer_to($){	my $var_name = shift;		if ($var_name =~ /^\*(.*)$/) {		return $1;	} elsif ($var_name =~ /^\&(.*)$/) {		return "&($var_name)";	} else {		return "&$var_name";	}}sub get_value_of($){	my $var_name = shift;	if ($var_name =~ /^\&(.*)$/) {		return $1;	} else {		return "*$var_name";	}}###################################################################### check that a variable we get from ParseExpr isn't a null pointersub check_null_pointer($$){	my ($self, $size) = @_;	if ($size =~ /^\*/) {		my $size2 = substr($size, 1);		$self->pidl("if ($size2 == NULL) return NT_STATUS_INVALID_PARAMETER_MIX;");	}}###################################################################### work out is a parse function should be declared static or notsub fn_declare($$$){	my ($self,$fn,$decl) = @_;	if (has_property($fn, "public")) {		$self->pidl_hdr("$decl;\n");		$self->pidl("_PUBLIC_ $decl");	} else {		$self->pidl("static $decl");	}}############################ pull a scalar elementsub EjsPullScalar($$$$$$$){	my ($self, $e, $l, $var, $name, $env) = @_;	return if (has_property($e, "value"));	if (ref($e->{TYPE}) eq "HASH" and not defined($e->{TYPE}->{NAME})) {		$self->EjsTypePull($e->{TYPE}, $var);	} else {		my $pl = Parse::Pidl::NDR::GetPrevLevel($e, $l);        $var = get_pointer_to($var);        # have to handle strings specially :(		if (Parse::Pidl::Typelist::scalar_is_reference($e->{TYPE})			and (defined($pl) and $pl->{TYPE} eq "POINTER")) {                $var = get_pointer_to($var);        }    	my $t;		if (ref($e->{TYPE}) eq "HASH") {			$t = "$e->{TYPE}->{TYPE}_$e->{TYPE}->{NAME}";		} else {			$t = $e->{TYPE};		}		$self->pidl("EJS_CHECK(ejs_pull_$t(ejs, v, $name, $var));");	}}############################ pull a pointer elementsub EjsPullPointer($$$$$$){	my ($self, $e, $l, $var, $name, $env) = @_;	$self->pidl("if (ejs_pull_null(ejs, v, $name)) {");	$self->indent;	if ($l->{POINTER_TYPE} eq "ref") {		$self->pidl("return NT_STATUS_INVALID_PARAMETER_MIX;");	} else {		$self->pidl("$var = NULL;");	}	$self->deindent;	$self->pidl("} else {");	$self->indent;	$self->pidl("EJS_ALLOC(ejs, $var);");	$var = get_value_of($var);			$self->EjsPullElement($e, GetNextLevel($e, $l), $var, $name, $env);	$self->deindent;	$self->pidl("}");}############################ pull a string elementsub EjsPullString($$$$$$){	my ($self, $e, $l, $var, $name, $env) = @_;	my $pl = GetPrevLevel($e, $l);	$var = get_pointer_to($var);	if (defined($pl) and $pl->{TYPE} eq "POINTER") {		$var = get_pointer_to($var);	}	$self->pidl("EJS_CHECK(ejs_pull_string(ejs, v, $name, $var));");}############################ pull an array elementsub EjsPullArray($$$$$$){	my ($self, $e, $l, $var, $name, $env) = @_;	my $nl = GetNextLevel($e, $l);	my $length = ParseExpr($l->{LENGTH_IS}, $env, $e);	my $size = ParseExpr($l->{SIZE_IS}, $env, $e);	my $pl = GetPrevLevel($e, $l);	if ($pl && $pl->{TYPE} eq "POINTER") {		$var = get_pointer_to($var);	}	# uint8 arrays are treated as data blobs	if ($nl->{TYPE} eq 'DATA' && $e->{TYPE} eq 'uint8') {		if (!$l->{IS_FIXED}) {			$self->check_null_pointer($size);			$self->pidl("EJS_ALLOC_N(ejs, $var, $size);");		}		$self->check_null_pointer($length);		$self->pidl("ejs_pull_array_uint8(ejs, v, $name, $var, $length);");		return;	}	my $avar = $var . "[i]";	$self->pidl("{");	$self->indent;	$self->pidl("uint32_t i;");	if (!$l->{IS_FIXED}) {		$self->pidl("EJS_ALLOC_N(ejs, $var, $size);");	}	$self->pidl("for (i=0;i<$length;i++) {");	$self->indent;	$self->pidl("char *id = talloc_asprintf(ejs, \"%s.%u\", $name, i);");	$self->EjsPullElement($e, $nl, $avar, "id", $env);	$self->pidl("talloc_free(id);");	$self->deindent;	$self->pidl("}");	$self->pidl("ejs_push_uint32(ejs, v, $name \".length\", &i);");	$self->deindent;	$self->pidl("}");}############################ pull a switch elementsub EjsPullSwitch($$$$$$){	my ($self, $e, $l, $var, $name, $env) = @_;	my $switch_var = ParseExpr($l->{SWITCH_IS}, $env, $e);	$self->pidl("ejs_set_switch(ejs, $switch_var);");	$self->EjsPullElement($e, GetNextLevel($e, $l), $var, $name, $env);}############################ pull a structure elementsub EjsPullElement($$$$$$){	my ($self, $e, $l, $var, $name, $env) = @_;	if (($l->{TYPE} eq "POINTER")) {		$self->EjsPullPointer($e, $l, $var, $name, $env);	} elsif (has_property($e, "charset")) {		$self->EjsPullString($e, $l, $var, $name, $env);	} elsif ($l->{TYPE} eq "ARRAY") {		$self->EjsPullArray($e, $l, $var, $name, $env);	} elsif ($l->{TYPE} eq "DATA") {		$self->EjsPullScalar($e, $l, $var, $name, $env);	} elsif (($l->{TYPE} eq "SWITCH")) {		$self->EjsPullSwitch($e, $l, $var, $name, $env);	} else {		$self->pidl("return ejs_panic(ejs, \"unhandled pull type $l->{TYPE}\");");	}}############################################## pull a structure/union element at top levelsub EjsPullElementTop($$$){	my ($self, $e, $env) = @_;	my $l = $e->{LEVELS}[0];	my $var = ParseExpr($e->{NAME}, $env, $e);	my $name = "\"$e->{NAME}\"";	$self->EjsPullElement($e, $l, $var, $name, $env);}############################ pull a structsub EjsStructPull($$$){	my ($self, $d, $varname) = @_;	my $env = GenerateStructEnv($d, $varname);	$self->pidl("EJS_CHECK(ejs_pull_struct_start(ejs, &v, name));");    foreach my $e (@{$d->{ELEMENTS}}) {		$self->EjsPullElementTop($e, $env);	}}############################ pull a unionsub EjsUnionPull($$$){	my ($self, $d, $varname) = @_;	my $have_default = 0;	$self->pidl("EJS_CHECK(ejs_pull_struct_start(ejs, &v, name));");	$self->pidl("switch (ejs->switch_var) {");	$self->indent;	foreach my $e (@{$d->{ELEMENTS}}) {		if ($e->{CASE} eq "default") {			$have_default = 1;		}		$self->pidl("$e->{CASE}:");		$self->indent;		if ($e->{TYPE} ne "EMPTY") {			$self->EjsPullElementTop($e, { $e->{NAME} => "$varname->$e->{NAME}"});		}		$self->pidl("break;");		$self->deindent;	}	if (! $have_default) {		$self->pidl("default:");		$self->indent;		$self->pidl("return ejs_panic(ejs, \"Bad switch value\");");		$self->deindent;	}	$self->deindent;	$self->pidl("}");}############################################### put the enum elements in the constants arraysub EjsEnumConstant($$){	my ($self, $d) = @_;	my $v = 0;	foreach my $e (@{$d->{ELEMENTS}}) {		my $el = $e;		chomp $el;		if ($el =~ /^(.*)=\s*(.*)\s*$/) {			$el = $1;			$v = $2;		}		$self->{constants}->{$el} = $v;		$v++;	}}############################ pull a enumsub EjsEnumPull($$$){	my ($self, $d, $varname) = @_;	$self->EjsEnumConstant($d);	$self->pidl("unsigned e;");	$self->pidl("EJS_CHECK(ejs_pull_enum(ejs, v, name, &e));");	$self->pidl("*$varname = e;");}############################ pull a bitmapsub EjsBitmapPull($$$){	my ($self, $d, $varname) = @_;	my $type_fn = $d->{BASE_TYPE};	$self->pidl("EJS_CHECK(ejs_pull_$type_fn(ejs, v, name, $varname));");}sub EjsTypePullFunction($$$){	sub EjsTypePullFunction($$$);	my ($self, $d, $name) = @_;	return if (has_property($d, "noejs"));	if ($d->{TYPE} eq "TYPEDEF") {		$self->EjsTypePullFunction($d->{DATA}, $name);		return;	}	if ($d->{TYPE} eq "STRUCT") {		$self->fn_declare($d, "NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, struct $name *r)");	} elsif ($d->{TYPE} eq "UNION") {		$self->fn_declare($d, "NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, union $name *r)");	} elsif ($d->{TYPE} eq "ENUM") {		$self->fn_declare($d, "NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, enum $name *r)");	} elsif ($d->{TYPE} eq "BITMAP") {		my($type_decl) = Parse::Pidl::Typelist::mapTypeName($d->{BASE_TYPE});		$self->fn_declare($d, "NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, const char *name, $type_decl *r)");	}	$self->pidl("{");	$self->indent;	$self->EjsTypePull($d, "r");	$self->pidl("return NT_STATUS_OK;");	$self->deindent;	$self->pidl("}\n");}sub EjsTypePull($$$){	my ($self, $d, $varname) = @_;	if ($d->{TYPE} eq 'STRUCT') {		$self->EjsStructPull($d, $varname);	} elsif ($d->{TYPE} eq 'UNION') {		$self->EjsUnionPull($d, $varname);	} elsif ($d->{TYPE} eq 'ENUM') {		$self->EjsEnumPull($d, $varname);	} elsif ($d->{TYPE} eq 'BITMAP') {		$self->EjsBitmapPull($d, $varname);	} else {		warn "Unhandled pull $varname of type $d->{TYPE}";	}}###################### generate a functionsub EjsPullFunction($$){	my ($self, $d) = @_;	my $env = GenerateFunctionInEnv($d);	my $name = $d->{NAME};	$self->pidl("\nstatic NTSTATUS ejs_pull_$name(struct ejs_rpc *ejs, struct MprVar *v, struct $name *r)");	$self->pidl("{");	$self->indent;	$self->pidl("EJS_CHECK(ejs_pull_struct_start(ejs, &v, \"input\"));");	# we pull non-array elements before array elements as arrays	# may have length_is() or size_is() properties that depend	# on the non-array elements	foreach my $e (@{$d->{ELEMENTS}}) {		next unless (grep(/in/, @{$e->{DIRECTION}}));		next if (has_property($e, "length_is") || has_property($e, "size_is"));		$self->EjsPullElementTop($e, $env);	}	foreach my $e (@{$d->{ELEMENTS}}) {		next unless (grep(/in/, @{$e->{DIRECTION}}));		next unless (has_property($e, "length_is") || has_property($e, "size_is"));		$self->EjsPullElementTop($e, $env);	}	$self->pidl("return NT_STATUS_OK;");	$self->deindent;	$self->pidl("}\n");}############################ push a scalar elementsub EjsPushScalar($$$$$$){	my ($self, $e, $l, $var, $name, $env) = @_;	if (ref($e->{TYPE}) eq "HASH" and not defined($e->{TYPE}->{NAME})) {		$self->EjsTypePush($e->{TYPE}, get_pointer_to($var));	} else {    # have to handle strings specially :(        my $pl = GetPrevLevel($e, $l);		if ((not Parse::Pidl::Typelist::scalar_is_reference($e->{TYPE}))			or (defined($pl) and $pl->{TYPE} eq "POINTER")) {					$var = get_pointer_to($var);			}		$self->pidl("EJS_CHECK(".TypeFunctionName("ejs_push", $e->{TYPE})."(ejs, v, $name, $var));");	}}############################ push a string elementsub EjsPushString($$$$$$){	my ($self, $e, $l, $var, $name, $env) = @_;	my $pl = GetPrevLevel($e, $l);	if (defined($pl) and $pl->{TYPE} eq "POINTER") {		$var = get_pointer_to($var);	}	$self->pidl("EJS_CHECK(ejs_push_string(ejs, v, $name, $var));");}############################ push a pointer element

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -