sl@0: #!perl -w
sl@0: # Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: # All rights reserved.
sl@0: # This component and the accompanying materials are made available
sl@0: # under the terms of "Eclipse Public License v1.0"
sl@0: # which accompanies this distribution, and is available
sl@0: # at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: #
sl@0: # Initial Contributors:
sl@0: # Nokia Corporation - initial contribution.
sl@0: #
sl@0: # Contributors:
sl@0: #
sl@0: # Description:
sl@0: #
sl@0: 
sl@0: use strict;
sl@0: 
sl@0: #
sl@0: # A simple class to manage feature flags for a feature set data file.
sl@0: #
sl@0: package FeatureFlag;
sl@0: 
sl@0: # Create a feature flag object.
sl@0: sub new
sl@0: {
sl@0: 	my $arg = shift;
sl@0: 	my $class = ref($arg) || $arg;
sl@0: 	my($uid, $sf, $ud) = @_;
sl@0: 	die "You must specify a UID when creating a FeatureFlag object"
sl@0: 	    unless(defined($uid));
sl@0: 	$sf = 0 unless(defined($sf));
sl@0: 	$ud = 0 unless(defined($ud));
sl@0: 
sl@0: 	my $self = {
sl@0: 			     uid => $uid,
sl@0: 			     statusflags => $sf,
sl@0: 			     userdata => $ud,
sl@0: 				 endian => "LE",
sl@0: 			   };
sl@0: 	bless $self, $class;
sl@0: 	return $self;
sl@0: }
sl@0: 
sl@0: sub Endian
sl@0: {
sl@0: 	my $self = shift;
sl@0: 	return undef unless(ref($self));
sl@0: 	my $arg = shift;
sl@0: 	return $self->{endian} unless(defined($arg) and $arg =~ m/(^BE$|^LE$)/i);
sl@0: 	$self->{endian} = lc($1);
sl@0: 	return $self->{endian};
sl@0: }
sl@0: 
sl@0: # Return a twelve byte string 'feature flag' information.
sl@0: sub BinaryContent
sl@0: {
sl@0: 	my $self = shift;
sl@0: 	return undef unless(ref($self));
sl@0: 	my @arr = ( $self->UID(), $self->StatusFlags(), $self->UserData() );
sl@0: 
sl@0: 	# Decide whether we want big or little endian output.
sl@0: 	# According to the documentation, 'V', 'N' are GUARANTEED to be 32-bit.
sl@0: 	my $packstring = "V3"; # Little endian.
sl@0: 	   $packstring = "N3" if($self->Endian() eq "BE");
sl@0: 
sl@0: 	my $string = pack $packstring, @arr;
sl@0: 	return $string;
sl@0: }
sl@0: 
sl@0: # A single 32-bit number.
sl@0: sub UID
sl@0: {
sl@0: 	my $self = shift;
sl@0: 	return undef unless(ref($self));
sl@0: 	my $uid = shift;
sl@0: 	return $self->{uid} unless(defined($uid));
sl@0: 	$uid = int($uid);
sl@0: 	$self->{uid} = $uid;
sl@0: 	return $uid;
sl@0: }
sl@0: 
sl@0: # A single 32-bit number.
sl@0: sub StatusFlags
sl@0: {
sl@0: 	my $self = shift;
sl@0: 	return undef unless(ref($self));
sl@0: 	my $sf = shift;
sl@0: 	return $self->{statusflags} unless(defined($sf));
sl@0: 	$sf = int($sf);
sl@0: 	$self->{statusflags} = $sf;
sl@0: 	return $sf;
sl@0: }
sl@0: 
sl@0: # A single 32-bit number.
sl@0: sub UserData
sl@0: {
sl@0: 	my $self = shift;
sl@0: 	return undef unless(ref($self));
sl@0: 	my $ud = shift;
sl@0: 	return $self->{userdata} unless(defined($ud));
sl@0: 	$ud = int($ud);
sl@0: 	$self->{userdata} = $ud;
sl@0: 	return $ud;
sl@0: }
sl@0: 
sl@0: # Display the content of the feature flag in english.
sl@0: sub Show
sl@0: {
sl@0: 	my $self = shift;
sl@0: 	return undef unless(ref($self));
sl@0: 	my $fd = shift;
sl@0: 	$fd = *STDOUT unless(defined($fd));
sl@0: 	printf $fd "UID 0x%08x\n", $self->UID();
sl@0: 	printf $fd "Status Flags 0x%08x\n", $self->StatusFlags();
sl@0: 
sl@0: 	# Supported?
sl@0: 	print "\t";
sl@0: 	print "Not " unless($self->Supported);
sl@0: 	print "Supported\n";
sl@0: 
sl@0: 	# Upgradable?
sl@0: 	print "\t";
sl@0: 	print "Not " unless($self->Upgradable);
sl@0: 	print "Upgradable\n";
sl@0: 
sl@0: 	# Modifiable?
sl@0: 	print "\t";
sl@0: 	print "Not " unless($self->Modifiable);
sl@0: 	print "Modifiable\n";
sl@0: 	                              
sl@0: 	# BlackListed?
sl@0: 	print "\t";
sl@0: 	print "Not " unless($self->BlackListed);
sl@0: 	print "BlackListed\n";
sl@0: 
sl@0: 	# Uninitialised?
sl@0: 	print "\t";
sl@0: 	print "Not " unless($self->Uninitialised); # Double negative.
sl@0: 	print "Uninitialised\n";
sl@0: 
sl@0: 	# Persisted?
sl@0: 	print "\t";
sl@0: 	print "Not " unless($self->Persisted);
sl@0: 	print "Persisted\n";
sl@0: 
sl@0: 	printf $fd "User Data 0x%08x\n\n", $self->UserData();
sl@0: 	return 1;
sl@0: }
sl@0: 
sl@0: 1;
sl@0: # ###########################################################################
sl@0: 
sl@0: # The following methods operate on the 'StatusFlags' member, just setting
sl@0: # or clearing bits as required.
sl@0: #
sl@0: # Bits 6 through 31 are currently reserved, 23/7/07.
sl@0: #
sl@0: 
sl@0: sub Supported
sl@0: {
sl@0: 	my $self = shift;
sl@0: 	return undef unless(ref($self));
sl@0: 	my $arg = shift;
sl@0:    	my $sp = $self->StatusFlags;
sl@0: 	if(defined($arg))
sl@0: 	{
sl@0: 	    $arg = 0 if( $arg =~ m/EXCLUDE/i );
sl@0:     	$arg = 1 if( $arg =~ m/FEATURE/i );
sl@0:     	if($arg) { $sp |= 1; } else { $sp &= ~1; };
sl@0:     	$self->StatusFlags($sp);
sl@0: 		return $arg;
sl@0: 	}
sl@0: 	else
sl@0: 	{
sl@0: 		return ($sp & 1);
sl@0: 	}
sl@0: }
sl@0: 
sl@0: sub Upgradable
sl@0: {
sl@0: 	my $self = shift;
sl@0: 	return undef unless(ref($self));
sl@0: 	my $arg = shift;
sl@0:     my $sp = $self->StatusFlags;
sl@0: 	if(defined($arg))
sl@0: 	{
sl@0:     	if($arg) { $sp |= 2; } else { $sp &= ~2; };
sl@0:     	$self->StatusFlags($sp);
sl@0: 		return $arg;
sl@0: 	}
sl@0: 	else
sl@0: 	{
sl@0: 		return ($sp & 2);
sl@0: 	}
sl@0: }
sl@0: 
sl@0: sub Modifiable
sl@0: {
sl@0: 	my $self = shift;
sl@0: 	return undef unless(ref($self));
sl@0: 	my $arg = shift;
sl@0:     my $sp = $self->StatusFlags;
sl@0: 	if(defined($arg))
sl@0: 	{
sl@0:     	if($arg) { $sp |= 4; } else { $sp &= ~4; };
sl@0:     	$self->StatusFlags($sp);
sl@0: 		return $arg;
sl@0: 	}
sl@0: 	else
sl@0: 	{
sl@0: 		return ($sp & 4);
sl@0: 	}
sl@0: }
sl@0: 
sl@0: sub BlackListed
sl@0: {
sl@0: 	my $self = shift;
sl@0: 	return undef unless(ref($self));
sl@0: 	my $arg = shift;
sl@0:    	my $sp = $self->StatusFlags;
sl@0: 	if(defined($arg))
sl@0: 	{
sl@0:     	if($arg) { $sp |= 8; } else { $sp &= ~8; };
sl@0:     	$self->StatusFlags($sp);
sl@0: 		return($arg);
sl@0: 	}
sl@0: 	else
sl@0: 	{
sl@0: 		return ($sp & 8);
sl@0: 	}
sl@0: }
sl@0: 
sl@0: sub Uninitialised
sl@0: {
sl@0: 	my $self = shift;
sl@0: 	return undef unless(ref($self));
sl@0: 	my $arg = shift;
sl@0:    	my $sp = $self->StatusFlags;
sl@0: 	if(defined($arg))
sl@0: 	{
sl@0:     	if($arg) { $sp |= 16; } else { $sp &= ~16; };
sl@0:     	$self->StatusFlags($sp);
sl@0: 		return($arg);
sl@0: 	}
sl@0: 	else
sl@0: 	{
sl@0: 		return ($sp & 16);
sl@0: 	}
sl@0: }
sl@0: 
sl@0: sub Uninitialized
sl@0: {
sl@0: 	return Uninitialised(@_);
sl@0: }
sl@0: 
sl@0: sub Persisted
sl@0: {
sl@0: 	my $self = shift;
sl@0: 	return undef unless(ref($self));
sl@0: 	my $arg = shift;
sl@0:     my $sp = $self->StatusFlags;
sl@0: 	if(defined($arg))
sl@0: 	{
sl@0:     	if($arg) { $sp |= 32; } else { $sp &= ~32; };
sl@0:     	$self->StatusFlags($sp);
sl@0: 		return($arg);
sl@0: 	}
sl@0: 	else
sl@0: 	{
sl@0: 		return ($sp & 32);
sl@0: 	}
sl@0: }
sl@0: 
sl@0: 
sl@0: # ###########################################################################
sl@0: 
sl@0: 1;
sl@0: