## 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;