Copyright (c) 2004, 2008 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation
/******************************************************************************* * Copyright (c) 2004, 2008 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/
package org.eclipse.core.runtime.content; import java.io.IOException; import java.io.InputStream; import java.util.*; import org.eclipse.core.internal.content.ContentMessages; import org.eclipse.core.runtime.*; import org.eclipse.osgi.util.NLS;
A content describer for binary formats that present some simple signature at a known, fixed offset.

This executable extension supports three parameters: "signature", "offset" and "required", the first one being mandatory. If the ":-" method is used, then the value is treated as the "signature".

The "signature" parameter is a sequence of hex codes, one for each byte in the signature. For example, "CA FE BA BE" would be a signature for Java class files.

The "offset" parameter is an integer indicating the offset where the signature's first byte is found.

The "required" parameter is a boolean (default is " true") indicating whether the absence of a signature should deem the contents validity status as IContentDescriber.INVALID or IContentDescriber.INDETERMINATE.

This class is not intended to be subclassed or instantiated by clients, only to be referenced by the "describer" configuration element in extensions to the org.eclipse.core.runtime.contentTypes extension point.

Since:3.0
/** * A content describer for binary formats that present some * simple signature at a known, fixed offset. * <p> * This executable extension supports three parameters: * "signature", "offset" and "required", the first one being mandatory. * If the * <code>":-"</code> method is used, then the value is treated as the * "signature". * </p> * <p> * The "signature" parameter is a sequence of hex codes, one for each byte in * the signature. For example, "CA FE BA BE" would be a signature for Java * class files. * </p> * <p> * The "offset" parameter is an integer indicating the offset where the * signature's first byte is found. * </p> * <p> * The "required" parameter is a boolean (default is " true") indicating whether * the absence of a signature should deem the contents validity status as * IContentDescriber.INVALID or IContentDescriber.INDETERMINATE. * </p> * <p> * This class is not intended to be subclassed or instantiated by clients, * only to be referenced by the "describer" configuration element in * extensions to the <code>org.eclipse.core.runtime.contentTypes</code> * extension point. * </p> * * @since 3.0 */
public final class BinarySignatureDescriber implements IContentDescriber, IExecutableExtension { private final static String SIGNATURE = "signature"; //$NON-NLS-1$ private final static String OFFSET = "offset"; //$NON-NLS-1$ private static final Object REQUIRED = "required"; //$NON-NLS-1$ private byte[] signature; private int offset; private boolean required = true; /* (Intentionally not included in javadoc) * @see IContentDescriber#describe(InputStream, IContentDescription) */ @Override public int describe(InputStream contents, IContentDescription description) throws IOException { byte[] buffer = new byte[signature.length]; int notValid = required ? INVALID : INDETERMINATE; if (contents.skip(offset) < offset) return notValid; if (contents.read(buffer) != buffer.length) return notValid; for (int i = 0; i < signature.length; i++) if (signature[i] != buffer[i]) return notValid; return VALID; } @Override public QualifiedName[] getSupportedOptions() { return new QualifiedName[0]; } @Override public void setInitializationData(IConfigurationElement config, String propertyName, Object data) throws CoreException { try { if (data instanceof String) signature = parseSignature((String) data); else if (data instanceof Hashtable) { Hashtable<?,?> parameters = (Hashtable<?,?>) data; if (!parameters.containsKey(SIGNATURE)) { String message = NLS.bind(ContentMessages.content_badInitializationData, BinarySignatureDescriber.class.getName()); throw new CoreException(new Status(IStatus.ERROR, ContentMessages.OWNER_NAME, 0, message, null)); } signature = parseSignature((String) parameters.get(SIGNATURE)); if (parameters.containsKey(OFFSET)) offset = Integer.parseInt((String) parameters.get(OFFSET)); if (parameters.containsKey(REQUIRED)) required = Boolean.valueOf((String) parameters.get(REQUIRED)).booleanValue(); } } catch (NumberFormatException nfe) { String message = NLS.bind(ContentMessages.content_badInitializationData, BinarySignatureDescriber.class.getName()); throw new CoreException(new Status(IStatus.ERROR, ContentMessages.OWNER_NAME, 0, message, nfe)); } } private static byte[] parseSignature(String data) { List<Byte> bytes = new ArrayList<>(); StringTokenizer tokenizer = new StringTokenizer(data, " \t\n\r\f,"); //$NON-NLS-1$ while (tokenizer.hasMoreTokens()) bytes.add(Byte.valueOf((byte) Integer.parseInt(tokenizer.nextToken().trim(), 16))); byte[] signature = new byte[bytes.size()]; for (int i = 0; i < signature.length; i++) signature[i] = bytes.get(i).byteValue(); return signature; } }