imgtools/buildrom/tools/featureparser.pm
changeset 0 044383f39525
child 590 360bd6b35136
equal deleted inserted replaced
-1:000000000000 0:044383f39525
       
     1 #
       
     2 # Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 # All rights reserved.
       
     4 # This component and the accompanying materials are made available
       
     5 # under the terms of the License "Eclipse Public License v1.0"
       
     6 # which accompanies this distribution, and is available
       
     7 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 #
       
     9 # Initial Contributors:
       
    10 # Nokia Corporation - initial contribution.
       
    11 #
       
    12 # Contributors:
       
    13 #
       
    14 # Description: 
       
    15 #
       
    16 
       
    17 # This package contains routines to read the information from the Feature List XML file.
       
    18 package featureparser;  # Base class implementation of feature list xml parser
       
    19 
       
    20 # Include the genericparser to use API to read from XML file.
       
    21 use genericparser;
       
    22 use strict;
       
    23 
       
    24 #
       
    25 # Class constructor
       
    26 #
       
    27 sub new {
       
    28 	my $class = shift;
       
    29 
       
    30 	my $object = {};
       
    31 	
       
    32 	# Class members
       
    33 	$object->{_DEFAULT_RANGE} = [];        # Array of default ranges
       
    34 	$object->{_DEFAULT_INCLUDE_COUNT} = 0;       # Default include range count
       
    35 	$object->{_DEFAULT_EXCLUDE_COUNT} = 0;       # Default exclude range count
       
    36 	
       
    37 	$object->{_FILENAME} = undef;      # Current xml file parsing
       
    38 	$object->{_ROOT_ELEMENT} = undef;  # Root element pointer of current xml file
       
    39 	
       
    40 	bless($object, $class);
       
    41 	return $object;
       
    42 }
       
    43 
       
    44 #
       
    45 # Public methods
       
    46 #
       
    47 
       
    48 # Get/Set the _DEFAULT_RANGE member value of this class
       
    49 # @param : array of default ranges (optional for GET)
       
    50 #
       
    51 sub defaultRangeList 
       
    52 {
       
    53 	my $object = shift; 
       
    54 	return 0 if(!&ISREF($object,qw(defaultRangeList)));
       
    55 	
       
    56 	if (@_)
       
    57 	{ 
       
    58 		$object->{_DEFAULT_RANGE} = shift; 
       
    59 	}
       
    60 	return $object->{_DEFAULT_RANGE};
       
    61 }
       
    62 
       
    63 # Get/Set the _DEFAULT_INCLUDE_COUNT member value of this class
       
    64 # @param : default include feature count (optional for GET)
       
    65 #
       
    66 sub defaultIncludeCount
       
    67 {
       
    68 	my $object = shift; 
       
    69 	return 0 if(!&ISREF($object,qw(defaultIncludeCount)));
       
    70 	
       
    71 	if (@_)
       
    72 	{ 
       
    73 		$object->{_DEFAULT_INCLUDE_COUNT} = shift; 
       
    74 	}
       
    75 	return $object->{_DEFAULT_INCLUDE_COUNT};
       
    76 }
       
    77 
       
    78 # Get/Set the _DEFAULT_EXCLUDE_COUNT member value of this class
       
    79 # @param : default exclude feature count (optional for GET)
       
    80 #
       
    81 sub defaultExcludeCount 
       
    82 {
       
    83 	my $object = shift; 
       
    84 	return 0 if(!&ISREF($object,qw(defaultExcludeCount)));
       
    85 	
       
    86 	if (@_) 
       
    87 	{ 
       
    88 		$object->{_DEFAULT_EXCLUDE_COUNT} = shift; 
       
    89 	}
       
    90 	return $object->{_DEFAULT_EXCLUDE_COUNT};
       
    91 }
       
    92 
       
    93 # Get/Set the _FILENAME member value of this class
       
    94 # @param : xml file name (optional for GET)
       
    95 #
       
    96 sub fileName 
       
    97 {
       
    98 	my $object = shift; 
       
    99 	return 0 if(!&ISREF($object,qw(fileName)));
       
   100 	
       
   101 	if (@_) 
       
   102 	{ 
       
   103 		$object->{_FILENAME} = shift; 
       
   104 	}
       
   105 	return $object->{_FILENAME};
       
   106 }
       
   107 
       
   108 # Get/Set the _ROOT_ELEMENT member value of this class
       
   109 # @param : root element document pointer (optional for GET)
       
   110 #
       
   111 sub rootElement 
       
   112 {
       
   113 	my $object = shift; 
       
   114 	return 0 if(!&ISREF($object,qw(rootElement)));
       
   115 	
       
   116 	if (@_) 
       
   117 	{ 
       
   118 		$object->{_ROOT_ELEMENT} = shift; 
       
   119 	}
       
   120 	return $object->{_ROOT_ELEMENT};
       
   121 }
       
   122 
       
   123 # Parse the feature xml file
       
   124 # @param : xml file name to parse
       
   125 #
       
   126 sub parseXMLFile 
       
   127 {
       
   128 	my $object = shift; 
       
   129 	return 0 if(!&ISREF($object,qw(parseXMLFile)));
       
   130 	
       
   131 	my $file = shift; # Get the featuredatabase XML filename
       
   132 	$object->fileName($file);
       
   133 	
       
   134 	# Check for the existence of xml file
       
   135 	if(!(-e $file)) 
       
   136 	{
       
   137 		ERROR($file." doesn\'t exist");
       
   138 		return 0;
       
   139 	}
       
   140 	
       
   141 	#Parse the file and Get root Element
       
   142 	my $root = &genericparser::getRootElement($file);
       
   143 	$object->rootElement($root);
       
   144 	
       
   145 	if($root)
       
   146 	{
       
   147 		#Read the <featureset>/<feature> elements
       
   148 		if( !($object->createFeatureMap()) ) 
       
   149 		{
       
   150 			return 0;
       
   151 		}
       
   152 		#Read the <defaultfeaturerange> elements
       
   153 		if( !($object->createDefaultRangeMap()) ) 
       
   154 		{
       
   155 			return 0;
       
   156 		}
       
   157 		
       
   158 		return 1;
       
   159 	}
       
   160 
       
   161 	return -1;
       
   162 }
       
   163 
       
   164 # Read the <defaultfeaturerange> elements
       
   165 # @param - input range attribute set
       
   166 #
       
   167 sub createDefaultRangeMap
       
   168 {
       
   169 	my ($object, @attrSet) = @_; 
       
   170 	return 0 if(!&ISREF($object,"createDefaultRangeMap"));
       
   171 	
       
   172 	# Get the reference to the default feature range list from the object
       
   173 	my $rangeList = $object->defaultRangeList();
       
   174 	foreach my $currNode (@attrSet)
       
   175 	{
       
   176 		my ($min, $max);
       
   177 		my %attrHashMap = ();
       
   178 
       
   179 		# Get the range attributes
       
   180 		$object->readRangeAttributes($currNode, \%attrHashMap);
       
   181 		
       
   182 		#Get the lower and higher uids
       
   183 		$min = $attrHashMap{min};
       
   184 		$max = $attrHashMap{max};
       
   185 		
       
   186 		#Validate it
       
   187 		if((!&IsValidNum($min)) or (!&IsValidNum($max))) {
       
   188 			&ERROR("Valid hexadecimal or decimal value expected in default range");
       
   189 			return 0;
       
   190 		}
       
   191 
       
   192 		#Convert it to decimal
       
   193 		$attrHashMap{min} = &ConvertHexToDecimal($min);
       
   194 		$attrHashMap{max} = &ConvertHexToDecimal($max);
       
   195 		if( $attrHashMap{min} > $attrHashMap{max} ) {
       
   196 			&ERROR("Mininum/Lower UID value ".$min." is greater than Maximum/Higher UID value ".$max);
       
   197 			return 0;
       
   198 		}
       
   199 	
       
   200 		#Add it to the existing range list
       
   201 		my $include = 1;
       
   202 		foreach my $node (@$rangeList) { #Check the range already exists
       
   203 			if(($node->{min} == $attrHashMap{min}) && ($node->{max} == $attrHashMap{max}) 
       
   204 				&& ($node->{support} eq $attrHashMap{support})) {
       
   205 				$include = 0;
       
   206 			}
       
   207 		}
       
   208 		if($include) { # If it is a new range attribute then add it to the list
       
   209 			push @$rangeList, \%attrHashMap;
       
   210 			$object->defaultIncludeCount($object->defaultIncludeCount()+1) if(lc($attrHashMap{support}) eq "include");
       
   211 			$object->defaultExcludeCount($object->defaultExcludeCount()+1) if(lc($attrHashMap{support}) eq "exclude");
       
   212 		}
       
   213 	}
       
   214 
       
   215 	return 1;
       
   216 }
       
   217 
       
   218 # Get the default include ranges of min and max values in 2dimensional array
       
   219 #
       
   220 sub getDefaultIncludeInfo()
       
   221 {
       
   222 	my $object = shift; 
       
   223 	return 0 if(!&ISREF($object,qw(getDefaultIncludeInfo)));
       
   224 	
       
   225 	my @result;	
       
   226 	my %tempHash=();
       
   227 	
       
   228 	my $rangeList = $object->defaultRangeList();
       
   229 	foreach my $range (@$rangeList)
       
   230 	{
       
   231 		if(lc($range->{"support"}) eq "include" )
       
   232 		{
       
   233 			my $min_value=$range->{"min"};
       
   234 			my $max_value=$range->{"max"};
       
   235 			$tempHash{$min_value} = $max_value;
       
   236 		}				
       
   237 	}
       
   238 
       
   239 	my $index = 0;
       
   240 	my @sortedHash = sort keys %tempHash;
       
   241 
       
   242 	foreach my $key (@sortedHash)
       
   243 	{
       
   244 		push @{$result[$index]},$key;
       
   245 		push @{$result[$index]},$tempHash{$key};	
       
   246 		$index++;
       
   247 	}	
       
   248 	return @result;
       
   249 }
       
   250 
       
   251 # Get the default exclude ranges of min and max values in 2dimensional array
       
   252 #
       
   253 sub getDefaultExcludeInfo()
       
   254 {
       
   255 	my $object = shift; 
       
   256 	return 0 if(!&ISREF($object,qw(getDefaultExcludeInfo)));
       
   257 	
       
   258 	my @result;
       
   259 	my %tempHash=();
       
   260 	
       
   261 	my $rangeList = $object->defaultRangeList();
       
   262 	foreach my $range (@$rangeList)
       
   263 	{
       
   264 		if(lc($range->{"support"}) eq "exclude" )
       
   265 		{
       
   266 			my $min_value=$range->{"min"};
       
   267 			my $max_value=$range->{"max"};
       
   268 			$tempHash{$min_value} = $max_value;
       
   269 		}				
       
   270 	}
       
   271 
       
   272 	my $index = 0;
       
   273 	my @sortedHash = sort {$a <=> $b}(keys %tempHash);
       
   274 	foreach my $key (@sortedHash){
       
   275 		push @{$result[$index]},$key;
       
   276 		push @{$result[$index]},$tempHash{$key};
       
   277 		$index++;
       
   278 	}
       
   279 	return @result;
       
   280 }
       
   281 
       
   282 # Get the count of total number of ranges that are either included or excluded on the device as default
       
   283 # 
       
   284 sub getDefaultTotalCount()
       
   285 {
       
   286 	my $object = shift; 
       
   287 	return 0 if(!&ISREF($object,qw(getDefaultTotalCount)));
       
   288 	
       
   289 	return ($object->defaultIncludeCount() + $object->defaultExcludeCount());
       
   290 }
       
   291 
       
   292 # For a given uid value, this function checks if the given uid is within the default=present range.
       
   293 # @param : UID to check
       
   294 #
       
   295 sub getRangeEntry
       
   296 {
       
   297 	my $object = shift; 
       
   298 	return 0 if(!&ISREF($object,qw(getRangeEntry)));
       
   299 	
       
   300 	my $aUid = shift;
       
   301 	my $length = $object->getDefaultTotalCount();
       
   302 	my $pos = 0;
       
   303 	my $rangeRef;
       
   304 
       
   305 	my $rangeList = $object->defaultRangeList();
       
   306 	foreach my $range (@$rangeList)
       
   307 	{
       
   308 		if ( (lc($range->{"support"}) eq "include") and ($range->{"min"} <= $aUid) and ($range->{"max"} >= $aUid) )
       
   309 		{
       
   310 			return $range;
       
   311 		}
       
   312 	}
       
   313 	return undef;
       
   314 }
       
   315 
       
   316 # Get the list of features
       
   317 #
       
   318 sub getFeatures($$)
       
   319 {
       
   320 	my ($includeFeatureRef, $excludeFeatureRef) = @_;
       
   321 	my %FeatureMap = ();
       
   322 	my @FeatList = ();
       
   323 	my $featRef;
       
   324 	my $uid;
       
   325 
       
   326 	foreach my $feat (@$excludeFeatureRef)
       
   327 	{
       
   328 		$uid = $feat->{uid};
       
   329 
       
   330 		$featRef = $FeatureMap{$uid};
       
   331 
       
   332 		if( $featRef->{include} == 1 )
       
   333 		{
       
   334 			&ERROR("The feature $feat->{name} was added into the exclude as well as include list");
       
   335 			return 0;
       
   336 		}
       
   337 		elsif($featRef->{exclude} == 1)
       
   338 		{
       
   339 #			Already added to the final feature list
       
   340 			next;
       
   341 		}
       
   342 		else
       
   343 		{
       
   344 			$FeatureMap{$uid} = $feat;
       
   345 			push @FeatList, $feat;
       
   346 		}
       
   347 	}
       
   348 
       
   349 	foreach my $feat (@$includeFeatureRef)
       
   350 	{
       
   351 		$uid = $feat->{uid};
       
   352 
       
   353 		$featRef = $FeatureMap{$uid};
       
   354 
       
   355 		if( $featRef->{exclude} == 1 )
       
   356 		{
       
   357 			&ERROR("The feature $feat->{name} was added into the exclude as well as include list");
       
   358 			return 0;
       
   359 		}
       
   360 		elsif($featRef->{include} == 1)
       
   361 		{
       
   362 #			Already added to the final feature list
       
   363 			next;
       
   364 		}
       
   365 		else
       
   366 		{
       
   367 			$FeatureMap{$uid} = $feat;
       
   368 			push @FeatList, $feat;
       
   369 		}
       
   370 	}
       
   371 
       
   372 	return \@FeatList;
       
   373 }
       
   374 
       
   375 # ========================================================================
       
   376 # Wrappers for generic xml parser
       
   377 # ========================================================================
       
   378 sub featureparser::getnodefromTree 
       
   379 { 
       
   380 	&genericparser::getNodeFromTree(@_); 
       
   381 }
       
   382 
       
   383 sub getattrValue 
       
   384 { 
       
   385 	&genericparser::getAttrValue(@_); 
       
   386 }
       
   387 
       
   388 sub getelementValue 
       
   389 { 
       
   390 	&genericparser::getElementValue(@_); 
       
   391 }
       
   392 
       
   393 # ========================================================================
       
   394 # Utility sub routines
       
   395 # ========================================================================
       
   396 # Check whether the object is reference type
       
   397 # @param : the object reference
       
   398 #
       
   399 sub ISREF 
       
   400 {
       
   401 	my ($object, $method) = @_;
       
   402 	if(!ref($object)) 
       
   403 	{ 
       
   404 		&ERROR("**Object is not reference-type for the method($method)");
       
   405 		return 0;
       
   406 	}
       
   407 	return 1;
       
   408 }
       
   409 
       
   410 # Parser debugging routines
       
   411 #
       
   412 sub WARN 
       
   413 { 
       
   414 	print "WARNING: ".$_[0]."\n";
       
   415 }
       
   416 sub ERROR 
       
   417 { 
       
   418 	print "ERROR: ".$_[0]."\n";
       
   419 }
       
   420 
       
   421 # Return Decimal value for the given Hexadecimal number.
       
   422 # @param : HexaDecimal Value
       
   423 #
       
   424 sub ConvertHexToDecimal 
       
   425 {
       
   426 	my $val = shift;
       
   427 	if(grep /^0x/i, $val) 
       
   428 	{
       
   429 		# Input is Hexadecimal value, convert to Decimal
       
   430 		return hex($val);	 
       
   431 	}
       
   432 	else 
       
   433 	{
       
   434 		# Decimal value
       
   435 		return $val;
       
   436 	}
       
   437 }
       
   438 
       
   439 # Validate if the given value is a valid number
       
   440 #
       
   441 sub IsValidNum 
       
   442 {
       
   443 	my $num = shift;
       
   444 	return 1 if($num =~ /^\d+$|^0[x][\da-f]+/i);
       
   445 	return 0;
       
   446 }
       
   447 
       
   448 # Validate if the given UID value is a valid number (either decimal or hexadecimal number)
       
   449 #
       
   450 sub ValidateUIDValue 
       
   451 {
       
   452 	my $fuid = shift;
       
   453 	# check to ensure that uid value contains only valid digits (decimal/hexadecimal)
       
   454 	if(IsValidNum $fuid) 
       
   455 	{
       
   456 		return 1;
       
   457 	}
       
   458 	else 
       
   459 	{
       
   460 		&ERROR("Invalid UID value".$fuid."\n");
       
   461 		return 0;
       
   462 	}
       
   463 }
       
   464 
       
   465 1;