package org.yamcs.xtceproc; import java.nio.BufferOverflowException; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.util.Set; import java.util.SortedSet; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.yamcs.ContainerExtractionResult; import org.yamcs.xtce.RateInStream; import org.yamcs.xtce.SequenceContainer; import org.yamcs.xtce.SequenceEntry; import org.yamcs.xtceproc.ContainerProcessingContext.ContainerProcessingPosition; import org.yamcs.xtceproc.ContainerProcessingContext.ContainerProcessingResult; public class SequenceContainerProcessor { Logger log=LoggerFactory.getLogger(this.getClass().getName()); ContainerProcessingContext pcontext; SequenceContainerProcessor(ContainerProcessingContext pcontext) { this.pcontext = pcontext; } public void extract(SequenceContainer seq) { ContainerProcessingResult result = pcontext.result; ContainerProcessingPosition position = pcontext.position; ByteBuffer bb = position.bb; //First add it to the result result.containers.add(new ContainerExtractionResult(seq, bb.asReadOnlyBuffer(), position.bitPosition, result.acquisitionTime, result.generationTime)); RateInStream ris = seq.getRateInStream(); if(ris != null) { result.expirationTime = result.acquisitionTime + ris.getMaxInterval(); } int maxposition = position.bitPosition; //then extract the entries SortedSet<SequenceEntry> entries = pcontext.subscription.getEntries(seq); if(entries!=null) { for (SequenceEntry se:entries) { try { switch(se.getReferenceLocation()) { case previousEntry: position.bitPosition+=se.getLocationInContainerInBits(); break; case containerStart: position.bitPosition=se.getLocationInContainerInBits(); } if(pcontext.ignoreOutOfContainerEntries && (position.bitPosition >= position.bb.capacity()*8)) { //the next entry is outside of the packet break; } if(se.getRepeatEntry()==null) { pcontext.sequenceEntryProcessor.extract(se); } else { //this entry is repeated several times long n = pcontext.valueProcessor.getValue(se.getRepeatEntry().getCount()); for (int i=0; i<n; i++) { pcontext.sequenceEntryProcessor.extract(se); position.bitPosition += se.getRepeatEntry().getOffsetSizeInBits(); } } } catch (BufferUnderflowException|BufferOverflowException|IndexOutOfBoundsException e) { log.warn("Got "+e.getClass().getName()+" when extracting from the buffer of length "+bb.capacity()+" bytes bitPosition "+position.bitPosition+" entry: "+se); break; } if(position.bitPosition>maxposition) { maxposition = position.bitPosition; } } } Set<SequenceContainer> inheritingContainers = pcontext.subscription.getInheritingContainers(seq); boolean hasDerived=false; if(inheritingContainers!=null) { //And then any derived containers int bitp = position.bitPosition; for(SequenceContainer sc:inheritingContainers) { if(sc.getRestrictionCriteria().isMet(pcontext.criteriaEvaluator)) { hasDerived=true; position.bitPosition=bitp; extract(sc); if(position.bitPosition>maxposition) { maxposition = position.bitPosition; } } } } position.bitPosition=maxposition; //Finaly update the stats. We add the packet into the statistics only if it doesn't have a derived container if(!hasDerived && (result.stats != null)) { result.stats.newPacket(seq.getName(), (entries==null)?0:entries.size(), result.acquisitionTime, result.generationTime); } } }