bintools/rcomp/src/RESOURCE.CPP
author Mike Kinghan <mikek@symbian.org>
Thu, 25 Nov 2010 13:59:07 +0000
changeset 40 68f68128601f
parent 2 39c28ec933dd
permissions -rwxr-xr-x
1) Add the sbsv1 components from sftools/dev/build to make the linux_build package independent of the obsolete buildtools package. 2) Enhance romnibus.pl so that it generate the symbol file for the built rom when invoked by Raptor 3) Make the maksym.pl tool portable for Linux as well as Windows. 4) Remove the of armasm2as.pl from the e32tools component in favour of the copy now exported from sbsv1/e32util.

/*
* Copyright (c) 1997-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: 
*
*/


#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "RESOURCE.H"
#include "TOKENS.H"  
#include "ERRORHAN.H"

// ResourceItem

ResourceItem::ResourceItem(const String& aLabelToSet, int aResourceItemType):
	iLabel(aLabelToSet),
	iLineNumber(0),
	iResourceItemType(aResourceItemType)
	{}

ResourceItem & ResourceItem::operator= ( const ResourceItem &)
	{
	assert(0);
	return * this;
	}

void ResourceItem::Set(const String* aFileNameToSet, int aLineNumberToSet)
	{
	iFileName = aFileNameToSet;
	iLineNumber = aLineNumberToSet;
	}

void ResourceItem::RegisterErrorLocation()
	{
	ErrorHandler::Register(iFileName,iLineNumber);
	}

int ResourceItem::GetResourceItemType()
	{
	return iResourceItemType;
	}

String ResourceItem::GetLabel()
	{
	return iLabel;
	}

/***************************************************************/
/* SimpleResourceItem                                          */
/***************************************************************/
SimpleResourceItem::SimpleResourceItem(SimpleStructItem* aItem):
	ResourceItem(aItem->iLabel, ESimpleResourceItem),
	iStructItem(aItem),
	iValueSet(0)
	{}	

void SimpleResourceItem::Set(const String& aValueToSet)
	{
	ResourceItem::Set( ErrorHandler::GetFileName(), ErrorHandler::GetLineNumber() );
	
	unsigned long lengthLimit = 0;	// max length of string, 0 = unchecked
	switch ( iStructItem->iItemType)
		{
		case L_LTEXT8:
		case L_LTEXT16:
			lengthLimit = 255;	// length encoded as a single byte
			// fall through...
		case L_TEXT8:
		case L_BUF8:
		case L_TEXT16:
		case L_BUF16:
			if ( iStructItem->iLengthLimit.Length() > 0)
			{
				NumericValue limit(iStructItem->iLengthLimit, L_LONG);
				lengthLimit = limit.GetULong();
			}
			if ( lengthLimit && aValueToSet.ExportLength(TargetCharacterSet,SourceCharacterSet) > lengthLimit )
			{
				char buf[256];
				sprintf(buf, "Text length exceeds specified limit of %lx", lengthLimit);
				ErrorHandler::OutputErrorLine( buf);
				exit(1);
			}
		}
	
	iValue = aValueToSet;
	iValueSet = 1;
	}

void SimpleResourceItem::Set(const StringArray& /*aValues*/)
	{
	// Can't store array of values
	ErrorHandler::OutputErrorLine( "SimpleResourceItem cannot hold array of values");
	exit(1);
	}

ResourceItemArray * SimpleResourceItem::GetRIA()
	{
	assert(0);	// Don't have RIA in this class.
	return NULL;
	}

void SimpleResourceItem::AddDefault()
	{
	if(!iValueSet)
		iValue = iStructItem->iDefault;
	}

void SimpleResourceItem::SetSRLink(unsigned long aSRLinkToSet)
	{
	if(iStructItem->iItemType == L_SRLINK)
		iLinkValue = aSRLinkToSet;
	}

// ArrayResourceItem

ArrayResourceItem::ArrayResourceItem( ArrayStructItem * p):
	ResourceItem( p->iLabel, EArrayResourceItem),
	iStructItem(p)
	{}	

ArrayResourceItem::~ArrayResourceItem()
	{
	iValues.DeleteAll();
	}

