blob: b48a6c440017d64c38f14d2c8ad1400edd5cc3be [file] [log] [blame]
/*******************************************************************************
* 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);
}
}