Esempio n. 1
0
        /// <summary><inheritDoc/></summary>
        public virtual int Get(long position, byte[] bytes, int off, int len)
        {
            GroupedRandomAccessSource.SourceEntry entry = GetSourceEntryForOffset(position);
            // if true, we have run out of data to read from
            if (entry == null)
            {
                return(-1);
            }
            long offN      = entry.OffsetN(position);
            int  remaining = len;

            while (remaining > 0)
            {
                // if true, we have run out of data to read from
                if (entry == null)
                {
                    break;
                }
                if (offN > entry.source.Length())
                {
                    break;
                }
                int count = entry.source.Get(offN, bytes, off, remaining);
                if (count == -1)
                {
                    break;
                }
                off       += count;
                position  += count;
                remaining -= count;
                offN       = 0;
                entry      = GetSourceEntryForOffset(position);
            }
            return(remaining == len ? -1 : len - remaining);
        }
Esempio n. 2
0
        /// <summary>
        /// Returns the SourceEntry that contains the byte at the specified offset
        /// sourceReleased is called as a notification callback so subclasses can take care of cleanup
        /// when the source is no longer the active source
        /// </summary>
        /// <param name="offset">the offset of the byte to look for</param>
        /// <returns>the SourceEntry that contains the byte at the specified offset</returns>
        private GroupedRandomAccessSource.SourceEntry GetSourceEntryForOffset(long offset)
        {
            if (offset >= size)
            {
                return(null);
            }
            if (offset >= currentSourceEntry.firstByte && offset <= currentSourceEntry.lastByte)
            {
                return(currentSourceEntry);
            }
            // hook to allow subclasses to release resources if necessary
            SourceReleased(currentSourceEntry.source);
            int startAt = GetStartingSourceIndex(offset);

            for (int i = startAt; i < sources.Length; i++)
            {
                if (offset >= sources[i].firstByte && offset <= sources[i].lastByte)
                {
                    currentSourceEntry = sources[i];
                    SourceInUse(currentSourceEntry.source);
                    return(currentSourceEntry);
                }
            }
            return(null);
        }
Esempio n. 3
0
 // by default, do nothing
 /// <summary>
 /// <inheritDoc/>
 /// The source that contains the byte at position is retrieved, the correct offset into that source computed, then the value
 /// from that offset in the underlying source is returned.
 /// </summary>
 public virtual int Get(long position)
 {
     GroupedRandomAccessSource.SourceEntry entry = GetSourceEntryForOffset(position);
     // if true, we have run out of data to read from
     if (entry == null)
     {
         return(-1);
     }
     return(entry.source.Get(entry.OffsetN(position)));
 }
Esempio n. 4
0
        /// <summary>
        /// Constructs a new
        /// <see cref="GroupedRandomAccessSource"/>
        /// based on the specified set of sources
        /// </summary>
        /// <param name="sources">the sources used to build this group</param>
        public GroupedRandomAccessSource(IRandomAccessSource[] sources)
        {
            this.sources = new GroupedRandomAccessSource.SourceEntry[sources.Length];
            long totalSize = 0;

            for (int i = 0; i < sources.Length; i++)
            {
                this.sources[i] = new GroupedRandomAccessSource.SourceEntry(i, sources[i], totalSize);
                totalSize      += sources[i].Length();
            }
            size = totalSize;
            currentSourceEntry = this.sources[sources.Length - 1];
            SourceInUse(currentSourceEntry.source);
        }