void ArrayResourceItem::Set(const String& /*aValue*/)
	{
	// Can't store single value
	ErrorHandler::OutputErrorLine( "ArrayResourceItem requires array of values");
	exit(1);
	}

void ArrayResourceItem::Set(const StringArray& aValuesToSet)
	{
	ResourceItem::Set(ErrorHandler::GetFileName(),ErrorHandler::GetLineNumber());
	iValues = aValuesToSet;
	}

ResourceItemArray * ArrayResourceItem::GetRIA()
	{
	assert(0);	// Don't have RIA in this class.
	return NULL;
	}

void ArrayResourceItem::AddDefault()
	{
	StringArrayIterator NextActual(iValues);
	String* actualvalue;
	StringArrayIterator NextDefault( iStructItem->iDefaults);
	String* defaultvalue;
	// Iterate through actual values and default values.
	while((actualvalue = NextActual()) != NULL)
		{
		if((defaultvalue = NextDefault()) == NULL)
			return;	// Stop if end of defaults reached.
		}
	// Having reached the end of the actual values see if there are any
	// default values to add.
	while((defaultvalue = NextDefault()) != NULL)
		iValues.Add(new String (*defaultvalue));
	}

void ArrayResourceItem::SetSRLink(unsigned long /*aSRLinkToSet*/)
	{}

// StructTypeResourceItem

StructTypeResourceItem::StructTypeResourceItem(StructTypeStructItem* p):
	ResourceItem( p->iLabel, EStructTypeResourceItem),
	iStructItem(p)
	{}	

void StructTypeResourceItem::Set(const String& aStructName)
	{
	ResourceItem::Set(ErrorHandler::GetFileName(),ErrorHandler::GetLineNumber());
	iResourceItems.FillFromStruct(aStructName);
	}

void StructTypeResourceItem::Set(const StringArray& /*aValues*/)
	{
	// Can't store array of values
	ErrorHandler::OutputErrorLine( "StructTypeResourceItem cannot hold array of values");
	exit(1);
	}

ResourceItemArray * StructTypeResourceItem::GetRIA()
	{
	return& iResourceItems;
	}

void StructTypeResourceItem::AddDefault()
	{
	ResourceItemArrayIterator NextActualItem(iResourceItems);
	ResourceItem * pActualItem;
	
	// Add defaults to each of the items already set up.
	while( ( pActualItem = NextActualItem() ) != NULL)
		pActualItem->AddDefault();
	}

void StructTypeResourceItem::SetSRLink(unsigned long /*aSRLinkToSet*/)
	{}

// StructArrayResourceItem

StructArrayResourceItem::StructArrayResourceItem(StructArrayStructItem* p):
	ResourceItem(p->iLabel, EStructArrayResourceItem),
	iStructItem(p),
	iLastRIA( NULL)
	{}	

void StructArrayResourceItem::Set( const String & StructName)
	{
	ResourceItem::Set( ErrorHandler::GetFileName(), ErrorHandler::GetLineNumber() );
	ResourceItemArray* p = new ResourceItemArray;
	iArrayOfResourceItemArrays.Add(p);
	p->FillFromStruct( StructName);
	iLastRIA = p;
	}

void StructArrayResourceItem::Set(const StringArray& /*aValues*/)
	{}

ResourceItemArray * StructArrayResourceItem::GetRIA()
	{
	return iLastRIA;
	}

void StructArrayResourceItem::AddDefault()
	{
	ResourceItemArrayArrayIterator next(iArrayOfResourceItemArrays);
	ResourceItemArray * p;
	while( ( p = next() ) != NULL)
		p->AddDefault();
	}

void StructArrayResourceItem::SetSRLink(unsigned long /*aSRLinkToSet*/)
	{}

// ResourceItemArray

ResourceItemArray::ResourceItemArray():
	iLenType(0)
	{}
	
ResourceItemArray::~ResourceItemArray()
	{
	DeleteAll();
	}
	
void ResourceItemArray::Add( ResourceItem * p)
	{
	Array::Add( p);
	}

