From 992e64134b04747bacafbcdc3307afa641e1a21c Mon Sep 17 00:00:00 2001 From: Alain Magloire Date: Fri, 8 Jul 2005 21:32:14 +0000 Subject: [PATCH] 2005-07-08 Alain Magloire PR 100585:We need to bacth the fire of event. Actually the CModelOperation needed to be change to be aware of nested operation in the same thread. * model/org/eclipse/cdt/internal/core/model/BinaryRunner.java * model/org/eclipse/cdt/internal/core/model/CElement.java * model/org/eclipse/cdt/internal/core/model/CModel.java * model/org/eclipse/cdt/internal/core/model/CModelManager.java * model/org/eclipse/cdt/internal/core/model/CModelException.java * model/org/eclipse/cdt/internal/core/model/ContentTypeProcessor.java * model/org/eclipse/cdt/internal/core/model/PathEntryContainerUpdatesOperation.java * model/org/eclipse/cdt/internal/core/model/PathEntryManager.java * model/org/eclipse/cdt/internal/core/model/PathEntryStoreChangedOperation.java * model/org/eclipse/cdt/internal/core/model/SetPathEntryContainerOperation.java * model/org/eclipse/cdt/internal/core/model/TranslationUnit.java * model/org/eclipse/cdt/internal/core/model/WorkingCopy.java --- core/org.eclipse.cdt.core/ChangeLog | 21 ++ .../cdt/internal/core/model/BinaryRunner.java | 67 ++++--- .../cdt/internal/core/model/CElement.java | 17 +- .../cdt/internal/core/model/CModel.java | 15 +- .../internal/core/model/CModelManager.java | 56 ++---- .../internal/core/model/CModelOperation.java | 103 +++++++++- .../core/model/ContentTypeProcessor.java | 70 ++++--- .../PathEntryContainerUpdatesOperation.java | 90 +++++++++ .../internal/core/model/PathEntryManager.java | 180 ++---------------- .../model/PathEntryStoreChangedOperation.java | 40 ++++ .../model/SetPathEntryContainerOperation.java | 116 +++++++++++ .../internal/core/model/TranslationUnit.java | 8 +- .../cdt/internal/core/model/WorkingCopy.java | 6 +- .../org/eclipse/cdt/utils/macho/MachO.java | 59 +++--- 14 files changed, 538 insertions(+), 310 deletions(-) create mode 100644 core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryContainerUpdatesOperation.java create mode 100644 core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryStoreChangedOperation.java create mode 100644 core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/SetPathEntryContainerOperation.java diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog index a7a5d7a599d..70fc2cf28b7 100644 --- a/core/org.eclipse.cdt.core/ChangeLog +++ b/core/org.eclipse.cdt.core/ChangeLog @@ -1,3 +1,24 @@ +2005-07-08 Alain Magloire + PR 100585:We need to bacth the fire of event. Actually the CModelOperation needed to be + change to be aware of nested operation in the same thread. + * model/org/eclipse/cdt/internal/core/model/BinaryRunner.java + * model/org/eclipse/cdt/internal/core/model/CElement.java + * model/org/eclipse/cdt/internal/core/model/CModel.java + * model/org/eclipse/cdt/internal/core/model/CModelManager.java + * model/org/eclipse/cdt/internal/core/model/CModelException.java + * model/org/eclipse/cdt/internal/core/model/ContentTypeProcessor.java + * model/org/eclipse/cdt/internal/core/model/PathEntryContainerUpdatesOperation.java + * model/org/eclipse/cdt/internal/core/model/PathEntryManager.java + * model/org/eclipse/cdt/internal/core/model/PathEntryStoreChangedOperation.java + * model/org/eclipse/cdt/internal/core/model/SetPathEntryContainerOperation.java + * model/org/eclipse/cdt/internal/core/model/TranslationUnit.java + * model/org/eclipse/cdt/internal/core/model/WorkingCopy.java + +2005-07-08 Alain Magloire + PR 102434: Patch from Chris Wiebe for the MachO parser + * model/org/eclipse/cdt/internal/core/model/CModelManager.java + * utils/org/eclipse/cdt/utils/macho/MachO.java + 2005-07-06 David Inglis fixed bug#102546 diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryRunner.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryRunner.java index 4a5a900267c..08d503e7ae1 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryRunner.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/BinaryRunner.java @@ -15,10 +15,11 @@ import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CoreModelUtil; -import org.eclipse.cdt.core.model.ElementChangedEvent; import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICElementDelta; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.IOutputEntry; +import org.eclipse.cdt.core.model.IParent; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -37,6 +38,42 @@ import org.eclipse.core.runtime.jobs.Job; public class BinaryRunner { + class BinaryRunnerOperation extends CModelOperation { + + BinaryRunnerOperation(ICProject cproj) { + super(cproj); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.model.CModelOperation#isReadOnly() + */ + public boolean isReadOnly() { + return true; + } + + protected void executeOperation() throws CModelException { + ICProject cproj = (ICProject)getElementsToProcess()[0]; + IParent[] containers = new IParent[2]; + containers[0] = cproj.getBinaryContainer(); + containers[1] = cproj.getArchiveContainer(); + CModelManager factory = CModelManager.getDefault(); + ICElement root = factory.getCModel(); + CElementDelta cdelta = new CElementDelta(root); + cdelta.changed(cproj, ICElementDelta.F_CONTENT); + for (int j = 0; j < containers.length; ++j) { + IParent container = containers[j]; + ICElement[] children = container.getChildren(); + if (children.length > 0) { + cdelta.added((ICElement)container); + for (int i = 0; i < children.length; i++) { + cdelta.added(children[i]); + } + } + } + addDelta(cdelta); + } + + } ICProject cproject; Job runner; @@ -68,9 +105,10 @@ public class BinaryRunner { vbin.removeChildren(); cproject.getProject().accept(new Visitor(monitor), IContainer.INCLUDE_PHANTOMS); - fireEvents(cproject, vbin); - fireEvents(cproject, vlib); - + + CModelOperation op = new BinaryRunnerOperation(cproject); + op.runOperation(monitor); + monitor.done(); } catch (CoreException e) { return e.getStatus(); @@ -100,27 +138,6 @@ public class BinaryRunner { } } - void fireEvents(ICProject cproj, Parent container) { - // Fired the event. - try { - ICElement[] children = container.getChildren(); - if (children.length > 0) { - CModelManager factory = CModelManager.getDefault(); - ICElement root = factory.getCModel(); - CElementDelta cdelta = new CElementDelta(root); - cdelta.added(cproj); - cdelta.added(container); - for (int i = 0; i < children.length; i++) { - cdelta.added(children[i]); - } - factory.registerCModelDelta(cdelta); - factory.fire(ElementChangedEvent.POST_CHANGE); - } - } catch (CModelException e) { - // - } - } - private class Visitor implements IResourceProxyVisitor { private IProgressMonitor vMonitor; private IProject project; diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElement.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElement.java index cb9047daf35..fc0b92539f3 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElement.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElement.java @@ -20,6 +20,7 @@ import org.eclipse.cdt.core.model.IOpenable; import org.eclipse.cdt.core.model.IParent; import org.eclipse.cdt.core.model.ISourceRange; import org.eclipse.cdt.core.model.ISourceReference; +import org.eclipse.cdt.core.model.ISourceRoot; import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourceAttributes; @@ -260,6 +261,9 @@ public abstract class CElement extends PlatformObject implements ICElement { case C_PROJECT: return "CPROJECT"; //$NON-NLS-1$ case C_CCONTAINER: + if (this instanceof ISourceRoot) { + return "SOURCE_ROOT"; //$NON-NLS-1$ + } return "CCONTAINER"; //$NON-NLS-1$ case C_UNIT: if (this instanceof IWorkingCopy) { @@ -292,17 +296,16 @@ public abstract class CElement extends PlatformObject implements ICElement { return "C_NAMESPACE"; //$NON-NLS-1$ case C_USING: return "C_USING"; //$NON-NLS-1$ + case C_VCONTAINER: + return "C_CONTAINER"; //$NON-NLS-1$ + case C_BINARY: + return "C_BINARY"; //$NON-NLS-1$ + case C_ARCHIVE: + return "C_ARCHIVE"; //$NON-NLS-1$ default: return "UNKNOWN"; //$NON-NLS-1$ } } - - /** - * Runs a C Model Operation - */ - protected void runOperation(CModelOperation operation, IProgressMonitor monitor) throws CModelException { - CModelManager.getDefault().runOperation(operation, monitor); - } /** * Close the C Element diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModel.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModel.java index cbef50daed9..f0b4a388d9b 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModel.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModel.java @@ -115,11 +115,13 @@ public class CModel extends Openable implements ICModel { public void delete(ICElement[] elements, boolean force, IProgressMonitor monitor) throws CModelException { + CModelOperation op; if (elements != null && elements[0] != null && elements[0].getElementType() <= ICElement.C_UNIT) { - runOperation(new DeleteResourceElementsOperation(elements, force), monitor); + op = new DeleteResourceElementsOperation(elements, force); } else { - runOperation(new DeleteElementsOperation(elements, force), monitor); + op = new DeleteElementsOperation(elements, force); } + op.runOperation(monitor); } public void move(ICElement[] elements, ICElement[] containers, ICElement[] siblings, @@ -133,12 +135,13 @@ public class CModel extends Openable implements ICModel { public void rename(ICElement[] elements, ICElement[] destinations, String[] renamings, boolean force, IProgressMonitor monitor) throws CModelException { + CModelOperation op; if (elements != null && elements[0] != null && elements[0].getElementType() <= ICElement.C_UNIT) { - runOperation(new RenameResourceElementsOperation(elements, destinations, - renamings, force), monitor); + op = new RenameResourceElementsOperation(elements, destinations, renamings, force); } else { - runOperation(new RenameElementsOperation(elements, destinations, renamings, force), monitor); + op = new RenameElementsOperation(elements, destinations, renamings, force); } + op.runOperation(monitor); } /** @@ -151,7 +154,7 @@ public class CModel extends Openable implements ICModel { op.setInsertBefore(elements[i], siblings[i]); } } - runOperation(op, monitor); + op.runOperation(monitor); } protected CElementInfo createElementInfo () { diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java index b97ed3b1a6e..d743e449637 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java @@ -50,13 +50,11 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IResourceDelta; -import org.eclipse.core.resources.IResourceStatus; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.content.IContentTypeManager.IContentTypeChangeListener; @@ -80,8 +78,6 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe */ protected DeltaProcessor fDeltaProcessor = new DeltaProcessor(); - protected ContentTypeProcessor fContentTypeProcessor = new ContentTypeProcessor(); - /** * Queue of deltas created explicily by the C Model that * have yet to be fired. @@ -563,8 +559,9 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe } byte[] bytes = new byte[hints]; if (hints > 0) { + InputStream is = null; try { - InputStream is = file.getContents(); + is = file.getContents(); int count = 0; // Make sure we read up to 'hints' bytes if we possibly can while (count < hints) { @@ -573,7 +570,6 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe break; count += bytesRead; } - is.close(); if (count > 0 && count < bytes.length) { byte[] array = new byte[count]; System.arraycopy(bytes, 0, array, 0, count); @@ -583,6 +579,14 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe return null; } catch (IOException e) { return null; + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) { + // ignore + } + } } } @@ -775,7 +779,11 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe * @see org.eclipse.core.runtime.content.IContentTypeManager.IContentTypeListener#contentTypeChanged() */ public void contentTypeChanged(ContentTypeChangeEvent event) { - fContentTypeProcessor.processContentTypeChanges(event); + ContentTypeProcessor.processContentTypeChanges(new ContentTypeChangeEvent[]{ event }); + } + + public void contentTypeChanged(ContentTypeChangeEvent[] events) { + ContentTypeProcessor.processContentTypeChanges(events); } public void fire(int eventType) { @@ -786,7 +794,7 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe * Fire C Model deltas, flushing them after the fact. * If the firing mode has been turned off, this has no effect. */ - public void fire(ICElementDelta customDeltas, int eventType) { + void fire(ICElementDelta customDeltas, int eventType) { if (fFire) { ICElementDelta deltaToNotify; if (customDeltas == null) { @@ -945,38 +953,6 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe } } - /** - * Runs a C Model Operation - */ - public void runOperation(CModelOperation operation, IProgressMonitor monitor) throws CModelException { - boolean hadAwaitingDeltas = !fCModelDeltas.isEmpty(); - try { - if (operation.isReadOnly()) { - operation.run(monitor); - } else { - // use IWorkspace.run(...) to ensure that a build will be done in autobuild mode - getCModel().getUnderlyingResource().getWorkspace() - .run(operation, operation.getSchedulingRule(), IWorkspace.AVOID_UPDATE, monitor); - } - } catch (CoreException ce) { - if (ce instanceof CModelException) { - throw (CModelException)ce; - } else if (ce.getStatus().getCode() == IResourceStatus.OPERATION_FAILED) { - Throwable e = ce.getStatus().getException(); - if (e instanceof CModelException) { - throw (CModelException)e; - } - } - throw new CModelException(ce); - } finally { -// fire only if there were no awaiting deltas (if there were, they would come from a resource modifying operation) - // and the operation has not modified any resource - if (!hadAwaitingDeltas && !operation.hasModifiedResource()) { - fire(ElementChangedEvent.POST_CHANGE); - } // else deltas are fired while processing the resource delta - } - } - /** * Returns the set of elements which are out of synch with their buffers. */ diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelOperation.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelOperation.java index 66ad458beff..cf7c15ca4bd 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelOperation.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelOperation.java @@ -5,6 +5,7 @@ package org.eclipse.cdt.internal.core.model; * All Rights Reserved. */ import java.io.InputStream; +import java.util.ArrayList; import java.util.HashMap; import org.eclipse.cdt.core.model.CModelException; @@ -95,6 +96,11 @@ public abstract class CModelOperation implements IWorkspaceRunnable, IProgressMo */ protected boolean hasModifiedResource = false; + /* + * A per thread stack of java model operations (PerThreadObject of ArrayList). + */ + protected static ThreadLocal operationStacks = new ThreadLocal(); + protected CModelOperation() { } /** @@ -162,7 +168,7 @@ public abstract class CModelOperation implements IWorkspaceRunnable, IProgressMo } /* - * Registers the given reconcile delta with the Java Model Manager. + * Registers the given reconcile delta with the C Model Manager. */ protected void addReconcileDelta(IWorkingCopy workingCopy, ICElementDelta delta) { HashMap reconcileDeltas = CModelManager.getDefault().reconcileDeltas; @@ -531,6 +537,53 @@ public abstract class CModelOperation implements IWorkspaceRunnable, IProgressMo } } + /* + * Returns the stack of operations running in the current thread. + * Returns an empty stack if no operations are currently running in this thread. + */ + protected ArrayList getCurrentOperationStack() { + ArrayList stack = (ArrayList)operationStacks.get(); + if (stack == null) { + stack = new ArrayList(); + operationStacks.set(stack); + } + return stack; + } + + /* + * Removes the last pushed operation from the stack of running operations. + * Returns the poped operation or null if the stack was empty. + */ + protected CModelOperation popOperation() { + ArrayList stack = getCurrentOperationStack(); + int size = stack.size(); + if (size > 0) { + if (size == 1) { // top level operation + operationStacks.set(null); // release reference (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=33927) + } + return (CModelOperation)stack.remove(size-1); + } else { + return null; + } + } + + /* + * Pushes the given operation on the stack of operations currently running in this thread. + */ + protected void pushOperation(CModelOperation operation) { + getCurrentOperationStack().add(operation); + } + + /* + * Returns whether this operation is the first operation to run in the current thread. + */ + protected boolean isTopLevelOperation() { + ArrayList stack; + return + (stack = this.getCurrentOperationStack()).size() > 0 + && stack.get(0) == this; + } + /** * Main entry point for C Model operations. Executes this operation * and registers any deltas created. @@ -541,19 +594,57 @@ public abstract class CModelOperation implements IWorkspaceRunnable, IProgressMo public void run(IProgressMonitor monitor) throws CoreException { CModelManager manager= CModelManager.getDefault(); int previousDeltaCount = manager.fCModelDeltas.size(); + pushOperation(this); try { fMonitor = monitor; execute(); } finally { - registerDeltas(); - // Fire if we change somethings - if ((manager.fCModelDeltas.size() > previousDeltaCount || !manager.reconcileDeltas.isEmpty()) - && !this.hasModifiedResource()) { - manager.fire(ElementChangedEvent.POST_CHANGE); + try { + registerDeltas(); + // Fire if we change somethings + if (isTopLevelOperation()) { + if ((manager.fCModelDeltas.size() > previousDeltaCount || !manager.reconcileDeltas.isEmpty()) + && !this.hasModifiedResource()) { + manager.fire(ElementChangedEvent.POST_CHANGE); + } + } + } finally { + popOperation(); } } } + /** + * Main entry point for C Model operations. Runs a C Model Operation as an IWorkspaceRunnable + * if not read-only. + */ + public void runOperation(IProgressMonitor monitor) throws CModelException { + ICModelStatus status = verify(); + if (!status.isOK()) { + throw new CModelException(status); + } + try { + if (isReadOnly()) { + run(monitor); + } else { + // use IWorkspace.run(...) to ensure that a build will be done in autobuild mode + getCModel().getUnderlyingResource().getWorkspace() + .run(this, getSchedulingRule(), IWorkspace.AVOID_UPDATE, monitor); + } + } catch (CoreException ce) { + if (ce instanceof CModelException) { + throw (CModelException)ce; + } else if (ce.getStatus().getCode() == IResourceStatus.OPERATION_FAILED) { + Throwable e = ce.getStatus().getException(); + if (e instanceof CModelException) { + throw (CModelException)e; + } + } + throw new CModelException(ce); + } + } + + /** * @see IProgressMonitor */ diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ContentTypeProcessor.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ContentTypeProcessor.java index 8227a58eea1..1ab73e54ec4 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ContentTypeProcessor.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ContentTypeProcessor.java @@ -17,7 +17,6 @@ import java.util.List; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CoreModel; -import org.eclipse.cdt.core.model.ElementChangedEvent; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElementDelta; import org.eclipse.cdt.core.model.ICModel; @@ -38,31 +37,54 @@ import org.eclipse.core.runtime.preferences.IScopeContext; /** * ContentType processor */ -public class ContentTypeProcessor { +public class ContentTypeProcessor extends CModelOperation { CModelManager fManager; CElementDelta fCurrentDelta; + ContentTypeChangeEvent[] fEvents; - public void processContentTypeChanges(ContentTypeChangeEvent event) { - ICElement root = CModelManager.getDefault().getCModel(); - fCurrentDelta = new CElementDelta(root); + public ContentTypeProcessor(ContentTypeChangeEvent[] events) { + super(CModelManager.getDefault().getCModel()); + this.fEvents = events; fManager = CModelManager.getDefault(); - IContentType contentType = event.getContentType(); - - // only interested in our contentTypes - // Go through the events and generate deltas - ICProject[] cprojects = getAffectedProjects(event); - for (int k = 0; k < cprojects.length; ++k) { - ICProject cproject = cprojects[k]; - processContentType(cproject, contentType, event.getContext()); - } + ICElement root = fManager.getCModel(); + fCurrentDelta = new CElementDelta(root); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.internal.core.model.CModelOperation#isReadOnly() + */ + public boolean isReadOnly() { + return true; + } + protected void executeOperation() throws CModelException { + for (int i = 0; i < fEvents.length; ++i) { + IContentType contentType = fEvents[i].getContentType(); + IScopeContext context = fEvents[i].getContext(); + ICProject[] cprojects = getAffectedProjects(fEvents[i]); + for (int k = 0; k < cprojects.length; ++k) { + processContentType(cprojects[k], contentType, context); + } + } + if (fCurrentDelta.getAffectedChildren().length > 0) { - fManager.fire(fCurrentDelta, ElementChangedEvent.POST_CHANGE); + addDelta(fCurrentDelta); + } + } + + + + static public void processContentTypeChanges(ContentTypeChangeEvent[] events) { + try { + CModelOperation op = new ContentTypeProcessor(events); + op.runOperation(null); + } catch (CModelException e) { + // } } - boolean isRegisteredContentTypeId(String id) { + private boolean isRegisteredContentTypeId(String id) { String[] ids = CoreModel.getRegistedContentTypeIds(); for (int i = 0; i < ids.length; i++) { if (ids[i].equals(id)) { @@ -72,7 +94,7 @@ public class ContentTypeProcessor { return false; } - void processContentType(ICElement celement, IContentType contentType, IScopeContext context) { + protected void processContentType(ICElement celement, IContentType contentType, IScopeContext context) { if (celement instanceof IOpenable) { int type = celement.getElementType(); // if the type is not a TranslationUnit @@ -139,13 +161,11 @@ public class ContentTypeProcessor { String id = ((ITranslationUnit)celement).getContentTypeId(); if (contentType.getId().equals(id)) { try { - if (! contentType.isAssociatedWith(celement.getElementName(), context)) { - IContentType cType = CCorePlugin.getContentType(celement.getCProject().getProject(), celement.getElementName()); - if (cType != null && isRegisteredContentTypeId(cType.getId())) { - elementChanged(celement); - } else { - elementRemoved(celement, celement.getParent()); - } + IContentType cType = CCorePlugin.getContentType(celement.getCProject().getProject(), celement.getElementName()); + if (cType != null && isRegisteredContentTypeId(cType.getId())) { + elementChanged(celement); + } else { + elementRemoved(celement, celement.getParent()); } } catch (CoreException e) { // @@ -224,7 +244,7 @@ public class ContentTypeProcessor { fManager.releaseCElement(celement); } - protected void elementChanged(ICElement element) throws CModelException { + private void elementChanged(ICElement element) throws CModelException { // For Binary/Archive We can not call close() to do the work // closing will remove the element from the {Binary,Archive}Container // We neef to clear the cache explicitely diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryContainerUpdatesOperation.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryContainerUpdatesOperation.java new file mode 100644 index 00000000000..e0492ae4114 --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryContainerUpdatesOperation.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2005 QnX Software 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: + * Qnx Software Systems - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.core.model; + +import java.util.ArrayList; + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICElementDelta; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IOpenable; +import org.eclipse.cdt.core.model.IPathEntryContainer; +import org.eclipse.cdt.core.model.IPathEntryContainerExtension; +import org.eclipse.cdt.core.model.PathEntryContainerChanged; + +public class PathEntryContainerUpdatesOperation extends CModelOperation { + + IPathEntryContainerExtension container; + PathEntryContainerChanged[] events; + + public PathEntryContainerUpdatesOperation(IPathEntryContainerExtension container, PathEntryContainerChanged[] events) { + super(CModelManager.getDefault().getCModel()); + this.container = container; + this.events = events; + } + protected void executeOperation() throws CModelException { + PathEntryManager pathEntryManager = PathEntryManager.getDefault(); + ArrayList list = new ArrayList(events.length); + for (int i = 0; i < events.length; ++i) { + PathEntryContainerChanged event = events[i]; + ICElement celement = CoreModel.getDefault().create(event.getPath()); + if (celement != null) { + // Sanity check the container __must__ be set on the project. + boolean foundContainer = false; + IPathEntryContainer[] containers = pathEntryManager.getPathEntryContainers(celement.getCProject()); + for (int k = 0 ; k < containers.length; ++k) { + if (containers[k].getPath().equals(container.getPath())) { + foundContainer = true; + break; + } + } + if (!foundContainer) { + continue; + } + // remove the element info caching. + if (celement instanceof IOpenable) { + try { + ((IOpenable)celement).close(); + // Make sure we clear the cache on the project too + if (!(celement instanceof ICProject)) { + celement.getCProject().close(); + } + } catch (CModelException e) { + // ignore. + } + } + int flag =0; + if (event.isIncludeChange()) { + flag |= ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE; + } + if (event.isMacroChange()) { + flag |= ICElementDelta.F_CHANGED_PATHENTRY_MACRO; + } + CElementDelta delta = new CElementDelta(celement.getCModel()); + delta.changed(celement, flag); + list.add(delta); + } + } + if (list.size() > 0) { + final ICElementDelta[] deltas = new ICElementDelta[list.size()]; + list.toArray(deltas); + CModelManager manager = CModelManager.getDefault(); + for (int i = 0; i < deltas.length; i++) { + addDelta(deltas[i]); + } + } + + } + +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryManager.java index 623942e9b4a..1fb25c8071d 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryManager.java @@ -37,7 +37,6 @@ import org.eclipse.cdt.core.model.IIncludeFileEntry; import org.eclipse.cdt.core.model.ILibraryEntry; import org.eclipse.cdt.core.model.IMacroEntry; import org.eclipse.cdt.core.model.IMacroFileEntry; -import org.eclipse.cdt.core.model.IOpenable; import org.eclipse.cdt.core.model.IOutputEntry; import org.eclipse.cdt.core.model.IPathEntry; import org.eclipse.cdt.core.model.IPathEntryContainer; @@ -518,7 +517,7 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange try { IPathEntry[] oldResolvedEntries = getCachedResolvedPathEntries(cproject); SetPathEntriesOperation op = new SetPathEntriesOperation(cproject, oldResolvedEntries, newEntries); - CModelManager.getDefault().runOperation(op, monitor); + op.runOperation(monitor); } catch (CoreException e) { throw new CModelException(e); } @@ -570,96 +569,9 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange public void setPathEntryContainer(ICProject[] affectedProjects, IPathEntryContainer newContainer, IProgressMonitor monitor) throws CModelException { - if (monitor != null && monitor.isCanceled()) { - return; - } - IPath containerPath = (newContainer == null) ? new Path("") : newContainer.getPath(); //$NON-NLS-1$ - final int projectLength = affectedProjects.length; - final ICProject[] modifiedProjects = new ICProject[projectLength]; - System.arraycopy(affectedProjects, 0, modifiedProjects, 0, projectLength); - final IPathEntry[][] oldResolvedEntries = new IPathEntry[projectLength][]; - // filter out unmodified project containers - int remaining = 0; - for (int i = 0; i < projectLength; i++) { - if (monitor != null && monitor.isCanceled()) { - return; - } - ICProject affectedProject = affectedProjects[i]; - boolean found = false; - IPathEntry[] rawPath = getRawPathEntries(affectedProject); - for (int j = 0, cpLength = rawPath.length; j < cpLength; j++) { - IPathEntry entry = rawPath[j]; - if (entry.getEntryKind() == IPathEntry.CDT_CONTAINER) { - IContainerEntry cont = (IContainerEntry)entry; - if (cont.getPath().equals(containerPath)) { - found = true; - break; - } - } - } - if (!found) { - // filter out this project - does not reference the container - // path - modifiedProjects[i] = null; - // Still add it to the cache - containerPut(affectedProject, containerPath, newContainer); - continue; - } - IPathEntryContainer oldContainer = containerGet(affectedProject, containerPath, true); - if (oldContainer != null && newContainer != null && oldContainer.equals(newContainer)) { - modifiedProjects[i] = null; // filter out this project - - // container did not change - continue; - } - remaining++; - oldResolvedEntries[i] = removeCachedResolvedPathEntries(affectedProject); - containerPut(affectedProject, containerPath, newContainer); - } - // Nothing change. - if (remaining == 0) { - return; - } - - // trigger model refresh - try { - //final boolean canChangeResources = - // !ResourcesPlugin.getWorkspace().isTreeLocked(); - CoreModel.run(new IWorkspaceRunnable() { - - public void run(IProgressMonitor progressMonitor) throws CoreException { - - boolean shouldFire = false; - CModelManager mgr = CModelManager.getDefault(); - for (int i = 0; i < projectLength; i++) { - if (progressMonitor != null && progressMonitor.isCanceled()) { - return; - } - ICProject affectedProject = modifiedProjects[i]; - if (affectedProject == null) { - continue; // was filtered out - } - // Only fire deltas if we had previous cache - if (oldResolvedEntries[i] != null) { - IPathEntry[] newEntries = getResolvedPathEntries(affectedProject); - ICElementDelta[] deltas = generatePathEntryDeltas(affectedProject, oldResolvedEntries[i], newEntries); - if (deltas.length > 0) { - affectedProject.close(); - shouldFire = true; - for (int j = 0; j < deltas.length; j++) { - mgr.registerCModelDelta(deltas[j]); - } - } - } - } - if (shouldFire) { - mgr.fire(ElementChangedEvent.POST_CHANGE); - } - } - }, monitor); - } catch (CoreException e) { - // - } + SetPathEntryContainerOperation op = new SetPathEntryContainerOperation(affectedProjects, newContainer); + op.runOperation(monitor); } public synchronized IPathEntryContainer[] getPathEntryContainers(ICProject cproject) { @@ -780,7 +692,7 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange return null; } - private synchronized IPathEntryContainer containerGet(ICProject cproject, IPath containerPath, boolean bCreateLock) { + synchronized IPathEntryContainer containerGet(ICProject cproject, IPath containerPath, boolean bCreateLock) { Map projectContainers = (Map)Containers.get(cproject); if (projectContainers == null) { projectContainers = new HashMap(); @@ -795,7 +707,7 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange return container; } - private synchronized void containerPut(ICProject cproject, IPath containerPath, IPathEntryContainer container) { + synchronized void containerPut(ICProject cproject, IPath containerPath, IPathEntryContainer container) { Map projectContainers = (Map)Containers.get(cproject); if (projectContainers == null) { projectContainers = new HashMap(); @@ -814,71 +726,18 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange } } - private synchronized void containerRemove(ICProject cproject) { + synchronized void containerRemove(ICProject cproject) { Containers.remove(cproject); } public void pathEntryContainerUpdates(IPathEntryContainerExtension container, PathEntryContainerChanged[] events, IProgressMonitor monitor) { - - ArrayList list = new ArrayList(events.length); - for (int i = 0; i < events.length; ++i) { - PathEntryContainerChanged event = events[i]; - ICElement celement = CoreModel.getDefault().create(event.getPath()); - if (celement != null) { - // Sanity check the container __must__ be set on the project. - boolean foundContainer = false; - IPathEntryContainer[] containers = getPathEntryContainers(celement.getCProject()); - for (int k = 0 ; k < containers.length; ++k) { - if (containers[k].getPath().equals(container.getPath())) { - foundContainer = true; - break; - } - } - if (!foundContainer) { - continue; - } - // remove the element info caching. - if (celement instanceof IOpenable) { - try { - ((IOpenable)celement).close(); - // Make sure we clear the cache on the project too - if (!(celement instanceof ICProject)) { - celement.getCProject().close(); - } - } catch (CModelException e) { - // ignore. - } - } - int flag =0; - if (event.isIncludeChange()) { - flag |= ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE; - } - if (event.isMacroChange()) { - flag |= ICElementDelta.F_CHANGED_PATHENTRY_MACRO; - } - CElementDelta delta = new CElementDelta(celement.getCModel()); - delta.changed(celement, flag); - list.add(delta); - } - } - if (list.size() > 0) { - final ICElementDelta[] deltas = new ICElementDelta[list.size()]; - list.toArray(deltas); - try { - CoreModel.run(new IWorkspaceRunnable() { - - public void run(IProgressMonitor progressMonitor) throws CoreException { - CModelManager manager = CModelManager.getDefault(); - for (int i = 0; i < deltas.length; i++) { - manager.registerCModelDelta(deltas[i]); - } - manager.fire(ElementChangedEvent.POST_CHANGE); - } - }, monitor); - } catch (CoreException e) { - // log the error. - } + + PathEntryContainerUpdatesOperation op = new PathEntryContainerUpdatesOperation(container, events); + try { + op.runOperation(monitor); + } catch (CModelException e) { + // } } @@ -1301,24 +1160,15 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange } CModelManager manager = CModelManager.getDefault(); - ICProject cproject = manager.create(project); + final ICProject cproject = manager.create(project); if (event.hasClosed()) { setPathEntryStore(project, null); containerRemove(cproject); } if (project.isAccessible()) { try { - // Clear the old cache entries. - IPathEntry[] oldResolvedEntries = removeCachedResolvedPathEntries(cproject); - IPathEntry[] newResolvedEntries = getResolvedPathEntries(cproject); - ICElementDelta[] deltas = generatePathEntryDeltas(cproject, oldResolvedEntries, newResolvedEntries); - if (deltas.length > 0) { - cproject.close(); - for (int i = 0; i < deltas.length; i++) { - manager.registerCModelDelta(deltas[i]); - } - manager.fire(ElementChangedEvent.POST_CHANGE); - } + CModelOperation op = new PathEntryStoreChangedOperation(cproject); + op.runOperation(null); } catch (CModelException e) { CCorePlugin.log(e); } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryStoreChangedOperation.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryStoreChangedOperation.java new file mode 100644 index 00000000000..41ae789c04f --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryStoreChangedOperation.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2005 QnX Software 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: + * Qnx Software Systems - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.core.model; + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ICElementDelta; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IPathEntry; + +public class PathEntryStoreChangedOperation extends CModelOperation { + + public PathEntryStoreChangedOperation(ICProject cproject) { + super(cproject); + } + + protected void executeOperation() throws CModelException { + PathEntryManager manager = PathEntryManager.getDefault(); + ICProject cproject = (ICProject)getElementToProcess(); + // Clear the old cache entries. + IPathEntry[] oldResolvedEntries = manager.removeCachedResolvedPathEntries(cproject); + IPathEntry[] newResolvedEntries = manager.getResolvedPathEntries(cproject); + ICElementDelta[] deltas = manager.generatePathEntryDeltas(cproject, oldResolvedEntries, newResolvedEntries); + if (deltas.length > 0) { + cproject.close(); + for (int i = 0; i < deltas.length; i++) { + addDelta(deltas[i]); + } + } + } + +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/SetPathEntryContainerOperation.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/SetPathEntryContainerOperation.java new file mode 100644 index 00000000000..5ab36322c05 --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/SetPathEntryContainerOperation.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2005 QnX Software 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: + * Qnx Software Systems - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.core.model; + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ICElementDelta; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IContainerEntry; +import org.eclipse.cdt.core.model.IPathEntry; +import org.eclipse.cdt.core.model.IPathEntryContainer; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +public class SetPathEntryContainerOperation extends CModelOperation { + + IPathEntryContainer newContainer; + ICProject[] affectedProjects; + PathEntryManager fPathEntryManager; + + public SetPathEntryContainerOperation(ICProject[] affectedProjects, IPathEntryContainer newContainer) { + super(affectedProjects); + this.affectedProjects = affectedProjects; + this.newContainer = newContainer; + fPathEntryManager = PathEntryManager.getDefault(); + } + + protected void executeOperation() throws CModelException { + if (isCanceled()) { + return; + } + + IPath containerPath = (newContainer == null) ? new Path("") : newContainer.getPath(); //$NON-NLS-1$ + final int projectLength = affectedProjects.length; + final ICProject[] modifiedProjects = new ICProject[projectLength]; + System.arraycopy(affectedProjects, 0, modifiedProjects, 0, projectLength); + final IPathEntry[][] oldResolvedEntries = new IPathEntry[projectLength][]; + // filter out unmodified project containers + int remaining = 0; + for (int i = 0; i < projectLength; i++) { + if (isCanceled()) { + return; + } + ICProject affectedProject = affectedProjects[i]; + boolean found = false; + IPathEntry[] rawPath = fPathEntryManager.getRawPathEntries(affectedProject); + for (int j = 0, cpLength = rawPath.length; j < cpLength; j++) { + IPathEntry entry = rawPath[j]; + if (entry.getEntryKind() == IPathEntry.CDT_CONTAINER) { + IContainerEntry cont = (IContainerEntry)entry; + if (cont.getPath().equals(containerPath)) { + found = true; + break; + } + } + } + if (!found) { + // filter out this project - does not reference the container + // path + modifiedProjects[i] = null; + // Still add it to the cache + fPathEntryManager.containerPut(affectedProject, containerPath, newContainer); + continue; + } + IPathEntryContainer oldContainer = fPathEntryManager.containerGet(affectedProject, containerPath, true); + if (oldContainer != null && newContainer != null && oldContainer.equals(newContainer)) { + modifiedProjects[i] = null; // filter out this project - + // container did not change + continue; + } + remaining++; + oldResolvedEntries[i] = fPathEntryManager.removeCachedResolvedPathEntries(affectedProject); + fPathEntryManager.containerPut(affectedProject, containerPath, newContainer); + } + + // Nothing change. + if (remaining == 0) { + return; + } + + // trigger model refresh + + CModelManager mgr = CModelManager.getDefault(); + for (int i = 0; i < projectLength; i++) { + if (isCanceled()) { + return; + } + ICProject affectedProject = modifiedProjects[i]; + if (affectedProject == null) { + continue; // was filtered out + } + // Only fire deltas if we had previous cache + if (oldResolvedEntries[i] != null) { + IPathEntry[] newEntries = fPathEntryManager.getResolvedPathEntries(affectedProject); + ICElementDelta[] deltas = fPathEntryManager.generatePathEntryDeltas(affectedProject, oldResolvedEntries[i], newEntries); + if (deltas.length > 0) { + affectedProject.close(); + //shouldFire = true; + for (int j = 0; j < deltas.length; j++) { + addDelta(deltas[j]); + } + } + } + } + + } + +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java index abbe7bc5563..1ec2ca01db2 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java @@ -71,7 +71,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit { if (sibling != null) { op.createBefore(sibling); } - CModelManager.getDefault().runOperation(op, monitor); + op.runOperation(monitor); return getInclude(includeName); } @@ -80,7 +80,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit { if (sibling != null) { op.createBefore(sibling); } - CModelManager.getDefault().runOperation(op, monitor); + op.runOperation(monitor); return getUsing(usingName); } @@ -89,7 +89,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit { if (sibling != null) { op.createBefore(sibling); } - CModelManager.getDefault().runOperation(op, monitor); + op.runOperation(monitor); return getNamespace(namespace); } @@ -465,7 +465,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit { return workingCopy; } CreateWorkingCopyOperation op = new CreateWorkingCopyOperation(this, perFactoryWorkingCopies, factory, requestor); - runOperation(op, monitor); + op.runOperation(monitor); return (IWorkingCopy)op.getResultElements()[0]; } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopy.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopy.java index 5b95571a02c..ab50a643b3a 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopy.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/WorkingCopy.java @@ -83,7 +83,7 @@ public class WorkingCopy extends TranslationUnit implements IWorkingCopy { ITranslationUnit original = this.getOriginalElement(); if (original.exists()) { CommitWorkingCopyOperation op= new CommitWorkingCopyOperation(this, force); - runOperation(op, monitor); + op.runOperation(monitor); } else { String contents = this.getSource(); if (contents == null) return; @@ -135,7 +135,7 @@ public class WorkingCopy extends TranslationUnit implements IWorkingCopy { } try { DestroyWorkingCopyOperation op = new DestroyWorkingCopyOperation(this); - runOperation(op, null); + op.runOperation(null); } catch (CModelException e) { // do nothing } @@ -356,7 +356,7 @@ public class WorkingCopy extends TranslationUnit implements IWorkingCopy { if (this.useCount == 0) throw newNotPresentException(); //was destroyed ReconcileWorkingCopyOperation op = new ReconcileWorkingCopyOperation(this, forceProblemDetection); - runOperation(op, monitor); + op.runOperation(monitor); } /** diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO.java index b51aa1075f2..f5162242d61 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/macho/MachO.java @@ -179,33 +179,32 @@ public class MachO { sizeofcmds = makeInt(bytes, offset, isle); offset += 4; flags = makeInt(bytes, offset, isle); offset += 4; } - - private final short makeShort(byte [] val, int offset, boolean isle) throws IOException { - if (val.length < offset + 2) - throw new IOException(); - if ( isle ) { - return (short)(((val[offset + 1] & 0xff) << 8) + (val[offset + 0] & 0xff)); - } - return (short)(((val[offset + 0] & 0xff) << 8) + (val[offset + 1] & 0xff)); + } + + private static final short makeShort(byte [] val, int offset, boolean isle) throws IOException { + if (val.length < offset + 2) + throw new IOException(); + if ( isle ) { + return (short)(((val[offset + 1] & 0xff) << 8) + (val[offset + 0] & 0xff)); } - - private final int makeInt(byte [] val, int offset, boolean isle) throws IOException - { - if (val.length < offset + 4) - throw new IOException(); - if ( isle ) { - return (((val[offset + 3] & 0xff) << 24) | - ((val[offset + 2] & 0xff) << 16) | - ((val[offset + 1] & 0xff) << 8) | - (val[offset + 0] & 0xff)); - } else { - return (((val[offset + 0] & 0xff) << 24) | - ((val[offset + 1] & 0xff) << 16) | - ((val[offset + 2] & 0xff) << 8) | - (val[offset + 3] & 0xff)); - } + return (short)(((val[offset + 0] & 0xff) << 8) + (val[offset + 1] & 0xff)); + } + + private static final int makeInt(byte [] val, int offset, boolean isle) throws IOException + { + if (val.length < offset + 4) + throw new IOException(); + if ( isle ) { + return (((val[offset + 3] & 0xff) << 24) | + ((val[offset + 2] & 0xff) << 16) | + ((val[offset + 1] & 0xff) << 8) | + (val[offset + 0] & 0xff)); + } else { + return (((val[offset + 0] & 0xff) << 24) | + ((val[offset + 1] & 0xff) << 16) | + ((val[offset + 2] & 0xff) << 8) | + (val[offset + 3] & 0xff)); } - } public class LoadCommand { @@ -1029,10 +1028,12 @@ public class MachO { } public static boolean isMachOHeader(byte[] bytes) { - boolean isle = false; - int offset = 0; - int magic = (bytes[0] << 24) + (bytes[1] << 16) + (bytes[2] << 8) + bytes[3]; - return (magic == MachO.MachOhdr.MH_MAGIC || magic == MachO.MachOhdr.MH_CIGAM); + try { + int magic = makeInt(bytes, 0, false); + return (magic == MachO.MachOhdr.MH_MAGIC || magic == MachO.MachOhdr.MH_CIGAM); + } catch (IOException e) { + return false; + } } public void dispose() {