我有一個稍微更先進的階級,我想寫一個toString()
爲問題與Android的
爲了完成什麼,我想,我需要能夠改變的分配toString()實現某些變數在做toString()
。
爲了讓它變得簡單我將刪除一些除了允許它工作的東西。
public enum PacketElementType {
NONE((byte)0, "None"),
BYTE((byte)1, "Byte"),
SHORT((byte)2, "Short"),
INT((byte)3, "Int"),
LONG((byte)4, "Long"),
FLOAT((byte)5, "Float"),
STRING((byte)6, "String"),
BIN((byte)7, "Bin");
private final byte typeValue;
private final String typeName;
PacketElementType(byte type, String name)
{
this.typeValue = type;
this.typeName = name;
}
public String getTypeName() {
return typeName;
}
public byte getTypeValue() {
return typeValue;
}
}
public class Packet {
private final int DEFAULT_SIZE = 1024 * 2;
private final int ADD_SIZE = 1024;
private byte[] _buffer = new byte[1];
private int _ptr = 0;
private int _bodyStart = 0;
private int _elements, _bodyLen = 0;
private int op;
private long id;
public Packet(int op, long id) {
setOp(op);
setId(id);
_buffer = new byte[DEFAULT_SIZE];
}
public int getOp() {
return op;
}
public void setOp(int op) {
this.op = op;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public PacketElementType peek() {
int pie = _ptr;
if (pie + 2 > _buffer.length)
return PacketElementType.NONE;
return PacketElementType.values()[_buffer[_ptr]];
}
protected Packet putSimple(PacketElementType type, byte... val) {
int len = val.length + 1;
this.ensureSize(len);
_buffer[++_ptr] = type.getTypeValue();
System.arraycopy(val, 0, _buffer, _ptr, val.length);
_ptr += val.length;
_elements++;
_bodyLen += len;
return this;
}
public Packet putByte(byte val) {
return this.putSimple(PacketElementType.BYTE, val);
}
public Packet putByte(boolean val) {
return this.putByte(val ? (byte) 1 : (byte) 0);
}
public byte getByte() throws Exception {
if (this.peek() != PacketElementType.BYTE)
throw new Exception("Expected Byte, got " + this.peek().getTypeName() + ".");
_ptr += 1;
return _buffer[++_ptr];
}
protected void ensureSize(int required) {
if (_ptr + required >= _buffer.length) {
byte[] b = new byte[_buffer.length + Math.max(ADD_SIZE, required * 2)];
System.arraycopy(_buffer, 0, b, 0, _buffer.length);
_buffer = b;
}
}
private boolean isValidType(PacketElementType type)
{
return (type.getTypeValue() >= PacketElementType.BYTE.getTypeValue() && type.getTypeValue() <= PacketElementType.BIN.getTypeValue());
}
protected String toStringHack()
{
StringBuilder result = new StringBuilder();
int prevPtu = _ptr;
_ptr = _bodyStart;
try {
result.append(String.format("Op: %1$08d %3$s, Id: %2$016d\r\n", this.getOp(), this.getId(), Op.getName(this.getOp())));
} catch (IllegalAccessException e) {
e.printStackTrace();
return result.append("Failed to convert packet to string").toString();
}
PacketElementType type;
for (int i = 1; (this.isValidType(type = this.peek()) && _ptr < _buffer.length); ++i)
{
if (type == PacketElementType.BYTE)
{
byte data = 0;
try {
data = getByte();
} catch (Exception e) {
e.printStackTrace();
result.append("Failed to parse element at position ").append(i);
continue;
}
result.append(String.format("%1&03d [%2$s] Byte : %3$s", i, String.format("%1$016d", data), data));
}
}
return result.toString();
}
//TODO: toString
@Override
public String toString()
{
return toStringHack();
}
}
public class Op {
public class Msgr
{
}
public static String getName(int op) throws IllegalAccessException {
for (Field field : Op.class.getFields())
{
if ((int)field.get(null) == op)
return field.getName();
}
for (Field field : Op.Msgr.class.getFields())
{
if ((int)field.get(null) == op)
return field.getName();
}
return "?";
}
}
[2
當調試,_ptr
不會toString()
設置,而不是在調試時,_ptr
不會putSimple()
設置。
我真的很喜歡拉我的頭髮,謝謝,如果你能幫助我,我真的很高興!請再次感謝你!
爲了測試這種錯誤,請查看下面的例子:
Packet p = new Packet(1, 10001).putByte(true);
Toast.makeText(this, p.toString(), Toast.LENGTH_LONG).show();
我,我扔在這裏面內置的測試類,然後再嘗試它在OnCreate從主要活動。
toString()
將只返回操作和Id,因爲_ptr
是,peek()
將嘗試讀取從該位置開始的字節,而不是在0,它會找到我們的1個字節。
編輯
好像... _ptr = _bodyStart;
被看作是比其他的分配的東西,這可能嗎?
什麼是將其作爲獨立類進行調試的步驟?你會有一個主要方法來創建一個數據包對象,然後在最終調用toString()之前設置一些數據?你能發佈測試代碼嗎? – ramp
謝謝你看看!〜我繼續編輯我的問題,以提供更多細節和缺課。 ^^ – ImaBrokeDude