Ejemplo n.º 1
0
        /// <summary>
        ///     获取内部的缓冲区内存
        ///     <para>* 使用此方法后总是会强制回收内部资源</para>
        /// </summary>
        /// <returns>返回缓冲区内存</returns>
        public byte[] GetBytes()
        {
            if (_segments.Count == 0)
            {
                return(null);
            }
            int totalSize = _segments.Count == 1
                                ? (int)_segments[0].Offset
                                : (int)_segments.Sum(segment => ThriftProtocolMemoryAllotter.SegmentSize - segment.RemainingSize);
            uint offset = 0;

            byte[] data = new byte[totalSize];
            for (int i = 0; i < _segments.Count; i++)
            {
                IMemorySegment segment = _segments[i];
                //un-usage segment.
                if (segment.Offset == 0)
                {
                    continue;
                }
                Marshal.Copy(new IntPtr(segment.GetPointer()), data, (int)offset, (int)segment.Offset);
                offset += segment.Offset;
                //always recover used resource.
                ThriftProtocolMemoryAllotter.Instance.Giveback(segment);
            }
            //recover resources.
            _currentIndex = 0;
            _segments     = null;
            return(data);
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     向指定内存段的指定偏移处回写一个void*
        /// </summary>
        /// <param name="position">回写位置</param>
        /// <param name="value">回写值</param>
        /// <param name="length">回写长度</param>
        public void WriteBackMemory(MemoryPosition position, void *value, uint length)
        {
            //well-done, needn't cross memory segments.
            if (MemoryAllotter.SegmentSize - position.SegmentOffset == 0)
            {
                position.SegmentIndex++;
                position.SegmentOffset = 0;
            }
            IMemorySegment segment           = GetSegment(position.SegmentIndex);
            int            startSegmentIndex = position.SegmentIndex;
            uint           remainingSize     = (MemoryAllotter.SegmentSize - position.SegmentOffset);

            if (remainingSize >= length)
            {
                Buffer.MemoryCopy((void *)new IntPtr(value), (void *)new IntPtr(_segments[position.SegmentIndex].GetPointer() + position.SegmentOffset), length /*protective range*/, length);
            }
            //Native.Win32API.memcpy(new IntPtr(_segments[position.SegmentIndex].GetPointer() + position.SegmentOffset), new IntPtr(value), length);
            else
            {
                uint trueRemainingSize = length;
                uint continueSize      = 0U;
                do
                {
                    Buffer.MemoryCopy(
                        (void *)new IntPtr((byte *)value + continueSize),
                        (void *)new IntPtr(segment.GetPointer() + (position.SegmentIndex - startSegmentIndex == 0 ? position.SegmentOffset : 0)),
                        MemoryAllotter.SegmentSize /*protective range*/,
                        (remainingSize < trueRemainingSize ? remainingSize : (trueRemainingSize < MemoryAllotter.SegmentSize ? trueRemainingSize : MemoryAllotter.SegmentSize)));
                    //Native.Win32API.memcpy(
                    //    new IntPtr(segment.GetPointer() +(position.SegmentIndex - startSegmentIndex == 0 ? position.SegmentOffset : 0)),
                    //    new IntPtr((byte*)value + continueSize),
                    //    (remainingSize < trueRemainingSize? remainingSize: (trueRemainingSize < MemoryAllotter.SegmentSize? trueRemainingSize: MemoryAllotter.SegmentSize)));
                    if (trueRemainingSize <= remainingSize)
                    {
                        trueRemainingSize = 0U;
                    }
                    else
                    {
                        trueRemainingSize -= remainingSize;
                    }
                    segment       = GetSegment(++position.SegmentIndex);
                    continueSize += remainingSize;
                    remainingSize = MemoryAllotter.SegmentSize;
                } while (trueRemainingSize > 0U);
            }
        }