zoukankan      html  css  js  c++  java
  • c# 指针的操作

    /// <summary>
        /// 指针的操作
        /// </summary>
        internal class PointerHelper
        {
            private byte* _pBuffer;
            private bool _disposed;
            private GCHandle _pinnedGCHandle;
            private bool _needToFreeGCHandle;
            private int _capacity;
    
            /// <summary>
            /// 
            /// </summary>
            public byte[] Data { get; private set; }
    
            /// <summary>
            /// Attach a view to a byte[] for providing direct access
            /// </summary>
            /// <param name="buffer">buffer to which the view is attached.</param>
            public PointerHelper(byte[] buffer)
            {
                if (buffer == null) throw new ArgumentNullException("buffer");
    
                this.Data = buffer;
    
                // pin the buffer so it does not get moved around by GC, this is required since we use pointers
                _pinnedGCHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
                _needToFreeGCHandle = true;
    
                _pBuffer = (byte*)_pinnedGCHandle.AddrOfPinnedObject().ToPointer();
                _capacity = buffer.Length;
            }
    
            /// <summary>
            /// Capacity of the underlying buffer
            /// </summary>
            public int Capacity
            {
                get { return _capacity; }
            }
    
            /// <summary>
            /// Gets the <see cref="byte"/> value at a given index.
            /// </summary>
            /// <param name="index">index in bytes from which to get.</param>
            /// <returns>the value at a given index.</returns>
            public char CharGet(int index)
            {
                return (char)*(_pBuffer + index);
            }
    
            /// <summary>
            /// Writes a <see cref="byte"/> value to a given index.
            /// </summary>
            /// <param name="index">index in bytes for where to put.</param>
            /// <param name="value">value to be written</param>
            public void CharPut(int index, char value)
            {
                *(_pBuffer + index) = (byte)value;
            }
    
            /// <summary>
            /// Gets the <see cref="sbyte"/> value at a given index.
            /// </summary>
            /// <param name="index"> index in bytes from which to get.</param>
            /// <returns>the value at a given index.</returns>
            public sbyte Int8Get(int index)
            {
                return *(sbyte*)(_pBuffer + index);
            }
    
            /// <summary>
            /// Writes a <see cref="sbyte"/> value to a given index.
            /// </summary>
            /// <param name="index">index in bytes for where to put.</param>
            /// <param name="value">value to be written</param>
            public void Int8Put(int index, sbyte value)
            {
                *(sbyte*)(_pBuffer + index) = value;
            }
    
            /// <summary>
            /// Gets the <see cref="byte"/> value at a given index.
            /// </summary>
            /// <param name="index"> index in bytes from which to get.</param>
            /// <returns>the value at a given index.</returns>
            public byte UInt8Get(int index)
            {
                return *(_pBuffer + index);
            }
    
            /// <summary>
            /// Writes a <see cref="byte"/> value to a given index.
            /// </summary>
            /// <param name="index">index in bytes for where to put.</param>
            /// <param name="value">value to be written</param>
            public void UInt8Put(int index, byte value)
            {
                *(_pBuffer + index) = value;
            }
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="index"></param>
            /// <returns></returns>
            public bool BoolGet(int index)
            {
                return *(_pBuffer + index) == 1;
            }
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="index"></param>
            /// <param name="value"></param>
            public void BoolPut(int index, bool value)
            {
                *(_pBuffer + index) = (byte)(value ? 1 : 0);
            }
    
            /// <summary>
            /// Gets the <see cref="short"/> value at a given index.
            /// </summary>
            /// <param name="index"> index in bytes from which to get.</param>
            /// <returns>the value at a given index.</returns>
            public short Int16Get(int index)
            {
                return *(short*)(_pBuffer + index);
            }
    
            /// <summary>
            /// Writes a <see cref="short"/> value to a given index.
            /// </summary>
            /// <param name="index">index in bytes for where to put.</param>
            /// <param name="value">value to be written</param>
            public void Int16Put(int index, short value)
            {
                *(short*)(_pBuffer + index) = value;
            }
    
            /// <summary>
            /// Gets the <see cref="int"/> value at a given index.
            /// </summary>
            /// <param name="index"> index in bytes from which to get.</param>
            /// <returns>the value at a given index.</returns>
            public int Int32Get(int index)
            {
                return *(int*)(_pBuffer + index);
            }
    
            /// <summary>
            /// Writes a <see cref="int"/> value to a given index.
            /// </summary>
            /// <param name="index">index in bytes for where to put.</param>
            /// <param name="value">value to be written</param>
            public void Int32Put(int index, int value)
            {
                *(int*)(_pBuffer + index) = value;
            }
    
            /// <summary>
            /// Gets the <see cref="long"/> value at a given index.
            /// </summary>
            /// <param name="index"> index in bytes from which to get.</param>
            /// <returns>the value at a given index.</returns>
            public long Int64Get(int index)
            {
                return *(long*)(_pBuffer + index);
            }
    
            /// <summary>
            /// Writes a <see cref="long"/> value to a given index.
            /// </summary>
            /// <param name="index">index in bytes for where to put.</param>
            /// <param name="value">value to be written</param>
            public void Int64Put(int index, long value)
            {
                *(long*)(_pBuffer + index) = value;
            }
    
            /// <summary>
            /// Gets the <see cref="ushort"/> value at a given index.
            /// </summary>
            /// <param name="index"> index in bytes from which to get.</param>
            /// <returns>the value at a given index.</returns>
            public ushort UInt16Get(int index)
            {
                return *(ushort*)(_pBuffer + index);
            }
    
            /// <summary>
            /// Writes a <see cref="ushort"/> value to a given index.
            /// </summary>
            /// <param name="index">index in bytes for where to put.</param>
            /// <param name="value">value to be written</param>
            public void UInt16Put(int index, ushort value)
            {
                *(ushort*)(_pBuffer + index) = value;
            }
    
            /// <summary>
            /// Gets the <see cref="uint"/> value at a given index.
            /// </summary>
            /// <param name="index"> index in bytes from which to get.</param>
            /// <returns>the value at a given index.</returns>
            public uint UInt32Get(int index)
            {
                return *(uint*)(_pBuffer + index);
            }
    
            /// <summary>
            /// Writes a <see cref="uint"/> value to a given index.
            /// </summary>
            /// <param name="index">index in bytes for where to put.</param>
            /// <param name="value">value to be written</param>
            public void UInt32Put(int index, uint value)
            {
                *(uint*)(_pBuffer + index) = value;
            }
    
            /// <summary>
            /// Gets the <see cref="ulong"/> value at a given index.
            /// </summary>
            /// <param name="index"> index in bytes from which to get.</param>
            /// <returns>the value at a given index.</returns>
            public ulong UInt64Get(int index)
            {
                return *(ulong*)(_pBuffer + index);
            }
    
            /// <summary>
            /// Writes a <see cref="ulong"/> value to a given index.
            /// </summary>
            /// <param name="index">index in bytes for where to put.</param>
            /// <param name="value">value to be written</param>
            public void UInt64Put(int index, ulong value)
            {
                *(ulong*)(_pBuffer + index) = value;
            }
    
            /// <summary>
            /// Gets the <see cref="float"/> value at a given index.
            /// </summary>
            /// <param name="index"> index in bytes from which to get.</param>
            /// <returns>the value at a given index.</returns>
            public float FloatGet(int index)
            {
                return *(float*)(_pBuffer + index);
            }
    
            /// <summary>
            /// Writes a <see cref="float"/> value to a given index.
            /// </summary>
            /// <param name="index">index in bytes for where to put.</param>
            /// <param name="value">value to be written</param>
            public void FloatPut(int index, float value)
            {
                *(float*)(_pBuffer + index) = value;
            }
    
            /// <summary>
            /// Gets the <see cref="double"/> value at a given index.
            /// </summary>
            /// <param name="index"> index in bytes from which to get.</param>
            /// <returns>the value at a given index.</returns>
            public double DoubleGet(int index)
            {
                return *(double*)(_pBuffer + index);
            }
    
            /// <summary>
            /// Writes a <see cref="double"/> value to a given index.
            /// </summary>
            /// <param name="index">index in bytes for where to put.</param>
            /// <param name="value">value to be written</param>
            public void DoublePut(int index, double value)
            {
                *(double*)(_pBuffer + index) = value;
            }
    
            /// <summary>
            /// 字符串存储为两位数字=字符串长度   +  字符串(每个字符占两个字节)
            /// </summary>
            /// <param name="index"></param>
            /// <param name="length">chars</param>
            /// <returns></returns>
            public string StringGet(int index, int length)
            {
                int len = UInt16Get(index);
                if (len <= 0) return string.Empty;
    
                return new string((char*)(_pBuffer + index + 2), 0, len);
            }
    
            /// <summary>
            /// 字符串存储为两位数字=字符串长度   +  字符串(每个字符占两个字节)
            /// </summary>
            /// <param name="index"></param>
            /// <param name="length">chars</param>
            /// <param name="value"></param>
            public void StringPut(int index, int length, string value)
            {
                if (string.IsNullOrWhiteSpace(value))
                {
                    UInt16Put(index, 0);
                }
                else
                {
                    char[] chars = value.ToCharArray();
                    int len = Math.Min(length, chars.Length);
                    UInt16Put(index, (UInt16)len);
                    Marshal.Copy(chars, 0, (IntPtr)(_pBuffer + index + 2), len);
                }
            }
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="index"></param>
            /// <param name="length"></param>
            /// <returns></returns>
            public byte[] BinaryGet(int index, int length)
            {
                byte[] dest = new byte[length];
                GetBytes(index, dest, 0, length);
                return dest;
            }
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="index"></param>
            /// <param name="length"></param>
            /// <param name="src"></param>
            /// <returns></returns>
            public void BinaryPut(int index, int length, byte[] src)
            {
                SetBytes(index, src, 0, Math.Min(src.Length, length));
            }
    
            /// <summary>
            /// 
            /// </summary>
            /// <param name="index"></param>
            /// <param name="length"></param>
            /// <param name="dest"></param>
            /// <returns></returns>
            public int GetBytes(int index, int length, ref byte[] dest)
            {
                if (dest == null) return 0;
    
                return GetBytes(index, dest, 0, Math.Min(length, dest.Length));
            }
    
            /// <summary>
            /// Copies a range of bytes from the underlying into a supplied byte array.
            /// </summary>
            /// <param name="index">index  in the underlying buffer to start from.</param>
            /// <param name="destination">array into which the bytes will be copied.</param>
            /// <param name="offsetDestination">offset in the supplied buffer to start the copy</param>
            /// <param name="length">length of the supplied buffer to use.</param>
            /// <returns>count of bytes copied.</returns>
            public int GetBytes(int index, byte[] destination, int offsetDestination, int length)
            {
                int count = Math.Min(length, _capacity - index);
                Marshal.Copy((IntPtr)(_pBuffer + index), destination, offsetDestination, count);
    
                return count;
            }
    
            /// <summary>
            /// Writes a byte array into the underlying buffer.
            /// </summary>
            /// <param name="index">index  in the underlying buffer to start from.</param>
            /// <param name="src">source byte array to be copied to the underlying buffer.</param>
            /// <param name="offset">offset in the supplied buffer to begin the copy.</param>
            /// <param name="length">length of the supplied buffer to copy.</param>
            /// <returns>count of bytes copied.</returns>
            public int SetBytes(int index, byte[] src, int offset, int length)
            {
                int count = Math.Min(length, _capacity - index);
                Marshal.Copy(src, offset, (IntPtr)(_pBuffer + index), count);
    
                return count;
            }
    
            /// <summary>
            /// 
            /// </summary>
            public void Reset()
            {
                Array.Clear(this.Data, 0, this.Data.Length);
            }
    
            /// <summary>
            /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
            /// </summary>
            /// <filterpriority>2</filterpriority>
            public override void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this);
    
                base.Dispose();
            }
    
            /// <summary>
            /// Destructor for <see cref="DirectBuffer"/>
            /// </summary>
            ~PointerHelper()
            {
                Dispose(false);
            }
    
            private void Dispose(bool disposing)
            {
                if (_disposed)
                    return;
    
                FreeGCHandle();
    
                _disposed = true;
            }
    
            private void FreeGCHandle()
            {
                if (_needToFreeGCHandle)
                {
                    _pinnedGCHandle.Free();
                    _needToFreeGCHandle = false;
                }
            }
        }
  • 相关阅读:
    Linux操作系统分析之进程的创建与可执行程序的加载
    Linux操作系统分析之计算机是怎样工作的
    求二项分布的数学期望与方差的工式及证明过程
    世界就是一个班
    软件版妻子
    时代变迁
    也许ASP真的不行了???
    新一字诗
    祝女同志节日快乐!
    写啥
  • 原文地址:https://www.cnblogs.com/lcawen/p/14412895.html
Copyright © 2011-2022 走看看