package org.yamcs.ui.packetviewer;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.swing.text.BadLocationException;
import javax.swing.text.StyledDocument;
import org.yamcs.parameter.ParameterValue;
import org.yamcs.parameter.ParameterValueList;
import org.yamcs.xtce.Parameter;
/**
* A packet appearing in the packet viewer list. Can be only partially loaded (i.e. the header only).
*/
public class ListPacket {
private static final String HEX_CHARS = "0123456789abcdef";
private String name;
private long fileOffset;
byte[] buf;
int length;
boolean incomplete=false;
long generationTime;
//these are the parameters that are shown in the left bar (in fact all parameters extracted by the extractor,so could be more than what is shown)
private ParameterValueList columnParameters;
ListPacket(byte[] b, int length) {
buf = b.clone();
this.length = length;
}
ListPacket(byte[] buf, int length, long fileOffset) {
this(buf, length);
this.fileOffset = fileOffset;
this.incomplete = true;
}
public void setName(String opsname) {
this.name = opsname;
}
@Override
public String toString() {
return name;
}
void load(File srcFile) throws IOException {
if (incomplete) {
FileInputStream reader = null;
try {
reader = new FileInputStream(srcFile);
byte[] data = new byte[length];
reader.skip(fileOffset + buf.length);
int remaining = length - buf.length;
int res = reader.read(data, 16, remaining);
if(res != remaining) throw new IOException("short read, expected "+remaining+", got "+res);
System.arraycopy(buf, 0, data, 0, buf.length);
buf=data;
} finally {
if (reader != null) reader.close();
}
incomplete=false;
}
}
void hexdump(StyledDocument hexDoc) {
try {
hexDoc.remove(0, hexDoc.getLength());
for (int i = 0; i < buf.length; ) {
// build one row of hexdump: offset, hex bytes, ascii bytes
StringBuilder asciiBuf = new StringBuilder();
StringBuilder hexBuf = new StringBuilder();
hexBuf.append(HEX_CHARS.charAt(i>>12));
hexBuf.append(HEX_CHARS.charAt((i>>8) & 0x0f));
hexBuf.append(HEX_CHARS.charAt((i>>4) & 0x0f));
hexBuf.append(HEX_CHARS.charAt(i & 0x0f));
hexBuf.append(' ');
for (int j = 0; j < 16; ++j, ++i) {
if (i < buf.length) {
byte b = buf[i];
hexBuf.append(HEX_CHARS.charAt((b>>4) & 0x0f));
hexBuf.append(HEX_CHARS.charAt(b & 0x0f));
if ((j & 1) == 1) hexBuf.append(' ');
char c = (b < 32) || (b > 126) ? '.' : (char)b;
asciiBuf.append(c);
} else {
hexBuf.append((j & 1) == 1 ? " " : " ");
asciiBuf.append(' ');
}
}
hexBuf.append(asciiBuf);
hexBuf.append('\n');
hexDoc.insertString(hexDoc.getLength(), hexBuf.toString(), hexDoc.getStyle("fixed"));
}
} catch (BadLocationException x) {
System.err.println("cannot format hexdump of "+name+": "+x.getMessage());
}
}
public long getGenerationTime() {
return generationTime;
}
public int getLength() {
return length;
}
public byte[] getBuffer() {
return buf;
}
public void setColumnParameters(ParameterValueList pvlist) {
this.columnParameters = pvlist;
}
public ParameterValue getParameterColumn(Parameter p) {
return columnParameters.getLastInserted(p);
}
public String getName() {
return name;
}
public void setGenerationTime(long generationTime) {
this.generationTime = generationTime;
}
}