.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "File::KDBX::Util 3pm" .TH File::KDBX::Util 3pm "2022-11-20" "perl v5.36.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" File::KDBX::Util \- Utility functions for working with KDBX files .SH "VERSION" .IX Header "VERSION" version 0.906 .SH "FUNCTIONS" .IX Header "FUNCTIONS" .SS "load_xs" .IX Subsection "load_xs" .Vb 2 \& $bool = load_xs(); \& $bool = load_xs($version); .Ve .PP Attempt to load File::KDBX::XS. Return truthy if it is loaded. If \f(CW$version\fR is given, it will check that at least the given version is loaded. .SS "assert" .IX Subsection "assert" .Vb 1 \& assert { ... }; .Ve .PP Write an executable comment. Only executed if \f(CW\*(C`DEBUG\*(C'\fR is set in the environment. .SS "can_fork" .IX Subsection "can_fork" .Vb 1 \& $bool = can_fork; .Ve .PP Determine if perl can fork, with logic lifted from \*(L"\s-1CAN_FORK\*(R"\s0 in Test2::Util. .SS "clone" .IX Subsection "clone" .Vb 1 \& $clone = clone($thing); .Ve .PP Clone deeply. This is an unadorned alias to Storable \f(CW\*(C`dclone\*(C'\fR. .SS "clone_nomagic" .IX Subsection "clone_nomagic" .Vb 1 \& $clone = clone_nomagic($thing); .Ve .PP Clone deeply without keeping [most of] the magic. .PP \&\fB\s-1WARNING:\s0\fR At the moment the implementation is naïve and won't respond well to nontrivial data or recursive structures. .SS "\s-1DEBUG\s0" .IX Subsection "DEBUG" Constant number indicating the level of debuggingness. .SS "dumper" .IX Subsection "dumper" .Vb 2 \& $str = dumper $thing; \& dumper $thing; # in void context, prints to STDERR .Ve .PP Like Data::Dumper but slightly terser in some cases relevent to File::KDBX. .SS "empty" .IX Subsection "empty" .SS "nonempty" .IX Subsection "nonempty" .Vb 1 \& $bool = empty $thing; \& \& $bool = nonempty $thing; .Ve .PP Test whether a thing is empty (or nonempty). An empty thing is one of these: .IP "\(bu" 4 nonexistent .IP "\(bu" 4 \&\f(CW\*(C`undef\*(C'\fR .IP "\(bu" 4 zero-length string .IP "\(bu" 4 zero-length array .IP "\(bu" 4 hash with zero keys .IP "\(bu" 4 reference to an empty thing (recursive) .PP Note in particular that zero \f(CW0\fR is not considered empty because it is an actual value. .SS "erase" .IX Subsection "erase" .Vb 2 \& erase($string, ...); \& erase(\e$string, ...); .Ve .PP Overwrite the memory used by one or more string. .SS "erase_scoped" .IX Subsection "erase_scoped" .Vb 3 \& $scope_guard = erase_scoped($string, ...); \& $scope_guard = erase_scoped(\e$string, ...); \& undef $scope_guard; # erase happens here .Ve .PP Get a scope guard that will cause scalars to be erased later (i.e. when the scope ends). This is useful if you want to make sure a string gets erased after you're done with it, even if the scope ends abnormally. .PP See \*(L"erase\*(R". .SS "extends" .IX Subsection "extends" .Vb 1 \& extends $class; .Ve .PP Set up the current module to inheret from another module. .SS "has" .IX Subsection "has" .Vb 1 \& has $name => %options; .Ve .PP Create an attribute getter/setter. Possible options: .IP "\(bu" 4 \&\f(CW\*(C`is\*(C'\fR \- Either \*(L"rw\*(R" (default) or \*(L"ro\*(R" .IP "\(bu" 4 \&\f(CW\*(C`default\*(C'\fR \- Default value .IP "\(bu" 4 \&\f(CW\*(C`coerce\*(C'\fR \- Coercive function .SS "format_uuid" .IX Subsection "format_uuid" .Vb 2 \& $string_uuid = format_uuid($raw_uuid); \& $string_uuid = format_uuid($raw_uuid, $delimiter); .Ve .PP Format a 128\-bit \s-1UUID\s0 (given as a string of 16 octets) into a hexidecimal string, optionally with a delimiter to break up the \s-1UUID\s0 visually into five parts. Examples: .PP .Vb 3 \& my $uuid = uuid(\*(Aq01234567\-89AB\-CDEF\-0123\-456789ABCDEF\*(Aq); \& say format_uuid($uuid); # \-> 0123456789ABCDEF0123456789ABCDEF \& say format_uuid($uuid, \*(Aq\-\*(Aq); # \-> 01234567\-89AB\-CDEF\-0123\-456789ABCDEF .Ve .PP This is the inverse of \*(L"uuid\*(R". .SS "generate_uuid" .IX Subsection "generate_uuid" .Vb 3 \& $uuid = generate_uuid; \& $uuid = generate_uuid(\e%set); \& $uuid = generate_uuid(\e&test_uuid); .Ve .PP Generate a new random \s-1UUID.\s0 It's pretty unlikely that this will generate a repeat, but if you're worried about that you can provide either a set of existing UUIDs (as a hashref where the keys are the elements of a set) or a function to check for existing UUIDs, and this will be sure to not return a \s-1UUID\s0 already in provided set. Perhaps an example will make it clear: .PP .Vb 6 \& my %uuid_set = ( \& uuid(\*(Aq12345678\-9ABC\-DEFG\-1234\-56789ABCDEFG\*(Aq) => \*(Aqwhatever\*(Aq, \& ); \& $uuid = generate_uuid(\e%uuid_set); \& # OR \& $uuid = generate_uuid(sub { !$uuid_set{$_} }); .Ve .PP Here, \f(CW$uuid\fR can't be \*(L"12345678\-9ABC\-DEFG\-1234\-56789ABCDEFG\*(R". This example uses \*(L"uuid\*(R" to easily pack a 16\-byte \s-1UUID\s0 from a literal, but it otherwise is not a consequential part of the example. .SS "gunzip" .IX Subsection "gunzip" .Vb 1 \& $unzipped = gunzip($string); .Ve .PP Decompress an octet stream. .SS "gzip" .IX Subsection "gzip" .Vb 1 \& $zipped = gzip($string); .Ve .PP Compress an octet stream. .SS "int64" .IX Subsection "int64" .Vb 1 \& $int = int64($string); .Ve .PP Get a scalar integer capable of holding 64\-bit values, initialized with a given default value. On a 64\-bit perl, it will return a regular SvIV. On a 32\-bit perl it will return a Math::BigInt. .SS "pack_Ql" .IX Subsection "pack_Ql" .Vb 1 \& $bytes = pack_Ql($int); .Ve .PP Like \f(CW\*(C`pack(\*(AqQ<\*(Aq, $int)\*(C'\fR, but also works on 32\-bit perls. .SS "pack_ql" .IX Subsection "pack_ql" .Vb 1 \& $bytes = pack_ql($int); .Ve .PP Like \f(CW\*(C`pack(\*(Aqq<\*(Aq, $int)\*(C'\fR, but also works on 32\-bit perls. .SS "unpack_Ql" .IX Subsection "unpack_Ql" .Vb 1 \& $int = unpack_Ql($bytes); .Ve .PP Like \f(CW\*(C`unpack(\*(AqQ<\*(Aq, $bytes)\*(C'\fR, but also works on 32\-bit perls. .SS "unpack_ql" .IX Subsection "unpack_ql" .Vb 1 \& $int = unpack_ql($bytes); .Ve .PP Like \f(CW\*(C`unpack(\*(Aqq<\*(Aq, $bytes)\*(C'\fR, but also works on 32\-bit perls. .SS "is_uuid" .IX Subsection "is_uuid" .Vb 1 \& $bool = is_uuid($thing); .Ve .PP Check if a thing is a \s-1UUID\s0 (i.e. scalar string of length 16). .SS "list_attributes" .IX Subsection "list_attributes" .Vb 1 \& @attributes = list_attributes($package); .Ve .PP Get a list of attributes for a class. .SS "load_optional" .IX Subsection "load_optional" .Vb 1 \& $package = load_optional($package); .Ve .PP Load a module that isn't required but can provide extra functionality. Throw if the module is not available. .SS "memoize" .IX Subsection "memoize" .Vb 1 \& \e&memoized_code = memoize(\e&code, ...); .Ve .PP Memoize a function. Extra arguments are passed through to \f(CW&code\fR when it is called. .SS "pad_pkcs7" .IX Subsection "pad_pkcs7" .Vb 1 \& $padded_string = pad_pkcs7($string, $block_size), .Ve .PP Pad a block using the PKCS#7 method. .SS "query" .IX Subsection "query" .Vb 2 \& $query = query(@where); \& $query\->(\e%data); .Ve .PP Generate a function that will run a series of tests on a passed hashref and return true or false depending on if the data record in the hash matched the specified logic. .PP The logic can be specified in a manner similar to \*(L"\s-1WHERE CLAUSES\*(R"\s0 in SQL::Abstract which was the inspiration for this function, but this code is distinct, supporting an overlapping but not identical feature set and having its own bugs. .PP See \*(L"Declarative Syntax\*(R" in File::KDBX for examples. .SS "query_any" .IX Subsection "query_any" Get either a \*(L"query\*(R" or \*(L"simple_expression_query\*(R", depending on the arguments. .SS "read_all" .IX Subsection "read_all" .Vb 2 \& $size = read_all($fh, my $buffer, $size); \& $size = read_all($fh, my $buffer, $size, $offset); .Ve .PP Like \*(L"read \s-1FILEHANDLE,SCALAR,LENGTH,OFFSET\*(R"\s0 in perlfunc but returns \f(CW\*(C`undef\*(C'\fR if not all \f(CW$size\fR bytes are read. This is considered an error, distinguishable from other errors by \f(CW$!\fR not being set. .SS "recurse_limit" .IX Subsection "recurse_limit" .Vb 3 \& \e&limited_code = recurse_limit(\e&code); \& \e&limited_code = recurse_limit(\e&code, $max_depth); \& \e&limited_code = recurse_limit(\e&code, $max_depth, \e&error_handler); .Ve .PP Wrap a function with a guard to prevent deep recursion. .SS "search" .IX Subsection "search" .Vb 2 \& # Generate a query on\-the\-fly: \& \e@matches = search(\e@records, @where); \& \& # Use a pre\-compiled query: \& $query = query(@where); \& \e@matches = search(\e@records, $query); \& \& # Use a simple expression: \& \e@matches = search(\e@records, \e\*(Aqquery terms\*(Aq, @fields); \& \e@matches = search(\e@records, \e\*(Aqquery terms\*(Aq, $operator, @fields); \& \& # Use your own subroutine: \& \e@matches = search(\e@records, \e&query); \& \e@matches = search(\e@records, sub { $record = shift; ... }); .Ve .PP Execute a linear search over an array of records using a \*(L"query\*(R". A \*(L"record\*(R" is usually a hash. .SS "simple_expression_query" .IX Subsection "simple_expression_query" .Vb 2 \& $query = simple_expression_query($expression, @fields); \& $query = simple_expression_query($expression, $operator, @fields); .Ve .PP Generate a query, like \*(L"query\*(R", to be used with \*(L"search\*(R" but built from a \*(L"simple expression\*(R" as described here . .PP An expression is a string with one or more space-separated terms. Terms with spaces can be enclosed in double quotes. Terms are negated if they are prefixed with a minus sign. A record must match every term on at least one of the given fields. .SS "snakify" .IX Subsection "snakify" .Vb 1 \& $string = snakify($string); .Ve .PP Turn a CamelCase string into snake_case. .SS "split_url" .IX Subsection "split_url" .Vb 1 \& ($scheme, $auth, $host, $port, $path, $query, $hash, $usename, $password) = split_url($url); .Ve .PP Split a \s-1URL\s0 into its parts. .PP For example, \f(CW\*(C`http://user:pass@localhost:4000/path?query#hash\*(C'\fR gets split like: .IP "\(bu" 4 \&\f(CW\*(C`http\*(C'\fR .IP "\(bu" 4 \&\f(CW\*(C`user:pass\*(C'\fR .IP "\(bu" 4 \&\f(CW\*(C`host\*(C'\fR .IP "\(bu" 4 \&\f(CW4000\fR .IP "\(bu" 4 \&\f(CW\*(C`/path\*(C'\fR .IP "\(bu" 4 \&\f(CW\*(C`?query\*(C'\fR .IP "\(bu" 4 \&\f(CW\*(C`#hash\*(C'\fR .IP "\(bu" 4 \&\f(CW\*(C`user\*(C'\fR .IP "\(bu" 4 \&\f(CW\*(C`pass\*(C'\fR .SS "to_bool" .IX Subsection "to_bool" .SS "to_number" .IX Subsection "to_number" .SS "to_string" .IX Subsection "to_string" .SS "to_time" .IX Subsection "to_time" .SS "to_tristate" .IX Subsection "to_tristate" .SS "to_uuid" .IX Subsection "to_uuid" Various typecasting / coercive functions. .SS "trim" .IX Subsection "trim" .Vb 1 \& $string = trim($string); .Ve .PP The ubiquitous \f(CW\*(C`trim\*(C'\fR function. Removes all whitespace from both ends of a string. .SS "try_load_optional" .IX Subsection "try_load_optional" .Vb 1 \& $package = try_load_optional($package); .Ve .PP Try to load a module that isn't required but can provide extra functionality, and return true if successful. .SS "uri_escape_utf8" .IX Subsection "uri_escape_utf8" .Vb 1 \& $string = uri_escape_utf8($string); .Ve .PP Percent-encode arbitrary text strings, like for a \s-1URI.\s0 .SS "uri_unescape_utf8" .IX Subsection "uri_unescape_utf8" .Vb 1 \& $string = uri_unescape_utf8($string); .Ve .PP Inverse of \*(L"uri_escape_utf8\*(R". .SS "uuid" .IX Subsection "uuid" .Vb 1 \& $raw_uuid = uuid($string_uuid); .Ve .PP Pack a 128\-bit \s-1UUID\s0 (given as a hexidecimal string with optional \f(CW\*(C`\-\*(C'\fR's, like \&\f(CW\*(C`12345678\-9ABC\-DEFG\-1234\-56789ABCDEFG\*(C'\fR) into a string of exactly 16 octets. .PP This is the inverse of \*(L"format_uuid\*(R". .SS "\s-1UUID_NULL\s0" .IX Subsection "UUID_NULL" Get the null \s-1UUID\s0 (i.e. string of 16 null bytes). .SH "BUGS" .IX Header "BUGS" Please report any bugs or feature requests on the bugtracker website .PP When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature. .SH "AUTHOR" .IX Header "AUTHOR" Charles McGarvey .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" This software is copyright (c) 2022 by Charles McGarvey. .PP This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.