/** * Encodes payload in a big switch statement. Types are: EMPTY, KEY_KEY, PUBLIC_KEY, * KEY_KEY_PUBLIC_KEY, MAP_KEY_DATA, MAP_KEY_DATA_TTL, SET_DATA_TTL, MAP_KEY_KEY, SET_KEYS, * SET_NEIGHBORS, BYTE_ARRAY, INTEGER, USER1, USER2, USER3 * * @param contentType The type of the content to encode * @param input The ProtocolChunkedInput to fill * @param message The message which contains the payload * @throws NoSuchAlgorithmException * @throws SignatureException * @throws InvalidKeyException */ private static int encodePayloadType( final Content content, final ProtocolChunkedInput input, final Message message) { final int size; final byte[] data; int count; switch (content) { case KEY: input.copyToCurrent(message.getKey().toByteArray()); return 20; case KEY_KEY: input.copyToCurrent(message.getKeyKey1().toByteArray()); input.copyToCurrent(message.getKeyKey2().toByteArray()); return 40; case MAP_KEY_DATA: count = 4; if (message.isConvertNumber480to160()) { Map<Number480, Data> dataMap = message.getDataMapConvert(); input.copyToCurrent(dataMap.size()); for (Map.Entry<Number480, Data> entry : dataMap.entrySet()) { input.copyToCurrent(entry.getKey().getContentKey().toByteArray()); count += 20; count += encodeData(input, message, entry.getValue()); } return count; } else { input.copyToCurrent(message.getDataMap().size()); for (Map.Entry<Number160, Data> entry : message.getDataMap().entrySet()) { input.copyToCurrent(entry.getKey().toByteArray()); count += 20; count += encodeData(input, message, entry.getValue()); } return count; } case MAP_KEY_KEY: Map<Number160, Number160> keyMap = message.getKeyMap(); size = keyMap.size(); input.copyToCurrent(size); for (final Map.Entry<Number160, Number160> entry : keyMap.entrySet()) { input.copyToCurrent(entry.getKey().toByteArray()); input.copyToCurrent(entry.getValue().toByteArray()); } return 4 + (size * (20 + 20)); case SET_KEYS: if (message.isConvertNumber480to160()) { Collection<Number480> keys = message.getKeysConvert(); size = keys.size(); input.copyToCurrent(size); for (Number480 key : keys) input.copyToCurrent(key.getContentKey().toByteArray()); return 4 + (size * 20); } else { size = message.getKeys().size(); input.copyToCurrent(size); for (Number160 key : message.getKeys()) input.copyToCurrent(key.toByteArray()); return 4 + (size * 20); } case SET_NEIGHBORS: count = 1; size = Math.min( message.getNeighbors().size(), Math.min(message.getUseAtMostNeighbors(), MAX_BYTE)); input.copyToCurrent((byte) size); final Iterator<PeerAddress> iterator = message.getNeighbors().iterator(); for (int i = 0; iterator.hasNext() && i < size; i++) { byte[] data1 = iterator.next().toByteArray(); input.copyToCurrent(data1); count += data1.length; } return count; case SET_TRACKER_DATA: count = 1; final Collection<TrackerData> trackerDatas = message.getTrackerData(); input.copyToCurrent((byte) trackerDatas.size()); for (TrackerData trackerData : trackerDatas) { byte[] data1 = trackerData.getPeerAddress().toByteArray(); input.copyToCurrent(data1); count += data1.length; if (trackerData.getAttachement() != null) { input.copyToCurrent((byte) 1); input.copyToCurrent(trackerData.getLength()); count += 5; input.copyToCurrent( trackerData.getAttachement(), trackerData.getOffset(), trackerData.getLength()); count += trackerData.getLength(); } else { input.copyToCurrent((byte) 0); count += 1; } } return count; case CHANNEL_BUFFER: ChannelBuffer tmpBuffer = message.getPayload1(); if (tmpBuffer == null) tmpBuffer = message.getPayload2(); else message.setPayload1(null); size = tmpBuffer.writerIndex(); input.copyToCurrent(size); input.copyToCurrent(tmpBuffer.slice()); return 4 + size; case LONG: input.copyToCurrent(message.getLong()); return 8; case INTEGER: input.copyToCurrent(message.getInteger()); return 4; case PUBLIC_KEY: data = message.getPublicKey().getEncoded(); size = data.length; input.copyToCurrent((short) size); input.copyToCurrent(data); return 2 + size; case PUBLIC_KEY_SIGNATURE: // flag to encode public key data = message.getPublicKey().getEncoded(); size = data.length; input.copyToCurrent((short) size); input.copyToCurrent(data); message.setHintSign(true); // count 40 for the signature, which comes later in ProtocolChunkedInput return 40 + 2 + size; case EMPTY: case RESERVED1: case RESERVED2: case RESERVED3: default: return 0; } }