Example #1
0
        /// <summary>
        /// Splits a stream into chunks using a <see cref="ChunkStream"/>, and wraps them into
        /// <see cref="StreamedDataBlock"/> instances that can be sent to an <see cref="IUploadTransferHandler"/>.
        /// This overload allows to resume a transfer and start with a given offset.
        /// <br/>This extension method also takes care of implicitly completing the upload by setting the
        /// <see cref="IDataBlock.IsLastBlock"/> property of the last block to true.
        /// </summary>
        /// <param name="sourceStream">The source stream that provides the data to be uploaded.</param>
        /// <param name="token">An upload token that defines the resource.</param>
        /// <param name="resourceLength">The total length of the submitted stream.</param>
        /// <param name="blockSize">The block size to be used. All blocks (except the last one) will have
        /// this size.</param>
        /// <param name="initialBlockNumber">The initial block number to be used.</param>
        /// <param name="offset">The offset of the first written block (0 to start at the beginning of the stream).</param>
        /// <param name="writerAction">An action that is being invoked for every created <see cref="StreamedDataBlock"/>
        /// instance.</param>
        /// <remarks>The position within the stream is only set according to the submitted
        /// <paramref name="offset"/> if the underlying <paramref name="sourceStream"/> supports seeking as indicated by
        /// its <see cref="Stream.CanSeek"/> property.</remarks>
        public static void WriteTo(this Stream sourceStream, UploadToken token, long resourceLength, int blockSize, long initialBlockNumber, long offset, Action <StreamedDataBlock> writerAction)
        {
            long remaining   = resourceLength;
            long position    = offset;
            long blockNumber = initialBlockNumber;

            while (remaining > 0)
            {
                //decorate the stream with a chunk stream that limits access to a block of data
                int         chunkSize = (int)Math.Min(remaining, blockSize);
                ChunkStream cs        = new ChunkStream(sourceStream, chunkSize, position, sourceStream.CanSeek);

                StreamedDataBlock dataBlock = new StreamedDataBlock
                {
                    TransferTokenId = token.TransferId,
                    BlockLength     = chunkSize,
                    BlockNumber     = blockNumber,
                    Data            = cs,
                    Offset          = position
                };

                //update position within stream and remaining bytes
                position  += chunkSize;
                remaining -= chunkSize;
                blockNumber++;

                if (remaining == 0)
                {
                    //implicitly complete the transfer by marking the last block
                    dataBlock.IsLastBlock = true;
                }

                writerAction(dataBlock);
            }
        }
    public void Init()
    {
      receivedBlocks = new List<BufferedDataBlock>();
      source = new byte[100000];
      target = new List<byte>();
      new Random(DateTime.Now.Millisecond).NextBytes(source);

      token = new UploadToken { TransferId = "MyToken", MaxBlockSize = 3000 };
    }
    public void Init()
    {
      receivedBlocks = new List<BufferedDataBlock>();
      source = new byte[100000];
      target = new List<byte>();
      new Random(DateTime.Now.Millisecond).NextBytes(source);

      //token indicates 10 blocks were already submitted
      token = new UploadToken { TransferId = "MyToken", MaxBlockSize = 3000, TransmittedBlockCount = 10};
    }
