我正在尝试为
编写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()
只返回Op和Id,因为_ptr
处于,peek()
将尝试读取从该位置开始而不是0的字节,它将找到我们的1字节
似乎...... _ptr = _bodyStart;
被视为除了作业以外的其他内容,这可能吗?
答案 0 :(得分:1)
您看到的结果是正确的 - 调试器在评估之前向您显示这些变量。在此之后添加一行(如日志或smth。)并在其上设置断点。
答案 1 :(得分:1)
所以事实证明我只缺少一小部分小细节.....根本不是很小,我为之前没有看到这个而道歉。由于toString()
调用格式错误以及String.format()
在ptr
完成后未能将toString()
设置回原始值,result.append(String.format("%1&03d [%2$s] Byte : %3$s", i, String.format("%1$016d", data), data));
会失败。
%1
应该是(我&
之后$
而不是String hello = String.format("%1$03d [%2$s] Byte : %3$d\r\n", i, StringUtils.leftPad(String.format("%02X", data), 16, '.'), (int) data);
ptr = prevPtu;
在返回字符串之前,我需要执行以下操作
{{1}}
,发生以下情况: