@Override
public int encode(EncodeContext cxt, PValue value, int parentLength,
PTypeConstraintStorage constraint, ByteOrder byteOrder, PFpbTypeEVAttrs priorityAttrs)
throws EncodeException {
if (cxt.withEncodeAction()) {
IReadWritableBitBuffer buffer = cxt.getBuffer();
//Segment开始位置
int startOffset = buffer.position();
int result = super.encode(cxt, value, parentLength, constraint, byteOrder,
priorityAttrs);
//Segment结束位置
int curPosition = cxt.getBuffer().position();
try {
assert startOffset % FpbConstants.OCTET_BITS == 0;
assert curPosition % FpbConstants.OCTET_BITS == 0;
IRecordSetValue ipHeader;
byte[] pseudoBlock;
int upperPrtlBytes = (curPosition - startOffset) / FpbConstants.OCTET_BITS;
//取得IPV4 Header
ipHeader = (IRecordSetValue)cxt.getFieldStackMap().peekField(
Ipv4TypeEVExtFactory.HEADER_FIELD);
if (ipHeader != null) {
pseudoBlock = createV4PseudoHeader(cxt, (IContainerValue)value,
ipHeader, upperPrtlBytes, startOffset);
} else {
//取得IPV6 Header
ipHeader = (IRecordSetValue)cxt.getFieldStackMap().peekField(
Ipv6TypeEVExtFactory.HEADER_FIELD);
if (ipHeader != null) {
pseudoBlock = createV6PseudoHeader(cxt, (IContainerValue)value,
ipHeader, upperPrtlBytes, startOffset);
} else {
throw new EncodeException(targetTypeMeta,
MetaException.CODE.LOWER_LAYER_PROTOCOL_WRONG_ERROR,
"Ipv4Protocol or Ipv6Protocol");
}
}
//计算Checksum
byte[] checksum = FpbUtils.internetChecksum(pseudoBlock);
if (isUdp) {
buffer.position(startOffset + UDP_CHECKSUM_FIELD_OFFSET);
//UDP的特殊处理0x0000->0xFFFF
if (checksum[0] == 0 && checksum[1] == 0) {
checksum[0] = (byte)0xFF;
checksum[1] = (byte)0xFF;
}
} else {
buffer.position(startOffset + TCP_CHECKSUM_FIELD_OFFSET);
}
buffer.putByte(checksum);
} catch (BitBufferException e) {
throw new EncodeException(targetTypeMeta,
MetaException.CODE.BIT_BUFFER_EXCEPTION_ERROR, e);
}
//恢复Position
buffer.position(curPosition);
return result;
} else {
return super.encode(cxt, value, parentLength, constraint, byteOrder,
priorityAttrs);
}