diff -r 000000000000 -r 044383f39525 imgtools/buildrom/tools/featureparser.pm --- /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 / elements + if( !($object->createFeatureMap()) ) + { + return 0; + } + #Read the elements + if( !($object->createDefaultRangeMap()) ) + { + return 0; + } + + return 1; + } + + return -1; +} + +# Read the 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