You are here

Bit Flags in Actionscript: An Example

It seems that when writing Actionscript I am so accustomed to doing things a certain way that often I forget there may be better ways to accomplish something. This happened recently on a project I am working on. I was creating the classes that defined the various user types and what permissions each type has. I decided that the best way to do this was to create a abstract ‘User’ class and subclass it to create each actual user type.

So the basic design looks like this. UserUML The abstract ‘User’ class would define all of the permissions as boolean properties with each permission initially set to ‘false’ so that the ‘User’ class wouldn’t have any permissions. Each sub class would then define the permissions that type has by setting the properties to ‘true’. Also in this case we want the properties to be immutable so we only define a getter method for each property. So an example of the ‘User’ class would look like this:

    public class User 
    { 
        //-------------------------------------------------------------------------- 
        // 
        //  Constructor 
        // 
        //-------------------------------------------------------------------------- 
 
        /** 
         * Constructor 
         * 
         */        
        public function User() 
        {
 
        }
 
        //-------------------------------------------------------------------------- 
        // 
        //  Properties 
        // 
        //-------------------------------------------------------------------------- 
 
        //---------------------------------- 
        //  canCreateUser 
        //---------------------------------- 
 
        /** 
         * @private 
         * Storage of the canCreateUser property 
         */        
        protected var _canCreateUser:Boolean = false;
 
        /** 
         * A flag to determine if the user has permissions to create other users  
         * 
         */        
        public function get canCreateUser():Boolean 
        { 
            return _canCreateUser; 
        }
 
        //---------------------------------- 
        //  canEdit 
        //---------------------------------- 
 
        /** 
         * @private 
         * Storage of the canEdit property 
         */    
        protected var _canEdit:Boolean = false;
 
        /** 
         * A flag to determine if the user has permissions to edit data 
         * 
         */    
        public function get canEdit():Boolean 
        { 
            return _canEdit; 
        }
 
        //---------------------------------- 
        //  canPrint 
        //---------------------------------- 
 
        /** 
         * @private 
         * Storage of the canPrint property 
         */    
        protected var _canPrint:Boolean = false;
 
        /** 
         * A flag to determine if the user has permissions to create print data  
         * 
         */    
        public function get canPrint():Boolean 
        { 
            return _canPrint; 
        }
 
        //---------------------------------- 
        //  canSave 
        //---------------------------------- 
 
        /** 
         * @private 
         * Storage of the canSave property 
         */    
        protected var _canSave:Boolean = false;
 
        /** 
         * A flag to determine if the user has permissions to save data  
         * 
         */    
        public function get canSave():Boolean 
        { 
            return _canSave;  
        }  
    }

and as an example the sub class ‘Authenticated User’ would look like this:

public class AuthenticatedUser extends User  
{ 
    //-------------------------------------------------------------------------- 
    // 
    //  Constructor 
    // 
    //-------------------------------------------------------------------------- 
 
    /** 
     * Constructor 
     * 
     */        
    public function AuthenticatedUser() 
    { 
        super(); 
 
        _canEdit = true; 
        _canPrint = true; 
        _canSave = true; 
    } 
}

This would give the ‘Authenticated User’ permissions to edit, save and print but not permission to create new users. Now this will work quite well and it uses Polymorphism so that the program doesn’t need to worry what type of user was instantiated. It can store a ‘User’ data type and use the interface of that class to get the various permissions. When I look at this code something bothers me but I can’t quite put my finger on it. It works but it doesn’t look clean for some reason. As you add permissions you would simply keep creating properties in the abstract ‘User’ class and the properties list could get quite long. Also you would litter you code with conditional statements like

if(user.canEdit) 
{ 
   // do something 
} 
if(user.canSave) 
{ 
   // do something 
}

This is when it occurred to me that bit flags may be a better solutions to store the permissions. So what are bit flags? From Wikipedia ‘In computer programming, flag refers to one or more bits that are used to store a binary value or code that has an assigned meaning.’ Basically a bit flag stores a boolean value in a single bit, 0 for ‘false’ and 1 for ‘true’. I am not going to get into theory or explain bitwise operators here. If you want to learn more about bits or need a refresher Thibault Imbert is writing a book on the subject. Check out chapter 1 for an explanation of bits and bitwise operators. To use bit flags in our ‘User’ classes we need to make a few changes. First we need to externalize all of the possible permission variables to an ‘enum’ class (a class with just static constants). This really isn’t necessary as these could be defined on the User class. I just prefer a separate class.

