private TcpSackOption(byte[] rawData, int offset, int length) throws IllegalRawDataException { if (length < 2) { StringBuilder sb = new StringBuilder(50); sb.append("The raw data length must be more than 1. rawData: ") .append(ByteArrays.toHexString(rawData, " ")) .append(", offset: ") .append(offset) .append(", length: ") .append(length); throw new IllegalRawDataException(sb.toString()); } if (rawData[offset] != kind.value()) { StringBuilder sb = new StringBuilder(100); sb.append("The kind must be: ") .append(kind.valueAsString()) .append(" rawData: ") .append(ByteArrays.toHexString(rawData, " ")) .append(", offset: ") .append(offset) .append(", length: ") .append(length); throw new IllegalRawDataException(sb.toString()); } this.length = rawData[1 + offset]; int lengthFieldAsInt = getLengthAsInt(); if (lengthFieldAsInt < 2) { throw new IllegalRawDataException( "The value of length field must be more than 1 but: " + lengthFieldAsInt); } if ((lengthFieldAsInt - 2) % (INT_SIZE_IN_BYTES * 2) != 0) { StringBuilder sb = new StringBuilder(100); sb.append("The value of length field must be an integer multiple of 8 octets long but: ") .append(lengthFieldAsInt); throw new IllegalRawDataException(sb.toString()); } if (length < lengthFieldAsInt) { StringBuilder sb = new StringBuilder(100); sb.append("rawData is too short. length field: ") .append(lengthFieldAsInt) .append(", rawData: ") .append(ByteArrays.toHexString(rawData, " ")) .append(", offset: ") .append(offset) .append(", length: ") .append(length); throw new IllegalRawDataException(sb.toString()); } for (int i = 2; i < lengthFieldAsInt; i += INT_SIZE_IN_BYTES * 2) { sacks.add( new Sack( ByteArrays.getInt(rawData, i + offset), ByteArrays.getInt(rawData, i + INT_SIZE_IN_BYTES + offset))); } }
@Override public byte[] getRawData() { byte[] rawData = new byte[length()]; rawData[0] = kind.value(); rawData[1] = length; int offset = 2; for (Sack sack : sacks) { System.arraycopy( ByteArrays.toByteArray(sack.leftEdge), 0, rawData, offset, INT_SIZE_IN_BYTES); System.arraycopy( ByteArrays.toByteArray(sack.rightEdge), 0, rawData, offset + INT_SIZE_IN_BYTES, INT_SIZE_IN_BYTES); offset += INT_SIZE_IN_BYTES * 2; } return rawData; }