C#實現ByteBuffer類

           在寫網絡程序的時候,經常需要往一個數組裏面壓數據或者取數據,而Java中再Java.nio中有個ByteBuffer能很方便的實現,Delphi中也有個Stream類有着同樣的功能,這裏我就模仿JAVA用C#做個最基礎的ByteBuffer類

           下面是代碼

          

using System;


namespace System.ByteBuffer
{
    
/// <summary>
    
/// 創建一個可變長的Byte數組方便Push數據和Pop數據
    
/// 數組的最大長度爲1024,超過會產生溢出
    
/// 數組的最大長度由常量MAX_LENGTH設定
    
/// 
    
/// 注:由於實際需要,可能要從左到右取數據,所以這裏
    
/// 定義的Pop函數並不是先進後出的函數,而是從0開始.
    
/// 
    
/// @Author: Red_angelX
    
/// </summary>

    class ByteBuffer
    
{
        
//數組的最大長度
        private const int MAX_LENGTH = 1024;
        
        
//固定長度的中間數組
        private byte[] TEMP_BYTE_ARRAY = new byte[MAX_LENGTH];
        
        
//當前數組長度
        private int CURRENT_LENGTH = 0;

        
//當前Pop指針位置
        private int CURRENT_POSITION = 0;

        
//最後返回數組
        private byte[] RETURN_ARRAY;

        
/// <summary>
        
/// 默認構造函數
        
/// </summary>

        public ByteBuffer()
        
{
            
this.Initialize();
        }


        
/// <summary>
        
/// 重載的構造函數,用一個Byte數組來構造
        
/// </summary>
        
/// <param name="bytes">用於構造ByteBuffer的數組</param>

        public ByteBuffer(byte[] bytes)
        
{
            
this.Initialize();
            
this.PushByteArray(bytes);
        }

    

        
/// <summary>
        
/// 獲取當前ByteBuffer的長度
        
/// </summary>

        public int Length
        
{
            
get
            
{
                
return CURRENT_LENGTH;
            }

        }


        
/// <summary>
        
/// 獲取/設置當前出棧指針位置
        
/// </summary>

        public int Position
        
{
            
get
            
{
                
return CURRENT_POSITION;
            }

            
set
            
{
                CURRENT_POSITION 
= value;
            }

        }


        
/// <summary>
        
/// 獲取ByteBuffer所生成的數組
        
/// 長度必須小於 [MAXSIZE]
        
/// </summary>
        
/// <returns>Byte[]</returns>

        public byte[] ToByteArray()
        
{
            
//分配大小
            RETURN_ARRAY = new byte[CURRENT_LENGTH];
            
//調整指針
            Array.Copy(TEMP_BYTE_ARRAY, 0, RETURN_ARRAY, 0, CURRENT_LENGTH);
            
return RETURN_ARRAY;
        }


        
/// <summary>
        
/// 初始化ByteBuffer的每一個元素,並把當前指針指向頭一位
        
/// </summary>

        public void Initialize()
        
{
            TEMP_BYTE_ARRAY.Initialize();
            CURRENT_LENGTH 
= 0;
            CURRENT_POSITION 
= 0;
        }


        
/// <summary>
        
/// 向ByteBuffer壓入一個字節
        
/// </summary>
        
/// <param name="by">一位字節</param>

        public void PushByte(byte by)
        
{
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= by;
        }


        
/// <summary>
        
/// 向ByteBuffer壓入數組
        
/// </summary>
        
/// <param name="ByteArray">數組</param>

        public void PushByteArray(byte[] ByteArray)
        
{
            
//把自己CopyTo目標數組
            ByteArray.CopyTo(TEMP_BYTE_ARRAY, CURRENT_LENGTH);
            
//調整長度
            CURRENT_LENGTH += ByteArray.Length;
        }


        
/// <summary>
        
/// 向ByteBuffer壓入兩字節的Short
        
/// </summary>
        
/// <param name="Num">2字節Short</param>

