blob: 9e78a9bd6a4abfedceeb414452932643c1fae706 [file] [log] [blame]
/********************************************************************************
* Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
package org.eclipse.mdm.openatfx.mdf.mdf3;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.SeekableByteChannel;
/**
* <p>
* Channel group block: Description of a channel group, i.e. signals which are
* always measured jointly
* </p>
* This block describes the structure of a channel group. A channel group
* consists of different channels which are measured jointly at the same rate.
*
* @author Christian Rechner
*/
class CGBLOCK extends BLOCK {
public static String BLOCK_ID = "CG";
// LINK 1 Pointer to next data Channel group block (CGBLOCK) (NIL allowed)
private long lnkNextCgBlock;
// LINK 1 Pointer to first channel block (CNBLOCK) (NIL allowed)
private long lnkFirstCnBlock;
// LINK 1 Pointer to channel group comment text (TXBLOCK) (NIL allowed)
private long lnkChannelGroupComment;
// UINT16 1 Record ID
private int recordId;
// UINT16 1 Number of channels
private int noOfChannels;
// UINT16 1 Data record size in bytes (without the record ID), i.e. data
// size of the channel group for each sample
private int dataRecordSize;
// UINT32 1 Number of records
private long noOfRecords;
// LINK 1 Pointer to first sample reduction block (SRBLOCK) (NIL allowed)
private long lnkFirstSrBlock;
/**
* Constructor.
*
* @param sbc
* The byte channel pointing to the MDF file.
* @param pos
* The position of the block within the MDF file.
*/
private CGBLOCK(SeekableByteChannel sbc, long pos) {
super(sbc, pos);
}
public long getLnkNextCgBlock() {
return lnkNextCgBlock;
}
private void setLnkNextCgBlock(long lnkNextCgBlock) {
this.lnkNextCgBlock = lnkNextCgBlock;
}
public long getLnkFirstCnBlock() {
return lnkFirstCnBlock;
}
private void setLnkFirstCnBlock(long lnkFirstCnBlock) {
this.lnkFirstCnBlock = lnkFirstCnBlock;
}
public long getLnkChannelGroupComment() {
return lnkChannelGroupComment;
}
private void setLnkChannelGroupComment(long lnkChannelGroupComment) {
this.lnkChannelGroupComment = lnkChannelGroupComment;
}
public int getRecordId() {
return recordId;
}
private void setRecordId(int recordId) {
this.recordId = recordId;
}
public int getNoOfChannels() {
return noOfChannels;
}
private void setNoOfChannels(int noOfChannels) {
this.noOfChannels = noOfChannels;
}
public int getDataRecordSize() {
return dataRecordSize;
}
private void setDataRecordSize(int dataRecordSize) {
this.dataRecordSize = dataRecordSize;
}
public long getNoOfRecords() {
return noOfRecords;
}
private void setNoOfRecords(long noOfRecords) {
this.noOfRecords = noOfRecords;
}
public long getLnkFirstSrBlock() {
return lnkFirstSrBlock;
}
private void setLnkFirstSrBlock(long lnkFirstSrBlock) {
this.lnkFirstSrBlock = lnkFirstSrBlock;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return "CGBLOCK [lnkNextCgBlock=" + lnkNextCgBlock + ", lnkFirstCnBlock=" + lnkFirstCnBlock
+ ", lnkChannelGroupComment=" + lnkChannelGroupComment + ", recordId=" + recordId + ", noOfChannels="
+ noOfChannels + ", dataRecordSize=" + dataRecordSize + ", noOfRecords=" + noOfRecords
+ ", lnkFirstSrBlock=" + lnkFirstSrBlock + "]";
}
public CGBLOCK getNextCgBlock() throws IOException {
if (lnkNextCgBlock > 0) {
return CGBLOCK.read(sbc, lnkNextCgBlock);
}
return null;
}
public CNBLOCK getFirstCnBlock() throws IOException {
if (lnkFirstCnBlock > 0) {
return CNBLOCK.read(sbc, lnkFirstCnBlock);
}
return null;
}
public TXBLOCK getChannelGroupComment() throws IOException {
if (lnkChannelGroupComment > 0) {
return TXBLOCK.read(sbc, lnkChannelGroupComment);
}
return null;
}
/**
* Reads a CGBLOCK from the channel starting at pos
*
* @param sbc
* The channel to read from.
* @param pos
* The position to start reading.
* @return The block data.
* @throws IOException
* The exception.
*/
public static CGBLOCK read(SeekableByteChannel sbc, long pos) throws IOException {
CGBLOCK block = new CGBLOCK(sbc, pos);
// read block header
ByteBuffer bb = ByteBuffer.allocate(4);
bb.order(ByteOrder.LITTLE_ENDIAN);
sbc.position(pos);
sbc.read(bb);
bb.rewind();
// CHAR 2 Block type identifier
block.setId(Mdf3Util.readChars(bb, 2));
if (!block.getId().equals(BLOCK_ID)) {
throw new IOException("Wrong block type - expected '" + BLOCK_ID + "', found '" + block.getId() + "'");
}
// UINT16 1 Block size of this block in bytes
block.setLength(Mdf3Util.readUInt16(bb));
// read block
bb = ByteBuffer.allocate(block.getLength() - 4);
bb.order(ByteOrder.LITTLE_ENDIAN);
sbc.position(pos + 4);
sbc.read(bb);
bb.rewind();
// LINK 1 Pointer to next data Channel group block (CGBLOCK) (NIL
// allowed)
block.setLnkNextCgBlock(Mdf3Util.readLink(bb));
// LINK 1 Pointer to first channel block (CNBLOCK) (NIL allowed)
block.setLnkFirstCnBlock(Mdf3Util.readLink(bb));
// LINK 1 Pointer to channel group comment text (TXBLOCK) (NIL allowed)
block.setLnkChannelGroupComment(Mdf3Util.readLink(bb));
// UINT16 1 Record ID
block.setRecordId(Mdf3Util.readUInt16(bb));
// UINT16 1 Number of channels
block.setNoOfChannels(Mdf3Util.readUInt16(bb));
// UINT16 1 Data record size in bytes (without the record ID), i.e. data
// size of the channel group for each
// sample
block.setDataRecordSize(Mdf3Util.readUInt16(bb));
// UINT32 1 Number of records
block.setNoOfRecords(Mdf3Util.readUInt32(bb));
// LINK 1 Pointer to first sample reduction block (SRBLOCK) (NIL
// allowed)
// Valid since version 3.30. Default value: NIL.
if (block.getLength() > 26) {
block.setLnkFirstSrBlock(Mdf3Util.readLink(bb));
}
return block;
}
}