Commit before switching to sql compact
[pithos-ms-client] / trunk / Pithos.Network / TreeHash.cs
index 90e0e90..766400a 100644 (file)
-#region
-/* -----------------------------------------------------------------------
- * <copyright file="TreeHash.cs" company="GRNet">
- * 
- * Copyright 2011-2012 GRNET S.A. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or
- * without modification, are permitted provided that the following
- * conditions are met:
- *
- *   1. Redistributions of source code must retain the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above
- *      copyright notice, this list of conditions and the following
- *      disclaimer in the documentation and/or other materials
- *      provided with the distribution.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and
- * documentation are those of the authors and should not be
- * interpreted as representing official policies, either expressed
- * or implied, of GRNET S.A.
- * </copyright>
- * -----------------------------------------------------------------------
- */
-#endregion
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
-using System.IO;
-using System.Text;
-using System.Threading.Tasks;
-
-using System.Linq;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-
-namespace Pithos.Network
-{
-    public class TreeHash
-    {
-        private const string DEFAULT_HASH_ALGORITHM = "sha256";
-        private const long DEFAULT_BLOCK_SIZE = 4*1024*1024;
-        public string BlockHash { get; set; }
-        public long BlockSize { get; set; }
-        
-        private long _bytes;
-        public long Bytes
-        {
-            get
-            {
-                Contract.Ensures(Contract.Result<long>() >= 0);
-                return _bytes;
-            }
-            set
-            {
-                if (value<0)
-                    throw new ArgumentOutOfRangeException("Bytes");
-                Contract.Requires(value >= 0);
-                Contract.EndContractBlock();
-                
-                _bytes = value;
-            }
-        }
-        
-
-
-        public Guid FileId { get; set; }
-
-        private readonly Lazy<byte[]> _topHash;        
-        public byte[] TopHash
-        {
-            get { return _topHash.Value; }
-        }
-
-        private IList<byte[]> _hashes=new List<byte[]>();
-
-        public IList<byte[]> Hashes
-        {
-            get { return _hashes; }
-            set
-            {
-                _hashes = value;
-                _topHash.Force();
-            }
-        }
-
-        [ContractInvariantMethod]
-        private void Invariants()
-        {
-            Contract.Invariant(_bytes>=0);
-        }
-        
-
-       public TreeHash(string algorithm)
-        {
-            BlockHash = algorithm;            
-            _topHash = new Lazy<byte[]>(() =>
-            {
-                //
-                //Cast the hashes to an IList or create a new list out of the hashes
-                var hashMap = (_hashes as IList<byte[]>)??_hashes.ToList();
-                return Signature.CalculateTopHash(hashMap, BlockHash);
-            });
-        }
-
-        //Returns a Json representation of the hashes, as required by Pithos
-        public string ToJson()
-        {
-            var value = new JObject();
-            //We avoid using JObject's dynamic features because they use exceptions to detect new properties.
-            value["block_hash"] = BlockHash;
-            //Create a string array for all the hashes           
-            
-            string[] hashes=null ;
-            if (Hashes!=null)
-                hashes= GetHashesAsStrings();
-            value["hashes"]= new JArray(hashes);
-            value["block_size"] = BlockSize;
-            value["bytes"] = Bytes;
-            
-            var json = JsonConvert.SerializeObject(value, Formatting.None);
-            return json;
-        }
-
-        private string[] _stringHashes;
-        //Returns the hashes as an array of hash strings. Used for serialization to Json
-        public string[] GetHashesAsStrings()
-        {
-            return _stringHashes 
-                ?? (_stringHashes = Hashes.Select(hash => hash.ToHashString()).ToArray());
-        }
-
-        ConcurrentDictionary<string, long> _blocks;
-        //Retruns the hashes as a dictionary to the block location. Used to locate blocks
-        public IDictionary<string,long> HashDictionary
-        {
-            get
-            {
-                Func<ConcurrentDictionary<string, long>> blocksInit = () =>
-                {
-                    var blocks =
-                        new ConcurrentDictionary<string, long>();
-                    if (Hashes == null)
-                        return blocks;
-
-                    var blockIndex = 0;
-                    foreach (var hash in this.Hashes)
-                    {
-                        blocks[hash.ToHashString()] = blockIndex++;
-                    }
-                    return blocks;
-                };
-
-                return _blocks ?? (_blocks = blocksInit());
-            }
-        }
-
-        public string MD5 { get; set; }
-
-        //Saves the Json representation to a file
-        public async Task Save(string filePath)
-        {
-            if (String.IsNullOrWhiteSpace(filePath))
-                throw new ArgumentNullException("filePath");
-
-            var fileName = FileId.ToString("N");
-            var path = Path.Combine(filePath, fileName);
-            if (!Directory.Exists(filePath))
-                Directory.CreateDirectory(filePath);
-
-            var json = await TaskEx.Run(() => ToJson()).ConfigureAwait(false);
-            await FileAsync.WriteAllText(path, json).ConfigureAwait(false);
-        }
-
-        public static async Task<TreeHash> LoadTreeHash(string dataPath,Guid fileId)
-        {
-            var fileName = fileId.ToString("N");
-            var path = Path.Combine(dataPath, fileName);
-
-            var json = await FileAsync.ReadAllText(path).ConfigureAwait(false);
-            var treeHash = Parse(json);
-            treeHash.FileId = fileId;
-            return treeHash;
-        }
-
-        public static TreeHash Empty = new TreeHash(DEFAULT_HASH_ALGORITHM)
-        {
-            BlockSize = DEFAULT_BLOCK_SIZE,
-            Bytes = 0
-        };
-
-        //Parse a json string and return a TreeHash
-        //Returns an empty TreeHash if the string is null or empty
-        public static TreeHash Parse(string json)
-        {
-            if (String.IsNullOrWhiteSpace(json))
-                return Empty;            
-
-            var value = JsonConvert.DeserializeObject<JObject>(json);
-            if (value==null)
-                throw new ArgumentException("The json parameter doesn't contain any json data","json");
-            Contract.Assume(value!=null);
-
-            var blockHash = (string) value["block_hash"];
-            var size = value.Value<int>("block_size");
-            var bytes = value.Value<long>("bytes");
-            var hashes = value.Value<JArray>("hashes");
-            var hashValues = from JToken token in hashes
-                             select token.Value<string>().ToBytes();
-
-            var treeHash = new TreeHash(blockHash)
-                               {
-                                   BlockSize = size,
-                                   Hashes = hashValues.ToList(),
-                                   Bytes = bytes
-                               };
-            return treeHash;
-        }
-    }
+#region\r
+/* -----------------------------------------------------------------------\r
+ * <copyright file="TreeHash.cs" company="GRNet">\r
+ * \r
+ * Copyright 2011-2012 GRNET S.A. All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or\r
+ * without modification, are permitted provided that the following\r
+ * conditions are met:\r
+ *\r
+ *   1. Redistributions of source code must retain the above\r
+ *      copyright notice, this list of conditions and the following\r
+ *      disclaimer.\r
+ *\r
+ *   2. Redistributions in binary form must reproduce the above\r
+ *      copyright notice, this list of conditions and the following\r
+ *      disclaimer in the documentation and/or other materials\r
+ *      provided with the distribution.\r
+ *\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS\r
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR\r
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\r
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\r
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * The views and conclusions contained in the software and\r
+ * documentation are those of the authors and should not be\r
+ * interpreted as representing official policies, either expressed\r
+ * or implied, of GRNET S.A.\r
+ * </copyright>\r
+ * -----------------------------------------------------------------------\r
+ */\r
+#endregion\r
+using System;\r
+using System.Collections.Concurrent;\r
+using System.Collections.Generic;\r
+using System.Diagnostics.Contracts;\r
+using System.IO;\r
+using System.Text;\r
+using System.Threading.Tasks;\r
+\r
+using System.Linq;\r
+using Newtonsoft.Json;\r
+using Newtonsoft.Json.Linq;\r
+\r
+namespace Pithos.Network\r
+{\r
+    public class TreeHash\r
+    {\r
+        public const string DEFAULT_HASH_ALGORITHM = "sha256";\r
+        public const long DEFAULT_BLOCK_SIZE = 4*1024*1024;\r
+        public string BlockHash { get; set; }\r
+        public long BlockSize { get; set; }\r
+        \r
+        private long _bytes;\r
+        public long Bytes\r
+        {\r
+            get\r
+            {\r
+                Contract.Ensures(Contract.Result<long>() >= 0);\r
+                return _bytes;\r
+            }\r
+            set\r
+            {\r
+                if (value<0)\r
+                    throw new ArgumentOutOfRangeException("Bytes");\r
+                Contract.Requires(value >= 0);\r
+                Contract.EndContractBlock();\r
+                \r
+                _bytes = value;\r
+            }\r
+        }\r
+        \r
+\r
+\r
+        public Guid FileId { get; set; }\r
+\r
+        private readonly Lazy<byte[]> _topHash;        \r
+        public byte[] TopHash\r
+        {\r
+            get { return _topHash.Value; }\r
+        }\r
+\r
+        private IList<byte[]> _hashes=new List<byte[]>();\r
+\r
+        public IList<byte[]> Hashes\r
+        {\r
+            get { return _hashes; }\r
+            set\r
+            {\r
+                _hashes = value;\r
+                _topHash.Force();\r
+            }\r
+        }\r
+\r
+        [ContractInvariantMethod]\r
+        private void Invariants()\r
+        {\r
+            Contract.Invariant(_bytes>=0);\r
+        }\r
+        \r
+\r
+       public TreeHash(string algorithm)\r
+        {\r
+            BlockHash = algorithm;            \r
+            _topHash = new Lazy<byte[]>(() =>\r
+            {\r
+                //\r
+                //Cast the hashes to an IList or create a new list out of the hashes\r
+                var hashMap = (_hashes as IList<byte[]>)??_hashes.ToList();\r
+                return Signature.CalculateTopHash(hashMap, BlockHash);\r
+            });\r
+        }\r
+\r
+        //Returns a Json representation of the hashes, as required by Pithos\r
+        public string ToJson()\r
+        {\r
+            var value = new JObject();\r
+            //We avoid using JObject's dynamic features because they use exceptions to detect new properties.\r
+            value["block_hash"] = BlockHash;\r
+            //Create a string array for all the hashes           \r
+            \r
+            string[] hashes=null ;\r
+            if (Hashes!=null)\r
+                hashes= GetHashesAsStrings();\r
+            value["hashes"]= new JArray(hashes);\r
+            value["block_size"] = BlockSize;\r
+            value["bytes"] = Bytes;\r
+            \r
+            var json = JsonConvert.SerializeObject(value, Formatting.None);\r
+            return json;\r
+        }\r
+\r
+        private string[] _stringHashes;\r
+        //Returns the hashes as an array of hash strings. Used for serialization to Json\r
+        public string[] GetHashesAsStrings()\r
+        {\r
+            return _stringHashes \r
+                ?? (_stringHashes = Hashes.Select(hash => hash.ToHashString()).ToArray());\r
+        }\r
+\r
+        ConcurrentDictionary<string, long> _blocks;\r
+        \r
+        //Retruns the hashes as a dictionary to the block location. Used to locate blocks\r
+        public IDictionary<string,long> HashDictionary\r
+        {\r
+            get\r
+            {\r
+                Func<ConcurrentDictionary<string, long>> blocksInit = () =>\r
+                {\r
+                    var blocks =\r
+                        new ConcurrentDictionary<string, long>();\r
+                    if (Hashes == null)\r
+                        return blocks;\r
+\r
+                    var blockIndex = 0;\r
+                    foreach (var hash in this.Hashes)\r
+                    {\r
+                        blocks[hash.ToHashString()] = blockIndex++;\r
+                    }\r
+                    return blocks;\r
+                };\r
+\r
+                return _blocks ?? (_blocks = blocksInit());\r
+            }\r
+        }\r
+\r
+        private string _md5=Signature.MD5_EMPTY;\r
+        public string MD5\r
+        {\r
+            get { return _md5; }\r
+            set { _md5 = value; }\r
+        }\r
+\r
+        //Saves the Json representation to a file\r
+        public async Task Save(string filePath)\r
+        {\r
+            if (String.IsNullOrWhiteSpace(filePath))\r
+                throw new ArgumentNullException("filePath");\r
+\r
+            var fileName = FileId.ToString("N");\r
+            var path = Path.Combine(filePath, fileName);\r
+            if (!Directory.Exists(filePath))\r
+                Directory.CreateDirectory(filePath);\r
+\r
+            var json = await TaskEx.Run(() => ToJson()).ConfigureAwait(false);\r
+            await FileAsync.WriteAllText(path, json).ConfigureAwait(false);\r
+        }\r
+\r
+        public static async Task<TreeHash> LoadTreeHash(string dataPath,Guid fileId)\r
+        {\r
+            var fileName = fileId.ToString("N");\r
+            var path = Path.Combine(dataPath, fileName);\r
+\r
+            var json = await FileAsync.ReadAllText(path).ConfigureAwait(false);\r
+            var treeHash = Parse(json);\r
+            treeHash.FileId = fileId;\r
+            return treeHash;\r
+        }\r
+\r
+        public static TreeHash Empty = new TreeHash(DEFAULT_HASH_ALGORITHM)\r
+        {\r
+            BlockSize = DEFAULT_BLOCK_SIZE,\r
+            Bytes = 0\r
+        };\r
+\r
+        //Parse a json string and return a TreeHash\r
+        //Returns an empty TreeHash if the string is null or empty\r
+        public static TreeHash Parse(string json)\r
+        {\r
+            if (String.IsNullOrWhiteSpace(json))\r
+                return Empty;            \r
+\r
+            var value = JsonConvert.DeserializeObject<JObject>(json);\r
+            if (value==null)\r
+                throw new ArgumentException("The json parameter doesn't contain any json data","json");\r
+            Contract.Assume(value!=null);\r
+\r
+            var blockHash = (string) value["block_hash"];\r
+            var size = value.Value<int>("block_size");\r
+            var bytes = value.Value<long>("bytes");\r
+            var hashes = value.Value<JArray>("hashes");\r
+            var hashValues = from JToken token in hashes\r
+                             select token.Value<string>().ToBytes();\r
+\r
+            var treeHash = new TreeHash(blockHash)\r
+                               {\r
+                                   BlockSize = size,\r
+                                   Hashes = hashValues.ToList(),\r
+                                   Bytes = bytes\r
+                               };\r
+            return treeHash;\r
+        }\r
+    }\r
 }
\ No newline at end of file