public class UserPermissions 
{ 
    public static const CAN_CREATE_USER:uint = 1 << 0; 
 
    public static const CAN_EDIT:uint = 1 << 1; 
 
    public static const CAN_PRINT:uint = 1 << 2; 
 
    public static const CAN_SAVE:uint = 1 << 3; 
}

Each permission is stored as a ‘uint’ data type. The syntax I am using with the left shift operator is equal to

public class UserPermissions 
{ 
    public static const CAN_CREATE_USER:uint = 1; 
 
    public static const CAN_EDIT:uint = 2; 
 
    public static const CAN_PRINT:uint = 4; 
 
    public static const CAN_SAVE:uint = 8; 
}

I find the first way cleaner because I don’t have to do math I simply need to know how to count and I can easily see if I made a mistake. These values in terms of a byte are equal to 1 = 00000001 2 = 00000010 4 = 00000100 8 = 00001000 and so on up to the maximum number of bits that can be stored in a ‘uint’. From this you can see the pattern that emerges and how it relates to the left shift operator. Each constant simply shifts ‘1’ over by the value following the left shift operator. These ‘flags’ can now be combined into a single ‘uint’ to form a value. If you combine the 4 values above you will have 00000001 + 00000010 + 00000100 + 00001000 = 00001111 This value can also be expressed as 15 so a user with all of the permission would have a variable like permssions = 15 So an updated ‘User’ class will now look like this

public class User 
{ 
    //-------------------------------------------------------------------------- 
    // 
    //  Constructor 
    // 
    //-------------------------------------------------------------------------- 
 
    /** 
     * Constructor  
     *  
     */         
    public function User() 
    {
 
    }
 
    //-------------------------------------------------------------------------- 
    // 
    //  Properties 
    // 
    //-------------------------------------------------------------------------- 
 
    //---------------------------------- 
    //  permissions 
    //---------------------------------- 
 
    /** 
     * A value to indicate the permissions each user has 
     */         
    protected var permissions:uint = 0; 
 
    //-------------------------------------------------------------------------- 
    // 
    //  Methods 
    // 
    //-------------------------------------------------------------------------- 
 
    /** 
     *  
     * @param permission 
     * @return  
     *  
     */         
    public function hasPermission(permission:uint):Boolean 
    { 
        return BitFlagUtil.isSet(permissions, permission);  
    }
 
}

and an updated ‘AuthenticatedUser’ class would look like this

public class AuthenticatedUser extends User  
{ 
    //-------------------------------------------------------------------------- 
    // 
    //  Constructor 
    // 
    //-------------------------------------------------------------------------- 
 
    /** 
     * Constructor 
     * 
     */        
    public function AuthenticatedUser() 
    { 
        super();  
 
        permissions = 7; 
    } 
}

But once a gain we are back to doing math. A better way to set the permissions is to use the Bitwise OR operator to set the various flags to true. So the above is equivalent to

public class AuthenticatedUser extends User  
{ 
    //-------------------------------------------------------------------------- 
    // 
    //  Constructor 
    // 
    //-------------------------------------------------------------------------- 
 
    /** 
     * Constructor 
     * 
     */        
    public function AuthenticatedUser() 
    { 
        super();   
        permissions = UserPermissions.CAN_EDIT | 
              UserPermissions.CAN_PRINT | 
                UserPermissions.CAN_SAVE; 
    } 
}

The class BitFlaguUtil that is referenced in the hasPermissions method of the User class is in the Flex 4 sdk. It is found in mx.utils but for some reason it has been left out of the code hinting in Flash Builder so you have to manually import it. Basically it just uses the bitwise AND operator to check if a bit is set.

public static function isSet(flags:uint, flagMask:uint):Boolean 
{ 
    return flagMask == (flags & flagMask); 
}

So with these changes we have a much cleaner solution. If we need to add permissions we add a constant to the enum class UserPermissions and then set that permission in any class that has it. We also have a simpler interface for the application to use. If we need to check if a user has a particular permission we just call 'hasPermission' on the base User class.

if(user.hasPermission(UserPermissions.CAN_SAVE)) 
{ 
   // do something     
}

Blog Topics: 
Content Type: 

Comments

Another interesting task is how to convert a string of options to a union of BitFlags.

Consider a string 'properties, size, displayList" that should be converted to an integer representation of BitFlags.

Using lessons from Javascript and functional programming, a very elegant solution is available in AS3: http://bit.ly/kmbcrH

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.