/*******************************************************************************
* Copyright (c) 2007, 2010 Wind River Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Wind River Systems - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model;
import java.math.BigInteger;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.model.LanguageManager;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.presentation.ISourcePresentationCreator;
import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.presentation.SourcePresentationCreatorFactory;
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.ui.IEditorInput;
/**
* Holds information about a source file.
*/
public class SourceFileInfo {
public final String fFileKey;
public final IStorage fFile; // fEdition is subject to change; this records value given to us at construction
public IStorage fEdition;
public BigInteger[] fLine2Addr;
public Addr2Line[] fAddr2Line;
public volatile IDocument fSource;
public volatile boolean fValid;
public Object fLinesNode;
public Throwable fError;
public volatile SourceReadingJob fReadingJob;
public volatile Job fEditionJob;
public ISourcePresentationCreator fPresentationCreator;
public BigInteger fStartAddress = BigInteger.ONE.shiftLeft(64).subtract(BigInteger.ONE);
public BigInteger fEndAddress= BigInteger.ZERO;
public SourceFileInfo(String fileKey, IStorage file) {
fFileKey = fileKey;
fFile = fEdition = file;
}
/**
* Initialize source document.
* @throws CoreException
*/
public void initSource() throws CoreException {
SourceDocumentProvider provider = DsfUIPlugin.getSourceDocumentProvider();
IEditorInput input = new SourceEditorInput(fEdition);
synchronized (provider) {
provider.connect(input);
}
IStatus status = provider.getStatus(input);
if (status != null && !status.isOK()) {
throw new CoreException(status);
}
}
/**
* Initialize presentation creator.
* @param viewer
*/
public void initPresentationCreator(ITextViewer viewer) {
SourceDocumentProvider provider = DsfUIPlugin.getSourceDocumentProvider();
IEditorInput input = new SourceEditorInput(fEdition);
IDocument doc = provider.getDocument(input);
if (doc != null) {
IContentType contentType= null;
if (fEdition instanceof IFile) {
IFile file= (IFile)fEdition;
contentType= CCorePlugin.getContentType(file.getProject(), file.getName());
} else {
contentType= CCorePlugin.getContentType(fEdition.getName());
}
ILanguage language= null;
if (contentType != null) {
language= LanguageManager.getInstance().getLanguage(contentType);
}
if (language != null) {
fPresentationCreator= SourcePresentationCreatorFactory.create(language, fEdition, viewer);
}
int lines = doc.getNumberOfLines();
fLine2Addr = new BigInteger[lines];
fAddr2Line = new Addr2Line[lines / 10 + 1];
// assign fSource last, triggering source update
fSource = doc;
}
}
/**
* Dispose this object.
*/
public void dispose() {
if (fReadingJob != null) {
if (!fReadingJob.cancel()) {
fReadingJob.dispose();
}
fReadingJob = null;
}
if (fPresentationCreator != null) {
fPresentationCreator.dispose();
fPresentationCreator = null;
}
SourceDocumentProvider provider = DsfUIPlugin.getSourceDocumentProvider();
synchronized (provider) {
provider.disconnect(new SourceEditorInput(fEdition));
}
fSource = null;
fValid = false;
// fLinesNode = null;
}
public String getLine(int lineNr) {
return getLines(lineNr, lineNr);
}
public String getLines(int first, int last) {
try {
int startOffset = fSource.getLineOffset(first);
int endOffset;
if (last < fSource.getNumberOfLines()-1) {
IRegion lastRegion = fSource.getLineInformation(last+1);
endOffset = lastRegion.getOffset();
} else {
// last line
IRegion lastRegion = fSource.getLineInformation(last);
endOffset = lastRegion.getOffset() + lastRegion.getLength();
}
return fSource.get(startOffset, endOffset - startOffset);
} catch (BadLocationException e) {
return null;
}
}
public IRegion getRegion(int line, int length) {
try {
IRegion lineRegion = fSource.getLineInformation(line);
return new Region(lineRegion.getOffset(), length);
} catch (BadLocationException e) {
return null;
}
}
/**
* Get or create text presentation for the given region.
* Must be called in display thread.
* @param region
* @return text presentation
*/
public TextPresentation getPresentation(IRegion region) {
if (fSource != null && fPresentationCreator != null) {
return fPresentationCreator.getPresentation(region, fSource);
}
return null;
}
/**
* @return offset of given line
*/
public int getLineOffset(int line) {
if (fSource != null) {
try {
return fSource.getLineOffset(line);
} catch (BadLocationException e) {
// ignored
}
}
return -1;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return fEdition.toString();
}
}