Package com.slytechs.file.snoop

Source Code of com.slytechs.file.snoop.SnoopRawIterator

/**
* Copyright (C) 2007 Sly Technologies, Inc. This library is free software; you
* can redistribute it and/or modify it under the terms of the GNU Lesser
* General Public License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version. This
* library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details. You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package com.slytechs.file.snoop;

import java.io.Closeable;
import java.io.IOException;
import java.nio.ByteBuffer;

import org.jnetstream.capture.file.HeaderReader;
import org.jnetstream.capture.file.RecordFilterTarget;
import org.jnetstream.capture.file.snoop.SnoopBlockRecord;
import org.jnetstream.capture.file.snoop.SnoopFile;
import org.jnetstream.capture.file.snoop.SnoopPacketRecord;
import org.jnetstream.filter.Filter;


import com.slytechs.capture.file.editor.AbstractRawIterator;
import com.slytechs.capture.file.editor.PartialLoader;
import com.slytechs.utils.collection.SeekResult;
import com.slytechs.utils.io.AutoflushMonitor;
import com.slytechs.utils.region.FlexRegion;

/**
* @author Mark Bednarczyk
* @author Sly Technologies, Inc.
*/
public class SnoopRawIterator
    extends AbstractRawIterator {

  private final SnoopPacketRecord.SnoopPacketHeader SECONDS = SnoopPacketRecord.SnoopPacketHeader.Seconds;

  private final SnoopPacketRecord.SnoopPacketHeader MICROS = SnoopPacketRecord.SnoopPacketHeader.Microseconds;


  /**
   *
   * @param edits
   * @param lengthGetter
   * @param autoflush
   * @param closeable
   * @throws IOException
   */
  public SnoopRawIterator(FlexRegion<PartialLoader> edits, HeaderReader lengthGetter,
      AutoflushMonitor autoflush, Closeable closeable) throws IOException {
    super(edits, SnoopFile.headerReader, autoflush, closeable, null);

    super.pattern = SnoopPacketRecord.pattern;
  }
 
  public SnoopRawIterator(FlexRegion<PartialLoader> edits, AutoflushMonitor autoflush,
      Closeable closeable, Filter<RecordFilterTarget> filter) throws IOException {
    super(edits, SnoopFile.headerReader, autoflush, closeable, filter);

    super.pattern = SnoopPacketRecord.pattern;
  }


  /*
   * (non-Javadoc)
   *
   * @see org.jnetstream.capture.file.FileIterator#seek(long, long)
   */
  public SeekResult seek(final long seconds, final long nanos)
      throws IOException {
    // Convert nanos to micros since PCAP only supports micros
    final long micros = nanos / 1000;

    // Calculate the start of the first record as a percentage
    final double start = (double) SnoopBlockRecord.HEADER_LENGTH
        / edits.getLength();

    /*
     * Now search for the record starting at the first record and ending at the
     * last record
     */
    return seek(seconds, micros, start, 1. - start);
  }

  private SeekResult seek(final long seconds, final long micros, double start,
      double length) throws IOException {
    ByteBuffer buffer;
    long s, m;

    seek(start);

    /*
     * If the search area, the length as a percentage is smaller then typical
     * SEARCH_LENGTH, then we simply iterate over packets until we find what we
     * are looking for
     */
    final long lengthInBytes = (long) ((double) edits.getLength() * length);
    if (lengthInBytes <= SEARCH_LENGTH) {
      return seekByIteration(seconds, micros);
    }

    /*
     * Otherwise, We divide the file into 2 half sections. Then we check which
     * half our timestamp should reside and we recursively call on ourselves to
     * subdivide each of the halfs until we narrow in on the right record
     */
    if (hasNext() == false) {
      throw new IllegalStateException(
          "Exhausted all records while searching for timestamp");
    } else {
      buffer = next();
      s = (Long) SECONDS.read(buffer, buffer.position());
      m = (Long) MICROS.read(buffer, buffer.position());

    }

    // Check if we are not already passed it
    if (seconds < s || (seconds == s && micros < m)) {
      seek(start);
      return SeekResult.Fullfilled;
    }

    final double half = start + length / 2.;

    seek(half);

    if (hasNext() == false) {
      throw new IllegalStateException(
          "Exhausted all records while searching for timestamp");
    } else {
      buffer = next();
      s = (Long) SECONDS.read(buffer, buffer.position());
      m = (Long) MICROS.read(buffer, buffer.position());
    }

    // Check if we are not already passed it
    if (seconds < s || (seconds == s && micros < m)) {
      return seek(seconds, micros, start, length / 2.);
    } else {
      return seek(seconds, micros, half, length / 2.);
    }
  }

  /**
   * @param seconds
   * @param micros
   * @return
   * @throws IOException
   */
  private SeekResult seekByIteration(long seconds, long micros)
      throws IOException {

    long p = getPosition();
    long s, m;

    while (hasNext()) {
      p = getPosition();
      ByteBuffer buffer = next();

      s = (Long) SECONDS.read(buffer, buffer.position());
      m = (Long) MICROS.read(buffer, buffer.position());

      if (s > seconds || (s == seconds && m >= micros)) {
        setPosition(p);

        return SeekResult.Fullfilled;
      }
    }

    /*
     * If we go passed the end record, we simply align on the last record. That
     * is if the timestamp is way in the future, past any timestamp in the file,
     * then we simply use the last/oldest record as the closest one to the
     * timestamp.
     */

    setPosition(p);

    return SeekResult.Fullfilled;
  }

  /* (non-Javadoc)
   * @see com.slytechs.capture.file.editor.AbstractRawIterator#getRecordHeaderLength(java.nio.ByteBuffer)
   */
  @Override
  protected int getRecordHeaderLength(ByteBuffer buffer) {
    return SnoopPacketRecord.HEADER_LENGTH;
  }

}
TOP

Related Classes of com.slytechs.file.snoop.SnoopRawIterator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.