/** * Combine payload of Data packet segments into a single buffer. * * @param segments list of Data packets * @return single buffer containing combined payload */ public static ByteBuffer combine(final List<Data> segments) { int size = 0; for (Data segment : segments) { size += segment.getContent().size(); } ByteBuffer payloadBuffer = ByteBuffer.allocate(size); for (Data segment : segments) { payloadBuffer.put(segment.getContent().getImmutableArray()); } payloadBuffer.flip(); return payloadBuffer; }
private boolean hasFinalBlockId(Data data) { return data.getMetaInfo().getFinalBlockId().getValue().size() > 0; }
/** * Compress and replace the {@link Data} content. Note: this stage will return * the same {@link Data} instance and will modify only its content. * * @param context the {@link Data} packet * @return the same packet but with GZIP-compressed content * @throws ProcessingStageException if compression fails */ @Override public Data process(Data context) throws ProcessingStageException { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); try (GZIPOutputStream stream = new GZIPOutputStream(buffer)) { stream.write(context.getContent().getImmutableArray(), 0, context.getContent().size()); stream.close(); } catch (IOException e) { throw new ProcessingStageException(e); } context.setContent(new Blob(buffer.toByteArray())); return context; }
/** * Decode multiple status entries as part of a StatusDatasetHelper. * * @param <T> Class implementing Decodable interface * @param segments list of Data packets * @param type class implementing Decodable interface * @return List decoded status entries * @throws ManagementException when decoding fails * @see <a href="http://redmine.named-data.net/projects/nfd/wiki/StatusDataset">StatusDataset</a> */ public static <T extends Decodable> List<T> wireDecode(final List<Data> segments, final Class<T> type) throws ManagementException { Blob payload = new Blob(combine(segments), false); List<T> entries = new ArrayList<>(); int endOffset = payload.size(); TlvDecoder decoder = new TlvDecoder(payload.buf()); while (decoder.getOffset() < endOffset) { try { T entry = type.newInstance(); entry.wireDecode(decoder); entries.add(entry); } catch (IllegalAccessException | InstantiationException | EncodingException e) { throw new ManagementException("Failed to read status dataset.", e); } } return entries; } }
/** * {@inheritDoc} */ @Override public void serve(Data data) throws IOException { if (!isRegistered()) { register(); } if (data.getContent().size() >= SegmentationHelper.DEFAULT_SEGMENT_SIZE) { InputStream stream = new ByteArrayInputStream(data.getContent().getImmutableArray()); List<Data> segments = SegmentationHelper.segment(data, stream); for (Data segment : segments) { logger.fine("Adding segment: " + segment.getName().toUri()); repository.put(segment); } } else { logger.fine("Adding segment: " + data.getName().toUri()); repository.put(data); } }
private Interest discover(BackoffRetryClient client, On<Long> onFound, On<Void> onComplete, On<Exception> onError) throws IOException { Interest interest = new Interest(topicPrefix); interest.setInterestLifetimeMilliseconds(STARTING_DISCOVERY_LIFETIME); interest.setExclude(excludeKnownPublishers()); client.retry(face, interest, (interest1, data) -> { if (stopped) { return; } LOGGER.log(Level.INFO, "Received discovery data ({0} bytes): {1}", new Object[]{data.getContent().size(), data.getName()}); found(data.getName(), onFound, onError); // TODO instead of inspecting name should look at content and examine for multiple publishers try { discover(client, onFound, onComplete, onError); // recursion } catch (IOException e) { LOGGER.log(Level.SEVERE, "Failed while discovering publishers, aborting: {0}", new Object[]{broadcastPrefix, e}); onError.on(e); // TODO re-call discover here? } }, interest2 -> { // TODO recall client here, we should never be done }); return interest; }
static Blob toResponse(Blob attributes, Blob content) { TlvEncoder encoder = new TlvEncoder(MESSAGE_PAYLOAD_INITIAL_CAPACITY); int initialLength = encoder.getLength(); encoder.writeBlobTlv(MESSAGE_CONTENT_MARKER, content.buf()); // encode backwards, see Tlv0_1_1WireFormat.java if(attributes != null && attributes.size() > 0){ encoder.writeBlobTlv(MESSAGE_ATTRIBUTES_MARKER, content.buf()); } encoder.writeTypeAndLength(MESSAGE_MARKER, encoder.getLength() - initialLength); return new Blob(encoder.getOutput(), false); }