예제 #1
0
  @Override
  public boolean putSubpiece(int piece, byte[] bs) throws IOException {
    // First check if the piece is correct.
    // If we were paranoid we could copy the array first.

    synchronized (bitfield) {
      if (bitfield.get(piece)) {
        return true; // No need to store twice.
      } else {
        bitfield.set(piece, false);
        needed--;
      }
    }
    assert (this.length != 0);
    int start = piece * metainfo.getSubpieceSize(0);
    FileChannel fc = getFileChannel();

    long raflen = this.length;
    while (start > raflen) {
      start -= raflen;
    }

    ByteBuffer bb = ByteBuffer.wrap(bs);
    fc.position(start);
    while (bb.hasRemaining()) {
      fc.write(bb);
    }

    return true;
  }
예제 #2
0
 @Override
 public String percent() {
   StringBuilder sb = new StringBuilder();
   float p = ((float) (nbSubpieces - needed) / nbSubpieces) * 100;
   sb.append(p).append("% ").append(bitfield.getChunkHumanReadable());
   return sb.toString();
 }
예제 #3
0
 @Override
 public void removeSubpiece(int subpiece) throws IOException {
   synchronized (bitfield) {
     bitfield.remove(subpiece);
     needed++;
   }
 }
예제 #4
0
 @Override
 public List<Integer> missingSubpieces(int piece) {
   List<Integer> result = new ArrayList<Integer>();
   int subpiece;
   if (bitfield.getPiece(piece)) {
     System.out.println("bug");
   }
   for (int i = 0; i < BitField.NUM_SUBPIECES_PER_PIECE; i++) {
     subpiece = piece * BitField.NUM_SUBPIECES_PER_PIECE + i;
     if (!bitfield.get(subpiece)) {
       result.add(subpiece);
     }
     if (subpiece == metainfo.getnbSubpieces() - 1) {
       return result;
     }
   }
   return result;
 }
예제 #5
0
 @Override
 public byte[] getPiece(int piece) throws IOException {
   if (!bitfield.getPiece(piece)) {
     return null;
   }
   byte[] bs = new byte[metainfo.getPieceSize(piece)];
   getUncheckedPiece(piece, bs);
   return bs;
 }
예제 #6
0
 /* create storage from infos about the path
  */
 public StorageFcByteBuf(MetaInfoExec metainfo, String baseDir, boolean seeding)
     throws IOException {
   this.metainfo = metainfo;
   this.baseDir = baseDir;
   nbSubpieces = metainfo.getnbSubpieces();
   bitfield = new BitField(metainfo.getnbSubpieces());
   if (!seeding) {
     needed = metainfo.getnbSubpieces();
   } else {
     needed = 0;
     for (int i = 0; i < (nbSubpieces / BitField.NUM_SUBPIECES_PER_PIECE) + 1; i++) {
       for (int j = 0; j < metainfo.getPieceNbSubPieces(i); j++) {
         bitfield.set(i * BitField.NUM_SUBPIECES_PER_PIECE + j, true);
       }
     }
   }
   this.length = metainfo.getLength();
 }
예제 #7
0
  /**
   * Returns a byte array containing the requested piece or null if the storage doesn't contain the
   * piece yet.
   */
  @Override
  public Map<Integer, byte[]> getSubpieces(int piece) throws IOException {
    if (!bitfield.getPiece(piece)) {
      return null;
    }

    Map<Integer, byte[]> result = new HashMap<Integer, byte[]>();

    int subpiece;
    for (int i = 0; i < BitField.NUM_SUBPIECES_PER_PIECE; i++) {
      subpiece = piece * BitField.NUM_SUBPIECES_PER_PIECE + i;
      byte[] bs = new byte[metainfo.getSubpieceSize(subpiece)];
      getUncheckedSubPiece(subpiece, bs, 0);
      result.put(subpiece, bs);
      if (subpiece == metainfo.getnbSubpieces() - 1) {
        return result;
      }
    }
    return result;
  }
