String[] types = DiskManagerImpl.getStorageTypes(download_manager);
boolean[] modified = new boolean[res.length];
boolean[] toSkip = new boolean[res.length];
int toSkipCount = 0;
DownloadManagerState dmState = download_manager.getDownloadState();
try {
dmState.suppressStateSave(true);
for(int i=0;i<res.length;i++)
{
if(!toChange[i])
continue;
final int idx = i;
int old_type = DiskManagerUtil.convertDMStorageTypeFromString( types[i] );
//System.out.println(old_type + " <> " + newStroageType);
if ( newStorageType == old_type )
{
modified[i] = true;
continue;
}
try{
File target_file = res[i].getFile( true );
// if the file doesn't exist then this is the start-of-day, most likely
// being called from the torrent-opener, so we don't need to do any
// file fiddling (in fact, if we do, we end up leaving zero length
// files for dnd files which then force a recheck when the download
// starts for the first time)
if ( target_file.exists()){
CacheFile cache_file =
CacheFileManagerFactory.getSingleton().createFile(
new CacheFileOwner()
{
public String
getCacheFileOwnerName()
{
return( download_manager.getInternalName());
}
public TOTorrentFile
getCacheFileTorrentFile()
{
return( res[idx].getTorrentFile() );
}
public File
getCacheFileControlFileDir()
{
return( download_manager.getDownloadState().getStateFile( ));
}
public int
getCacheMode()
{
return( CacheFileOwner.CACHE_MODE_NORMAL );
}
},
target_file,
DiskManagerUtil.convertDMStorageTypeToCache( newStorageType ));
cache_file.close();
toSkip[i] = ( newStorageType == FileSkeleton.ST_COMPACT || newStorageType == FileSkeleton.ST_REORDER_COMPACT )&& !res[i].isSkipped();
if(toSkip[i])
toSkipCount++;
}
modified[i] = true;
}catch( Throwable e ){
Debug.printStackTrace(e);
Logger.log(
new LogAlert(download_manager,
LogAlert.REPEATABLE,
LogAlert.AT_ERROR,
"Failed to change storage type for '" + res[i].getFile(true) +"': " + Debug.getNestedExceptionMessage(e)));
// download's not running - tag for recheck
RDResumeHandler.recheckFile( download_manager, res[i] );
}
types[i] = DiskManagerUtil.convertDMStorageTypeToString( newStorageType );
}
/*
* set storage type and skipped before we do piece clearing and file
* clearing checks as those checks work better when skipped/stype is set
* properly
*/
dmState.setListAttribute( DownloadManagerState.AT_FILE_STORE_TYPES, types);
if(toSkipCount > 0)
setSkipped(toSkip, true);
for(int i=0;i<res.length;i++)
{
if(!toChange[i])
continue;
// download's not running, update resume data as necessary
int cleared = RDResumeHandler.storageTypeChanged( download_manager, res[i] );
// try and maintain reasonable figures for downloaded. Note that because
// we don't screw with the first and last pieces of the file during
// storage type changes we don't have the problem of dealing with
// the last piece being smaller than torrent piece size
if (cleared > 0)
{
res[i].downloaded = res[i].downloaded - cleared * res[i].getTorrentFile().getTorrent().getPieceLength();
if (res[i].downloaded < 0) res[i].downloaded = 0;
}
}
DiskManagerImpl.storeFileDownloaded( download_manager, res, true );
doFileExistenceChecks(this, toChange, download_manager, newStorageType == FileSkeleton.ST_LINEAR || newStorageType == FileSkeleton.ST_REORDER );
} finally {
dmState.suppressStateSave(false);
dmState.save();
}
return modified;
}
};