Ejemplo n.º 1
0
 public String getString() {
   return ("type=" + type + ",acc=" + file_access.getString());
 }
Ejemplo n.º 2
0
 public void write(RandomAccessFile raf, DirectByteBuffer[] buffers, long position)
     throws FMFileManagerException {
   file_access.write(raf, buffers, position);
 }
Ejemplo n.º 3
0
  public void flush() throws FMFileManagerException {

    file_access.flush();
  }
Ejemplo n.º 4
0
 public void setPieceComplete(RandomAccessFile raf, int piece_number, DirectByteBuffer piece_data)
     throws FMFileManagerException {
   file_access.setPieceComplete(raf, piece_number, piece_data);
 }
Ejemplo n.º 5
0
 public void read(RandomAccessFile raf, DirectByteBuffer[] buffers, long offset)
     throws FMFileManagerException {
   file_access.read(raf, buffers, offset);
 }
Ejemplo n.º 6
0
 public boolean isPieceCompleteProcessingNeeded(int piece_number) {
   return (file_access.isPieceCompleteProcessingNeeded(piece_number));
 }
Ejemplo n.º 7
0
  public void setLength(RandomAccessFile raf, long length) throws FMFileManagerException {

    file_access.setLength(raf, length);
  }
Ejemplo n.º 8
0
  public long getLength(RandomAccessFile raf) throws FMFileManagerException {

    return (file_access.getLength(raf));
  }
Ejemplo n.º 9
0
  public void aboutToOpen() throws FMFileManagerException {

    file_access.aboutToOpen();
  }
Ejemplo n.º 10
0
  protected void convert(int target_type) throws FMFileManagerException {

    if (type == target_type) {

      return;
    }

    if (type == FMFile.FT_PIECE_REORDER || target_type == FMFile.FT_PIECE_REORDER) {

      if (target_type == FMFile.FT_PIECE_REORDER_COMPACT
          || type == FMFile.FT_PIECE_REORDER_COMPACT) {

        // these two access modes are in fact identical at the moment

        type = target_type;

        return;
      }

      throw (new FMFileManagerException("Conversion to/from piece-reorder not supported"));
    }

    File file = owner.getLinkedFile();

    RandomAccessFile raf = null;

    boolean ok = false;

    try {
      FMFileAccess target_access;

      if (target_type == FMFile.FT_LINEAR) {

        target_access = new FMFileAccessLinear(owner);

      } else {

        target_access =
            new FMFileAccessCompact(
                owner.getOwner().getTorrentFile(),
                control_dir,
                controlFileName,
                new FMFileAccessLinear(owner));
      }

      if (file.exists()) {

        raf = new RandomAccessFile(file, FMFileImpl.WRITE_ACCESS_MODE);

        // due to the simplistic implementation of compact we only actually need to deal with
        // the last piece of the file (first piece is in the right place already)

        FMFileAccessCompact compact_access;

        if (target_type == FMFile.FT_LINEAR) {

          compact_access = (FMFileAccessCompact) file_access;

        } else {

          compact_access = (FMFileAccessCompact) target_access;
        }

        long length = file_access.getLength(raf);

        long last_piece_start = compact_access.getLastPieceStart();
        long last_piece_length = compact_access.getLastPieceLength();

        // see if we have any potential data for the last piece

        if (last_piece_length > 0 && length > last_piece_start) {

          long data_length = length - last_piece_start;

          if (data_length > last_piece_length) {

            Debug.out(
                "data length inconsistent: len=" + data_length + ",limit=" + last_piece_length);

            data_length = last_piece_length;
          }

          DirectByteBuffer buffer =
              DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_FILE, (int) data_length);

          try {

            file_access.read(raf, new DirectByteBuffer[] {buffer}, last_piece_start);

            // see if we need to truncate

            if (target_type == FMFile.FT_COMPACT) {

              long first_piece_length = compact_access.getFirstPieceLength();

              long physical_length = raf.length();

              if (physical_length > first_piece_length) {

                raf.setLength(first_piece_length);
              }
            }

            buffer.flip(DirectByteBuffer.AL_FILE);

            target_access.write(raf, new DirectByteBuffer[] {buffer}, last_piece_start);

          } finally {

            buffer.returnToPool();
          }
        } else {

          // no last piece, truncate after the first piece

          if (target_type == FMFile.FT_COMPACT) {

            long first_piece_length = compact_access.getFirstPieceLength();

            long physical_length = raf.length();

            if (physical_length > first_piece_length) {

              raf.setLength(first_piece_length);
            }
          }
        }

        target_access.setLength(raf, length);

        target_access.flush();
      }

      type = target_type;
      file_access = target_access;

      ok = true;

    } catch (Throwable e) {

      Debug.printStackTrace(e);

      throw (new FMFileManagerException("convert fails", e));

    } finally {

      try {
        if (raf != null) {

          try {
            raf.close();

          } catch (Throwable e) {

            // override original exception if there isn't one

            if (ok) {

              ok = false;

              throw (new FMFileManagerException("convert fails", e));
            }
          }
        }
      } finally {

        if (!ok) {

          // conversion failed - replace with linear access, caller is responsible for
          // handling this (marking file requiring recheck)

          type = FMFile.FT_LINEAR;
          file_access = new FMFileAccessLinear(owner);
        }

        if (type == FMFile.FT_LINEAR) {

          new File(control_dir, controlFileName).delete();
        }
      }
    }
  }