예제 #8
0
  void checkCreateFiles() throws IOException {
    //        boolean resume = false;

    // Make sure all files are available and of correct length
    FileChannel fc = getFileChannel();

    // Check which pieces match and which don't
    nbSubpieces = metainfo.getnbSubpieces();
    byte[] piece = new byte[metainfo.getSubpieceSize(0) * BitField.NUM_SUBPIECES_PER_PIECE];
    for (int i = 0; i < metainfo.getNbChunks(); i++) {
      if (metainfo.haveHashes(i)) {
        for (int j = 0; j < metainfo.getChunkNbPieces(i); j++) {
          if (metainfo.checkPiece(
              i * BitField.NUM_PIECES_PER_CHUNK + j,
              getUncheckedPiece(i * BitField.NUM_PIECES_PER_CHUNK + j),
              0,
              metainfo.getPieceSize(i * BitField.NUM_PIECES_PER_CHUNK + j))) {
            for (int k = 0;
                k < metainfo.getPieceNbSubPieces(i * BitField.NUM_PIECES_PER_CHUNK + j);
                k++) {
              bitfield.set(
                  i * BitField.NUM_PIECES_PER_CHUNK * BitField.NUM_SUBPIECES_PER_PIECE
                      + j * BitField.NUM_SUBPIECES_PER_PIECE
                      + k,
                  true);
              needed--;
            }
          }
        }
      } else {
        byte[] chunkHashes =
            new byte[BitField.NUM_PIECES_PER_CHUNK * VodConfig.NUM_HASHES_IN_TORRENT_FILE];
        for (int j = 0; j < metainfo.getChunkNbPieces(i); j++) {
          int pieceLength = getUncheckedPiece(i * BitField.NUM_PIECES_PER_CHUNK + j, piece);
          if (pieceLength == 0) {
            break;
          }
          MessageDigest sha1;
          try {
            sha1 = MessageDigest.getInstance("SHA");
          } catch (NoSuchAlgorithmException nsae) {
            throw new InternalError("No SHA digest available: " + nsae);
          }

          sha1.update(piece, 0, pieceLength);
          byte[] hash = sha1.digest();

          System.arraycopy(
              hash,
              0,
              chunkHashes,
              j * VodConfig.NUM_HASHES_IN_TORRENT_FILE,
              VodConfig.NUM_HASHES_IN_TORRENT_FILE);
        }
        boolean correctHash =
            metainfo.checkChunk(
                i,
                chunkHashes,
                0,
                VodConfig.NUM_HASHES_IN_TORRENT_FILE * BitField.NUM_PIECES_PER_CHUNK);
        if (correctHash) {
          for (int j = 0; j < metainfo.getChunkNbPieces(i); j++) {
            for (int k = 0;
                k < metainfo.getPieceNbSubPieces(i * BitField.NUM_PIECES_PER_CHUNK + j);
                k++) {
              bitfield.set(
                  i * BitField.NUM_PIECES_PER_CHUNK * BitField.NUM_SUBPIECES_PER_PIECE
                      + j * BitField.NUM_SUBPIECES_PER_PIECE
                      + k,
                  true);
              needed--;
            }
          }
          metainfo.setPieceHashes(chunkHashes, i);
        }
      }
    }
  }
예제 #9
0
  @Override
  public void create(JProgressBar progressBar) throws IOException {
    // Calculate piece_hashes
    MessageDigest digest = null;
    try {
      digest = MessageDigest.getInstance("SHA");
    } catch (NoSuchAlgorithmException nsa) {
      throw new InternalError(nsa.toString());
    }

    byte[] pieceHashes = metainfo.getPieceHashes();

    byte[] piece = new byte[subpieceSize * BitField.NUM_SUBPIECES_PER_PIECE];
    for (int i = 0; i < (nbSubpieces / BitField.NUM_SUBPIECES_PER_PIECE) + 1; i++) {
      if (progressBar != null && (i % 100 == 0)) {
        int percentComplete = i / ((nbSubpieces / BitField.NUM_SUBPIECES_PER_PIECE) + 1);
        progressBar.setValue(percentComplete);
      }
      int pieceLength = getUncheckedPiece(i, piece);
      if (pieceLength > 0) {
        digest.update(piece, 0, pieceLength);
        byte[] hash = digest.digest();
        System.arraycopy(
            hash,
            0,
            pieceHashes,
            VodConfig.NUM_HASHES_IN_TORRENT_FILE * i,
            VodConfig.NUM_HASHES_IN_TORRENT_FILE);
        for (int j = 0; j < metainfo.getPieceNbSubPieces(i); j++) {
          bitfield.set(i * BitField.NUM_SUBPIECES_PER_PIECE + j, true);
        }
      }
    }

    boolean[] initializedPieceHash = metainfo.getInitializedPieceHashes();
    byte[] chunkHash = metainfo.getChunksHashes();

    byte[] chunk = new byte[BitField.NUM_PIECES_PER_CHUNK * VodConfig.NUM_HASHES_IN_TORRENT_FILE];
    for (int i = 0;
        i
            < pieceHashes.length
                / BitField.NUM_PIECES_PER_CHUNK
                / VodConfig.NUM_HASHES_IN_TORRENT_FILE;
        i++) {
      for (int j = 0;
          j < BitField.NUM_PIECES_PER_CHUNK * VodConfig.NUM_HASHES_IN_TORRENT_FILE;
          j++) {
        chunk[j] =
            pieceHashes[
                i * BitField.NUM_PIECES_PER_CHUNK * VodConfig.NUM_HASHES_IN_TORRENT_FILE + j];
      }
      digest.update(chunk, 0, chunk.length);
      byte[] hash = digest.digest();
      System.arraycopy(
          hash,
          0,
          chunkHash,
          VodConfig.NUM_HASHES_IN_TORRENT_FILE * i,
          VodConfig.NUM_HASHES_IN_TORRENT_FILE);
      initializedPieceHash[i] = true;
    }
    // Reannounce to force recalculating the info_hash.
    metainfo = metainfo.reannounce();
  }