Beispiel #1
0
long File::rfind(const ByteVector &pattern, long fromOffset, const ByteVector &before)
{
    if(!d->stream || pattern.size() > d->bufferSize)
        return -1;

    // The position in the file that the current buffer starts at.

    ByteVector buffer;

    // These variables are used to keep track of a partial match that happens at
    // the end of a buffer.

    /*
    int previousPartialMatch = -1;
    int beforePreviousPartialMatch = -1;
    */

    // Save the location of the current read pointer.  We will restore the
    // position using seek() before all returns.

    long originalPosition = tell();

    // Start the search at the offset.

    long bufferOffset;
    if(fromOffset == 0) {
        seek(-1 * int(d->bufferSize), End);
        bufferOffset = tell();
    }
    else {
        seek(fromOffset + -1 * int(d->bufferSize), Beginning);
        bufferOffset = tell();
    }

    // See the notes in find() for an explanation of this algorithm.

    for(buffer = readBlock(d->bufferSize); buffer.size() > 0; buffer = readBlock(d->bufferSize)) {

        // TODO: (1) previous partial match

        // (2) pattern contained in current buffer

        long location = buffer.rfind(pattern);
        if(location >= 0) {
            seek(originalPosition);
            return bufferOffset + location;
        }

        if(!before.isNull() && buffer.find(before) >= 0) {
            seek(originalPosition);
            return -1;
        }

        // TODO: (3) partial match

        bufferOffset -= d->bufferSize;
        seek(bufferOffset);
    }

    // Since we hit the end of the file, reset the status before continuing.

    clear();

    seek(originalPosition);

    return -1;
}
Beispiel #2
0
long File::rfind(const ByteVector &pattern, long fromOffset, const ByteVector &before)
{
  if(!d->stream || pattern.size() > bufferSize())
      return -1;

  // The position in the file that the current buffer starts at.

  ByteVector buffer;

  // These variables are used to keep track of a partial match that happens at
  // the end of a buffer.

  /*
  int previousPartialMatch = -1;
  int beforePreviousPartialMatch = -1;
  */

  // Save the location of the current read pointer.  We will restore the
  // position using seek() before all returns.

  long originalPosition = tell();

  // Start the search at the offset.

  if(fromOffset == 0)
    fromOffset = length();

  long bufferLength = bufferSize();
  long bufferOffset = fromOffset + pattern.size();

  // See the notes in find() for an explanation of this algorithm.

  while(true) {

    if(bufferOffset > bufferLength) {
      bufferOffset -= bufferLength;
    }
    else {
      bufferLength = bufferOffset;
      bufferOffset = 0;
    }
    seek(bufferOffset);

    buffer = readBlock(bufferLength);
    if(buffer.isEmpty())
      break;

    // TODO: (1) previous partial match

    // (2) pattern contained in current buffer

    const long location = buffer.rfind(pattern);
    if(location >= 0) {
      seek(originalPosition);
      return bufferOffset + location;
    }

    if(!before.isEmpty() && buffer.find(before) >= 0) {
      seek(originalPosition);
      return -1;
    }

    // TODO: (3) partial match
  }

  // Since we hit the end of the file, reset the status before continuing.

  clear();

  seek(originalPosition);

  return -1;
}