blob: 2f953323ceab85eaf292864430f31658d55e953e [file] [log] [blame]
/*
* Copyright (c) 2016 Audi AG
* 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
*/
package org.eclipse.mdm.mdfsorter.mdf4;
import java.io.IOException;
import java.math.BigInteger;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.mdm.mdfsorter.MDFParser;
/**
* The Channel Group Block
*
* @author Christian Rechner, Tobias Leemann
*
*/
public class CGBLOCK extends MDF4GenBlock {
/** Data section */
// Record ID, value must be less than maximum unsigned integer value allowed
// by dg_rec_id_size in parent DGBLOCK.
// UINT64
private long recordId;
// Number of cycles, i.e. number of samples for this channel group.
// This specifies the number of records of this type in the data block.
// UINT64
private long cycleCount;
// Flags
// The value contains the following bit flags (Bit 0 = LSB):
// Bit 0: VLSD channel group flag.
// Bit 1: Bus event channel group flag
// Bit 2: Plain bus event channel group flag
// UINT16
private int flags;
// Value of character to be used as path separator, 0 if no path separator
// specified.
// UINT16
private int pathSeparator;
// Normal CGBLOCK:
// Number of data Bytes (after record ID) used for signal values in record,
// i.e. size of plain data for each
// recorded sample of this channel group.
// VLSD CGBLOCK:
// Low part of a UINT64 value that specifies the total size in Bytes of all
// variable length signal values for the
// recorded samples of this channel group.
// UINT32
private long dataBytes;
// Normal CGBLOCK:
// Number of additional Bytes for record used for invalidation bits. Can be
// zero if no invalidation bits are used at
// all. Invalidation bits may only occur in the specified number of Bytes
// after the data Bytes, not within the data
// Bytes that contain the signal values.
// VLSD CGBLOCK:
// High part of UINT64 value that specifies the total size in Bytes of all
// variable length signal values for the
// recorded samples of this channel group, i.e. the total size in Bytes can
// be calculated by cg_data_bytes +
// (cg_inval_bytes << 32)
// Note: this value does not include the Bytes used to specify the length of
// each VLSD value!
private long invalBytes;
/**
* Parse a HLBLOCK from an existing MDFGenBlock
*
* @param parent
* The already existing MDF Generic Block.
*/
public CGBLOCK(MDF4GenBlock parent) {
super(parent.getPos());
setLength(parent.getLength());
setLinkCount(parent.getLinkCount());
setId(parent.getId());
setLinks(parent.getLinks());
parent.setPrec(this);
}
public MDF4GenBlock getLnkCgNext() {
return links[0];
}
public MDF4GenBlock getLnkCnFirst() {
return links[1];
}
public MDF4GenBlock getLnkTxAcqName() {
return links[2];
}
public MDF4GenBlock getLnkSiAcqSource() {
return links[3];
}
public MDF4GenBlock getLnkSrFirst() {
return links[4];
}
public MDF4GenBlock getLnkMdComment() {
return links[5];
}
public long getRecordId() {
return recordId;
}
public long getCycleCount() {
return cycleCount;
}
public int getFlags() {
return flags;
}
public int getPathSeparator() {
return pathSeparator;
}
public long getDataBytes() {
return dataBytes;
}
public long getInvalBytes() {
return invalBytes;
}
public void setRecordId(long recordId) {
this.recordId = recordId;
}
public void setCycleCount(long cycleCount) {
this.cycleCount = cycleCount;
}
private void setFlags(int flags) {
this.flags = flags;
}
public void setPathSeparator(int pathSeparator) {
this.pathSeparator = pathSeparator;
}
private void setDataBytes(long dataBytes) {
this.dataBytes = dataBytes;
}
private void setInvalBytes(long invalBytes) {
this.invalBytes = invalBytes;
}
public boolean isVLSDChannel() {
return BigInteger.valueOf(flags).testBit(0);
}
/**
* Get the number of Bytes that are used in Variable Length Signal Data
* (VLSD) values This value is calculated from dataBytes and invalBytes.
* (see Specification)
*
* @return The value.
*/
public long getVLSDlength() {
return dataBytes + (invalBytes << 32);
}
public void setIsVlSD(boolean isVLSD) {
if (isVLSD) {
flags = flags | 0x1;
} else {
flags = flags & -2;
}
}
/**
* Returns a list with all VLSDChannels in this group
*
* @return The list of CNBLOCKs.
*/
public List<CNBLOCK> getVLSDChannels() {
LinkedList<CNBLOCK> ret = new LinkedList<CNBLOCK>();
CNBLOCK next = (CNBLOCK) getLnkCnFirst();
while (next != null) {
// check if vlsd channel
if (next.getChannelType() == 1) {
ret.add(next);
}
next = (CNBLOCK) next.getLnkCnNext();
}
return ret;
}
@Override
public String toString() {
return "CGBLOCK [recordId=" + recordId + ", cycleCount=" + cycleCount
+ ", flags=" + flags + ", pathSeparator=" + pathSeparator
+ ", dataBytes=" + dataBytes + ", invalBytes=" + invalBytes
+ "]";
}
/**
* @see MDF4GenBlock#parse(byte[])
*/
@Override
public void parse(byte[] content) throws IOException {
// UINT64: Record ID
setRecordId(
MDF4Util.readUInt64(MDFParser.getDataBuffer(content, 0, 8)));
// UINT64: Number of cycles
setCycleCount(
MDF4Util.readUInt64(MDFParser.getDataBuffer(content, 8, 16)));
// UINT16: Flags
setFlags(MDF4Util.readUInt16(MDFParser.getDataBuffer(content, 16, 18)));
// UINT16: Value of character to be used as path separator, 0 if no path
// separator specified.
setPathSeparator(
MDF4Util.readUInt16(MDFParser.getDataBuffer(content, 18, 20)));
// UINT32: Number of data Bytes (after record ID) used for signal values
// in record.
setDataBytes(
MDF4Util.readUInt32(MDFParser.getDataBuffer(content, 24, 28)));
// UINT32: Number of additional Bytes for record used for invalidation
// bits.
setInvalBytes(
MDF4Util.readUInt32(MDFParser.getDataBuffer(content, 28, 32)));
}
@Override
public byte[] getBodyBytes() {
int arraylen = 32;
byte[] ret = new byte[arraylen];
byte[] recID = MDF4Util.getBytesUInt64(getRecordId());
System.arraycopy(recID, 0, ret, 0, 8);
byte[] cyccount = MDF4Util.getBytesUInt64(getCycleCount());
System.arraycopy(cyccount, 0, ret, 8, 8);
byte[] flags = MDF4Util.getBytesUInt16(getFlags());
System.arraycopy(flags, 0, ret, 16, 2);
byte[] pathsep = MDF4Util.getBytesUInt16(getPathSeparator());
System.arraycopy(pathsep, 0, ret, 18, 2);
// 4 Spacer bytes
byte[] databytes = MDF4Util.getBytesUInt32(getDataBytes());
System.arraycopy(databytes, 0, ret, 24, 4);
byte[] invalbytes = MDF4Util.getBytesUInt32(getInvalBytes());
System.arraycopy(invalbytes, 0, ret, 28, 4);
return ret;
}
}