/// <summary> /// Continue to read data until the end of an element, then call /// elementListener.onReceivedElement(element ). The buffer passed to /// onReceivedElement is only valid during this call. If you need the data /// later, you must copy. /// </summary> /// /// <param name="data"></param> /// <exception cref="EncodingException">For invalid encoding.</exception> public void onReceivedData(ByteBuffer data) { // We may repeatedly set data to a slice as we read elements. data = data.slice(); // Process multiple objects in the data. while (true) { bool gotElementEnd; int offset; try { if (!usePartialData_) { // This is the beginning of an element. if (data.remaining() <= 0) // Wait for more data. return; } // Scan the input to check if a whole TLV object has been read. tlvStructureDecoder_.seek(0); gotElementEnd = tlvStructureDecoder_.findElementEnd(data); offset = tlvStructureDecoder_.getOffset(); } catch (EncodingException ex) { // Reset to read a new element on the next call. usePartialData_ = false; tlvStructureDecoder_ = new TlvStructureDecoder(); throw ex; } if (gotElementEnd) { // Got the remainder of an element. Report to the caller. ByteBuffer element; if (usePartialData_) { // We have partial data from a previous call, so append this data and point to partialData. partialData_.ensuredPut(data, 0, offset); element = partialData_.flippedBuffer(); // Assume we don't need to use partialData anymore until needed. usePartialData_ = false; } else { // We are not using partialData, so just point to the input data buffer. element = data.duplicate(); element.limit(offset); } // Reset to read a new object. Do this before calling onReceivedElement // in case it throws an exception. data.position(offset); data = data.slice(); tlvStructureDecoder_ = new TlvStructureDecoder(); elementListener_.onReceivedElement(element); if (data.remaining() <= 0) // No more data in the packet. return; // else loop back to decode. } else { // Save remaining data for a later call. if (!usePartialData_) { usePartialData_ = true; partialData_.position(0); } if (partialData_.buffer().position() + data.remaining() > net.named_data.jndn.util.Common.MAX_NDN_PACKET_SIZE) { // Reset to read a new element on the next call. usePartialData_ = false; tlvStructureDecoder_ = new TlvStructureDecoder(); throw new EncodingException( "The incoming packet exceeds the maximum limit Face.getMaxNdnPacketSize()"); } partialData_.ensuredPut(data); return; } } }
/// <summary> /// Create a new ElementReader with the elementListener. /// </summary> /// /// <param name="elementListener">The ElementListener used by onReceivedData.</param> public ElementReader(ElementListener elementListener) { this.tlvStructureDecoder_ = new TlvStructureDecoder(); this.partialData_ = new DynamicByteBuffer(1000); elementListener_ = elementListener; }