imgtools/buildrom/tools/featureparser.pm
changeset 0 044383f39525
child 590 360bd6b35136
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/buildrom/tools/featureparser.pm	Tue Oct 27 16:36:35 2009 +0000
@@ -0,0 +1,465 @@
+#
+# Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of the License "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description: 
+#
+
+# This package contains routines to read the information from the Feature List XML file.
+package featureparser;  # Base class implementation of feature list xml parser
+
+# Include the genericparser to use API to read from XML file.
+use genericparser;
+use strict;
+
+#
+# Class constructor
+#
+sub new {
+	my $class = shift;
+
+	my $object = {};
+	
+	# Class members
+	$object->{_DEFAULT_RANGE} = [];        # Array of default ranges
+	$object->{_DEFAULT_INCLUDE_COUNT} = 0;       # Default include range count
+	$object->{_DEFAULT_EXCLUDE_COUNT} = 0;       # Default exclude range count
+	
+	$object->{_FILENAME} = undef;      # Current xml file parsing
+	$object->{_ROOT_ELEMENT} = undef;  # Root element pointer of current xml file
+	
+	bless($object, $class);
+	return $object;
+}
+
+#
+# Public methods
+#
+
+# Get/Set the _DEFAULT_RANGE member value of this class
+# @param : array of default ranges (optional for GET)
+#
+sub defaultRangeList 
+{
+	my $object = shift; 
+	return 0 if(!&ISREF($object,qw(defaultRangeList)));
+	
+	if (@_)
+	{ 
+		$object->{_DEFAULT_RANGE} = shift; 
+	}
+	return $object->{_DEFAULT_RANGE};
+}
+
+# Get/Set the _DEFAULT_INCLUDE_COUNT member value of this class
+# @param : default include feature count (optional for GET)
+#
+sub defaultIncludeCount
+{
+	my $object = shift; 
+	return 0 if(!&ISREF($object,qw(defaultIncludeCount)));
+	
+	if (@_)
+	{ 
+		$object->{_DEFAULT_INCLUDE_COUNT} = shift; 
+	}
+	return $object->{_DEFAULT_INCLUDE_COUNT};
+}
+
+# Get/Set the _DEFAULT_EXCLUDE_COUNT member value of this class
+# @param : default exclude feature count (optional for GET)
+#
+sub defaultExcludeCount 
+{
+	my $object = shift; 
+	return 0 if(!&ISREF($object,qw(defaultExcludeCount)));
+	
+	if (@_) 
+	{ 
+		$object->{_DEFAULT_EXCLUDE_COUNT} = shift; 
+	}
+	return $object->{_DEFAULT_EXCLUDE_COUNT};
+}
+
+# Get/Set the _FILENAME member value of this class
+# @param : xml file name (optional for GET)
+#
+sub fileName 
+{
+	my $object = shift; 
+	return 0 if(!&ISREF($object,qw(fileName)));
+	
+	if (@_) 
+	{ 
+		$object->{_FILENAME} = shift; 
+	}
+	return $object->{_FILENAME};
+}
+
+# Get/Set the _ROOT_ELEMENT member value of this class
+# @param : root element document pointer (optional for GET)
+#
+sub rootElement 
+{
+	my $object = shift; 
+	return 0 if(!&ISREF($object,qw(rootElement)));
+	
+	if (@_) 
+	{ 
+		$object->{_ROOT_ELEMENT} = shift; 
+	}
+	return $object->{_ROOT_ELEMENT};
+}
+
+# Parse the feature xml file
+# @param : xml file name to parse
+#
+sub parseXMLFile 
+{
+	my $object = shift; 
+	return 0 if(!&ISREF($object,qw(parseXMLFile)));
+	
+	my $file = shift; # Get the featuredatabase XML filename
+	$object->fileName($file);
+	
+	# Check for the existence of xml file
+	if(!(-e $file)) 
+	{
+		ERROR($file." doesn\'t exist");
+		return 0;
+	}
+	
+	#Parse the file and Get root Element
+	my $root = &genericparser::getRootElement($file);
+	$object->rootElement($root);
+	
+	if($root)
+	{
+		#Read the <featureset>/<feature> elements
+		if( !($object->createFeatureMap()) ) 
+		{
+			return 0;
+		}
+		#Read the <defaultfeaturerange> elements
+		if( !($object->createDefaultRangeMap()) ) 
+		{
+			return 0;
+		}
+		
+		return 1;
+	}
+
+	return -1;
+}
+
+# Read the <defaultfeaturerange> elements
+# @param - input range attribute set
+#
+sub createDefaultRangeMap
+{
+	my ($object, @attrSet) = @_; 
+	return 0 if(!&ISREF($object,"createDefaultRangeMap"));
+	
+	# Get the reference to the default feature range list from the object
+	my $rangeList = $object->defaultRangeList();
+	foreach my $currNode (@attrSet)
+	{
+		my ($min, $max);
+		my %attrHashMap = ();
+
+		# Get the range attributes
+		$object->readRangeAttributes($currNode, \%attrHashMap);
+		
+		#Get the lower and higher uids
+		$min = $attrHashMap{min};
+		$max = $attrHashMap{max};
+		
+		#Validate it
+		if((!&IsValidNum($min)) or (!&IsValidNum($max))) {
+			&ERROR("Valid hexadecimal or decimal value expected in default range");
+			return 0;
+		}
+
+		#Convert it to decimal
+		$attrHashMap{min} = &ConvertHexToDecimal($min);
+		$attrHashMap{max} = &ConvertHexToDecimal($max);
+		if( $attrHashMap{min} > $attrHashMap{max} ) {
+			&ERROR("Mininum/Lower UID value ".$min." is greater than Maximum/Higher UID value ".$max);
+			return 0;
+		}
+	
+		#Add it to the existing range list
+		my $include = 1;
+		foreach my $node (@$rangeList) { #Check the range already exists
+			if(($node->{min} == $attrHashMap{min}) && ($node->{max} == $attrHashMap{max}) 
+				&& ($node->{support} eq $attrHashMap{support})) {
+				$include = 0;
+			}
+		}
+		if($include) { # If it is a new range attribute then add it to the list
+			push @$rangeList, \%attrHashMap;
+			$object->defaultIncludeCount($object->defaultIncludeCount()+1) if(lc($attrHashMap{support}) eq "include");
+			$object->defaultExcludeCount($object->defaultExcludeCount()+1) if(lc($attrHashMap{support}) eq "exclude");
+		}
+	}
+
+	return 1;
+}
+
+# Get the default include ranges of min and max values in 2dimensional array
+#
+sub getDefaultIncludeInfo()
+{
+	my $object = shift; 
+	return 0 if(!&ISREF($object,qw(getDefaultIncludeInfo)));
+	
+	my @result;	
+	my %tempHash=();
+	
+	my $rangeList = $object->defaultRangeList();
+	foreach my $range (@$rangeList)
+	{
+		if(lc($range->{"support"}) eq "include" )
+		{
+			my $min_value=$range->{"min"};
+			my $max_value=$range->{"max"};
+			$tempHash{$min_value} = $max_value;
+		}				
+	}
+
+	my $index = 0;
+	my @sortedHash = sort keys %tempHash;
+
+	foreach my $key (@sortedHash)
+	{
+		push @{$result[$index]},$key;
+		push @{$result[$index]},$tempHash{$key};	
+		$index++;
+	}	
+	return @result;
+}
+
+# Get the default exclude ranges of min and max values in 2dimensional array
+#
+sub getDefaultExcludeInfo()
+{
+	my $object = shift; 
+	return 0 if(!&ISREF($object,qw(getDefaultExcludeInfo)));
+	
+	my @result;
+	my %tempHash=();
+	
+	my $rangeList = $object->defaultRangeList();
+	foreach my $range (@$rangeList)
+	{
+		if(lc($range->{"support"}) eq "exclude" )
+		{
+			my $min_value=$range->{"min"};
+			my $max_value=$range->{"max"};
+			$tempHash{$min_value} = $max_value;
+		}				
+	}
+
+	my $index = 0;
+	my @sortedHash = sort {$a <=> $b}(keys %tempHash);
+	foreach my $key (@sortedHash){
+		push @{$result[$index]},$key;
+		push @{$result[$index]},$tempHash{$key};
+		$index++;
+	}
+	return @result;
+}
+
+# Get the count of total number of ranges that are either included or excluded on the device as default
+# 
+sub getDefaultTotalCount()
+{
+	my $object = shift; 
+	return 0 if(!&ISREF($object,qw(getDefaultTotalCount)));
+	
+	return ($object->defaultIncludeCount() + $object->defaultExcludeCount());
+}
+
+# For a given uid value, this function checks if the given uid is within the default=present range.
+# @param : UID to check
+#
+sub getRangeEntry
+{
+	my $object = shift; 
+	return 0 if(!&ISREF($object,qw(getRangeEntry)));
+	
+	my $aUid = shift;
+	my $length = $object->getDefaultTotalCount();
+	my $pos = 0;
+	my $rangeRef;
+
+	my $rangeList = $object->defaultRangeList();
+	foreach my $range (@$rangeList)
+	{
+		if ( (lc($range->{"support"}) eq "include") and ($range->{"min"} <= $aUid) and ($range->{"max"} >= $aUid) )
+		{
+			return $range;
+		}
+	}
+	return undef;
+}
+
+# Get the list of features
+#
+sub getFeatures($$)
+{
+	my ($includeFeatureRef, $excludeFeatureRef) = @_;
+	my %FeatureMap = ();
+	my @FeatList = ();
+	my $featRef;
+	my $uid;
+
+	foreach my $feat (@$excludeFeatureRef)
+	{
+		$uid = $feat->{uid};
+
+		$featRef = $FeatureMap{$uid};
+
+		if( $featRef->{include} == 1 )
+		{
+			&ERROR("The feature $feat->{name} was added into the exclude as well as include list");
+			return 0;
+		}
+		elsif($featRef->{exclude} == 1)
+		{
+#			Already added to the final feature list
+			next;
+		}
+		else
+		{
+			$FeatureMap{$uid} = $feat;
+			push @FeatList, $feat;
+		}
+	}
+
+	foreach my $feat (@$includeFeatureRef)
+	{
+		$uid = $feat->{uid};
+
+		$featRef = $FeatureMap{$uid};
+
+		if( $featRef->{exclude} == 1 )
+		{
+			&ERROR("The feature $feat->{name} was added into the exclude as well as include list");
+			return 0;
+		}
+		elsif($featRef->{include} == 1)
+		{
+#			Already added to the final feature list
+			next;
+		}
+		else
+		{
+			$FeatureMap{$uid} = $feat;
+			push @FeatList, $feat;
+		}
+	}
+
+	return \@FeatList;
+}
+
+# ========================================================================
+# Wrappers for generic xml parser
+# ========================================================================
+sub featureparser::getnodefromTree 
+{ 
+	&genericparser::getNodeFromTree(@_); 
+}
+
+sub getattrValue 
+{ 
+	&genericparser::getAttrValue(@_); 
+}
+
+sub getelementValue 
+{ 
+	&genericparser::getElementValue(@_); 
+}
+
+# ========================================================================
+# Utility sub routines
+# ========================================================================
+# Check whether the object is reference type
+# @param : the object reference
+#
+sub ISREF 
+{
+	my ($object, $method) = @_;
+	if(!ref($object)) 
+	{ 
+		&ERROR("**Object is not reference-type for the method($method)");
+		return 0;
+	}
+	return 1;
+}
+
+# Parser debugging routines
+#
+sub WARN 
+{ 
+	print "WARNING: ".$_[0]."\n";
+}
+sub ERROR 
+{ 
+	print "ERROR: ".$_[0]."\n";
+}
+
+# Return Decimal value for the given Hexadecimal number.
+# @param : HexaDecimal Value
+#
+sub ConvertHexToDecimal 
+{
+	my $val = shift;
+	if(grep /^0x/i, $val) 
+	{
+		# Input is Hexadecimal value, convert to Decimal
+		return hex($val);	 
+	}
+	else 
+	{
+		# Decimal value
+		return $val;
+	}
+}
+
+# Validate if the given value is a valid number
+#
+sub IsValidNum 
+{
+	my $num = shift;
+	return 1 if($num =~ /^\d+$|^0[x][\da-f]+/i);
+	return 0;
+}
+
+# Validate if the given UID value is a valid number (either decimal or hexadecimal number)
+#
+sub ValidateUIDValue 
+{
+	my $fuid = shift;
+	# check to ensure that uid value contains only valid digits (decimal/hexadecimal)
+	if(IsValidNum $fuid) 
+	{
+		return 1;
+	}
+	else 
+	{
+		&ERROR("Invalid UID value".$fuid."\n");
+		return 0;
+	}
+}
+
+1;
\ No newline at end of file