Data::BitMask(3pm)

πŸ“¦
version 1.00 Β· 5 versions
, in ubuntu resolute, ubuntu stonking

πŸ’– Data::BitMask πŸ’–

okay bestie, welcome to the manual page for Data::BitMask, straight out of the User Contributed Perl Documentation. it does exactly one thing and it does it adorably: bitmask manipulation ✨


πŸŽ€ NAME πŸŽ€

Data::BitMask β€” bitmask manipulation. that's the whole name section, she's concise πŸ’…


🌸 SYNOPSIS 🌸

use Data::BitMask;

my $FileMask = Data::BitMask->new(
    READ =>    1,
    WRITE =>   2,
    EXECUTE => 4,
    RX =>      5,
    RWX =>     7,
    FULL =>    7,
  );

my $mask = $FileMask->build_mask('READ|WRITE');
print Data::Dumper->Dump([
    $FileMask->explain_mask($mask),
    $FileMask->break_mask($mask)
  ]);

my $mask2 = $FileMask->build_mask({FULL => 1, WRITE => 0});

like, look at her go πŸ¦‹


πŸ¦‹ DESCRIPTION πŸ¦‹

so here's the vibe: this module lets you make bitmask manipulator objects β€” little objects that build bitmask values out of a list of constants, and also break masks back apart using those same constants.

why is that iconic? because:

  • you don't have to pollute namespaces just to use constants 🧚
  • you can make sure only the appropriate constants get used for specific masks
  • breaking apart and explaining masks is genuinely easy
  • and honestly? interacting with masks is just way nicer for the user
important caveat bestie: this module only plays with masks that fit in Perl integers. and in some places it straight up presumes you're working with 32 bit integers (i.e. it canonicalizes negative values). don't come for her, she said what she said πŸ’€

she spends a modest amount of overhead creating the Data::BitMask object up front, specifically so that all your future mask manipulations go fast. it's giving "invest in yourself" πŸ’…

and! calls to build_mask, break_mask, and explain_mask are memoized, so repeated calls with the same parameters are speedy. periodt.

✨ Installation instructions ✨

you have four options for installing this module, choose your fighter:

  • using Module::Build 0.24 or later:
Build.PL
perl build test
perl build install
  • using ExtUtils::MakeMaker (which is part of the Perl core):
Makefile.PL
make test
make install
  • using the PPM (the file has the extension .ppm.zip) on CPAN, installing under ActivePerl for Win32 by unzipping the .ppm.zip file and then:
ppm install Data-BitMask.ppd
  • installing manually by copying lib/Data/Bitmask.pm to perl/site/lib/Data/Bitmask.pm 🫢

πŸ’œ Suggested Module Implementation πŸ’œ

here's one suggested approach to using bitmask manipulators inside a module:

{
my $cache;
sub SECURITY_INFORMATION {
  $cache ||= Data::BitMask->new(
      OWNER_SECURITY_INFORMATION => 0x1,
      GROUP_SECURITY_INFORMATION => 0x2,
      DACL_SECURITY_INFORMATION  => 0x4,
      SACL_SECURITY_INFORMATION  => 0x8,
    );
}
}

the bitmask manipulator can then be accessed as:

&SECURITY_INFORMATION->build_mask('DACL_SECURITY_INFORMATION');

or, if you're outside of the module, as:

&Win32::Security::SECURITY_INFORMATION->build_mask('DACL_SECURITY_INFORMATION');

this has several advantages, and yes I'm listing them all because they're all valid:

  • demand creation of the Data::Bitmask object πŸ¦‹ β€” creating objects with huge numbers of constants (i.e. hundreds or thousands) can be a bit time consuming, so this delays creation until the object actually gets used. and at the same time, the created object is cached. best of both, no cap.
  • easy access from within the module, and reasonably easy access from outside the module.
  • if the user wants it even easier from outside the module, you can support Exporter and let the sub be exported. slay.

πŸ‘‘ Method Reference πŸ‘‘

🌟 new 🌟

creates a new bitmask manipulator. pass a list of constant and value pairs.

the constants do not have to be disjoint, but order does matter. when executing explain_mask or explain_const, constants that are earlier in the list take precedence</> over those later in the list.

rules, bestie:

  • constant names are not allowed to have spaces or pipes in them
  • constant values have to be integers
  • constant names are case insensitive but preserving ✨

if the passed value for the constant name is an anonymous array, then it's presumed that the name is the first value and the remainder is name-value pairs of parameters. the only currently supported parameter is full_match, which implies the constant should only be returned from break_mask or explain_mask if it perfectly matches the mask being explained. for example:

[qw(FILES_ONLY_NO_INHERIT full_match 1)] =>    1,

🌟 add_constants 🌟

adds constants to an existing bitmask manipulator. pass a list of constant and value pairs just like for new.

constants get added to the end of the list (peep new for the whole ordering-precedence situation, it matters here too πŸ‘€).

the main use for add_constants is adding aggregate constants that were created by using build_mask.

🌟 build_mask 🌟

this one takes one of three things as a parameter:

  • scalar β€” the string is split on "|" and/or whitespace to generate a list of constants
  • ARRAY ref β€” the elements are the list of constants
  • HASH ref β€” keys with true values are the list of constants; keys with false values are subtracted from the resultant mask

in all situations, integers are legal in place of constant names and are treated as the value β€” after adding 2**32 to any negative integers.

🌟 break_mask 🌟

breaks a mask apart. pass a mask value as an integer.

returns a hash of all constants whose values are subsets of the passed mask. values are set to 1 so the result can safely be passed right back into build_mask. cute, right?

commonly used for operations like:

if ($MaskManipulator->break_mask($my_mask_value)->{CONSTANT}) {
ngl, the original page has a line here that literally just says "Note that break_mask accepts" and then… nothing πŸ’€ fr fr that's the whole sentence. I'm not making it up and I'm not finishing it for her either. iykyk.

to eliminate a constant from explain_mask or break_mask unless it perfectly matches, use full_match constants.

🌟 explain_mask 🌟

explains a mask in terms of a relatively minimal set of constants.

pass either a mask value as an integer, or any valid parameter for build_mask. returns a hash of constants that will recreate the mask. many times this will be the minimum number of constants necessary to describe the mask.

heads up: creating the true minimum set of constants is somewhat painful (see Knapsack problem). she's doing her best, okay 😭

the algorithm used by explain_mask is:

  1. first, test for a constant that perfectly matches the mask. if one is found, that's the obvious answer.
  2. in the absence of a perfect match, break_mask is used to generate a maximal solution.
  3. all simply occluded constants are then eliminated β€” that is to say, all constants in the list whose values are subsets of another single constant.

so for instance, if you had only three constants, AB => 3, BC => 6, and AC => 5, explain_mask would return all three when passed the value 7 β€” because no one constant is a subset of any single one of the others. the way that math works out is genuinely iconic πŸ”₯

to eliminate a constant from explain_mask or break_mask unless it perfectly matches, use full_match constants.

🌟 build_const 🌟

this one takes one of two things as a parameter:

  • scalar integer β€” if a scalar integer is passed, then the value is simply returned, after adding 2**32 to any negative integers
  • scalar β€” the string is looked up in the list of constants

🌟 explain_const 🌟

looks for a perfect match for the passed mask value. pass either a mask value as an integer or any valid parameter for build_mask.

if one is not found… it croaks 🐸 (dramatic, but fair).

🌟 get_constants 🌟

returns all constants passed either to new or add_constants. that's it, that's the whole function, she's an open book πŸ’–


πŸ’Œ AUTHOR πŸ’Œ

Toby Ovod-Everett, toby@ovod-everett.org

πŸ“œ LICENSE πŸ“œ

Copyright 2003, 2004 Toby Ovod-Everett. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.


okay bestie that's the whole page 🫢 this was perl v5.40.0, dated 2024-09-21, and it's the Data::BitMask(3pm) manual. go forth and mask responsibly. mwah πŸ’…βœ¨

πŸ“¦ where this page comes from