📄 util.pm
字号:
#################################################### utility functions to support pidl# Copyright tridge@samba.org 2000# released under the GNU GPLpackage util;###################################################################### load a data structure from a file (as saved with SaveStructure)sub LoadStructure($){ my $f = shift; my $contents = FileLoad($f); defined $contents || return undef; return eval "$contents";}use strict;###################################################################### flatten an array of arrays into a single arraysub FlattenArray2($) { my $a = shift; my @b; for my $d (@{$a}) { for my $d1 (@{$d}) { push(@b, $d1); } } return \@b;}###################################################################### flatten an array of arrays into a single arraysub FlattenArray($) { my $a = shift; my @b; for my $d (@{$a}) { for my $d1 (@{$d}) { push(@b, $d1); } } return \@b;}###################################################################### flatten an array of hashes into a single hashsub FlattenHash($) { my $a = shift; my %b; for my $d (@{$a}) { for my $k (keys %{$d}) { $b{$k} = $d->{$k}; } } return \%b;}###################################################################### traverse a perl data structure removing any empty arrays or# hashes and any hash elements that map to undefsub CleanData($){ sub CleanData($); my($v) = shift; if (ref($v) eq "ARRAY") { foreach my $i (0 .. $#{$v}) { CleanData($v->[$i]); if (ref($v->[$i]) eq "ARRAY" && $#{$v->[$i]}==-1) { $v->[$i] = undef; next; } } # this removes any undefined elements from the array @{$v} = grep { defined $_ } @{$v}; } elsif (ref($v) eq "HASH") { foreach my $x (keys %{$v}) { CleanData($v->{$x}); if (!defined $v->{$x}) { delete($v->{$x}); next; } if (ref($v->{$x}) eq "ARRAY" && $#{$v->{$x}}==-1) { delete($v->{$x}); next; } } }}###################################################################### return the modification time of a filesub FileModtime($){ my($filename) = shift; return (stat($filename))[9];}###################################################################### read a file into a stringsub FileLoad($){ my($filename) = shift; local(*INPUTFILE); open(INPUTFILE, $filename) || return undef; my($saved_delim) = $/; undef $/; my($data) = <INPUTFILE>; close(INPUTFILE); $/ = $saved_delim; return $data;}###################################################################### write a string into a filesub FileSave($$){ my($filename) = shift; my($v) = shift; local(*FILE); open(FILE, ">$filename") || die "can't open $filename"; print FILE $v; close(FILE);}###################################################################### return a filename with a changed extensionsub ChangeExtension($$){ my($fname) = shift; my($ext) = shift; if ($fname =~ /^(.*)\.(.*?)$/) { return "$1$ext"; } return "$fname$ext";}###################################################################### a dumper wrapper to prevent dependence on the Data::Dumper module# unless we actually need itsub MyDumper($){ require Data::Dumper; my $s = shift; return Data::Dumper::Dumper($s);}###################################################################### save a data structure into a filesub SaveStructure($$){ my($filename) = shift; my($v) = shift; FileSave($filename, MyDumper($v));}###################################################################### see if a pidl property list contains a give propertysub has_property($$){ my($e) = shift; my($p) = shift; if (!defined $e->{PROPERTIES}) { return undef; } return $e->{PROPERTIES}->{$p};}sub is_scalar_type($){ my($type) = shift; if ($type =~ /^u?int\d+/) { return 1; } if ($type =~ /char|short|long|NTTIME| time_t|error_status_t|boolean32|unsigned32| HYPER_T|wchar_t|DATA_BLOB/x) { return 1; } return 0;}# return the NDR alignment for a typesub type_align($){ my($e) = shift; my $type = $e->{TYPE}; if (need_wire_pointer($e)) { return 4; } return 4, if ($type eq "uint32"); return 4, if ($type eq "long"); return 2, if ($type eq "short"); return 1, if ($type eq "char"); return 1, if ($type eq "uint8"); return 2, if ($type eq "uint16"); return 4, if ($type eq "NTTIME"); return 4, if ($type eq "time_t"); return 8, if ($type eq "HYPER_T"); return 2, if ($type eq "wchar_t"); return 4, if ($type eq "DATA_BLOB"); # it must be an external type - all we can do is guess return 4;}# this is used to determine if the ndr push/pull functions will need# a ndr_flags field to split by buffers/scalarssub is_builtin_type($){ my($type) = shift; return 1, if (is_scalar_type($type)); return 0;}# determine if an element needs a reference pointer on the wire# in its NDR representationsub need_wire_pointer($){ my $e = shift; if ($e->{POINTERS} && !has_property($e, "ref")) { return $e->{POINTERS}; } return undef;}# determine if an element is a pass-by-reference structuresub is_ref_struct($){ my $e = shift; if (!is_scalar_type($e->{TYPE}) && has_property($e, "ref")) { return 1; } return 0;}# determine if an element is a pure scalar. pure scalars do not# have a "buffers" section in NDRsub is_pure_scalar($){ my $e = shift; if (has_property($e, "ref")) { return 1; } if (is_scalar_type($e->{TYPE}) && !$e->{POINTERS} && !array_size($e)) { return 1; } return 0;}# determine the array size (size_is() or ARRAY_LEN)sub array_size($){ my $e = shift; my $size = has_property($e, "size_is"); if ($size) { return $size; } $size = $e->{ARRAY_LEN}; if ($size) { return $size; } return undef;}# see if a variable needs to be allocated by the NDR subsystem on pullsub need_alloc($){ my $e = shift; if (has_property($e, "ref")) { return 0; } if ($e->{POINTERS} || array_size($e)) { return 1; } return 0;}# determine the C prefix used to refer to a variable when passing to a push# function. This will be '*' for pointers to scalar types, '' for scalar# types and normal pointers and '&' for pass-by-reference structuressub c_push_prefix($){ my $e = shift; if ($e->{TYPE} =~ "string") { return ""; } if (is_scalar_type($e->{TYPE}) && $e->{POINTERS}) { return "*"; } if (!is_scalar_type($e->{TYPE}) && !$e->{POINTERS} && !array_size($e)) { return "&"; } return "";}# determine the C prefix used to refer to a variable when passing to a pull# return '&' or ''sub c_pull_prefix($){ my $e = shift; if (!$e->{POINTERS} && !array_size($e)) { return "&"; } if ($e->{TYPE} =~ "string") { return "&"; } return "";}# determine if an element has a direct buffers componentsub has_direct_buffers($){ my $e = shift; if ($e->{POINTERS} || array_size($e)) { return 1; } return 0;}# return 1 if the string is a C constantsub is_constant($){ my $s = shift; if ($s =~ /^\d/) { return 1; } return 0;}# return 1 if this is a fixed arraysub is_fixed_array($){ my $e = shift; my $len = $e->{"ARRAY_LEN"}; if (defined $len && is_constant($len)) { return 1; } return 0;}# return 1 if this is a inline arraysub is_inline_array($){ my $e = shift; my $len = $e->{"ARRAY_LEN"}; if (is_fixed_array($e) || defined $len && $len ne "*") { return 1; } return 0;}1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -