Exemplo n.º 1
0
        public override void Write(byte[] buffer, int offset, int count)
        {
            //If there is no way to write or nothing to write then do nothing.
            if (IsDisposed || count <= 0)
            {
                return;
            }

            //Keep a counter for how much we can copy or move.
            long len;

            //If the buffer is null or empty return for now (dead space)...
            if (ArrayExtensions.IsNullOrEmpty(buffer, out len))
            {
                return;
            }

            //If more data was specified than exists use len
            if (count > len)
            {
                count = (int)len;
            }

            //While there is count and the position is less than the end
            while (count > 0)
            {
                //How much can be copied to the current segment with respect to count.
                len = Binary.Binary.Min(WorkingSegment.m_Length - m_Cursor, count);

                //Copy len from the buffer at the offset to the working segment's array at the offset + the cursor
                Array.Copy(buffer, offset, WorkingSegment.m_Array, WorkingSegment.m_Offset + m_Cursor, len);

                //Move the cursor
                m_Cursor += len;

                //Move the position
                m_Position += len;

                //Move the offset
                offset += (int)len;

                //Adjust count for len copied.
                //If there is nothing left to do return.
                if (0 == (count -= (int)len))
                {
                    return;
                }

                //If at the end of the current segment and not at the end of the stream
                if (m_Cursor >= WorkingSegment.m_Length && m_Position < m_Count)
                {
                    //Advance the segment
                    WorkingSegment = Segments[++m_Index];

                    //Set the cursor to 0
                    m_Cursor = 0;

                    //Do another iteration
                    continue;
                }

                //m_Position is >= m_Count

                //Add a copy of the memory which remains and set the WorkingSegment (could give via out)
                WritePersisted(buffer, offset, count);

                //Get the next segment and account for the segment added
                WorkingSegment = Segments[++m_Index];

                //Set the cursor
                m_Cursor = count;

                //Move the position
                m_Position += count;

                //Increase for the bytes written.
                m_Count += count;

                //Set count to 0;
                //count -= count;

                //Done
                break;
            }
        }
Exemplo n.º 2
0
        public override long Seek(long offset, System.IO.SeekOrigin origin)
        {
            if (IsDisposed)
            {
                return(-1);
            }

            switch (origin)
            {
            case System.IO.SeekOrigin.Begin:
            {
                //Nothing to do?
                if (m_Position.Equals(offset))
                {
                    return(m_Position);
                }

                //If the offset past or at the end (Could goto End)
                if (offset >= m_Count)
                {
                    offset = Binary.Binary.LongZero;

                    goto case System.IO.SeekOrigin.End;
                }
                else if (offset <= 0)
                {
                    //Should use End style when offset < 0 but not == 0...

                    WorkingSegment = Segments[(m_Index = 0)];

                    return(m_Cursor = m_Position = Binary.Binary.LongZero);
                }


                //Check for data within the current segment
                if (offset < m_Position)
                {
                    //If at the first byte in a new segment go to the last segment
                    if (m_Cursor.Equals(Binary.Binary.LongZero))
                    {
                        WorkingSegment = Segments[--m_Index];

                        m_Cursor = WorkingSegment.m_Length;
                    }

                    ////Determine the amount of movement relative to the position
                    //long diff = m_Position - offset;

                    ////If the offset is within the current segment then there is no change of index
                    //if ((m_Cursor -= diff) >= 0)
                    //{
                    //    m_Cursor -= diff;

                    //    //return m_Position -= diff;

                    //    return m_Position = offset;
                    //}

                    //Combined for performance, if the data is not wihin the segment we search from the beginning anyway.

                    //This could be optomized by searching backward but current should handle that, this implies the locations will always be somewhere in the segment or at the beginning of the stream.

                    //If the offset is within the current segment then there is no change of index
                    if ((m_Cursor -= m_Position - offset) >= Binary.Binary.LongZero)
                    {
                        return(m_Position = offset);
                    }

                    //Seek forward from 0 to find the segment
                    m_Position = m_Index = 0;

                    WorkingSegment = Segments[m_Index];
                }
                else         //offset > m_Position
                {
                    //Determine the amount of movement relative to the position
                    long diff = offset - m_Position;

                    //If the offset is within the current segment then there is no change of index
                    if ((m_Cursor += diff) < WorkingSegment.m_Length)
                    {
                        return(m_Position = offset);
                    }

                    //The position must be moved to the end of the segment with respect to where the cursor was previously.
                    //Keep the same offset for a greater position
                    //Account for where we are already.

                    //The position is added to for the length of the remaining data in the WorkingSegment.
                    //The offset is modified to account for the position in the stream
                    offset -= (m_Position += WorkingSegment.m_Length - (m_Cursor - diff));

                    //Move to the next segment
                    WorkingSegment = Segments[++m_Index];

                    //Set the cursor to 0
                    m_Cursor = Binary.Binary.LongZero;
                }

                //Seek forward to find the offset.
                do
                {
                    m_Cursor = Binary.Binary.Min(ref WorkingSegment.m_Length, ref offset);

                    m_Position += m_Cursor;

                    offset -= m_Cursor;

                    if (m_Cursor >= WorkingSegment.m_Length)
                    {
                        WorkingSegment = Segments[++m_Index];

                        m_Cursor = Binary.Binary.LongZero;
                    }
                }while (offset > Binary.Binary.LongZero);

                return(m_Position);
            }

            case System.IO.SeekOrigin.Current:
            {
                //If there is no change in offset return the position
                if (offset.Equals(Binary.Binary.LongZero))
                {
                    return(m_Position);
                }

                //When offset < 0
                if (offset < Binary.Binary.LongZero)
                {
                    //Make the offset based on the position
                    offset += m_Position;

                    goto case System.IO.SeekOrigin.Begin;
                }

                return(m_Position);
            }

            case System.IO.SeekOrigin.End:
            {
                //If the offset is referring to a index <= 0 goto the 0th position
                if (-offset >= m_Count)
                {
                    //<= 0 offset mean 0 to begin.
                    goto case System.IO.SeekOrigin.Begin;

                    //////If the offset desired is within the working segment no index change is required.
                    ////if (m_Cursor > 0 && offset <= m_Cursor)
                    ////{
                    ////    m_Cursor -= offset;

                    ////    return m_Position -= offset;
                    ////}


                    //////Seek backward to find the segment.
                    ////do
                    ////{
                    ////    m_Cursor = Binary.Binary.Min(ref m_Cursor, ref offset);

                    ////    m_Position -= m_Cursor;

                    ////    offset -= m_Cursor;

                    ////    if (offset > 0)
                    ////    {
                    ////        WorkingSegment = Segments[--m_Index];

                    ////        m_Cursor = WorkingSegment.m_Length;
                    ////    }
                    ////}
                    ////while (offset > 0);
                }

                //Move to the end position
                WorkingSegment = Segments[(m_Index = Segments.Count - 1)];

                //Set the cursor
                m_Cursor = WorkingSegment.m_Length;

                //Set the position
                m_Position = m_Count;

                //If the given offset refers to any other position seek from the end
                if (offset < 0)
                {
                    goto case System.IO.SeekOrigin.Current;
                }

                //position is now equal to given offset >= 0 from the end.
                return(m_Position);
            }

            default: return(m_Position);
            }
            //x86 may benefit from break and return
            //return m_Position
        }
Exemplo n.º 3
0
 public void InsertPersistedMemory(int index, MemorySegment toInsert)
 {
     InsertPersistedMemory(ref index, toInsert);
 }