--- a/imgtools/buildrom/tools/spitool.pm Fri Aug 13 14:59:05 2010 +0300
+++ b/imgtools/buildrom/tools/spitool.pm Wed Aug 18 17:23:33 2010 +0300
@@ -1,478 +1,478 @@
-#
-# Copyright (c) 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:
-#
-
-package spitool;
-
-use strict;
-use Exporter;
-use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
-
-$VERSION = 1.00;
-@ISA = qw(Exporter);
-@EXPORT = ();
-@EXPORT_OK = qw(createSpi);
-
-sub binarize { #converts decimal number to 4 byte litte endian format
- my $value = shift;
- my $remainder;
- my $returnValue;
- for(my $i=0;$i<4;$i++) {
- $remainder=$value % 256;
- $returnValue.=chr($remainder);
- $value = ($value-$remainder)/256;
- }
- return $returnValue;
-}
-
-sub convertUidFromText { #converts UID from hexadeciaml text value to decimal value, passes decimal value unchanged, returns -1 if invalid UID
- my $value = shift;
- if($value =~ /^0x([\da-fA-F]{1,8})$/i) {
- return hex $1;
- } elsif ($value =~ /^\d*$/) {
- return $value;
- } else {
- return -1;
- }
-}
-
-sub bin2hex { #converts 4 byte little endian value to 0x... hex text value
- my $value=shift;
- my $byte;
- my $quotient;
- my $remainder;
- my $hexValue="";
- for(my $i=0;$i<4;$i++) {
- $byte=ord(substr($value,$i,1));
- $remainder=$byte%16;
- $quotient=($byte-$remainder)/16;
- if($remainder>9) {
- $remainder= chr($remainder+55);
- }
- if($quotient>9) {
- $quotient= chr($quotient+55);
- }
- $hexValue=$quotient . $remainder . $hexValue;
- }
- return "0x" . $hexValue;
-}
-
-sub uidcrc { #returns decimal UID checksum value for the three inputs
- my $output = `uidcrc $_[0] $_[1] $_[2]`;
- if($output =~ /([^ ]*)$/i) {
- $output =$1;
- chomp $output;
- return hex($output);
- }
-}
-
-sub printZeroes { #prints as many hexadecimal zeroes to OUTPUTFILE as specified by input
- my $numberOfZeroes=shift;
- for(my $i=0;$i<$numberOfZeroes;$i++) {
- print OUTPUTFILE chr(0);
- }
-}
-
-sub bytes2dec { #calculates decimal value from inputted 4 byte little endian value
- my $bytes=shift;
- my @byteArray;
- for(my $i=0;$i<length $bytes;$i++) {
- $byteArray[$i]=ord(substr($bytes,$i,1));
- }
- my $decValue;
- for(my $i=0;$i<scalar @byteArray;$i++) {
- $decValue+=($byteArray[$i]*(2**($i*8)));
- }
- return $decValue;
-}
-
-sub print_usage
- {
-#........1.........2.........3.........4.........5.........6.........7.....
- print <<USAGE_EOF;
-
-Usage:
- spitool.pl [options] files directories
-
-Create an SPI file by concatenating the files and contents of directories,
-based on the options passed.
-
-The available options are:
-
--tSPIFileName -- SPIFileName is the name the produced SPI file will
- have (i.e. ecom-0-0.spi). If not specified, the name
- will be ecom-0-0.spi by default
--dTargetDir -- TargetDir is the directory where the SPI file should
- be created, ending with a \
--iExisting -- Existing is address and name of existing SPI file to
- concatenate specified files to
--uid<x>=<y> -- <x> has value 1, 2 or 3, <y> is an UID value in
- decimal or 0x... hexadecimal
--existinguid<x>=<y> -- <x> has value 1, 2 or 3, <y> is an UID value in
- decimal or 0x... hexadecimal
--existinguidcrc=<x> -- <x> is an UID value in decimal or 0x.. hexadecimal
--hide<ResourceFileNames> -- <ResourceFileNames> is the list of the resource files
- that are to be hidden in the SPI file separated by
- space or comma.
-
-If an existing SPI file is specified with the -i option then this file is
-used as a base and other data files are added to the end of this file,
-otherwise a new SPI file is created. In either case the produced SPI file
-is placed in the directory specified by the -d option and given the name
-specified with the -t option.
-
-Files which are to be concatenated into the SPI file should be specified
-on the command line by either specifying the file's name (and location), or
-by including a directory name, in which case all files from that directory
-will be included.
-
-The -uid options can be used to filter files for inclusion in the SPI file.
-This option can be included multiple times, so a list of UID1 values can be
-built up, and the same for UID2 and UID3 values. Each file on the command
-line is compared with this list, and if any of its UID values match a
-relevant value in the UID lists then that file will be included in the SPI
-file. If the file does not match any values it will be excluded.
-
-The -existinguid options allow the UID values that an existing SPI file
-should have to be specified. This will allow the possibility of checking
-that the correct type of files are being concatenated together.
-
-The -hide option can be used to mark a resource file as hidden in the SPI file.
-To mark a resource file as a hidden entry in the SPI file, the resource data
-length will be written as 0.
-
-USAGE_EOF
- }
-
-sub createSpi
- {
- my @resourceFiles=();
- my @hideresourceFiles=();
- my $spiFileName;
- my $targetDirectory;
- my $existingSpiFileName;
- my @uid;
- my @uidLengths = (0, 0, 0, 0);
- my @uid1;
- my @uid2;
- my @uid3;
- my @existingUid = (-1,-1,-1,-1);
- my $uidNumber;
- my $defaultSpiFileName = "ecom-0-0.spi";
- my $defaultTargetDirectory = "$ENV{EPOCROOT}epoc32\\tools\\";
- my @defaultUid = (-1,-1,-1,-1);
-
-##########################################################################################
-# Reading arguments phase
-##########################################################################################
-
- foreach my $arg (@_) {
- if ($arg =~ /^-t(.*)/i) { # set target SPI file
- $spiFileName = $1;
- next;
- }
- if ($arg =~ /^-d(.*)/i) { # set target ouput directory
- my $tempDirectory=$1;
- if((-d $tempDirectory) ) {
- $targetDirectory = $tempDirectory;
- next;
- }
- else
- {
- print "Output directory \'",$tempDirectory,"\' does not exist.\n";
- exit(1);
- }
- }
- if ($arg =~ /^-i(.*)/i) { # existing SPI file to use as a base
- my $tempFileName = $1;
- if((-e $tempFileName) && (!(-d $tempFileName))) {
- $existingSpiFileName = $tempFileName;
- next;
- }
- }
- if ($arg =~ /^-uid([1-3])\=(.*)/i) {
- $uid[$1-1][$uidLengths[$1-1]++] = $2;
- next;
- }
- if($arg=~/^-existinguidcrc\=(.*)/i) {
- $existingUid[3]=$1;
- next;
- }
- if ($arg =~ /^-existinguid([1-3])\=(.*)/i) {
- $existingUid[$1-1]=$2;
- next;
- }
- if ($arg =~ /^-hide(.*)/i) { # Collect the files to be hidden
- my $line = $1;
- $line =~ s/,/ /g;
- my @files = split(' ' , $line);
- foreach my $file (@files)
- {
- push @hideresourceFiles, $file;
- }
- next;
- }
- if (-d $arg) {
- if(($arg =~ m-^.:-) && ($arg =~ m-\\$-)) {
- unless(opendir(DIRECTORY, $arg)) { print "Exiting: $arg"; exit; }
- while (my $file=readdir(DIRECTORY)) {
- my $newfile = $arg.$file;
- if(!(-d $newfile)) {
- push @resourceFiles, $newfile;
- }
- }
- close(DIRECTORY);
- next;
- }
- }
- if ((-e $arg) && (!(-d $arg))) {
- push @resourceFiles, $arg;
- next;
- }
- if ($arg eq "-h") {
- print_usage;
- exit(1);
- }
- print "Unknown command: $arg\n";
- }
-
-#####################################################################################
-# UID phase
-#####################################################################################
-
- if(!(defined $spiFileName)) { #use default file name if none passed on command line
- $spiFileName = $defaultSpiFileName;
- }
- if(!(defined $targetDirectory)) { #use default target dir if none passed on command line
- $targetDirectory = $defaultTargetDirectory;
- }
- for(my $i=0;$i<3;$i++) { #if default UIDs specified then added to UID match lists
- if($defaultUid[$i]>=0) {
- $uid[$i][$uidLengths[$i]++] = $defaultUid[$i];
- }
- }
- for(my $i=0;$i<3;$i++) { #makes sure UIDs are valid UIDs
- my @tempUidArray;
- my $iterator=0;
- while(defined $uid[$i][$iterator]) {
- my $convertedUid=convertUidFromText($uid[$i][$iterator]);
- if ($convertedUid != -1) {
- push @tempUidArray, binarize($convertedUid);
- } else {
- print "Invalid UID: $uid[$i][$iterator]\n";
- }
- $iterator++;
- }
- for(my $j=0;$i<scalar @tempUidArray;$j++) {
- $uid[$i][$j]=$tempUidArray[$j];
- }
- for(my $j=scalar@tempUidArray;defined $uid[$i][$j];$j++) {
- undef $uid[$i][$j];
- }
- }
-#####################################################################################
-# Phase to split up resource names
-#####################################################################################
-
- my @resourceFilePaths;
- my @resourceFileNames;
- my @resourceExtensions;
- my @filestobehidden;
-
-# To mark the resource files as hidden in the SPI file by writing the data length as zero
- foreach my $file (@hideresourceFiles)
- {
- my $matchfound =0;
- my $i=0;
- for(;$i<scalar @resourceFiles && !$matchfound;$i++)
- {
- if (lc($file) eq lc($resourceFiles[$i]))
- {
- $filestobehidden[$i] = 1;
- $matchfound =1;
- }
- }
- if (!$matchfound)
- {
-# Those files that are to be hidden in the SPI file but not existing in the SPI
- if (! -e $file)
- {
- print "Warning: Hiding non-existent file $file\n";
- }
- push @resourceFiles,$file;
- $filestobehidden[$i] = 1;
- }
- }
-
- for(my $i=0;$i<scalar @resourceFiles;$i++) {
- if($resourceFiles[$i]=~m|\\|) {
- if($resourceFiles[$i]=~m|(.*)\\([^\\]*)$|) {
- $resourceFilePaths[$i]=$1;
- $resourceFileNames[$i]=$2;
- }
- if($resourceFileNames[$i]=~m|(.*)\.([^\.]*)|) {
- $resourceFileNames[$i]= $1;
- $resourceExtensions[$i]=$2;
- }
- } else {
- $resourceFilePaths[$i]="";
- if($resourceFiles[$i]=~m|(.*)\.([^\.]*)|) {
- $resourceFileNames[$i]= $1;
- $resourceExtensions[$i]=$2;
- }
- }
- }
-
- my %uid2values; #hash to hold UID2 values for each type of SPI file
- $uid2values{"ecom"} = 270556204;
-
-##########################################################
-# Existing file stage
-##########################################################
-
- my @spiUid = (270556203, 0, 0); #holds spi values (including CRC value)
- foreach my $key (keys(%uid2values)) { #searches through SPI types to match UID2 value
- if($spiFileName =~/^$key/) {
- $spiUid[1]=$uid2values{$key};
- }
- }
- $spiUid[3] = uidcrc($spiUid[0], $spiUid[1], $spiUid[2]);
- my $total=0; #used to keep track of position in SPI file
- my $buffer;
- my $spifile=File::Spec->catpath( "", $targetDirectory, $spiFileName );
- open OUTPUTFILE, ">$spifile" or die $!;
- binmode (OUTPUTFILE);
- if($existingSpiFileName) {
- open EXISTINGFILE, "$existingSpiFileName" or die $!;
- binmode (EXISTINGFILE);
-
- my @fileNameLengths;
- my @fileLengths;
- my @fileNames;
- my @fileContents;
-
- read(EXISTINGFILE,$buffer,4);
- read(EXISTINGFILE,$buffer,4);
- if(bytes2dec($buffer)!=$spiUid[1]) {
- print "Incompatible SPI files.\n";
- }
- read(EXISTINGFILE,$buffer,24);
- $total=32;
- my $existingSpiFileSize = (stat(EXISTINGFILE))[7];
- while($total<$existingSpiFileSize) { #loop to store information from files which are not being replaced
- read(EXISTINGFILE,$buffer,4);
- push @fileNameLengths, bytes2dec($buffer);
- read(EXISTINGFILE,$buffer,4);
- push @fileLengths, bytes2dec($buffer);
- read(EXISTINGFILE,$buffer,$fileNameLengths[$#fileNameLengths]);
- push @fileNames, $buffer;
- $total=$total+8+$fileNameLengths[$#fileNameLengths]+$fileLengths[$#fileLengths];
- my $padding = (4-(($fileNameLengths[$#fileNameLengths]+$fileLengths[$#fileLengths])%4))%4;
- read(EXISTINGFILE,$buffer,$fileLengths[$#fileLengths]+$padding);
- push @fileContents, $buffer;
- $total += (4-($total%4))%4;
- }
- close EXISTINGFILE;
- #next part prints to OUTPUTFILE the header and files which are not being replaced
- print OUTPUTFILE binarize($spiUid[0]) . binarize($spiUid[1]) . binarize($spiUid[2]) . binarize($spiUid[3]);
- printZeroes(16);
- $total=32;
- for(my $i=0; $i<scalar @fileNames; $i++) {
- my $flag=1;
- for(my $j=0; $j<scalar @resourceFileNames && $flag==1; $j++) {
- if($fileNames[$i] eq $resourceFileNames[$j]) {
- $flag=0;
- }
- }
- if($flag) {
- print OUTPUTFILE binarize($fileNameLengths[$i]) . binarize($fileLengths[$i]) . $fileNames[$i] . $fileContents[$i];
- $total=$total+8+length($fileNames[$i])+length($fileContents[$i]);
- }
- }
- } else { #prints header for target SPI file if there is no existing SPI file
- print OUTPUTFILE binarize($spiUid[0]) . binarize($spiUid[1]) . binarize($spiUid[2]) . binarize($spiUid[3]);
- printZeroes(16);
- $total=32;
- }
-
-####################################################################
-# Appending new data files to the SPI file
-####################################################################
-
- my $resourceFileSize;
- my $resourceFileSizeInBinary;
- my $resourceFileNameSize;
- my $resourceFileNameSizeInBinary;
- for(my $i=0; $i<scalar @resourceExtensions;$i++) {
-# To mark the resource files as hidden in the SPI file by writing the data length as zero
- if ($filestobehidden[$i] == 1)
- {
- $resourceFileNameSize = length($resourceFileNames[$i]);
- $resourceFileNameSizeInBinary = binarize($resourceFileNameSize);
- $resourceFileSize = 0;
- $resourceFileSizeInBinary = binarize($resourceFileSize);
- print OUTPUTFILE $resourceFileNameSizeInBinary . $resourceFileSizeInBinary . $resourceFileNames[$i];
- $total+=$resourceFileNameSize;
- my $padding = (4-(($resourceFileSize + $resourceFileNameSize)%4))%4;
- printZeroes($padding);
- $total+=$padding;
- }
- else
- {
- open RESOURCEFILE, "<$resourceFiles[$i]";
- binmode(RESOURCEFILE);
- my @fileUid; #stores UIDs from particular data file
- my $fileUid1;
- my $fileUid2;
- my $fileUid3;
- read(RESOURCEFILE,$fileUid[0],4);
- read(RESOURCEFILE,$fileUid[1],4);
- read(RESOURCEFILE,$fileUid[2],4);
- my $uidFlag=0; #changes to 1 if a UID value in data file matches a specified UID value
- my $uidExists=1; #changes to 1 if there are specified UIDs to match to
- for(my $j=0;$j<3 && (!$uidFlag);$j++) {
- my $k=0;
- while(defined $uid[$j][$k] && (!$uidFlag)) {
- $uidExists=0;
- if($uid[$j][$k] eq bin2hex($fileUid[$j])) {
- $uidFlag=1;
- }
- $k++;
- }
- }
- if(($uidFlag) || ($uidExists)) { #if suitable UIDs writes data file to SPI file
- $resourceFileSize = (stat(RESOURCEFILE))[7];
- $resourceFileNameSize = length($resourceFileNames[$i]);
- $resourceFileNameSizeInBinary = binarize($resourceFileNameSize);
- $resourceFileSizeInBinary = binarize($resourceFileSize);
- print OUTPUTFILE $resourceFileNameSizeInBinary . $resourceFileSizeInBinary . $resourceFileNames[$i];
- print OUTPUTFILE "$fileUid[0]$fileUid[1]$fileUid[2]";
- while(read(RESOURCEFILE,$buffer,1)) {
- print OUTPUTFILE $buffer;
- }
- $total+=$resourceFileSize;
- $total+=8;
- $total+=$resourceFileNameSize;
- my $padding = (4-(($resourceFileSize + $resourceFileNameSize)%4))%4;
- printZeroes($padding);
- $total+=$padding;
- }
- }
- }
- print "Created $spiFileName\n";
-}
-
-
-1;
+#
+# Copyright (c) 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:
+#
+
+package spitool;
+
+use strict;
+use Exporter;
+use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
+use romutl;
+
+$VERSION = 1.00;
+@ISA = qw(Exporter);
+@EXPORT = ();
+@EXPORT_OK = qw(createSpi);
+
+sub binarize { #converts decimal number to 4 byte litte endian format
+ my $value = shift;
+ my $remainder;
+ my $returnValue;
+ for(my $i=0;$i<4;$i++) {
+ $remainder=$value % 256;
+ $returnValue.=chr($remainder);
+ $value = ($value-$remainder)/256;
+ }
+ return $returnValue;
+}
+
+sub convertUidFromText { #converts UID from hexadeciaml text value to decimal value, passes decimal value unchanged, returns -1 if invalid UID
+ my $value = shift;
+ if($value =~ /^0x([\da-fA-F]{1,8})$/i) {
+ return hex $1;
+ } elsif ($value =~ /^\d*$/) {
+ return $value;
+ } else {
+ return -1;
+ }
+}
+
+sub bin2hex { #converts 4 byte little endian value to 0x... hex text value
+ my $value=shift;
+ my $byte;
+ my $quotient;
+ my $remainder;
+ my $hexValue="";
+ for(my $i=0;$i<4;$i++) {
+ $byte=ord(substr($value,$i,1));
+ $remainder=$byte%16;
+ $quotient=($byte-$remainder)/16;
+ if($remainder>9) {
+ $remainder= chr($remainder+55);
+ }
+ if($quotient>9) {
+ $quotient= chr($quotient+55);
+ }
+ $hexValue=$quotient . $remainder . $hexValue;
+ }
+ return "0x" . $hexValue;
+}
+
+sub uidcrc { #returns decimal UID checksum value for the three inputs
+ my $output = `uidcrc $_[0] $_[1] $_[2]`;
+ if($output =~ /([^ ]*)$/i) {
+ $output =$1;
+ chomp $output;
+ return hex($output);
+ }
+}
+
+sub printZeroes { #prints as many hexadecimal zeroes to OUTPUTFILE as specified by input
+ my $numberOfZeroes=shift;
+ for(my $i=0;$i<$numberOfZeroes;$i++) {
+ print OUTPUTFILE chr(0);
+ }
+}
+
+sub bytes2dec { #calculates decimal value from inputted 4 byte little endian value
+ my $bytes=shift;
+ my @byteArray;
+ for(my $i=0;$i<length $bytes;$i++) {
+ $byteArray[$i]=ord(substr($bytes,$i,1));
+ }
+ my $decValue;
+ for(my $i=0;$i<scalar @byteArray;$i++) {
+ $decValue+=($byteArray[$i]*(2**($i*8)));
+ }
+ return $decValue;
+}
+
+sub print_usage
+ {
+#........1.........2.........3.........4.........5.........6.........7.....
+ print <<USAGE_EOF;
+
+Usage:
+ spitool.pl [options] files directories
+
+Create an SPI file by concatenating the files and contents of directories,
+based on the options passed.
+
+The available options are:
+
+-tSPIFileName -- SPIFileName is the name the produced SPI file will
+ have (i.e. ecom-0-0.spi). If not specified, the name
+ will be ecom-0-0.spi by default
+-dTargetDir -- TargetDir is the directory where the SPI file should
+ be created, ending with a \
+-iExisting -- Existing is address and name of existing SPI file to
+ concatenate specified files to
+-uid<x>=<y> -- <x> has value 1, 2 or 3, <y> is an UID value in
+ decimal or 0x... hexadecimal
+-existinguid<x>=<y> -- <x> has value 1, 2 or 3, <y> is an UID value in
+ decimal or 0x... hexadecimal
+-existinguidcrc=<x> -- <x> is an UID value in decimal or 0x.. hexadecimal
+-hide<ResourceFileNames> -- <ResourceFileNames> is the list of the resource files
+ that are to be hidden in the SPI file separated by
+ space or comma.
+
+If an existing SPI file is specified with the -i option then this file is
+used as a base and other data files are added to the end of this file,
+otherwise a new SPI file is created. In either case the produced SPI file
+is placed in the directory specified by the -d option and given the name
+specified with the -t option.
+
+Files which are to be concatenated into the SPI file should be specified
+on the command line by either specifying the file's name (and location), or
+by including a directory name, in which case all files from that directory
+will be included.
+
+The -uid options can be used to filter files for inclusion in the SPI file.
+This option can be included multiple times, so a list of UID1 values can be
+built up, and the same for UID2 and UID3 values. Each file on the command
+line is compared with this list, and if any of its UID values match a
+relevant value in the UID lists then that file will be included in the SPI
+file. If the file does not match any values it will be excluded.
+
+The -existinguid options allow the UID values that an existing SPI file
+should have to be specified. This will allow the possibility of checking
+that the correct type of files are being concatenated together.
+
+The -hide option can be used to mark a resource file as hidden in the SPI file.
+To mark a resource file as a hidden entry in the SPI file, the resource data
+length will be written as 0.
+
+USAGE_EOF
+ }
+
+sub createSpi
+ {
+ my @resourceFiles=();
+ my @hideresourceFiles=();
+ my $spiFileName;
+ my $targetDirectory;
+ my $existingSpiFileName;
+ my @uid;
+ my @uidLengths = (0, 0, 0, 0);
+ my @uid1;
+ my @uid2;
+ my @uid3;
+ my @existingUid = (-1,-1,-1,-1);
+ my $uidNumber;
+ my $defaultSpiFileName = "ecom-0-0.spi";
+ my $defaultTargetDirectory = &get_epocroot."epoc32\/tools\/";
+ my @defaultUid = (-1,-1,-1,-1);
+
+##########################################################################################
+# Reading arguments phase
+##########################################################################################
+
+ foreach my $arg (@_) {
+ if ($arg =~ /^-t(.*)/i) { # set target SPI file
+ $spiFileName = $1;
+ next;
+ }
+ if ($arg =~ /^-d(.*)/i) { # set target ouput directory
+ my $tempDirectory=$1;
+ if((-d $tempDirectory) ) {
+ $targetDirectory = $tempDirectory;
+ next;
+ }
+ else
+ {
+ print "Output directory \'",$tempDirectory,"\' does not exist.\n";
+ exit(1);
+ }
+ }
+ if ($arg =~ /^-i(.*)/i) { # existing SPI file to use as a base
+ my $tempFileName = $1;
+ if((-e $tempFileName) && (!(-d $tempFileName))) {
+ $existingSpiFileName = $tempFileName;
+ next;
+ }
+ }
+ if ($arg =~ /^-uid([1-3])\=(.*)/i) {
+ $uid[$1-1][$uidLengths[$1-1]++] = $2;
+ next;
+ }
+ if($arg=~/^-existinguidcrc\=(.*)/i) {
+ $existingUid[3]=$1;
+ next;
+ }
+ if ($arg =~ /^-existinguid([1-3])\=(.*)/i) {
+ $existingUid[$1-1]=$2;
+ next;
+ }
+ if ($arg =~ /^-hide(.*)/i) { # Collect the files to be hidden
+ my $line = $1;
+ $line =~ s/,/ /g;
+ my @files = split(' ' , $line);
+ foreach my $file (@files)
+ {
+ push @hideresourceFiles, $file;
+ }
+ next;
+ }
+ if (-d $arg) {
+ if(($arg =~ m-^.:-) && ($arg =~ m-[\\\/]$-)) {
+ unless(opendir(DIRECTORY, $arg)) { print "Exiting: $arg"; exit; }
+ while (my $file=readdir(DIRECTORY)) {
+ my $newfile = $arg.$file;
+ if(!(-d $newfile)) {
+ push @resourceFiles, $newfile;
+ }
+ }
+ close(DIRECTORY);
+ next;
+ }
+ }
+ if ((-e $arg) && (!(-d $arg))) {
+ push @resourceFiles, $arg;
+ next;
+ }
+ if ($arg eq "-h") {
+ print_usage;
+ exit(1);
+ }
+ print "Unknown command: $arg\n";
+ }
+
+#####################################################################################
+# UID phase
+#####################################################################################
+
+ if(!(defined $spiFileName)) { #use default file name if none passed on command line
+ $spiFileName = $defaultSpiFileName;
+ }
+ if(!(defined $targetDirectory)) { #use default target dir if none passed on command line
+ $targetDirectory = $defaultTargetDirectory;
+ }
+ for(my $i=0;$i<3;$i++) { #if default UIDs specified then added to UID match lists
+ if($defaultUid[$i]>=0) {
+ $uid[$i][$uidLengths[$i]++] = $defaultUid[$i];
+ }
+ }
+ for(my $i=0;$i<3;$i++) { #makes sure UIDs are valid UIDs
+ my @tempUidArray;
+ my $iterator=0;
+ while(defined $uid[$i][$iterator]) {
+ my $convertedUid=convertUidFromText($uid[$i][$iterator]);
+ if ($convertedUid != -1) {
+ push @tempUidArray, binarize($convertedUid);
+ } else {
+ print "Invalid UID: $uid[$i][$iterator]\n";
+ }
+ $iterator++;
+ }
+ for(my $j=0;$i<scalar @tempUidArray;$j++) {
+ $uid[$i][$j]=$tempUidArray[$j];
+ }
+ for(my $j=scalar@tempUidArray;defined $uid[$i][$j];$j++) {
+ undef $uid[$i][$j];
+ }
+ }
+#####################################################################################
+# Phase to split up resource names
+#####################################################################################
+
+ my @resourceFilePaths;
+ my @resourceFileNames;
+ my @resourceExtensions;
+ my @filestobehidden;
+
+# To mark the resource files as hidden in the SPI file by writing the data length as zero
+ foreach my $file (@hideresourceFiles)
+ {
+ my $matchfound =0;
+ my $i=0;
+ for(;$i<scalar @resourceFiles && !$matchfound;$i++)
+ {
+ if (lc($file) eq lc($resourceFiles[$i]))
+ {
+ $filestobehidden[$i] = 1;
+ $matchfound =1;
+ }
+ }
+ if (!$matchfound)
+ {
+# Those files that are to be hidden in the SPI file but not existing in the SPI
+ if (! -e $file)
+ {
+ print "Warning: Hiding non-existent file $file\n";
+ }
+ push @resourceFiles,$file;
+ $filestobehidden[$i] = 1;
+ }
+ }
+
+ for(my $i=0;$i<scalar @resourceFiles;$i++) {
+ if($resourceFiles[$i]=~m|\/|) {
+ if($resourceFiles[$i]=~m|(.*)\/([^\/]*)$|) {
+ $resourceFilePaths[$i]=$1;
+ $resourceFileNames[$i]=$2;
+ }
+ if($resourceFileNames[$i]=~m|(.*)\.([^\.]*)|) {
+ $resourceFileNames[$i]= $1;
+ $resourceExtensions[$i]=$2;
+ }
+ } else {
+ $resourceFilePaths[$i]="";
+ if($resourceFiles[$i]=~m|(.*)\.([^\.]*)|) {
+ $resourceFileNames[$i]= $1;
+ $resourceExtensions[$i]=$2;
+ }
+ }
+ }
+ my %uid2values; #hash to hold UID2 values for each type of SPI file
+ $uid2values{"ecom"} = 270556204;
+
+##########################################################
+# Existing file stage
+##########################################################
+
+ my @spiUid = (270556203, 0, 0); #holds spi values (including CRC value)
+ foreach my $key (keys(%uid2values)) { #searches through SPI types to match UID2 value
+ if($spiFileName =~/^$key/) {
+ $spiUid[1]=$uid2values{$key};
+ }
+ }
+ $spiUid[3] = uidcrc($spiUid[0], $spiUid[1], $spiUid[2]);
+ my $total=0; #used to keep track of position in SPI file
+ my $buffer;
+ my $spifile=File::Spec->catpath( "", $targetDirectory, $spiFileName );
+ open OUTPUTFILE, ">$spifile" or die $!;
+ binmode (OUTPUTFILE);
+ if($existingSpiFileName) {
+ open EXISTINGFILE, "$existingSpiFileName" or die $!;
+ binmode (EXISTINGFILE);
+
+ my @fileNameLengths;
+ my @fileLengths;
+ my @fileNames;
+ my @fileContents;
+
+ read(EXISTINGFILE,$buffer,4);
+ read(EXISTINGFILE,$buffer,4);
+ if(bytes2dec($buffer)!=$spiUid[1]) {
+ print "Incompatible SPI files.\n";
+ }
+ read(EXISTINGFILE,$buffer,24);
+ $total=32;
+ my $existingSpiFileSize = (stat(EXISTINGFILE))[7];
+ while($total<$existingSpiFileSize) { #loop to store information from files which are not being replaced
+ read(EXISTINGFILE,$buffer,4);
+ push @fileNameLengths, bytes2dec($buffer);
+ read(EXISTINGFILE,$buffer,4);
+ push @fileLengths, bytes2dec($buffer);
+ read(EXISTINGFILE,$buffer,$fileNameLengths[$#fileNameLengths]);
+ push @fileNames, $buffer;
+ $total=$total+8+$fileNameLengths[$#fileNameLengths]+$fileLengths[$#fileLengths];
+ my $padding = (4-(($fileNameLengths[$#fileNameLengths]+$fileLengths[$#fileLengths])%4))%4;
+ read(EXISTINGFILE,$buffer,$fileLengths[$#fileLengths]+$padding);
+ push @fileContents, $buffer;
+ $total += (4-($total%4))%4;
+ }
+ close EXISTINGFILE;
+ #next part prints to OUTPUTFILE the header and files which are not being replaced
+ print OUTPUTFILE binarize($spiUid[0]) . binarize($spiUid[1]) . binarize($spiUid[2]) . binarize($spiUid[3]);
+ printZeroes(16);
+ $total=32;
+ for(my $i=0; $i<scalar @fileNames; $i++) {
+ my $flag=1;
+ for(my $j=0; $j<scalar @resourceFileNames && $flag==1; $j++) {
+ if($fileNames[$i] eq $resourceFileNames[$j]) {
+ $flag=0;
+ }
+ }
+ if($flag) {
+ print OUTPUTFILE binarize($fileNameLengths[$i]) . binarize($fileLengths[$i]) . $fileNames[$i] . $fileContents[$i];
+ $total=$total+8+length($fileNames[$i])+length($fileContents[$i]);
+ }
+ }
+ } else { #prints header for target SPI file if there is no existing SPI file
+ print OUTPUTFILE binarize($spiUid[0]) . binarize($spiUid[1]) . binarize($spiUid[2]) . binarize($spiUid[3]);
+ printZeroes(16);
+ $total=32;
+ }
+
+####################################################################
+# Appending new data files to the SPI file
+####################################################################
+
+ my $resourceFileSize;
+ my $resourceFileSizeInBinary;
+ my $resourceFileNameSize;
+ my $resourceFileNameSizeInBinary;
+ for(my $i=0; $i<scalar @resourceExtensions;$i++) {
+# To mark the resource files as hidden in the SPI file by writing the data length as zero
+ if ($filestobehidden[$i] == 1)
+ {
+ $resourceFileNameSize = length($resourceFileNames[$i]);
+ $resourceFileNameSizeInBinary = binarize($resourceFileNameSize);
+ $resourceFileSize = 0;
+ $resourceFileSizeInBinary = binarize($resourceFileSize);
+ print OUTPUTFILE $resourceFileNameSizeInBinary . $resourceFileSizeInBinary . $resourceFileNames[$i];
+ $total+=$resourceFileNameSize;
+ my $padding = (4-(($resourceFileSize + $resourceFileNameSize)%4))%4;
+ printZeroes($padding);
+ $total+=$padding;
+ }
+ else
+ {
+ open RESOURCEFILE, "<$resourceFiles[$i]";
+ binmode(RESOURCEFILE);
+ my @fileUid; #stores UIDs from particular data file
+ my $fileUid1;
+ my $fileUid2;
+ my $fileUid3;
+ read(RESOURCEFILE,$fileUid[0],4);
+ read(RESOURCEFILE,$fileUid[1],4);
+ read(RESOURCEFILE,$fileUid[2],4);
+ my $uidFlag=0; #changes to 1 if a UID value in data file matches a specified UID value
+ my $uidExists=1; #changes to 1 if there are specified UIDs to match to
+ for(my $j=0;$j<3 && (!$uidFlag);$j++) {
+ my $k=0;
+ while(defined $uid[$j][$k] && (!$uidFlag)) {
+ $uidExists=0;
+ if($uid[$j][$k] eq bin2hex($fileUid[$j])) {
+ $uidFlag=1;
+ }
+ $k++;
+ }
+ }
+ if(($uidFlag) || ($uidExists)) { #if suitable UIDs writes data file to SPI file
+ $resourceFileSize = (stat(RESOURCEFILE))[7];
+ $resourceFileNameSize = length($resourceFileNames[$i]);
+ $resourceFileNameSizeInBinary = binarize($resourceFileNameSize);
+ $resourceFileSizeInBinary = binarize($resourceFileSize);
+ print OUTPUTFILE $resourceFileNameSizeInBinary . $resourceFileSizeInBinary . $resourceFileNames[$i];
+ print OUTPUTFILE "$fileUid[0]$fileUid[1]$fileUid[2]";
+ while(read(RESOURCEFILE,$buffer,1)) {
+ print OUTPUTFILE $buffer;
+ }
+ $total+=$resourceFileSize;
+ $total+=8;
+ $total+=$resourceFileNameSize;
+ my $padding = (4-(($resourceFileSize + $resourceFileNameSize)%4))%4;
+ printZeroes($padding);
+ $total+=$padding;
+ }
+ }
+ }
+ print "Created $spiFileName\n";
+}
+
+
+1;