/*
* 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()();
}