package com.aionemu.packetsamurai.parser.datatree;
import java.io.DataOutput;
import java.io.IOException;
import java.nio.ByteBuffer;
import javax.swing.JComponent;
import javax.swing.JLabel;
import com.aionemu.packetsamurai.PacketSamurai;
import com.aionemu.packetsamurai.Util;
import com.aionemu.packetsamurai.parser.PartType;
import com.aionemu.packetsamurai.parser.DataStructure.DataPacketMode;
import com.aionemu.packetsamurai.parser.formattree.ForPart;
import com.aionemu.packetsamurai.parser.formattree.Part;
import com.aionemu.packetsamurai.parser.formattree.SwitchPart;
import com.aionemu.packetsamurai.parser.valuereader.Reader;
/**
* This class represent a ValuePart (c, h, d...) used to parse data from a raw packet, thus it may contain the data parsed from the packet.
*
* @author Gilles Duboscq
*/
public class ValuePart extends DataTreeNode
{
protected byte[] _bytes;
private int _bxSize = -1;
public ValuePart(DataTreeNodeContainer parent, Part part)
{
super(parent,part);
if(part instanceof ForPart || part instanceof SwitchPart)
{
throw new IllegalArgumentException("The model of a value part must be a basic part not a for/switch or any other container");
}
}
public void parse(ByteBuffer buf)
{
if(this.getMode() == DataPacketMode.FORGING)
throw new IllegalStateException("Can not parse on a Forging mode Data Packet Tree element");
int pos = buf.position();
int size = 0;
size = this.getBSize();
@SuppressWarnings("unused")
long maxSize = buf.remaining();
if (size > 65536)
{
if (PacketSamurai.VERBOSITY.ordinal() >= PacketSamurai.VerboseLevel.NORMAL.ordinal())
{
System.out.println("ZOMG a huge size!! :"+size+"! defaulting to 1");
}
size = 1;
}
// sets the raw bytes
_bytes = new byte[size];
buf.position(pos);
buf.get(_bytes);
}
public void forge(DataOutput stream) throws IOException
{
if(this.getMode() == DataPacketMode.PARSING)
throw new IllegalStateException("Can not call forge on a Parsing mode Data Packet Tree element");
try
{
stream.write(_bytes);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public PartType getType()
{
return this.getModelPart().getType();
}
public String getHexDump()
{
return Util.hexDump(_bytes);
}
public byte[] getBytes()
{
if(!this.getType().isReadableType())
throw new IllegalStateException("Trying to get bytes from a "+this.getType().getName());
return _bytes;
}
public int getBytesSize()
{
if (_bytes == null)
{
return 0;
}
return _bytes.length;
}
public void setBSize(int size)
{
if(size < 0)
{
if(PacketSamurai.VERBOSITY.ordinal() >= PacketSamurai.VerboseLevel.NORMAL.ordinal())
System.out.println("ZOMG a negative size!! defaulting to 0");
_bxSize = 0;
}
else
{
_bxSize = size;
}
}
public int getBSize()
{
if (_bxSize < 0)
{
if(getModelPart().isDynamicBSize())
{
ValuePart vp = this.getParentContainer().getPacketValuePartById(getModelPart().getBSizeId());
if (vp == null || !(vp instanceof IntValuePart))
PacketSamurai.getUserInterface().log("ValuePart: Invalid SizeId for bx: part can not be found or is not an integer");
else
this.setBSize(((IntValuePart)vp).getIntValue());
}
else
{
this.setBSize(getModelPart().getBSize());
}
}
return _bxSize;
}
public String getValueAsString()
{
return "";
}
/**
* @param bytes The bytes to set.
*/
public void setBytes(byte[] bytes)
{
if(this.getMode() == DataPacketMode.PARSING)
throw new IllegalStateException("Can not set value on a Parsing mode Data Packet Tree element");
_bytes = bytes;
}
public String readValue()
{
Reader r = this.getModelPart().getReader();
if(r != null)
{
return r.read(this);
}
return this.getValueAsString();
}
public JComponent readValueToComponent()
{
Reader r = this.getModelPart().getReader();
if(r != null)
{
return r.readToComponent(this);
}
return new JLabel(this.getValueAsString());
}
@Override
public String treeString()
{
return this.getModelPart().getName();
}
}