コード例 #1
0
 /// <summary>
 /// Tries to find a chunk in the chunk list which covers the given <paramref name="start"/> position.
 /// </summary>
 /// <param name="start">Start position.</param>
 /// <param name="addChunkIfNotExists">If set to <c>true</c>, the requested chunk will be added to the cache if it doesn't exist yet.</param>
 /// <param name="result">Returns the chunk or <c>null</c>, if no chunk was found for the given <paramref name="start"/> position.
 /// The returned chunk might not be filled yet.</param>
 /// <returns><c>true</c> if chunk was found.</returns>
 protected bool GetMatchingChunk(long start, bool addChunkIfNotExists, out HttpRangeChunk result)
 {
     if (start >= 0 && start < _length)
     {
         for (int i = _chunkCache.Count - 1; i >= 0; i--)
         {
             HttpRangeChunk chunk = _chunkCache[i];
             if (chunk.StartIndex <= start && chunk.EndIndex > start)
             {
                 // Reorder LRU cache
                 _chunkCache.RemoveAt(i);
                 if (chunk.IsErroneous)
                 {
                     // Retry if a chunk was erroneous
                     break;
                 }
                 _chunkCache.Add(chunk);
                 result = chunk;
                 return(true);
             }
         }
         if (addChunkIfNotExists)
         {
             AddChunk(start, out result);
             return(true);
         }
     }
     result = null;
     return(false);
 }
コード例 #2
0
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException();
            }
            if (offset + count > buffer.Length)
            {
                throw new ArgumentException();
            }
            if (offset < 0 || count < 0)
            {
                throw new ArgumentOutOfRangeException();
            }
            if (_chunkCache == null)
            {
                throw new ObjectDisposedException("CachedMultiSegmentHttpStream");
            }
            if (_position >= _length)
            {
                return(0);
            }
            HttpRangeChunk chunk = ProvideReadAhead(_position, NUM_READAHEAD_CHUNKS);

            if (chunk == null)
            {
                throw new IOException();
            }

            int numRead = chunk.Read(_position, buffer, offset, count);

            _position += numRead;
            return(numRead);
        }
コード例 #3
0
 /// <summary>
 /// Adds a new chunk to the cache and returns it.
 /// </summary>
 /// <param name="start">Start position.</param>
 /// <param name="chunk">Returns the cache.</param>
 /// <returns><c>true</c> if successful.</returns>
 private void AddChunk(long start, out HttpRangeChunk chunk)
 {
     if (_chunkCache.Count == MAX_NUM_CACHES)
     {
         // Remove chunk which hasn't been used the longest time
         _chunkCache[0].Dispose();
         _chunkCache.RemoveAt(0);
     }
     _chunkCache.Add(chunk = new HttpRangeChunk(start, start + CHUNK_SIZE, Length, _url, _localIpAddress));
 }
コード例 #4
0
        protected HttpRangeChunk ProvideReadAhead(long position, int numReadaheadChunks)
        {
            HttpRangeChunk result;

            if (!GetMatchingChunk(position, true, out result))
            {
                return(null);
            }
            HttpRangeChunk currentChunk = result;

            for (int i = numReadaheadChunks - 1; i > 0; i--)
            {
                if (!GetMatchingChunk(currentChunk.EndIndex, true, out currentChunk))
                {
                    break;
                }
            }
            return(result);
        }
コード例 #5
0
 /// <summary>
 /// Adds a new chunk to the cache and returns it.
 /// </summary>
 /// <param name="start">Start position.</param>
 /// <param name="chunk">Returns the cache.</param>
 /// <returns><c>true</c> if successful.</returns>
 private void AddChunk(long start, out HttpRangeChunk chunk)
 {
   if (_chunkCache.Count == MAX_NUM_CACHES)
   {
     // Remove chunk which hasn't been used the longest time
     _chunkCache[0].Dispose();
     _chunkCache.RemoveAt(0);
   }
   _chunkCache.Add(chunk = new HttpRangeChunk(start, start + CHUNK_SIZE, Length, _url, _localIpAddress));
 }
コード例 #6
0
 /// <summary>
 /// Tries to find a chunk in the chunk list which covers the given <paramref name="start"/> position.
 /// </summary>
 /// <param name="start">Start position.</param>
 /// <param name="addChunkIfNotExists">If set to <c>true</c>, the requested chunk will be added to the cache if it doesn't exist yet.</param>
 /// <param name="result">Returns the chunk or <c>null</c>, if no chunk was found for the given <paramref name="start"/> position.
 /// The returned chunk might not be filled yet.</param>
 /// <returns><c>true</c> if chunk was found.</returns>
 protected bool GetMatchingChunk(long start, bool addChunkIfNotExists, out HttpRangeChunk result)
 {
   if (start >= 0 && start < _length)
   {
     for (int i = _chunkCache.Count - 1; i >= 0; i--)
     {
       HttpRangeChunk chunk = _chunkCache[i];
       if (chunk.StartIndex <= start && chunk.EndIndex > start)
       {
         // Reorder LRU cache
         _chunkCache.RemoveAt(i);
         if (chunk.IsErroneous)
             // Retry if a chunk was erroneous
           break;
         _chunkCache.Add(chunk);
         result = chunk;
         return true;
       }
     }
     if (addChunkIfNotExists)
     {
       AddChunk(start, out result);
       return true;
     }
   }
   result = null;
   return false;
 }