void ResourceItemArray::FillFromStruct(const String& aStructName)
	{
	extern StructHeaderArray * pSHA;
	StructHeader * pSH = pSHA->Find(aStructName);
	StructItemArrayIterator next( pSH->iSIA);
	StructItem * pItem;
	while ( ( pItem = next() ) != NULL)
		Add( pItem->NewResourceItem() );
	iLenType = pSH->iLenType;
	}

void ResourceItemArray::Set( const String & Label, const String & Value)
	{
	ResourceItem * p = Find( Label);
	p->Set( Value);
	}

void ResourceItemArray::Set( const String & Label, const StringArray & Values)
	{
	ResourceItem * p = Find( Label);
	p->Set( Values);
	}

ResourceItem * ResourceItemArray::Find( const String & LabelSought)
	{
	ResourceItemArrayIterator next( * this);
	ResourceItem * p;
	
	while( ( p = next() ) != NULL)
		if ( p->iLabel == LabelSought)
			return p;
	
	ErrorHandler::OutputErrorLine( "Label not found");
	exit(1);
	}

void ResourceItemArray::AddDefault()
	{
	ResourceItemArrayIterator next( * this);
	ResourceItem * p;
	
	while( ( p = next() ) != NULL)
		p->AddDefault();
	}

// ResourceHeader

ResourceHeader::ResourceHeader(String aLabelToSet):
	iLabel(aLabelToSet),
	iLocal(0),
	iResourceId(0xdeaddead),
	iFormatAsHex(0),
	iContainsCompressedUnicode(false)
	{
	}

ResourceHeader::ResourceHeader():
	iLocal(0),
	iResourceId(0xdeaddead),
	iFormatAsHex(0),
	iContainsCompressedUnicode(false)
	{
	}

ResourceHeader::~ResourceHeader()
	{
	}

void ResourceHeader::AddDefault()
	{
	iRIA.AddDefault();
	}

void ResourceHeader::SetResourceId(NameIdMap& aMap, unsigned long aId, int aFormatAsHex)
	{
	iResourceId = aId;
	iFormatAsHex = aFormatAsHex;
	if (iLabel.Length() > 0)
		aMap.Add(iLabel, aId);

	ResourceItemArrayIterator next(iRIA);
	ResourceItem * pItem;
	while( ( pItem = next() ) != NULL)
		pItem->SetSRLink(aId);
	}

void ResourceHeader::StreamOut(RCBinaryStream& aStream, int& aSizeOfLargestResourceWhenUncompressed, const char* aDumpFile)
	{
	ResourceDataStream stream;
	iRIA.StreamOut(stream);
	if (aDumpFile!=NULL)
		{
		// dump the resource to aDumpFile in its uncompressed and unpadded state - LINKs, LLINKs, etc will be undefined
		stream.Dump(aDumpFile);
		}
	int sizeWhenUncompressed=0;
	iContainsCompressedUnicode=stream.StreamOutReturningWhetherContainsCompressedUnicode(aStream, sizeWhenUncompressed);
	// this check is unnecessary, zero size resources are allowed so
	// there is no benefit to this assert. 

	if (aSizeOfLargestResourceWhenUncompressed<sizeWhenUncompressed)
		{
		aSizeOfLargestResourceWhenUncompressed=sizeWhenUncompressed;
		}
	}

// ResourceItemArrayArray

ResourceItemArrayArray::ResourceItemArrayArray()
	{}

ResourceItemArrayArray::~ResourceItemArrayArray()
	{
	DeleteAll();
	}
	
void ResourceItemArrayArray::Add( ResourceItemArray * pNewItem)
	{
	Array::Add( pNewItem);
	}

// ResourceItemArrayIterator

ResourceItemArrayIterator::ResourceItemArrayIterator( const ResourceItemArray & c):
	ArrayIterator( c)
	{}

ResourceItem * ResourceItemArrayIterator::operator()()
	{
	return (ResourceItem *) ArrayIterator::operator()();
	}

// ResourceItemArrayArrayIterator

ResourceItemArrayArrayIterator::ResourceItemArrayArrayIterator(const ResourceItemArrayArray & c):
	ArrayIterator( c)
	{}

ResourceItemArray* ResourceItemArrayArrayIterator::operator()()
	{
	return (ResourceItemArray*) ArrayIterator::operator()();
	}