Ignore:
Timestamp:
11/06/11 23:56:04 (3 years ago)
Author:
lowjoel
Message:

Shifted all the plugin-extensible code to the Plugins assembly (Plugins.ExtensionPoints?). The code does not yet compile, because there are some inter-dependencies on the registrars.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eraser6/pluginsRewrite/Eraser.Manager/ErasureMethod.cs

    r2085 r2352  
    2323using System.Collections.Generic; 
    2424using System.Text; 
     25 
     26using System.Reflection; 
    2527using System.IO; 
    26 using System.Reflection; 
     28 
    2729using Eraser.Util; 
     30using Eraser.Plugins; 
     31using Eraser.Plugins.ExtensionPoints; 
    2832 
    2933namespace Eraser.Manager 
    3034{ 
    31     /// <summary> 
    32     /// An interface class representing the method for erasure. If classes only 
    33     /// inherit this class, then the method can only be used to erase abstract 
    34     /// streams, not unused drive space. 
    35     /// </summary> 
    36     public abstract class ErasureMethod : IRegisterable 
    37     { 
    38         public override string ToString() 
    39         { 
    40             if (Passes == 0) 
    41                 return Name; 
    42             return Passes == 1 ? S._("{0} (1 pass)", Name) : 
    43                 S._("{0} ({1} passes)", Name, Passes); 
    44         } 
    45  
    46         /// <summary> 
    47         /// The name of this erase pass, used for display in the UI 
    48         /// </summary> 
    49         public abstract string Name 
    50         { 
    51             get; 
    52         } 
    53  
    54         /// <summary> 
    55         /// The number of erase passes for this erasure method. 
    56         /// </summary> 
    57         public abstract int Passes 
    58         { 
    59             get; 
    60         } 
    61  
    62         /// <summary> 
    63         /// The GUID for this erasure method. 
    64         /// </summary> 
    65         public abstract Guid Guid 
    66         { 
    67             get; 
    68         } 
    69  
    70         /// <summary> 
    71         /// Calculates the total size of the erasure data that needs to be written. 
    72         /// This is mainly for use by the Manager to determine how much data needs 
    73         /// to be written to disk. 
    74         /// </summary> 
    75         /// <param name="paths">The list containing the file paths to erase. This 
    76         /// may be null if the list of paths are unknown.</param> 
    77         /// <param name="targetSize">The precomputed value of the total size of 
    78         /// the files to be erased.</param> 
    79         /// <returns>The total size of the files that need to be erased.</returns> 
    80         /// <remarks>This function MAY be slow. Most erasure methods can 
    81         /// calculate this amount fairly quickly as the number of files and the 
    82         /// total size of the files (the ones that take most computation time) 
    83         /// are already provided. However some exceptional cases may take a 
    84         /// long time if the data set is large.</remarks> 
    85         public abstract long CalculateEraseDataSize(ICollection<StreamInfo> paths, long targetSize); 
    86  
    87         /// <summary> 
    88         /// The main bit of the class! This function is called whenever data has 
    89         /// to be erased. Erase the stream passed in, using the given PRNG for 
    90         /// randomness where necessary. 
    91         ///  
    92         /// This function should be implemented thread-safe as using the same 
    93         /// instance, this function may be called across different threads. 
    94         /// </summary> 
    95         /// <param name="stream">The stream which needs to be erased.</param> 
    96         /// <param name="erasureLength">The length of the stream to erase. If all 
    97         /// data in the stream should be overwritten, then pass in the maximum 
    98         /// value for long, the function will take the minimum.</param> 
    99         /// <param name="prng">The PRNG source for random data.</param> 
    100         /// <param name="callback">The progress callback function.</param> 
    101         public abstract void Erase(Stream stream, long erasureLength, Prng prng, 
    102             ErasureMethodProgressFunction callback); 
    103  
    104         /// <summary> 
    105         /// Disk operation write unit. Chosen such that this value mod 3, 4, 512, 
    106         /// and 1024 is 0 
    107         /// </summary> 
    108         public const int DiskOperationUnit = 1536 * 4096; 
    109  
    110         /// <summary> 
    111         /// Unused space erasure file size. Each of the files used in erasing 
    112         /// unused space will be of this size. 
    113         /// </summary> 
    114         public const int FreeSpaceFileUnit = DiskOperationUnit * 36; 
    115  
    116         /// <summary> 
    117         /// Shuffles the passes in the input array, effectively randomizing the 
    118         /// order or rewrites. 
    119         /// </summary> 
    120         /// <param name="passes">The input set of passes.</param> 
    121         /// <returns>The shuffled set of passes.</returns> 
    122         protected static ErasureMethodPass[] ShufflePasses(ErasureMethodPass[] passes) 
    123         { 
    124             //Make a copy. 
    125             ErasureMethodPass[] result = new ErasureMethodPass[passes.Length]; 
    126             passes.CopyTo(result, 0); 
    127  
    128             //Randomize. 
    129             Prng rand = ManagerLibrary.Instance.PrngRegistrar[ManagerLibrary.Settings.ActivePrng]; 
    130             for (int i = 0; i < result.Length; ++i) 
    131             { 
    132                 int val = rand.Next(result.Length - 1); 
    133                 ErasureMethodPass tmpPass = result[val]; 
    134                 result[val] = result[i]; 
    135                 result[i] = tmpPass; 
    136             } 
    137  
    138             return result; 
    139         } 
    140  
    141         /// <summary> 
    142         /// Helper function. This function will write random data to the stream 
    143         /// using the provided PRNG. 
    144         /// </summary> 
    145         /// <param name="strm">The buffer to populate with data to write to disk.</param> 
    146         /// <param name="prng">The PRNG used.</param> 
    147         public static void WriteRandom(byte[] buffer, object value) 
    148         { 
    149             ((Prng)value).NextBytes(buffer); 
    150         } 
    151  
    152         /// <summary> 
    153         /// Helper function. This function will write the repeating pass constant. 
    154         /// to the provided buffer. 
    155         /// </summary> 
    156         /// <param name="strm">The buffer to populate with data to write to disk.</param> 
    157         /// <param name="value">The byte[] to write.</param> 
    158         public static void WriteConstant(byte[] buffer, object value) 
    159         { 
    160             byte[] constant = (byte[])value; 
    161             for (int i = 0; i < buffer.Length; ++i) 
    162                 buffer[i] = constant[i % constant.Length]; 
    163         } 
    164     } 
    165  
    166     /// <summary> 
    167     /// A simple callback for clients to retrieve progress information from 
    168     /// the erase method. 
    169     /// </summary> 
    170     /// <param name="lastWritten">The amount of data written to the stream since 
    171     /// the last call to the delegate.</param> 
    172     /// <param name="totalData">The total amount of data that must be written to 
    173     /// complete the erasure.</param> 
    174     /// <param name="currentPass">The current pass number. The total number 
    175     /// of passes can be found from the Passes property.</param> 
    176     public delegate void ErasureMethodProgressFunction(long lastWritten, long totalData, 
    177         int currentPass); 
    178  
    179     /// <summary> 
    180     /// A pass object. This object holds both the pass function, as well as the 
    181     /// data used for the pass (random, byte, or triplet) 
    182     /// </summary> 
    183     public class ErasureMethodPass 
    184     { 
    185         public override string ToString() 
    186         { 
    187             return OpaqueValue == null ? S._("Random") : OpaqueValue.ToString(); 
    188         } 
    189  
    190         /// <summary> 
    191         /// Constructor. 
    192         /// </summary> 
    193         /// <param name="function">The delegate to the function.</param> 
    194         /// <param name="opaqueValue">The opaque value passed to the function.</param> 
    195         public ErasureMethodPass(ErasureMethodPassFunction function, object opaqueValue) 
    196         { 
    197             Function = function; 
    198             OpaqueValue = opaqueValue; 
    199         } 
    200  
    201         /// <summary> 
    202         /// Executes the pass. 
    203         /// </summary> 
    204         /// <param name="buffer">The buffer to populate with the data to write.</param> 
    205         /// <param name="prng">The PRNG used for random passes.</param> 
    206         public void Execute(byte[] buffer, Prng prng) 
    207         { 
    208             Function(buffer, OpaqueValue == null ? prng : OpaqueValue); 
    209         } 
    210  
    211         /// <summary> 
    212         /// The function to execute for this pass. 
    213         /// </summary> 
    214         public ErasureMethodPassFunction Function { get; set; } 
    215  
    216         /// <summary> 
    217         /// The value to be passed to the executing function. 
    218         /// </summary> 
    219         public object OpaqueValue { get; set; } 
    220     } 
    221  
    222     /// <summary> 
    223     /// The prototype of a pass. 
    224     /// </summary> 
    225     /// <param name="strm">The buffer to populate with data to write to disk.</param> 
    226     /// <param name="opaque">An opaque value, depending on the type of callback.</param> 
    227     public delegate void ErasureMethodPassFunction(byte[] buffer, object opaque); 
    228  
    229     /// <summary> 
    230     /// This class adds functionality to the ErasureMethod class to erase 
    231     /// unused drive space. 
    232     /// </summary> 
    233     public abstract class UnusedSpaceErasureMethod : ErasureMethod 
    234     { 
    235         /// <summary> 
    236         /// This function will allow clients to erase a file in a set of files 
    237         /// used to fill the disk, thus achieving disk unused space erasure. 
    238         ///  
    239         /// By default, this function will simply call the Erase method inherited 
    240         /// from the ErasureMethod class. 
    241         ///  
    242         /// This function should be implemented thread-safe as using the same 
    243         /// instance, this function may be called across different threads. 
    244         /// </summary> 
    245         /// <param name="strm">The stream which needs to be erased.</param> 
    246         /// <param name="prng">The PRNG source for random data.</param> 
    247         /// <param name="callback">The progress callback function.</param> 
    248         public virtual void EraseUnusedSpace(Stream stream, Prng prng, ErasureMethodProgressFunction callback) 
    249         { 
    250             Erase(stream, long.MaxValue, prng, callback); 
    251         } 
    252     } 
    253  
    254     /// <summary> 
    255     /// Pass-based erasure method. This subclass of erasure methods follow a fixed 
    256     /// pattern (constant or random data) for every pass, although the order of 
    257     /// passes can be randomized. This is to simplify definitions of classes in 
    258     /// plugins. 
    259     ///  
    260     /// Since instances of this class apply data by passes, they can by default 
    261     /// erase unused drive space as well. 
    262     /// </summary> 
    263     public abstract class PassBasedErasureMethod : UnusedSpaceErasureMethod 
    264     { 
    265         public override int Passes 
    266         { 
    267             get { return PassesSet.Length; } 
    268         } 
    269  
    270         /// <summary> 
    271         /// Whether the passes should be randomized before running them in random 
    272         /// order. 
    273         /// </summary> 
    274         protected abstract bool RandomizePasses 
    275         { 
    276             get; 
    277         } 
    278  
    279         /// <summary> 
    280         /// The set of Pass objects describing the passes in this erasure method. 
    281         /// </summary> 
    282         protected abstract ErasureMethodPass[] PassesSet 
    283         { 
    284             get; 
    285         } 
    286  
    287         public override long CalculateEraseDataSize(ICollection<StreamInfo> paths, long targetSize) 
    288         { 
    289             //Simple. Amount of data multiplied by passes. 
    290             return targetSize * Passes; 
    291         } 
    292  
    293         public override void Erase(Stream stream, long erasureLength, Prng prng, 
    294             ErasureMethodProgressFunction callback) 
    295         { 
    296             //Randomize the order of the passes 
    297             ErasureMethodPass[] randomizedPasses = PassesSet; 
    298             if (RandomizePasses) 
    299                 randomizedPasses = ShufflePasses(randomizedPasses); 
    300  
    301             //Remember the starting position of the stream. 
    302             long strmStart = stream.Position; 
    303             long strmLength = Math.Min(stream.Length - strmStart, erasureLength); 
    304             long totalData = CalculateEraseDataSize(null, strmLength); 
    305  
    306             //Allocate memory for a buffer holding data for the pass. 
    307             byte[] buffer = new byte[Math.Min(DiskOperationUnit, strmLength)]; 
    308  
    309             //Run every pass! 
    310             for (int pass = 0; pass < Passes; ++pass) 
    311             { 
    312                 //Do a progress callback first. 
    313                 if (callback != null) 
    314                     callback(0, totalData, pass + 1); 
    315  
    316                 //Start from the beginning again 
    317                 stream.Seek(strmStart, SeekOrigin.Begin); 
    318  
    319                 //Write the buffer to disk. 
    320                 long toWrite = strmLength; 
    321                 int dataStopped = buffer.Length; 
    322                 while (toWrite > 0) 
    323                 { 
    324                     //Calculate how much of the buffer to write to disk. 
    325                     int amount = (int)Math.Min(toWrite, buffer.Length - dataStopped); 
    326  
    327                     //If we have no data left, get more! 
    328                     if (amount == 0) 
    329                     { 
    330                         randomizedPasses[pass].Execute(buffer, prng); 
    331                         dataStopped = 0; 
    332                         continue; 
    333                     } 
    334  
    335                     //Write the data. 
    336                     stream.Write(buffer, dataStopped, amount); 
    337                     stream.Flush(); 
    338                     toWrite -= amount; 
    339  
    340                     //Do a progress callback. 
    341                     if (callback != null) 
    342                         callback(amount, totalData, pass + 1); 
    343                 } 
    344             } 
    345         } 
    346     } 
    347  
    34835    /// <summary> 
    34936    /// Class managing all the erasure methods. This class pairs GUIDs with constructor 
     
    38370 
    38471            public override void Erase(Stream strm, long erasureLength, Prng prng, 
    385                 ErasureMethodProgressFunction callback) 
     72                ErasureMethod.ErasureMethodProgressFunction callback) 
    38673            { 
    38774                throw new InvalidOperationException("The DefaultMethod class should never " + 
Note: See TracChangeset for help on using the changeset viewer.