示例#1
0
        public async Task <Cid> PutAsync(JObject data,
                                         string contentType       = "dag-cbor",
                                         string multiHash         = MultiHash.DefaultAlgorithmName,
                                         string encoding          = MultiBase.DefaultAlgorithmName,
                                         bool pin                 = true,
                                         CancellationToken cancel = default)
        {
            await using (var ms = new MemoryStream())
                await using (var sw = new StreamWriter(ms))
                    using (var writer = new JsonTextWriter(sw))
                    {
                        await data.WriteToAsync(writer, cancel);

                        writer.Flush();
                        ms.Position = 0;
                        var format = GetDataFormat(contentType);
                        var block  = format.Serialize(CBORObject.ReadJSON(ms));
                        return(await _blockApi.PutAsync(block, contentType, multiHash, encoding, pin, cancel)
                               .ConfigureAwait(false));
                    }
        }
示例#2
0
        /// <summary>
        ///     Performs the chunking.
        /// </summary>
        /// <param name="stream">
        ///     The data source.
        /// </param>
        /// <param name="name">
        ///     A name for the data.
        /// </param>
        /// <param name="options">
        ///     The options when adding data to the IPFS file system.
        /// </param>
        /// <param name="blockService">
        ///     The destination for the chunked data block(s).
        /// </param>
        /// <param name="keyChain">
        ///     Used to protect the chunked data blocks(s).
        /// </param>
        /// <param name="cancel">
        ///     Is used to stop the task.  When cancelled, the <see cref="TaskCanceledException" /> is raised.
        /// </param>
        /// <returns>
        ///     A task that represents the asynchronous operation. The task's value is
        ///     the sequence of file system nodes of the added data blocks.
        /// </returns>
        public async Task <List <UnixFsNode> > ChunkAsync(Stream stream,
                                                          string name,
                                                          AddFileOptions options,
                                                          IBlockApi blockService,
                                                          IKeyApi keyChain,
                                                          CancellationToken cancel)
        {
            var protecting = !string.IsNullOrWhiteSpace(options.ProtectionKey);
            var nodes      = new List <UnixFsNode>();
            var chunkSize  = options.ChunkSize;
            var chunk      = new byte[chunkSize];
            var chunking   = true;
            var totalBytes = 0UL;

            while (chunking)
            {
                // Get an entire chunk.
                var length = 0;
                while (length < chunkSize)
                {
                    var n = await stream.ReadAsync(chunk, length, chunkSize - length, cancel).ConfigureAwait(false);

                    if (n < 1)
                    {
                        chunking = false;
                        break;
                    }

                    length     += n;
                    totalBytes += (uint)n;
                }

                //  Only generate empty block, when the stream is empty.
                if (length != 0 || nodes.Count <= 0)
                {
                    options.Progress?.Report(new TransferProgress
                    {
                        Name  = name,
                        Bytes = totalBytes
                    });

                    // if protected data, then get CMS structure.
                    if (protecting)
                    {
                        // TODO: Inefficent to copy chunk, use ArraySegment in DataMessage.Data
                        var plain = new byte[length];
                        Array.Copy(chunk, plain, length);
                        var cipher = await keyChain.CreateProtectedDataAsync(options.ProtectionKey, plain, cancel)
                                     .ConfigureAwait(false);

                        var cid = await blockService.PutAsync(
                            cipher,
                            "cms",
                            options.Hash,
                            options.Encoding,
                            options.Pin,
                            cancel).ConfigureAwait(false);

                        nodes.Add(new UnixFsNode
                        {
                            Id      = cid,
                            Size    = length,
                            DagSize = cipher.Length,
                            Links   = UnixFsLink.None
                        });
                    }
                    else if (options.RawLeaves)
                    {
                        // TODO: Inefficent to copy chunk, use ArraySegment in DataMessage.Data
                        var data = new byte[length];
                        Array.Copy(chunk, data, length);
                        var cid = await blockService.PutAsync(
                            data,
                            "raw",
                            options.Hash,
                            options.Encoding,
                            options.Pin,
                            cancel).ConfigureAwait(false);

                        nodes.Add(new UnixFsNode
                        {
                            Id      = cid,
                            Size    = length,
                            DagSize = length,
                            Links   = UnixFsLink.None
                        });
                    }
                    else
                    {
                        // Build the DAG.
                        var dm = new DataMessage
                        {
                            Type     = DataType.File,
                            FileSize = (ulong)length
                        };
                        if (length > 0)
                        {
                            // TODO: Inefficent to copy chunk, use ArraySegment in DataMessage.Data
                            var data = new byte[length];
                            Array.Copy(chunk, data, length);
                            dm.Data = data;
                        }

                        var pb = new MemoryStream();
                        Serializer.Serialize(pb, dm);
                        var dag = new DagNode(pb.ToArray(), null, options.Hash);

                        // Save it.
                        dag.Id = await blockService.PutAsync(
                            dag.ToArray(),
                            multiHash : options.Hash,
                            encoding : options.Encoding,
                            pin : options.Pin,
                            cancel : cancel).ConfigureAwait(false);

                        var node = new UnixFsNode
                        {
                            Id      = dag.Id,
                            Size    = length,
                            DagSize = dag.Size,
                            Links   = UnixFsLink.None
                        };
                        nodes.Add(node);
                    }
                }
            }

            return(nodes);
        }
示例#3
0
        public async Task <IDagNode> PutAsync(IDagNode node, CancellationToken cancel = default)
        {
            node.Id = await _blockApi.PutAsync(node.ToArray(), cancel : cancel).ConfigureAwait(false);

            return(node);
        }