Пример #1
0
        public byte[] serialize()
        {
            Dictionary <string, byte[]> bldata = new Dictionary <string, byte[]>();

            // -"-v1"
            // RelativeFilePath = Encoding.UTF8.GetBytes(string)
            // BytePosition = BitConverter.GetBytes(int)
            // ByteLength = BitConverter.GetBytes(int)
            // -"-v2"
            // BlobType = BitConverter.GetBytes(int)
            // -v3
            // Required: breaks compatability
            // ReferenceCount = BitConverter.GetBytes(int)
            // -v4
            // Required
            // IsMultiBlockReference = BitConverter.GetBytes(bool)
            // -v5
            // Required
            // BSetReferenceCounts.BackupSets =
            // BSetReferenceCounts.ReferenceCounts =
            // -v6
            // BlobType removed
            // IsMultiBlockReference removed
            // -v7
            // IsMultiBlockReference readded
            // -v8
            // BlockHashes = enum_encode
            // -v9
            // EncryptedHash = bytes

            bldata.Add("EncryptedHash-v9", EncryptedHash == null ? new byte[0] : EncryptedHash);
            bldata.Add("RelativeFilePath-v1", Encoding.UTF8.GetBytes(RelativeFilePath));
            bldata.Add("ByteLength-v1", BitConverter.GetBytes(ByteLength));

            bldata.Add("BSetReferenceCounts.BackupSets-v5", BinaryEncoding.enum_encode(BSetReferenceCounts.Keys.Select(bsr => bsr.serialize())));
            bldata.Add("BSetReferenceCounts.ReferenceCounts-v5", BinaryEncoding.enum_encode(BSetReferenceCounts.Values.Select(rc => BitConverter.GetBytes(rc))));

            bldata.Add("IsMultiBlockReference-v7", BitConverter.GetBytes(BlockHashes != null));
            if (BlockHashes != null)
            {
                bldata.Add("BlockHashes-v8", BinaryEncoding.enum_encode(BlockHashes));
            }

            return(BinaryEncoding.dict_encode(bldata));
        }
Пример #2
0
        /// <summary>
        /// Store this node and its descendents in a blobstore
        /// Breaks with circular references, but these should only occur
        /// with hard- (and soft-?) -links TODO: handle links
        /// </summary>
        /// <param name="blobs"></param>
        /// <param name="storeGetHash">Function called to store node data, returns hash</param>
        /// <returns>The hash of the stored tree and a tree of its child hashes.</returns>
        public (byte[] nodehash, HashTreeNode node) Store(Func <byte[], byte[]> storeGetHash)
        {
            List <(byte[] nodehash, HashTreeNode?node)> children = new List <(byte[] nodehash, HashTreeNode?node)>();
            List <byte[]> dirhashes = new List <byte[]>();

            foreach (MetadataNode dir in Directories.Values)
            {
                var(newhash, newnode) = dir.Store(storeGetHash);
                dirhashes.Add(newhash);
                children.Add((newhash, newnode));
            }
            foreach (var fm in Files.Values.AsEnumerable())
            {
                if (fm.FileHash == null)
                {
                    throw new NullReferenceException("Stored filehashes cannot be null");
                }
                children.Add((fm.FileHash, null));
            }
            Dictionary <string, byte[]> mtdata = new Dictionary <string, byte[]>();

            // -"-v1"
            // DirMetadata = FileMetadata DirMetadata.serialize()
            // Directories = enum_encode([Directories.Values MetadataNode.serialize(),... ])
            // Files = enum_encode([Files.Values FileMetadata.serialize(),... ])
            // -"-v2"
            // Directories = enum_encode([dirrefs,...])
            // "-v3"
            // DirectoriesMultiblock = enum_encode([BitConverter.GetBytes(multiblock),...])
            // -v4
            // removed DirectoriesMultiblock
            mtdata.Add("DirMetadata-v1", DirMetadata.serialize());
            mtdata.Add("Files-v1", BinaryEncoding.enum_encode(Files.Values.AsEnumerable()
                                                              .Select(fm => fm.serialize())));

            mtdata.Add("Directories-v2", BinaryEncoding.enum_encode(dirhashes));

            byte[]       nodehash = storeGetHash(BinaryEncoding.dict_encode(mtdata));
            HashTreeNode node     = new HashTreeNode(children);

            return(nodehash, node);
        }