[gparted/psusi/refactor: 6/19] Thread the internal copy algorithm (#685740)



commit 963927ce15f2a45d5a68a6cf92167a2fb8e75350
Author: Phillip Susi <psusi ubuntu com>
Date:   Sun Jan 20 10:33:54 2013 -0500

    Thread the internal copy algorithm (#685740)
    
    Have the copy code create a background thread to do the actual copying so
    that it won't block the main loop.
    
    Part of Bug 685740 - Refactor to use asynchronous command execution

 include/Copy_Blocks.h  |   70 +++++++++++++++
 include/GParted_Core.h |   19 ----
 include/Makefile.am    |    3 +-
 src/Copy_Blocks.cc     |  219 +++++++++++++++++++++++++++++++++++++++++++++
 src/GParted_Core.cc    |  232 +++---------------------------------------------
 src/Makefile.am        |    3 +-
 6 files changed, 304 insertions(+), 242 deletions(-)
---
diff --git a/include/Copy_Blocks.h b/include/Copy_Blocks.h
new file mode 100644
index 0000000..c60b9d8
--- /dev/null
+++ b/include/Copy_Blocks.h
@@ -0,0 +1,70 @@
+/*  Copyright (C) 2013 Phillip Susi
+ *
+ *  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 Library 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.
+ */
+
+#ifndef COPY_BLOCKS_H
+#define COPY_BLOCKS_H
+
+#include "../include/Operation.h"
+#include <parted/parted.h>
+
+namespace GParted {
+
+class copy_blocks {
+       const Glib::ustring & src_device;
+       const Glib::ustring & dst_device;
+       Byte_Value length;
+       Byte_Value blocksize;
+       OperationDetail &operationdetail;
+       bool readonly;
+       Byte_Value & total_done;
+       char *buf;
+       Byte_Value done;
+       PedDevice *lp_device_src;
+       PedDevice *lp_device_dst;
+       Sector offset_src;
+       Sector offset_dst;
+       Glib::Timer timer_total;
+       bool success;
+       Glib::ustring error_message;
+       bool set_progress_info();
+       void copy_thread();
+public:
+copy_blocks( const Glib::ustring & in_src_device,
+            const Glib::ustring & in_dst_device,
+            Sector src_start,
+            Sector dst_start,
+            Byte_Value in_length,
+            Byte_Value in_blocksize,
+            OperationDetail & in_operationdetail,
+            bool in_readonly,
+            Byte_Value & in_total_done ) :
+       src_device( in_src_device ),
+               dst_device ( in_dst_device ),
+               length ( in_length ),
+               blocksize ( in_blocksize ),
+               operationdetail ( in_operationdetail ),
+               readonly ( in_readonly ),
+               total_done ( in_total_done ),
+               offset_src ( src_start ),
+               offset_dst ( dst_start ) {};
+       bool copy();
+       void copy_block();
+};
+
+} // namespace GParted
+
+#endif // COPY_BLOCKS_H
diff --git a/include/GParted_Core.h b/include/GParted_Core.h
index d10ffc1..bea5d88 100644
--- a/include/GParted_Core.h
+++ b/include/GParted_Core.h
@@ -170,25 +170,6 @@ private:
 
        bool set_partition_type( const Partition & partition, OperationDetail & operationdetail ) ;
 
-       void set_progress_info( Sector total, Sector done, const Glib::Timer & timer, OperationDetail & 
operationdetail, bool readonly ) ;
-
-       bool copy_blocks( const Glib::ustring & src_device,
-                         const Glib::ustring & dst_device,
-                         Sector src_start,
-                         Sector dst_start,
-                         Byte_Value length,
-                         Byte_Value blocksize,
-                         OperationDetail & operationdetail,
-                         bool readonly,
-                         Byte_Value & total_done ) ;
-
-       bool copy_block( PedDevice * lp_device_src,
-                        PedDevice * lp_device_dst,
-                        Sector offset_src,
-                        Sector offset_dst,
-                        Byte_Value blocksize,
-                        Glib::ustring & error_message,
-                        bool readonly ) ; 
        bool calibrate_partition( Partition & partition, OperationDetail & operationdetail ) ;
        bool calculate_exact_geom( const Partition & partition_old,
                                   Partition & partition_new,
diff --git a/include/Makefile.am b/include/Makefile.am
index 5c3f554..7a8f1df 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -56,4 +56,5 @@ EXTRA_DIST = \
        reiserfs.h                      \
        ufs.h                           \
        xfs.h                           \
-       PipeCapture.h
+       PipeCapture.h                   \
+       Copy_Blocks.h
diff --git a/src/Copy_Blocks.cc b/src/Copy_Blocks.cc
new file mode 100644
index 0000000..fa9709b
--- /dev/null
+++ b/src/Copy_Blocks.cc
@@ -0,0 +1,219 @@
+/* Copyright (C) 2004 Bart 'plors' Hakvoort
+ * Copyright (C) 2008, 2009, 2010, 2011, 2012 Curtis Gedak
+ * Copyright (C) 2013 Phillip Susi
+ *
+ *  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 Library 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.
+ */
+
+#include "../include/Copy_Blocks.h"
+#include <gtkmm/main.h>
+#include <errno.h>
+
+namespace GParted {
+
+bool copy_blocks::set_progress_info()
+{
+       Byte_Value done = llabs(this->done);
+       OperationDetail &operationdetail = this->operationdetail.get_last_child().get_last_child();
+       operationdetail.fraction = done / static_cast<double>( length );
+
+       std::time_t time_remaining = Utils::round( (length - done) / ( done / timer_total.elapsed() ) );
+
+       operationdetail.progress_text =
+               String::ucompose( readonly ?
+                               /*TO TRANSLATORS: looks like  1.00 MiB of 16.00 MiB read (00:01:59 remaining) 
*/
+                               _("%1 of %2 read (%3 remaining)") :
+                               /*TO TRANSLATORS: looks like  1.00 MiB of 16.00 MiB copied (00:01:59 
remaining) */
+                               _("%1 of %2 copied (%3 remaining)"),
+                                 Utils::format_size( done, 1 ),
+                                 Utils::format_size( length,1 ),
+                                 Utils::format_time( time_remaining ) );
+
+       operationdetail.set_description(
+               String::ucompose( readonly ?
+                               /*TO TRANSLATORS: looks like  1.00 MiB of 16.00 MiB read */
+                               _("%1 of %2 read") :
+                               /*TO TRANSLATORS: looks like  1.00 MiB of 16.00 MiB copied */
+                               _("%1 of %2 copied"),
+                               Utils::format_size( done, 1 ), Utils::format_size( length, 1 ) ),
+                               FONT_ITALIC );
+       if (done == length || !success)
+       {
+               //reset fraction to -1 to make room for a new one (or a pulsebar)
+               operationdetail.get_last_child().get_last_child().fraction = -1;
+
+               //final description
+               operationdetail.get_last_child().get_last_child().set_description(
+                       String::ucompose( readonly ?
+                                         /*TO TRANSLATORS: looks like  1.00 MiB of 16.00 MiB read */
+                                         _("%1 of %2 read") :
+                                         /*TO TRANSLATORS: looks like  1.00 MiB of 16.00 MiB copied */
+                                         _("%1 of %2 copied"),
+                                         Utils::format_size( llabs( done ), 1 ),
+                                         Utils::format_size( length, 1 ) ),
+                       FONT_ITALIC );
+
+               if ( !success && !error_message.empty() )
+                       operationdetail.get_last_child().add_child(
+                               OperationDetail( error_message, STATUS_NONE, FONT_ITALIC ) );
+       }
+       return false;
+}
+
+static bool mainquit(void *dummy)
+{
+       Gtk::Main::quit();
+       return false;
+}
+
+void copy_blocks::copy_thread()
+{
+       if ( ped_device_open( lp_device_src ) &&
+            (lp_device_src == lp_device_dst || ped_device_open( lp_device_dst ) ) )
+       {
+               Byte_Value src_sector_size = lp_device_src ->sector_size;
+               Byte_Value dst_sector_size = lp_device_dst ->sector_size;
+
+               //Handle situation where we need to perform the copy beginning
+               //  with the end of the partition and finishing with the start.
+               if ( offset_src < offset_dst )
+               {
+                       blocksize -= 2*blocksize;
+                       done -= 2*done;
+                       offset_src += ( (length / src_sector_size) - 1 );
+                       /* Handle situation where src sector size is smaller than dst sector size and an 
additional partial dst sector is required. */
+                       offset_dst += ( ((length + (dst_sector_size - 1)) / dst_sector_size) - 1 );
+               }
+               success = true;
+       } else success = false;
+
+       ped_device_sync( lp_device_dst );
+
+       if ( success && done != 0 )
+       {
+               Byte_Value b = blocksize;
+               blocksize = done;
+               done = 0;
+               /* copy partial block first */
+               copy_block();
+               blocksize = b;
+       }
+       Glib::Timer timer_progress_timeout;
+       while( success && llabs( done ) < length )
+       {
+               copy_block();
+               if ( timer_progress_timeout.elapsed() >= 0.5 )
+               {
+                       Glib::signal_idle().connect( sigc::mem_fun(
+                                                            *this,
+                                                            &copy_blocks::set_progress_info) );
+                       timer_progress_timeout.reset();
+               }
+       }
+       total_done += llabs( done );
+
+       //close and destroy the devices..
+       ped_device_close( lp_device_src );
+       ped_device_destroy( lp_device_src );
+
+       if ( src_device != dst_device )
+       {
+               ped_device_close( lp_device_dst );
+               ped_device_destroy( lp_device_dst );
+       }
+
+       //set progress bar current info on completion
+       g_idle_add( (GSourceFunc)mainquit, NULL );
+}
+
+bool copy_blocks::copy()
+{
+       if ( blocksize > length )
+               blocksize = length;
+
+       if ( readonly )
+               operationdetail.add_child( OperationDetail(
+                               /*TO TRANSLATORS: looks like  read 16.00 MiB using a block size of 1.00 MiB */
+                               String::ucompose( _("read %1 using a block size of %2"), Utils::format_size( 
length, 1 ),
+                                       Utils::format_size( blocksize, 1 ) ) ) );
+       else
+               operationdetail.add_child( OperationDetail(
+                               /*TO TRANSLATORS: looks like  copy 16.00 MiB using a block size of 1.00 MiB */
+                               String::ucompose( _("copy %1 using a block size of %2"), Utils::format_size( 
length, 1 ),
+                                       Utils::format_size( blocksize, 1 ) ) ) );
+
+       done = length % blocksize;
+
+       lp_device_src = ped_device_get( src_device.c_str() );
+       lp_device_dst = src_device != dst_device ? ped_device_get( dst_device.c_str() ) : lp_device_src;
+       //add an empty sub which we will constantly update in the loop
+       operationdetail.get_last_child().add_child( OperationDetail( "", STATUS_NONE ) );
+       buf = static_cast<char *>( malloc( llabs( blocksize ) ) );
+       if ( buf )
+       {
+               Glib::Thread::create( sigc::mem_fun( *this, &copy_blocks::copy_thread ),
+                                     false );
+               Gtk::Main::run();
+               free( buf ) ;
+       }
+       else
+               error_message = Glib::strerror( errno );
+
+       operationdetail.get_last_child().set_status( success ? STATUS_SUCCES : STATUS_ERROR );
+       return success;
+}
+
+void copy_blocks::copy_block()
+{
+       Byte_Value sector_size_src = lp_device_src ->sector_size;
+       Byte_Value sector_size_dst = lp_device_dst ->sector_size;
+
+       //Handle case where src and dst sector sizes are different.
+       //    E.g.,  5 sectors x 512 bytes/sector = ??? 2048 byte sectors
+       Sector num_blocks_src = (llabs(blocksize) + (sector_size_src - 1) ) / sector_size_src;
+       Sector num_blocks_dst = (llabs(blocksize) + (sector_size_dst - 1) ) / sector_size_dst;
+
+       //Handle situation where we are performing copy operation beginning
+       //  with the end of the partition and finishing with the start.
+       if ( blocksize < 0 )
+       {
+               offset_src += (blocksize / sector_size_src);
+               offset_dst += (blocksize / sector_size_dst);
+       }
+
+       if ( blocksize != 0 )
+       {
+               if ( ped_device_read( lp_device_src, buf, offset_src, num_blocks_src ) )
+               {
+                       if ( readonly || ped_device_write( lp_device_dst, buf, offset_dst, num_blocks_dst ) )
+                               success = true;
+                       else {
+                               error_message = String::ucompose( _("Error while writing block at sector 
%1"), offset_dst );
+                               success = false;
+                       }
+               }
+               else
+                       error_message = String::ucompose( _("Error while reading block at sector %1"), 
offset_src );
+       }
+       if ( blocksize > 0 )
+       {
+               offset_src += (blocksize / sector_size_src);
+               offset_dst += (blocksize / sector_size_dst);
+       }
+       if( success )
+               done += blocksize;
+}
+
+} // namespace GParted
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index 9342384..fc29c8e 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -48,6 +48,7 @@
 #include "../include/hfsplus.h"
 #include "../include/reiser4.h"
 #include "../include/ufs.h"
+#include "../include/Copy_Blocks.h"
 #include <set>
 #include <cerrno>
 #include <cstring>
@@ -2743,7 +2744,7 @@ bool GParted_Core::copy_filesystem( const Glib::ustring & src_device,
                                      benchmark_blocksize,
                                      operationdetail .get_last_child(),
                                      readonly,
-                                     total_done ) ;
+                                     total_done ).copy();
                timer.stop() ;
 
                operationdetail .get_last_child() .get_last_child() .add_child( OperationDetail( 
@@ -2771,14 +2772,14 @@ bool GParted_Core::copy_filesystem( const Glib::ustring & src_device,
 
        if ( succes && llabs( done ) < src_length )
                succes = copy_blocks( src_device, 
-                                   dst_device,
-                                   src_start + ( dst_start > src_start ? 0 : (done / src_sector_size) ),
-                                   dst_start + ( dst_start > src_start ? 0 : (done / dst_sector_size) ),
-                                   src_length - llabs( done ),
-                                   optimal_blocksize,
-                                   operationdetail,
-                                   readonly,
-                                   total_done ) ;
+                                     dst_device,
+                                     src_start + ((done > 0 ? done : 0) / src_sector_size),
+                                     dst_start + ((done > 0 ? done : 0) / dst_sector_size),
+                                     src_length - llabs( done ),
+                                     optimal_blocksize,
+                                     operationdetail,
+                                     readonly,
+                                     total_done ).copy();
 
        operationdetail .add_child( OperationDetail( 
                String::ucompose( readonly ?
@@ -2798,8 +2799,6 @@ void GParted_Core::rollback_transaction( const Partition & partition_src,
 {
        if ( total_done > 0 )
        {
-               operationdetail .add_child( OperationDetail( _("roll back last transaction") ) ) ;
-
                //find out exactly which part of the file system was copied (and to where it was copied)..
                Partition temp_src = partition_src ;
                Partition temp_dst = partition_dst ;
@@ -2814,6 +2813,7 @@ void GParted_Core::rollback_transaction( const Partition & partition_src,
                        temp_src .sector_end = temp_src .sector_start + ( (total_done / temp_src 
.sector_size) - 1 ) ;
                        temp_dst .sector_end = temp_dst .sector_start + ( (total_done / temp_dst 
.sector_size) - 1 ) ;
                }
+               operationdetail.add_child( OperationDetail( _("roll back last transaction") ) );
 
                //and copy it back (NOTE the reversed dst and src)
                bool succes = copy_filesystem( temp_dst, temp_src, operationdetail .get_last_child() ) ;
@@ -2936,216 +2936,6 @@ bool GParted_Core::set_partition_type( const Partition & partition, OperationDet
        return return_value ;
 }
        
-void GParted_Core::set_progress_info( Byte_Value total,
-                                     Byte_Value done,
-                                     const Glib::Timer & timer,
-                                     OperationDetail & operationdetail,
-                                     bool readonly ) 
-{
-       operationdetail .fraction = done / static_cast<double>( total ) ;
-
-       std::time_t time_remaining = Utils::round( (total - done) / ( done / timer .elapsed() ) ) ;
-
-       operationdetail .progress_text = 
-               String::ucompose( readonly ?
-                               /*TO TRANSLATORS: looks like  1.00 MiB of 16.00 MiB read (00:01:59 remaining) 
*/
-                               _("%1 of %2 read (%3 remaining)") :
-                               /*TO TRANSLATORS: looks like  1.00 MiB of 16.00 MiB copied (00:01:59 
remaining) */
-                               _("%1 of %2 copied (%3 remaining)"),
-                                 Utils::format_size( done, 1 ),
-                                 Utils::format_size( total,1 ),
-                                 Utils::format_time( time_remaining) ) ; 
-                       
-       operationdetail .set_description( 
-               String::ucompose( readonly ?
-                               /*TO TRANSLATORS: looks like  1.00 MiB of 16.00 MiB read */
-                               _("%1 of %2 read") :
-                               /*TO TRANSLATORS: looks like  1.00 MiB of 16.00 MiB copied */
-                               _("%1 of %2 copied"),
-                               Utils::format_size( done, 1 ), Utils::format_size( total, 1 ) ),
-                               FONT_ITALIC ) ;
-}
-       
-bool GParted_Core::copy_blocks( const Glib::ustring & src_device,
-                               const Glib::ustring & dst_device,
-                               Sector src_start,
-                               Sector dst_start,
-                               Byte_Value length,
-                               Byte_Value blocksize,
-                               OperationDetail & operationdetail,
-                               bool readonly,
-                               Byte_Value & total_done ) 
-{
-       if ( blocksize > length )
-               blocksize = length ;
-
-       if ( readonly )
-               operationdetail .add_child( OperationDetail( 
-                               /*TO TRANSLATORS: looks like  read 16.00 MiB using a block size of 1.00 MiB */
-                               String::ucompose( _("read %1 using a block size of %2"), Utils::format_size( 
length, 1 ),
-                                       Utils::format_size( blocksize, 1 ) ) ) ) ;
-       else
-               operationdetail .add_child( OperationDetail( 
-                               /*TO TRANSLATORS: looks like  copy 16.00 MiB using a block size of 1.00 MiB */
-                               String::ucompose( _("copy %1 using a block size of %2"), Utils::format_size( 
length, 1 ),
-                                       Utils::format_size( blocksize, 1 ) ) ) ) ;
-
-       Byte_Value done = length % blocksize ; 
-
-       bool succes = false ;
-       PedDevice *lp_device_src = ped_device_get( src_device .c_str() );
-       PedDevice *lp_device_dst = src_device != dst_device ? ped_device_get( dst_device .c_str() ) : 
lp_device_src ;
-
-       if ( lp_device_src && lp_device_dst && ped_device_open( lp_device_src ) && ped_device_open( 
lp_device_dst ) )
-       {
-               Byte_Value src_sector_size = lp_device_src ->sector_size ;
-               Byte_Value dst_sector_size = lp_device_dst ->sector_size ;
-
-               //Handle situation where we need to perform the copy beginning
-               //  with the end of the partition and finishing with the start.
-               if ( dst_start > src_start )
-               {
-                       blocksize -= 2*blocksize ;
-                       done -= 2*done ;
-                       src_start += ( (length / src_sector_size) - 1 ) ;
-                       /* Handle situation where src sector size is smaller than dst sector size and an 
additional partial dst sector is required. */
-                       dst_start += ( ((length + (dst_sector_size - 1))/ dst_sector_size) - 1 ) ;
-               }
-
-               Glib::ustring error_message ;
-               buf = static_cast<char *>( malloc( llabs( blocksize ) ) ) ;
-               if ( buf )
-               {
-                       ped_device_sync( lp_device_dst ) ;
-
-                       succes = true ;
-                       if ( done != 0 )
-                               succes = copy_block( lp_device_src,
-                                               lp_device_dst,
-                                               src_start,
-                                               dst_start, 
-                                               done,
-                                               error_message,
-                                               readonly ) ;
-                       if ( ! succes )
-                               done = 0 ;
-
-                       //add an empty sub which we will constantly update in the loop
-                       operationdetail .get_last_child() .add_child( OperationDetail( "", STATUS_NONE ) ) ;
-
-                       Glib::Timer timer_progress_timeout, timer_total ;
-                       while( succes && llabs( done ) < length )
-                       {
-                               succes = copy_block( lp_device_src,
-                                                    lp_device_dst,
-                                                    src_start + (done / src_sector_size),
-                                                    dst_start + (done / dst_sector_size),
-                                                    blocksize,
-                                                    error_message,
-                                                    readonly ) ; 
-                               if ( succes )
-                                       done += blocksize ;
-
-                               if ( timer_progress_timeout .elapsed() >= 0.5 )
-                               {
-                                       set_progress_info( length,
-                                                          llabs( done + blocksize ),
-                                                          timer_total,
-                                                          operationdetail .get_last_child() 
.get_last_child(),
-                                                          readonly ) ;
-                       
-                                       timer_progress_timeout .reset() ;
-                               }
-                       }
-                       //set progress bar current info on completion
-                       set_progress_info( length,
-                                          llabs( done ),
-                                          timer_total,
-                                          operationdetail .get_last_child() .get_last_child(),
-                                          readonly ) ;
-                       
-                       free( buf ) ;
-               }
-               else
-                       error_message = Glib::strerror( errno ) ;
-
-               //reset fraction to -1 to make room for a new one (or a pulsebar)
-               operationdetail .get_last_child() .get_last_child() .fraction = -1 ;
-
-               //final description
-               operationdetail .get_last_child() .get_last_child() .set_description( 
-                       String::ucompose( readonly ?
-                                       /*TO TRANSLATORS: looks like  1.00 MiB of 16.00 MiB read */
-                                       _("%1 of %2 read") :
-                                       /*TO TRANSLATORS: looks like  1.00 MiB of 16.00 MiB copied */
-                                       _("%1 of %2 copied"),
-                                       Utils::format_size( llabs( done ), 1 ),
-                                       Utils::format_size( length, 1 ) ),
-                                       FONT_ITALIC ) ;
-               
-               if ( ! succes && ! error_message .empty() )
-                       operationdetail .get_last_child() .add_child( 
-                               OperationDetail( error_message, STATUS_NONE, FONT_ITALIC ) ) ;
-               
-               total_done += llabs( done ) ;
-       
-               //close and destroy the devices..
-               ped_device_close( lp_device_src ) ;
-               ped_device_destroy( lp_device_src ) ; 
-
-               if ( src_device != dst_device )
-               {
-                       ped_device_close( lp_device_dst ) ;
-                       ped_device_destroy( lp_device_dst ) ;
-               }
-       }
-
-       operationdetail .get_last_child() .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
-       return succes ;
-}
-
-bool GParted_Core::copy_block( PedDevice * lp_device_src,
-                              PedDevice * lp_device_dst,
-                              Sector offset_src,
-                              Sector offset_dst,
-                              Byte_Value block_length,
-                              Glib::ustring & error_message,
-                              bool readonly ) 
-{
-       Byte_Value sector_size_src = lp_device_src ->sector_size ;
-       Byte_Value sector_size_dst = lp_device_dst ->sector_size ;
-
-       //Handle case where src and dst sector sizes are different.
-       //    E.g.,  5 sectors x 512 bytes/sector = ??? 2048 byte sectors
-       Sector num_blocks_src = (llabs(block_length) + (sector_size_src - 1) ) / sector_size_src ;
-       Sector num_blocks_dst = (llabs(block_length) + (sector_size_dst - 1) ) / sector_size_dst ;
-
-       //Handle situation where we are performing copy operation beginning
-       //  with the end of the partition and finishing with the start.
-       if ( block_length < 0 )
-       {
-               block_length = llabs( block_length ) ;
-               offset_src -= ( (block_length / sector_size_src) - 1 ) ;
-               /* Handle situation where src sector size is smaller than dst sector size and an additional 
partial dst sector is required. */
-               offset_dst -= ( ( (block_length + (sector_size_dst - 1)) / sector_size_dst) - 1 ) ;
-       }
-
-       if ( block_length != 0 )
-       {
-               if ( ped_device_read( lp_device_src, buf, offset_src, num_blocks_src ) )
-               {
-                       if ( readonly || ped_device_write( lp_device_dst, buf, offset_dst, num_blocks_dst ) )
-                               return true ;
-                       else
-                               error_message = String::ucompose( _("Error while writing block at sector 
%1"), offset_dst ) ;
-               }
-               else
-                       error_message = String::ucompose( _("Error while reading block at sector %1"), 
offset_src ) ;
-       }
-
-       return false ;
-}
-
 bool GParted_Core::calibrate_partition( Partition & partition, OperationDetail & operationdetail ) 
 {
        if ( partition .type == TYPE_PRIMARY || partition .type == TYPE_LOGICAL || partition .type == 
TYPE_EXTENDED )
diff --git a/src/Makefile.am b/src/Makefile.am
index 8c0541f..16c0277 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -66,7 +66,8 @@ gpartedbin_SOURCES = \
        reiserfs.cc                     \
        ufs.cc                          \
        xfs.cc                          \
-       PipeCapture.cc
+       PipeCapture.cc                  \
+       Copy_Blocks.cc
 
 gpartedbin_LDFLAGS = -lparted
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]