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