Example #4
0
    /// <summary>
    /// Initializes a new instance of the <see cref="T:System.IO.Stream"/> class. 
    /// </summary>
    /// <param name="autoFlushThreshold">A threshold that causes the stream to aumatically flush
    /// its internal buffer once it reaches the defined size.<br/>
    /// If the threshold is 0, every write is immediately flushed.</param>
    /// <param name="outputAction">An action that is being invoked with created
    /// <see cref="BufferedDataBlock"/> instances when flushing the internal buffer.</param>
    /// <exception cref="ArgumentNullException">If <paramref name="token"/> or <paramref name="outputAction"
    /// is a null reference.</exception>
    /// <exception cref="ArgumentOutOfRangeException">Inf case the <paramref name="autoFlushThreshold"/>
    /// is negative.</exception>
    public BufferedBlockOutputStream(UploadToken token, int autoFlushThreshold, Action<BufferedDataBlock> outputAction)
    {
      if (token == null) throw new ArgumentNullException("token");
      if (outputAction == null) throw new ArgumentNullException("outputAction");
      if(autoFlushThreshold < 0)
      {
        throw new ArgumentOutOfRangeException("autoFlushThreshold",
                                              "Threshold for automatic flushing cannot be negative");
      }

      Token = token;
      AutoFlushThreshold = autoFlushThreshold;
      OutputAction = outputAction;
      InitialOffset = token.NextBlockOffset;
    }
    /// <summary>
    /// Splits a stream into chunks using a <see cref="ChunkStream"/>, and wraps them into
    /// <see cref="StreamedDataBlock"/> instances that can be sent to an <see cref="IUploadTransferHandler"/>.
    /// This overload allows to resume a transfer and start with a given offset.
    /// <br/>This extension method also takes care of implicitly completing the upload by setting the
    /// <see cref="IDataBlock.IsLastBlock"/> property of the last block to true.
    /// </summary>
    /// <param name="sourceStream">The source stream that provides the data to be uploaded.</param>
    /// <param name="token">An upload token that defines the resource.</param>
    /// <param name="resourceLength">The total length of the submitted stream.</param>
    /// <param name="blockSize">The block size to be used. All blocks (except the last one) will have
    /// this size.</param>
    /// <param name="initialBlockNumber">The initial block number to be used.</param>
    /// <param name="offset">The offset of the first written block (0 to start at the beginning of the stream).</param>
    /// <param name="writerAction">An action that is being invoked for every created <see cref="StreamedDataBlock"/>
    /// instance.</param>
    /// <remarks>The position within the stream is only set according to the submitted
    /// <paramref name="offset"/> if the underlying <paramref name="sourceStream"/> supports seeking as indicated by
    /// its <see cref="Stream.CanSeek"/> property.</remarks>
    public static void WriteTo(this Stream sourceStream, UploadToken token, long resourceLength, int blockSize, long initialBlockNumber, long offset, Action<StreamedDataBlock> writerAction)
    {
      long remaining = resourceLength;
      long position = offset;
      long blockNumber = initialBlockNumber;

      while(remaining > 0)
      {
        //decorate the stream with a chunk stream that limits access to a block of data
        int chunkSize = (int)Math.Min(remaining, blockSize);
        ChunkStream cs = new ChunkStream(sourceStream, chunkSize, position, sourceStream.CanSeek);

        StreamedDataBlock dataBlock = new StreamedDataBlock
                                 {
                                   TransferTokenId = token.TransferId,
                                   BlockLength = chunkSize,
                                   BlockNumber = blockNumber,
                                   Data = cs,
                                   Offset = position
                                 };

        //update position within stream and remaining bytes
        position += chunkSize;
        remaining -= chunkSize;
        blockNumber++;

        if(remaining == 0)
        {
          //implicitly complete the transfer by marking the last block
          dataBlock.IsLastBlock = true;
        }

        writerAction(dataBlock);
      }
    }
 /// <summary>
 /// Splits a stream into chunks using a <see cref="ChunkStream"/>, and wraps them into
 /// <see cref="StreamedDataBlock"/> instances that can be sent to an <see cref="IUploadTransferHandler"/>.
 /// This overload writes the whole stream to the target. In order to resume a transfer and start in the
 /// middle of the stream, use the overload of this method that takes an initial block number and offset.
 /// <br/>This extension method also takes care of implicitly completing the upload by setting the
 /// <see cref="IDataBlock.IsLastBlock"/> property of the last block to true.
 /// </summary>
 /// <param name="sourceStream">The source stream that provides the data to be uploaded. It is assumed that
 /// the reading position within the stream has already been set.</param>
 /// <param name="token">An upload token that defines the resource.</param>
 /// <param name="resourceLength">The total length of the submitted stream.</param>
 /// <param name="blockSize">The block size to be used. All blocks (except the last one) will have
 /// this size.</param>
 /// <param name="writerAction">An action that is being invoked for every created <see cref="StreamedDataBlock"/>
 /// instance.</param>
 public static void WriteTo(this Stream sourceStream, UploadToken token, long resourceLength, int blockSize, Action<StreamedDataBlock> writerAction)
 {
   WriteTo(sourceStream, token, resourceLength, blockSize, 0, 0, writerAction);
 }
Example #7
0
 /// <summary>
 /// Splits a stream into chunks using a <see cref="ChunkStream"/>, and wraps them into
 /// <see cref="StreamedDataBlock"/> instances that can be sent to an <see cref="IUploadTransferHandler"/>.
 /// This overload writes the whole stream to the target. In order to resume a transfer and start in the
 /// middle of the stream, use the overload of this method that takes an initial block number and offset.
 /// <br/>This extension method also takes care of implicitly completing the upload by setting the
 /// <see cref="IDataBlock.IsLastBlock"/> property of the last block to true.
 /// </summary>
 /// <param name="sourceStream">The source stream that provides the data to be uploaded. It is assumed that
 /// the reading position within the stream has already been set.</param>
 /// <param name="token">An upload token that defines the resource.</param>
 /// <param name="resourceLength">The total length of the submitted stream.</param>
 /// <param name="blockSize">The block size to be used. All blocks (except the last one) will have
 /// this size.</param>
 /// <param name="writerAction">An action that is being invoked for every created <see cref="StreamedDataBlock"/>
 /// instance.</param>
 public static void WriteTo(this Stream sourceStream, UploadToken token, long resourceLength, int blockSize, Action <StreamedDataBlock> writerAction)
 {
     WriteTo(sourceStream, token, resourceLength, blockSize, 0, 0, writerAction);
 }
Example #8
0
 /// <summary>
 /// Gets a download token for the <see cref="TargetFile"/> and
 /// assigns it to the <see cref="Token"/> property.
 /// </summary>
 /// <returns>The retrieved token.</returns>
 protected UploadToken InitToken()
 {
   Token = Uploads.RequestUploadToken(TargetFilePath, false, SourceFile.Length, "binary");
   return Token;
 }