/*
* This file is part of jsFlow.
*
* Copyright (c) 2009 DE-CIX Management GmbH <http://www.de-cix.net> - All rights
* reserved.
*
* Author: Thomas King <thomas.king@de-cix.net>
*
* This software is licensed under the Apache License, version 2.0. A copy of
* the license agreement is included in this distribution.
*/
package net.decix.jsflow.header;
import java.util.Vector;
import net.decix.util.HeaderBytesException;
import net.decix.util.HeaderParseException;
import net.decix.util.Utility;
public class ExpandedCounterSampleHeader {
// enterprise 0, format 4
private long seqNumber;
private long sourceIDType; // 0 = ifindex, 1 = smonVlanDataSource, 2 = entPhysicalEntry
private long sourceIDIndex;
private long numberCounterRecords;
private Vector<CounterRecordHeader> counterRecords;
public ExpandedCounterSampleHeader() {
counterRecords = new Vector<CounterRecordHeader>();
}
public long getSequenceNumber() {
return seqNumber;
}
public long getSourceIDType() {
return sourceIDType;
}
public long getSourceIDIndex() {
return sourceIDIndex;
}
public long getNumberCounterRecords() {
return numberCounterRecords;
}
public void setSequenceNumber(long seqNumber) {
this.seqNumber = seqNumber;
}
public void setSourceIDType(long sourceIDType) {
this.sourceIDType = sourceIDType;
}
public void setSourceIDIndex(long sourceIDIndex) {
this.sourceIDIndex = sourceIDIndex;
}
public void setNumberCounterRecords(long numberCounterRecords) {
this.numberCounterRecords = numberCounterRecords;
}
public void addCounterRecord(CounterRecordHeader counterRecord) {
counterRecords.add(counterRecord);
}
public Vector<CounterRecordHeader> getCounterRecords() {
return counterRecords;
}
public static ExpandedCounterSampleHeader parse(byte[] data) throws HeaderParseException {
try {
if (data.length < 16) throw new HeaderParseException("Data array too short.");
ExpandedCounterSampleHeader ecsh = new ExpandedCounterSampleHeader();
// sample sequence number
byte[] seqNumber = new byte[4];
System.arraycopy(data, 0, seqNumber, 0, 4);
ecsh.setSequenceNumber(Utility.fourBytesToLong(seqNumber));
// source id type
byte[] sourceIDType = new byte[4];
System.arraycopy(data, 4, sourceIDType, 0, 4);
ecsh.setSourceIDType(Utility.fourBytesToLong(sourceIDType));
// source id index
byte[] sourceIDIndex = new byte[4];
System.arraycopy(data, 8, sourceIDIndex, 0, 4);
ecsh.setSourceIDIndex(Utility.fourBytesToLong(sourceIDIndex));
// number counter records
byte[] numberCounterRecords = new byte[4];
System.arraycopy(data, 12, numberCounterRecords, 0, 4);
ecsh.setNumberCounterRecords(Utility.fourBytesToLong(numberCounterRecords));
// counter records
int offset = 16;
for (int i = 0; i < ecsh.getNumberCounterRecords(); i++) {
byte[] subData = new byte[data.length - offset];
System.arraycopy(data, offset, subData, 0, data.length - offset);
CounterRecordHeader cr = CounterRecordHeader.parse(subData);
ecsh.addCounterRecord(cr);
offset += (cr.getCounterDataLength() + 8);
}
return ecsh;
} catch (Exception e) {
throw new HeaderParseException("Parse error: " + e.getMessage());
}
}
public byte[] getBytes() throws HeaderBytesException {
try {
int lengthCounterRecords = 0;
for (CounterRecordHeader cr : counterRecords) {
lengthCounterRecords += (cr.getCounterDataLength() + 8);
}
byte[] data = new byte[16 + lengthCounterRecords];
// sequence number
System.arraycopy(Utility.longToFourBytes(seqNumber), 0, data, 0, 4);
// source id type
System.arraycopy(Utility.longToFourBytes(sourceIDType), 0, data, 4, 4);
// source id index
System.arraycopy(Utility.longToFourBytes(sourceIDIndex), 0, data, 8, 4);
// number counter records
System.arraycopy(Utility.longToFourBytes(numberCounterRecords), 0, data, 12, 4);
int offset = 0;
for (CounterRecordHeader cr : counterRecords) {
byte[] temp = cr.getBytes();
System.arraycopy(temp, 0, data, 16 + offset, temp.length);
offset += (cr.getCounterDataLength() + 8);
}
return data;
} catch (Exception e) {
throw new HeaderBytesException("Error while generating the bytes: " + e.getMessage());
}
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[ExpandedCounterSampleHeader]: ");
sb.append(" Sequence number: ");
sb.append(getSequenceNumber());
sb.append(", Source ID type: ");
sb.append(getSourceIDType());
sb.append(", Source ID index: ");
sb.append(getSourceIDIndex());
sb.append(", Counter records: ");
sb.append(getNumberCounterRecords());
for (CounterRecordHeader crh : this.getCounterRecords()) {
sb.append(crh);
sb.append(" ");
}
return sb.toString();
}
}