Skip to content

Commit

Permalink
implement loads
Browse files Browse the repository at this point in the history
  • Loading branch information
hbons committed Sep 7, 2011
1 parent dacfe39 commit 1948e58
Show file tree
Hide file tree
Showing 14 changed files with 738 additions and 210 deletions.
124 changes: 56 additions & 68 deletions Chunker.cs
Expand Up @@ -21,111 +21,99 @@

namespace Rainbows {


// Also turns chunk objects into a file.
//
public class Chunker {

public string OutputDirectory;

public delegate void ChunkCreatedHandler (string chunk_file_path, int chunk_size, string chunk_hash);
public event ChunkCreatedHandler ChunkCreated;

public delegate void ChunkingFinishedHandler (string [] chunk_paths);
public event ChunkingFinishedHandler ChunkingFinished;
public Crypto ChunkCrypto;

private Cryptographer cryptographer;
public delegate string NameChunkDelegate (string chunk_file_name);
public NameChunkDelegate NameChunk = delegate (string chunk_file_name) {
return null;
};


public Chunker (string output_directory)
{
this.cryptographer = null;
this.Init (output_directory);
}


public Chunker (string output_directory, Cryptographer cryptographer)
{
this.cryptographer = cryptographer;
this.Init (output_directory);
}


private void Init (string output_directory)
{
OutputDirectory = Path.Combine (output_directory, "objects");
OutputDirectory = output_directory;

if (!Directory.Exists (OutputDirectory))
Directory.CreateDirectory (OutputDirectory);
}


public void FileToChunks (string [] source_file_paths)
// Turns files into chunk objects and stores them in the database.
public string FileToChunks (string source_file_path, int chunk_size)
{
int chunk_size = 1024 * 1024 * 4;
List <string> chunk_paths = new List<string> ();

// TODO: threadpool and block
foreach (string source_file_path in source_file_paths) {

using (FileStream stream = File.OpenRead (source_file_path))
{
stream.Lock (0, stream.Length);
List<string> new_chunk_paths = new List<string> ();

try {
int current_chunk_size = 0;
var buffer = new byte [chunk_size];
int chunk_number = 1;
using (FileStream stream = File.OpenRead (source_file_path))
{
stream.Lock (0, stream.Length);
List<string> new_chunk_paths = new List<string> ();

while ((current_chunk_size = stream.Read (buffer, 0, buffer.Length)) > 0)
{
string hash = Cryptographer.SHA1 (buffer);
string chunk_file_name = hash.Substring (2);
string chunk_container = hash.Substring (0, 2);
string chunk_container_path = Path.Combine (OutputDirectory, chunk_container);
string chunk_file_path = Path.Combine (chunk_container_path, chunk_file_name);
try {
int current_chunk_size = 0;
byte[] buffer = new byte [chunk_size];
int chunk_number = 1;

// TODO: Calculate SHA1 hash of the full file here too
while ((current_chunk_size = stream.Read (buffer, 0, buffer.Length)) > 0)
{
string hash = Utils.SHA1 (buffer);
string chunk_file_path = NameChunk (hash);

if (!File.Exists (chunk_file_path)) {
if (!Directory.Exists (chunk_container_path))
Directory.CreateDirectory (chunk_container_path);
if (chunk_file_path == null)
chunk_file_path = Path.Combine (OutputDirectory, hash);

if (this.cryptographer != null) {
byte [] crypto_buffer = this.cryptographer.Encrypt (buffer);
File.WriteAllBytes (chunk_file_path, crypto_buffer);
string chunk_container_path = Path.GetDirectoryName (chunk_file_path);

} else {
File.WriteAllBytes (chunk_file_path, buffer);
new_chunk_paths.Add (chunk_file_path);
}

chunk_paths.Add (chunk_file_path);
// TODO: Calculate SHA1 hash of the full file here too

if (ChunkCreated != null) // TODO: return full file hash too
ChunkCreated (chunk_file_path, current_chunk_size, hash);
if (!File.Exists (chunk_file_path)) {
if (!Directory.Exists (chunk_container_path))
Directory.CreateDirectory (chunk_container_path);

Console.WriteLine ("Chunk " + hash + " created");
if (ChunkCrypto != null) {
byte [] crypto_buffer = ChunkCrypto.Encrypt (buffer);
File.WriteAllBytes (chunk_file_path, crypto_buffer);

} else {
Console.WriteLine ("Chunk " + hash + " exists");
File.WriteAllBytes (chunk_file_path, buffer);
new_chunk_paths.Add (chunk_file_path);
}

chunk_number++;
}
chunk_paths.Add (chunk_file_path);

if (ChunkCreated != null) // TODO: return full file hash too
ChunkCreated (chunk_file_path, current_chunk_size, hash);

Console.WriteLine ("Chunk " + hash + " created");

} catch (IOException) {
foreach (string new_chunk_path in new_chunk_paths) {
if (File.Exists (new_chunk_path))
File.Delete (new_chunk_path); // TODO: what to do with ongoing transfers?
} else {
Console.WriteLine ("Chunk " + hash + " exists");
}

} finally {
stream.Unlock (0, stream.Length);
chunk_number++;
}

} catch (IOException) {
foreach (string new_chunk_path in new_chunk_paths) {
if (File.Exists (new_chunk_path))
File.Delete (new_chunk_path); // TODO: what to do with ongoing transfers?
}

} finally {
stream.Unlock (0, stream.Length);
return ""; // Full hash
}
}

if (ChunkingFinished != null)
ChunkingFinished (chunk_paths.ToArray ());
}


Expand All @@ -139,8 +127,8 @@ public void ChunksToFile (string [] chunk_file_paths, string target_file_path)
foreach (string chunk_path in chunk_file_paths) {
buffer = File.ReadAllBytes (chunk_path);

if (this.cryptographer != null)
buffer = this.cryptographer.Decrypt (buffer);
if (ChunkCrypto != null)
buffer = ChunkCrypto.Decrypt (buffer);

stream.Write (buffer, 0, buffer.Length);
}
Expand Down
44 changes: 44 additions & 0 deletions ConnectionData.cs
@@ -0,0 +1,44 @@
// Rainbows, an experimental backend for SparkleShare
// Copyright (C) 2011 Hylke Bons <hylkebons@gmail.com>
//
// 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 3 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, see <http://www.gnu.org/licenses/>.


using System;
using System.IO;

namespace Rainbows {

public class ConnectionData : Uri {

public readonly string PrivateKey;
public readonly string User;
public readonly string Password;


public ConnectionData (Uri uri, string key_path) : base (uri.ToString ())
{
StreamReader reader = new StreamReader (key_path);
PrivateKey = reader.ReadToEnd ();

if (UserInfo.Contains (":")) {
Password = UserInfo.Substring (UserInfo.IndexOf (":"));
User = UserInfo.Substring (0, UserInfo.IndexOf (":"));

} else {
User = UserInfo;
}
}
}
}
13 changes: 2 additions & 11 deletions Cryptographer.cs → Crypto.cs
Expand Up @@ -21,7 +21,7 @@

namespace Rainbows {

public class Cryptographer {
public class Crypto {

private RijndaelManaged aes = new RijndaelManaged () {
KeySize = 256,
Expand All @@ -31,7 +31,7 @@ public class Cryptographer {
};


public Cryptographer (string password)
public Crypto (string password)
{
this.aes.IV = Convert.FromBase64String (password);
this.aes.Key = Convert.FromBase64String (password);
Expand All @@ -50,14 +50,5 @@ public Cryptographer (string password)
ICryptoTransform crypto = this.aes.CreateDecryptor ();
return crypto.TransformFinalBlock (buffer, 0, buffer.Length);
}


// Creates a SHA-1 hash of input
public static string SHA1 (byte [] buffer)
{
SHA1 sha1 = new SHA1CryptoServiceProvider ();
byte [] encoded_bytes = sha1.ComputeHash (buffer);
return BitConverter.ToString (encoded_bytes).ToLower ().Replace ("-", "");
}
}
}
38 changes: 38 additions & 0 deletions Exceptions.cs
@@ -0,0 +1,38 @@
// Rainbows, an experimental backend for SparkleShare
// Copyright (C) 2011 Hylke Bons <hylkebons@gmail.com>
//
// 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 3 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, see <http://www.gnu.org/licenses/>.


using System;

namespace Rainbows {

[Serializable]
public class TransferManagerException : Exception {

public TransferManagerException (string message) : base (message)
{
}
}


[Serializable]
public class TransferPluginException : Exception {

public TransferPluginException (string message) : base (message)
{
}
}
}

0 comments on commit 1948e58

Please sign in to comment.