        public void PushUInt16(UInt16 Num)
        
{
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)(((Num & 0xff00>> 8& 0xff);
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)((Num & 0x00ff& 0xff);
        }


        
/// <summary>
        
/// 向ByteBuffer壓入一個無符Int值
        
/// </summary>
        
/// <param name="Num">4字節UInt32</param>

        public void PushInt(UInt32 Num)
        
{
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)(((Num & 0xff000000>> 24& 0xff);
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)(((Num & 0x00ff0000>> 16& 0xff);
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)(((Num & 0x0000ff00>> 8& 0xff);
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)((Num & 0x000000ff& 0xff);
        }


        
/// <summary>
        
/// 向ByteBuffer壓入一個Long值
        
/// </summary>
        
/// <param name="Num">4字節Long</param>

        public void PushLong(long Num)
        
{
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)(((Num & 0xff000000>> 24& 0xff);
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)(((Num & 0x00ff0000>> 16& 0xff);
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)(((Num & 0x0000ff00>> 8& 0xff);
            TEMP_BYTE_ARRAY[CURRENT_LENGTH
++= (byte)((Num & 0x000000ff& 0xff);
        }


        
/// <summary>
        
/// 從ByteBuffer的當前位置彈出一個Byte,並提升一位
        
/// </summary>
        
/// <returns>1字節Byte</returns>

        public byte PopByte()
        
{
            
byte ret = TEMP_BYTE_ARRAY[CURRENT_POSITION++];
            
return ret;
        }


        
/// <summary>
        
/// 從ByteBuffer的當前位置彈出一個Short,並提升兩位
        
/// </summary>
        
/// <returns>2字節Short</returns>

        public UInt16 PopUInt16()
        
{
            
//溢出
            if (CURRENT_POSITION + 1 >= CURRENT_LENGTH)
            
{
                
return 0;
            }

            UInt16 ret 
= (UInt16)(TEMP_BYTE_ARRAY[CURRENT_POSITION] << 8 | TEMP_BYTE_ARRAY[CURRENT_POSITION + 1]);
            CURRENT_POSITION 
+= 2;
            
return ret;
        }


        
/// <summary>
        
/// 從ByteBuffer的當前位置彈出一個uint,並提升4位
        
/// </summary>
        
/// <returns>4字節UInt</returns>

        public uint PopUInt()
        
{            
            
if (CURRENT_POSITION + 3 >= CURRENT_LENGTH)
                
return 0;
            
uint ret = (uint)(TEMP_BYTE_ARRAY[CURRENT_POSITION] << 24 | TEMP_BYTE_ARRAY[CURRENT_POSITION + 1<< 16 | TEMP_BYTE_ARRAY[CURRENT_POSITION + 2<< 8 | TEMP_BYTE_ARRAY[CURRENT_POSITION + 3]);
            CURRENT_POSITION 
+= 4;
            
return ret;
        }


        
/// <summary>
        
/// 從ByteBuffer的當前位置彈出一個long,並提升4位
        
/// </summary>
        
/// <returns>4字節Long</returns>

        public long PopLong()
        
{
            
if (CURRENT_POSITION + 3 >= CURRENT_LENGTH)
                
return 0;
            
long ret = (long)(TEMP_BYTE_ARRAY[CURRENT_POSITION] << 24 | TEMP_BYTE_ARRAY[CURRENT_POSITION + 1<< 16 | TEMP_BYTE_ARRAY[CURRENT_POSITION + 2<< 8 | TEMP_BYTE_ARRAY[CURRENT_POSITION + 3]);
            CURRENT_POSITION 
+= 4;
            
return ret;
        }


        
/// <summary>
        
/// 從ByteBuffer的當前位置彈出長度爲Length的Byte數組,提升Length位
        
/// </summary>
        
/// <param name="Length">數組長度</param>
        
/// <returns>Length長度的byte數組</returns>

        public byte[] PopByteArray(int Length)
        
{
            
//溢出
            if (CURRENT_POSITION + Length >= CURRENT_LENGTH)
            
{
                
return new byte[0];
            }

            
byte[] ret = new byte[Length];
            Array.Copy(TEMP_BYTE_ARRAY, CURRENT_POSITION, ret, 
0, Length);
            
//提升位置
            CURRENT_POSITION += Length;
            
return ret;
        }


    }

}

           由於實際需要我是要從byteArray中從左到右取數據,所以才定義了一個CURRENT_POSITION的變量,如果需要從右到左彈數據並減小Buffer的長度則直接用 --CURRENT_LENGTH就可以了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章