Package com.aelitis.azureus.plugins.extseed.impl.getright

Source Code of com.aelitis.azureus.plugins.extseed.impl.getright.ExternalSeedReaderGetRight

/*
* Created on 16-Dec-2005
* Created by Paul Gardner
* Copyright (C) 2005, 2006 Aelitis, All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*
* AELITIS, SAS au capital de 46,603.30 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/

package com.aelitis.azureus.plugins.extseed.impl.getright;

import java.util.*;
import java.net.URL;
import java.net.URLEncoder;

import org.gudy.azureus2.core3.torrent.TOTorrent;
import org.gudy.azureus2.core3.torrent.TOTorrentFile;
import org.gudy.azureus2.plugins.peers.PeerManager;
import org.gudy.azureus2.plugins.torrent.Torrent;
import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentImpl;

import com.aelitis.azureus.core.peermanager.piecepicker.PiecePicker;
import com.aelitis.azureus.core.peermanager.piecepicker.PiecePriorityProvider;
import com.aelitis.azureus.plugins.extseed.ExternalSeedException;
import com.aelitis.azureus.plugins.extseed.ExternalSeedPlugin;
import com.aelitis.azureus.plugins.extseed.ExternalSeedReader;
import com.aelitis.azureus.plugins.extseed.impl.ExternalSeedReaderImpl;
import com.aelitis.azureus.plugins.extseed.impl.ExternalSeedReaderRequest;
import com.aelitis.azureus.plugins.extseed.util.ExternalSeedHTTPDownloader;
import com.aelitis.azureus.plugins.extseed.util.ExternalSeedHTTPDownloaderLinear;
import com.aelitis.azureus.plugins.extseed.util.ExternalSeedHTTPDownloaderListener;
import com.aelitis.azureus.plugins.extseed.util.ExternalSeedHTTPDownloaderRange;

public class
ExternalSeedReaderGetRight
  extends ExternalSeedReaderImpl
  implements PiecePriorityProvider
{
  private static final int  TARGET_REQUEST_SIZE_DEFAULT  = 256*1024;
 
  private URL      url;
  private int      port;
 
  private ExternalSeedHTTPDownloader[]  http_downloaders;
  private long[]              downloader_offsets;
  private long[]              downloader_lengths;
 
  private int      piece_size;
  private int      piece_group_size;
   
  private long[]    piece_priorities;
 
  private boolean    linear_download;
 
  protected
  ExternalSeedReaderGetRight(
    ExternalSeedPlugin     _plugin,
    Torrent          _torrent, 
    URL            _url,
    Map            _params )
 
    throws Exception
  {
    super( _plugin, _torrent, _url.getHost(), _params );
       
    int target_request_size  = getIntParam( _params, "req_size", TARGET_REQUEST_SIZE_DEFAULT );
   
    linear_download  = getBooleanParam( _params, "linear", false );

    url    = _url;
   
    port  = url.getPort();
   
    if ( port == -1 ){
     
      port = url.getDefaultPort();
    }
     
    piece_size = (int)getTorrent().getPieceSize();
   
    piece_group_size = target_request_size / piece_size;
   
    if ( piece_group_size == 0 ){
     
      piece_group_size  = 1;
    }
   
    TOTorrent  to_torrent = ((TorrentImpl)_torrent).getTorrent();

    String  ua = getUserAgent();
   
    if ( to_torrent.isSimpleTorrent()){
     
      http_downloaders =
        new ExternalSeedHTTPDownloader[]{
          linear_download?new ExternalSeedHTTPDownloaderLinear( url, ua ):new ExternalSeedHTTPDownloaderRange( url, ua )};
     
      downloader_offsets   = new long[]{ 0 };
      downloader_lengths  = new long[]{ to_torrent.getSize() };
     
    }else{
     
      TOTorrentFile[]  files = to_torrent.getFiles();
     
      http_downloaders = new ExternalSeedHTTPDownloader[ files.length ];
     
      downloader_offsets   = new long[ files.length ];
      downloader_lengths  = new long[ files.length ];

      long  offset  = 0;
     
        // encoding is a problem, assume ISO-8859-1
     
      String  base_url = url.toString();
     
      if ( base_url.endsWith( "/" )){
       
        base_url = base_url.substring( 0, base_url.length()-1 );
      }
     
      base_url += "/" + URLEncoder.encode( new String( to_torrent.getName(), "ISO-8859-1" ), "ISO-8859-1" ).replaceAll("\\+", "%20");
     
      for (int i=0;i<files.length;i++ ){
       
        TOTorrentFile  file = files[i];
       
        long length = file.getLength();
         
        String  file_url_str = base_url;
       
        byte[][] bits = file.getPathComponents();
       
        for (int j=0;j<bits.length;j++){
         
          file_url_str += "/" + URLEncoder.encode( new String( bits[j], "ISO-8859-1" ), "ISO-8859-1" ).replaceAll("\\+", "%20");
        }
       
        http_downloaders[i] = linear_download?new ExternalSeedHTTPDownloaderLinear( new URL( file_url_str), ua ):new ExternalSeedHTTPDownloaderRange( new URL( file_url_str), ua );
       
        downloader_offsets[i= offset;
        downloader_lengths[i= length;
       
        offset += length;
      }
    }
  }
 
  public boolean
  sameAs(
    ExternalSeedReader  other )
  {
    if ( other instanceof ExternalSeedReaderGetRight ){
     
      return( url.toString().equals(((ExternalSeedReaderGetRight)other).url.toString()));
    }
   
    return( false );
  }
 
  public String
  getName()
  {
    return( "GR: " + url );
  }
 
  public URL
  getURL()
  {
    return( url );
  }
 
  public int
  getPort()
  {
    return( port );
  }
 
  protected int
  getPieceGroupSize()
  {
    return( piece_group_size );
  }
 
  protected boolean
  getRequestCanSpanPieces()
  {
    return( true );
  }
   
  protected void
  setActiveSupport(
    PeerManager  peer_manager,
    boolean    active )
  {
    if ( linear_download ){
     
        // force overall download order to be from end of file to start (for BT peers)
     
      if ( peer_manager != null ){
       
        PiecePicker picker = PluginCoreUtils.unwrap( peer_manager ).getPiecePicker();
 
        if ( active ){
         
          piece_priorities = new long[peer_manager.getPieces().length];
         
          for ( int i=0;i<piece_priorities.length;i++){
           
            piece_priorities[i] = 10*1000 +  i;
          }
         
          picker.addPriorityProvider( this );
         
        }else{
         
          piece_priorities = null;
         
          picker.removePriorityProvider( this );
        }
      }
     
      if ( !active ){
       
        for ( ExternalSeedHTTPDownloader d: http_downloaders ){
         
          d.deactivate();
        }
      }
    }
  }
 
  public long[]
  updatePriorities(
    PiecePicker    picker )
  {
    return( piece_priorities );
  }
 
  public void
  calculatePriorityOffsets(
    PeerManager    peer_manager,
    int[]      base_priorities )
  {
    if ( linear_download ){
     
        // force us linear from front of file to end
     
      for (int i=0;i<base_priorities.length;i++){
       
        base_priorities[i] = TOP_PIECE_PRIORITY + base_priorities.length - ( i + 1 );
      }
    }else{
     
      super.calculatePriorityOffsets( peer_manager, base_priorities );
    }
  }
 
  protected void
  readData(
    ExternalSeedReaderRequest  request )
 
    throws ExternalSeedException
 
    readData( request.getStartPieceNumber(), request.getStartPieceOffset(), request.getLength(), request );
  }
 
  protected void
  readData(
    int                      start_piece_number,
    int                      start_piece_offset,
    int                      length,
    final ExternalSeedHTTPDownloaderListener  listener )
 
    throws ExternalSeedException
 
    setReconnectDelay( RECONNECT_DEFAULT, false );
   
    long  request_start   = start_piece_number * (long)piece_size + start_piece_offset;
    int    request_length  = length;
   
    if ( http_downloaders.length == 1 ){
   
      ExternalSeedHTTPDownloader http_downloader = http_downloaders[0];
     
          try{
        http_downloader.downloadRange(
            request_start,
            request_length,
            listener,
            isTransient());
 
          }catch( ExternalSeedException ese ){
           
            if ( http_downloader.getLastResponse() == 503 && http_downloader.getLast503RetrySecs() >= 0 ){
     
          int  retry_secs = http_downloader.getLast503RetrySecs();
         
          setReconnectDelay( retry_secs * 1000, true );
         
          throw( new ExternalSeedException( "Server temporarily unavailable, retrying in " + retry_secs + " seconds" ));
             
            }else{
             
              throw(ese);                 
            }
          }
    }else{
     
      long  request_end = request_start + request_length;
     
      // System.out.println( "Req: start=" + request_start + ", len=" + request_length );
     
      final  byte[][] overlap_buffer       = { null };
      final  int[]   overlap_buffer_position   = { 0 };
     
        // we've got to multiplex the (possible) multiple request buffers onto (possible) multi files
     
      for (int i=0;i<http_downloaders.length;i++){
       
        long  this_start   = downloader_offsets[i];
        long  this_end  = this_start + downloader_lengths[i];

        if ( this_end <= request_start ){
         
          continue;
        }
         
        if ( this_start >= request_end ){
         
          break;
        }
       
        long  sub_request_start   = Math.max( request_start,   this_start );
        long  sub_request_end    = Math.min( request_end,  this_end );
 
        final int  sub_len = (int)( sub_request_end - sub_request_start );
       
        if ( sub_len == 0 ){
         
          continue;
        }
       
        ExternalSeedHTTPDownloader http_downloader = http_downloaders[i];
       
        // System.out.println( "    sub_req: start=" + sub_request_start + ", len=" + sub_len + ",url=" + http_downloader.getURL());
       
        ExternalSeedHTTPDownloaderListener sub_request =
          new ExternalSeedHTTPDownloaderListener()
          {
            private int bytes_read;
             
            private byte[]  current_buffer       = overlap_buffer[0];
            private int    current_buffer_position  = overlap_buffer_position[0];
            private int    current_buffer_length  = current_buffer==null?-1:Math.min( current_buffer.length, current_buffer_position + sub_len );
           
            public byte[]
                getBuffer()
               
                  throws ExternalSeedException
                {
              if ( current_buffer == null ){
               
                current_buffer       = listener.getBuffer();
                current_buffer_position  = 0;
                current_buffer_length  = Math.min( current_buffer.length, sub_len - bytes_read );
              }
             
              return( current_buffer );
                }
               
                public void
                setBufferPosition(
                  int  position )
                {
                  current_buffer_position  = position;
                 
                  listener.setBufferPosition( position );
                }
               
                public int
                getBufferPosition()
                {
                  return( current_buffer_position );
                }
               
                public int
                getBufferLength()
                {
                  return( current_buffer_length );
                }
               
                public int
                getPermittedBytes()
               
                  throws ExternalSeedException
                {
                  return( listener.getPermittedBytes());
                }
               
                public int
                getPermittedTime()
                { 
                  return( listener.getPermittedTime());
                }
               
                public void
                reportBytesRead(
                  int    num )
                {
                  bytes_read += num;
                 
                  listener.reportBytesRead( num );
                }
               
                public boolean
                isCancelled()
                {
                  return( listener.isCancelled());
                }
               
                public void
                done()
                {
                    // the current buffer is full up to the declared length
                 
                  int rem = current_buffer.length - current_buffer_length;
                 
                  if ( bytes_read == sub_len ){
                   
                      // this request is complete. save any partial buffer for
                      // next request
                   
                    if ( rem == 0 ){
                     
                      overlap_buffer[0]       = null;
                      overlap_buffer_position[0= 0;
                     
                    }else{
                     
                      overlap_buffer[0]      = current_buffer;
                      overlap_buffer_position[0= current_buffer_length;
                    }
                  }
                 
                    // prepare for next buffer if needed
                 
                  current_buffer = null;
                 
                  if ( rem == 0 ){
                   
                    listener.done();
                  }
                }
          };
         
            try{
          http_downloader.downloadRange(
              sub_request_start - this_start,
              sub_len,
              sub_request,
              isTransient());
   
            }catch( ExternalSeedException ese ){
             
              if ( http_downloader.getLastResponse() == 503 && http_downloader.getLast503RetrySecs() >= 0 ){
       
            int  retry_secs = http_downloader.getLast503RetrySecs();
           
            setReconnectDelay( retry_secs * 1000, true );
           
            throw( new ExternalSeedException( "Server temporarily unavailable, retrying in " + retry_secs + " seconds" ));
               
              }else{
               
                throw(ese);                 
              }
            }
      }
    }
  }
}
TOP

Related Classes of com.aelitis.azureus.plugins.extseed.impl.getright.ExternalSeedReaderGetRight

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.