project/com.nokia.carbide.cpp.epoc.engine/src/com/nokia/carbide/internal/cpp/epoc/engine/model/mmp/BitmapBlockListConverter.java
Refactor out BSF/SBV support from SBSv2 Builder data. Create new package for SBSv2Query APIs (moved from builder tests).
/*
* Copyright (c) 2006-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 com.nokia.carbide.internal.cpp.epoc.engine.model.mmp;
import com.nokia.carbide.cpp.epoc.engine.EpocEnginePlugin;
import com.nokia.carbide.cpp.epoc.engine.image.IBitmapSource;
import com.nokia.carbide.cpp.epoc.engine.image.IImageSource;
import com.nokia.carbide.cpp.epoc.engine.image.ImageFormat;
import com.nokia.carbide.cpp.epoc.engine.model.EGeneratedHeaderFlags;
import com.nokia.carbide.cpp.epoc.engine.model.mmp.EMMPStatement;
import com.nokia.carbide.cpp.epoc.engine.model.mmp.IMMPBitmap;
import com.nokia.carbide.cpp.epoc.engine.preprocessor.AllNodesViewFilter;
import com.nokia.carbide.internal.api.cpp.epoc.engine.dom.ASTFactory;
import com.nokia.carbide.internal.api.cpp.epoc.engine.dom.IASTListNode;
import com.nokia.carbide.internal.api.cpp.epoc.engine.dom.IASTLiteralTextNode;
import com.nokia.carbide.internal.api.cpp.epoc.engine.dom.IASTNode;
import com.nokia.carbide.internal.api.cpp.epoc.engine.dom.IASTStatement;
import com.nokia.carbide.internal.api.cpp.epoc.engine.dom.mmp.ASTMMPFactory;
import com.nokia.carbide.internal.api.cpp.epoc.engine.dom.mmp.IASTMMPBitmapSourceStatement;
import com.nokia.carbide.internal.api.cpp.epoc.engine.dom.mmp.IASTMMPSingleArgumentStatement;
import com.nokia.carbide.internal.api.cpp.epoc.engine.dom.mmp.IASTMMPStartBlockStatement;
import com.nokia.carbide.internal.api.cpp.epoc.engine.dom.mmp.IASTMMPStatement;
import com.nokia.carbide.internal.cpp.epoc.engine.model.StructuredItemStatementListConverter;
import com.nokia.cpp.internal.api.utils.core.*;
import org.eclipse.core.runtime.IPath;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
/**
* Convert a START BITMAP ... END block.
*
*/
class BitmapBlockListConverter implements StructuredItemStatementListConverter<IASTMMPStartBlockStatement, IMMPBitmap> {
final static String BITMAP_KEYWORD = "BITMAP"; //$NON-NLS-1$
private MMPView view;
BitmapBlockListConverter(MMPView view) {
this.view = view;
}
/* (non-Javadoc)
* @see com.nokia.carbide.internal.cpp.epoc.engine.model.ViewBase.ListConverter#elementMatches(java.lang.Object, java.lang.Object)
*/
public boolean elementMatches(IMMPBitmap element, IMMPBitmap another) {
return element.getTargetFile().equalsIgnoreCase(another.getTargetFile());
}
/* (non-Javadoc)
* @see com.nokia.carbide.internal.cpp.epoc.engine.model.ViewBase.ListConverter#allowEmptyStatements()
*/
public boolean allowEmptyStatements() {
return false;
}
/* (non-Javadoc)
* @see com.nokia.carbide.internal.cpp.epoc.engine.model.ViewBase.ListConverter#fromNode(com.nokia.carbide.internal.api.cpp.epoc.engine.dom.IASTNode, com.nokia.carbide.internal.cpp.epoc.engine.model.ViewBase.ListArgumentInfoIter)
*/
public IMMPBitmap fromNode(IASTMMPStartBlockStatement node) {
if (!node.getBlockType().getValue().equalsIgnoreCase(BITMAP_KEYWORD))
return null;
if (node.getBlockArguments().size() < 1) {
EpocEnginePlugin.log(new IllegalArgumentException("Skipping malformed START BITMAP block in " + node.getSourceReference() +": " + node.getNewText())); //$NON-NLS-1$ //$NON-NLS-2$
return null;
}
IMMPBitmap bitmap = this.view.createMMPBitmap();
bitmap.setHeaderFlags(EGeneratedHeaderFlags.NoHeader);
bitmap.setTargetFile(node.getBlockArguments().get(0).getValue());
IPath currentSourcePath = view.defaultProjectRelativeSourcePath();
for (IASTMMPStatement stmt : node.getStatements()) {
if (EMMPStatement.TARGETPATH.matches(stmt)) {
bitmap.setTargetPath(FileUtils.createPossiblyRelativePath(((IASTMMPSingleArgumentStatement) stmt).getArgument().getValue()));
}
else if (EMMPStatement.HEADER.matches(stmt)) {
bitmap.setHeaderFlags(EGeneratedHeaderFlags.Header);
}
else if (EMMPStatement.HEADERONLY.matches(stmt)) {
bitmap.setHeaderFlags(EGeneratedHeaderFlags.HeaderOnly);
}
else if (EMMPStatement.SOURCEPATH.matches(stmt)) {
currentSourcePath = view.fromMmpToProjectPath(((IASTMMPSingleArgumentStatement) stmt).getArgument());
}
else if (EMMPStatement.BITMAP_SOURCE.matches(stmt)) {
IASTMMPBitmapSourceStatement bm = (IASTMMPBitmapSourceStatement) stmt;
ImageFormat format = null;
try {
format = new ImageFormat(bm.getFormat().getValue());
} catch (IllegalArgumentException e) {
String errmsg = e.getLocalizedMessage() + " in " + node.getNewText(); //$NON-NLS-1$ //$NON-NLS-2$
EpocEnginePlugin.log(Logging.newStatus(EpocEnginePlugin.getDefault(), new IllegalArgumentException(errmsg)));
format = new ImageFormat(true, 32, 32);
}
int skip = (format.getMaskDepth() != 0 ? 2 : 1);
for (int i = 0; i < bm.getArguments().size(); i += skip) {
IBitmapSource source = bitmap.createBitmapSource();
source.setColor(format.isColor());
source.setDepth(format.getDepth());
source.setMaskDepth(format.getMaskDepth());
IASTLiteralTextNode file = bm.getArguments().get(i);
IPath path = MMPView.combinePaths(currentSourcePath, file.getValue());
source.setPath(path);
if (skip == 2) {
try {
file = bm.getArguments().get(i + 1);
path = MMPView.combinePaths(currentSourcePath, file.getValue());
source.setMaskPath(path);
} catch (IndexOutOfBoundsException e) {
source.setMaskDepth(0);
EpocEnginePlugin.log(new IllegalArgumentException("Insufficient filenames supplied for bitmap list in " + bm.getSourceReference() + ": " + bm.getNewText())); //$NON-NLS-1$ //$NON-NLS-2$
}
}
bitmap.getSources().add(source);
}
}
else if (EMMPStatement.START_BLOCK.matches(stmt)
// marked unknown, not an actual IASTMMPStartBlockStatement
&& stmt.getNewText().toUpperCase().indexOf(BITMAP_KEYWORD) > 0
&& view.getViewConfiguration().getViewFilter() instanceof AllNodesViewFilter) {
// likely this #if construct under the "all" view, ignore:
//
// #ifdef MACRO
// START BITMAP a.mbm
// #else
// START BITMAP b.mbm
// #endif
// ...
// END
}
else {
EpocEnginePlugin.log(new IllegalArgumentException("Ignoring unknown statement in START BITMAP in " + stmt.getSourceReference() + ": " + stmt.getNewText())); //$NON-NLS-1$ //$NON-NLS-2$
}
}
return bitmap;
}
/* (non-Javadoc)
* @see com.nokia.carbide.internal.cpp.epoc.engine.model.ViewBase.ListConverter#toNode(java.lang.Object, com.nokia.carbide.internal.cpp.epoc.engine.model.ViewBase.ListArgumentInfoIter)
*/
public IASTMMPStartBlockStatement toNode(IMMPBitmap bitmap) {
if (!bitmap.isValid()) {
EpocEnginePlugin.log(new IllegalArgumentException("Invalid bitmap block info: " + bitmap)); //$NON-NLS-1$
return null;
}
IASTListNode<IASTLiteralTextNode> blockArguments = ASTFactory.createPreprocessorLiteralTextNodeList(
new String[] { bitmap.getTargetFile() });
IASTListNode<IASTMMPStatement> statements = ASTMMPFactory.createMMPStatementListNode();
if (bitmap.getTargetPath() != null) {
String targetPath = view.pathString(bitmap.getTargetPath());
if (targetPath.length() > 0) {
statements.add(ASTMMPFactory.createMMPSingleArgumentStatement(
EMMPStatement.TARGETPATH.toString(), targetPath));
}
}
switch (bitmap.getHeaderFlags()) {
case NoHeader:
// nothing
break;
case Header:
statements.add(ASTMMPFactory.createMMPFlagStatement(
EMMPStatement.HEADER.toString()));
break;
case HeaderOnly:
statements.add(ASTMMPFactory.createMMPFlagStatement(
EMMPStatement.HEADERONLY.toString()));
break;
default:
Check.checkState(false);
}
ImageFormat lastFormat = null;
List<IPath> files = new ArrayList<IPath>();
boolean isAbsolute = true;
IPath lastSourcePath = null;
CommonPathFinder pathFinder = new CommonPathFinder();
pathFinder.addDirectory(view.defaultProjectRelativeSourcePath());
ListIterator<IImageSource> sourceIter = bitmap.getSources().listIterator();
// Scan all the images of the same image format and emit one
// SOURCEPATH, if needed, plus one SOURCE, for all of them.
// But, break if a source is ever absolute and group those together.
while (sourceIter.hasNext()) {
IImageSource imageSource = sourceIter.next();
if (!(imageSource instanceof IBitmapSource))
continue;
IBitmapSource source = (IBitmapSource) imageSource;
ImageFormat format = new ImageFormat(source.isColor(), source.getDepth(), source.getMaskDepth());
if ((isAbsolute !=
(source.getPath().isAbsolute() || (source.getMaskPath() != null && source.getMaskPath().isAbsolute())))
|| (lastFormat == null || !format.equals(lastFormat)))
{
// flush a line
flushBitmapSource(statements, lastFormat, pathFinder, lastSourcePath, files);
lastSourcePath = pathFinder.getCommonPath();
pathFinder.reset(null);
lastFormat = format;
isAbsolute = source.getPath().isAbsolute() || (source.getMaskPath() != null && source.getMaskPath().isAbsolute());
files.clear();
}
if (!isAbsolute) {
pathFinder.addFile(source.getPath());
}
files.add(source.getPath());
if (format.getMaskDepth() != 0 && source.getMaskPath() != null) {
if (!isAbsolute) {
pathFinder.addFile(source.getMaskPath());
}
files.add(source.getMaskPath());
}
}
// flush leftovers
flushBitmapSource(statements, lastFormat, pathFinder, lastSourcePath, files);
IASTMMPStartBlockStatement blockStmt = ASTMMPFactory.createMMPStartBlockStatement(
ASTFactory.createPreprocessorLiteralTextNode(BITMAP_KEYWORD), //$NON-NLS-1$
blockArguments,
statements);
return blockStmt;
}
/**
*/
private void flushBitmapSource(IASTListNode<IASTMMPStatement> statements, ImageFormat format,
CommonPathFinder pathFinder, IPath lastSourcePath, List<IPath> paths) {
if (format == null || paths.size() == 0)
return;
IPath commonPath = pathFinder.getCommonPath();
if (commonPath != null && !lastSourcePath.equals(commonPath)) {
IASTMMPSingleArgumentStatement sourcePath = ASTMMPFactory.createMMPSingleArgumentStatement(
EMMPStatement.SOURCEPATH.toString(),
view.pathString(view.fromProjectToMmpPath(commonPath)));
statements.add(sourcePath);
}
IASTMMPBitmapSourceStatement source = ASTMMPFactory.createMMPBitmapSourceStatement(
format.toString(), new String[0]);
for (ListIterator<IPath> iterator = paths.listIterator(); iterator.hasNext(); ) {
IPath sourceP = iterator.next();
IPath relative = commonPath != null ? MMPView.fromProjectToRelativePath(
pathFinder.getCommonPath(), sourceP) : sourceP;
source.getArguments().add(ASTFactory.createPreprocessorLiteralTextNode(view.pathString(relative)));
}
statements.add(source);
}
/* (non-Javadoc)
* @see com.nokia.carbide.internal.cpp.epoc.engine.model.mmp.MMPView.StructuredItemListConverter#updateNode(com.nokia.carbide.internal.api.cpp.epoc.engine.dom.mmp.IASTMMPStatement, com.nokia.carbide.internal.api.cpp.epoc.engine.dom.mmp.IASTMMPStatement)
*/
public void updateNode(IASTMMPStartBlockStatement blockStmt, IASTMMPStartBlockStatement updatedNode) {
if (!blockStmt.getBlockArguments().equals(updatedNode.getBlockArguments())) {
blockStmt.setBlockArguments((IASTListNode<IASTLiteralTextNode>) updatedNode.getBlockArguments().copy());
}
if (!blockStmt.getStatements().equals(updatedNode.getStatements())) {
// merge the statements
view.mergeStatementList(blockStmt.getStatements(), updatedNode.getStatements());
}
}
/* (non-Javadoc)
* @see com.nokia.carbide.internal.cpp.epoc.engine.model.mmp.StatementListConverter#canAddToStatement(java.lang.Object)
*/
public boolean canAddToStatement(IMMPBitmap model) {
return false;
}
/* (non-Javadoc)
* @see com.nokia.carbide.internal.cpp.epoc.engine.model.mmp.StatementListConverter#createContextStatement(java.lang.Object)
*/
public IASTMMPStatement createContextStatement(IMMPBitmap model) {
return null;
}
public boolean changeRequiresNewContext(IMMPBitmap existing, IMMPBitmap newElement) {
return false;
}
public Pair<IASTNode, IASTNode> getInsertAnchors() {
return null;
}
public void associateContextStatement(IASTStatement stmt,
IASTStatement contextStmt) {
}
}