| /******************************************************************************* |
| * Copyright (c) 2011, 2014 Ericsson, Ecole Polytechnique de Montreal and others |
| * |
| * All rights reserved. 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: Matthew Khouzam - Initial API and implementation |
| * Contributors: Simon Marchi - Initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.tracecompass.ctf.core.event.types; |
| |
| import org.eclipse.jdt.annotation.NonNullByDefault; |
| import org.eclipse.jdt.annotation.Nullable; |
| import org.eclipse.tracecompass.ctf.core.CTFException; |
| import org.eclipse.tracecompass.ctf.core.event.io.BitBuffer; |
| import org.eclipse.tracecompass.ctf.core.event.scope.IDefinitionScope; |
| |
| /** |
| * A CTF string declaration. |
| * |
| * Strings are an array of bytes of variable size and are terminated by a '\0' |
| * "NULL" character. Their encoding is described in the TSDL meta-data. In |
| * absence of encoding attribute information, the default encoding is UTF-8. |
| * |
| * @version 1.0 |
| * @author Matthew Khouzam |
| * @author Simon Marchi |
| */ |
| @NonNullByDefault |
| public class StringDeclaration extends Declaration { |
| |
| private static final StringDeclaration STRING_DEC_UTF8 = new StringDeclaration(Encoding.UTF8); |
| private static final StringDeclaration STRING_DEC_ASCII = new StringDeclaration(Encoding.ASCII); |
| private static final StringDeclaration STRING_DEC_NO_ENC = new StringDeclaration(Encoding.NONE); |
| |
| // ------------------------------------------------------------------------ |
| // Attributes |
| // ------------------------------------------------------------------------ |
| |
| private static final int BITS_PER_BYTE = Byte.SIZE; |
| private final Encoding fEncoding; |
| |
| // ------------------------------------------------------------------------ |
| // Constructors |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * Generate an encoded string declaration |
| * |
| * @param encoding |
| * the encoding, utf8 or ascii |
| */ |
| private StringDeclaration(Encoding encoding) { |
| fEncoding = encoding; |
| } |
| |
| /** |
| * Create a StringDeclaration with the default UTF-8 encoding |
| * |
| * @return a {@link StringDeclaration} with UTF-8 encoding |
| */ |
| public static StringDeclaration getStringDeclaration() { |
| return STRING_DEC_UTF8; |
| } |
| |
| /** |
| * Create a StringDeclaration |
| * |
| * @param encoding |
| * the {@link Encoding} can be Encoding.UTF8, Encoding.ASCII or |
| * other |
| * @return a {@link StringDeclaration} |
| * @throws IllegalArgumentException |
| * if the encoding is not recognized. |
| */ |
| public static StringDeclaration getStringDeclaration(Encoding encoding) { |
| switch (encoding) { |
| case ASCII: |
| return STRING_DEC_ASCII; |
| case NONE: |
| return STRING_DEC_NO_ENC; |
| case UTF8: |
| return STRING_DEC_UTF8; |
| default: |
| throw new IllegalArgumentException("Unrecognized encoding: " + encoding); //$NON-NLS-1$ |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| // Getters/Setters/Predicates |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * |
| * @return the character encoding. |
| */ |
| public Encoding getEncoding() { |
| return fEncoding; |
| } |
| |
| @Override |
| public long getAlignment() { |
| // See ctf 4.2.5: Strings are always aligned on byte size. |
| return BITS_PER_BYTE; |
| } |
| |
| @Override |
| public int getMaximumSize() { |
| /* |
| * Every definition can have a different size, so we do not scope this. |
| * Minimum size is one byte (8 bits) though. |
| */ |
| return 8; |
| } |
| |
| // ------------------------------------------------------------------------ |
| // Operations |
| // ------------------------------------------------------------------------ |
| |
| @Override |
| public StringDefinition createDefinition(@Nullable IDefinitionScope definitionScope, |
| String fieldName, BitBuffer input) throws CTFException { |
| String value = read(input); |
| return new StringDefinition(this, definitionScope, fieldName, value); |
| } |
| |
| private String read(BitBuffer input) throws CTFException { |
| /* Offset the buffer position wrt the current alignment */ |
| alignRead(input); |
| |
| StringBuilder sb = new StringBuilder(); |
| char c = (char) input.get(BITS_PER_BYTE, false); |
| while (c != 0) { |
| sb.append(c); |
| c = (char) input.get(BITS_PER_BYTE, false); |
| } |
| return sb.toString(); |
| } |
| |
| @Override |
| public String toString() { |
| /* Only used for debugging */ |
| return "[declaration] string[" + Integer.toHexString(hashCode()) + ']'; //$NON-NLS-1$ |
| } |
| |
| @Override |
| public int hashCode() { |
| final int prime = 31; |
| int result = prime; |
| switch (fEncoding) { |
| case ASCII: |
| result += 1; |
| break; |
| case NONE: |
| result += 2; |
| break; |
| case UTF8: |
| result += 3; |
| break; |
| default: |
| break; |
| } |
| return result; |
| } |
| |
| @Override |
| public boolean equals(@Nullable Object obj) { |
| if (this == obj) { |
| return true; |
| } |
| if (obj == null) { |
| return false; |
| } |
| if (getClass() != obj.getClass()) { |
| return false; |
| } |
| StringDeclaration other = (StringDeclaration) obj; |
| return (fEncoding == other.fEncoding); |
| } |
| |
| @Override |
| public boolean isBinaryEquivalent(@Nullable IDeclaration other) { |
| return equals(other); |
| } |
| |
| } |