using System;
namespace AgoraIO.Media
{
///
/// 创建一个可变长的Byte数组方便Push数据和Pop数据
/// 数组的最大长度为1024,超过会产生溢出
/// 数组的最大长度由常量MAX_LENGTH设定
///
/// 注:由于实际需要,可能要从左到右取数据,所以这里
/// 定义的Pop函数并不是先进后出的函数,而是从0开始.
///
/// @Author: Red_angelX
///
public 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;
///
/// 默认构造函数
///
public ByteBuffer()
{
this.Initialize();
}
///
/// 重载的构造函数,用一个Byte数组来构造
///
/// 用于构造ByteBuffer的数组
public ByteBuffer(byte[] bytes)
{
this.Initialize();
this.PushByteArray(bytes);
}
///
/// 获取当前ByteBuffer的长度
///
public int Length
{
get
{
return CURRENT_LENGTH;
}
}
///
/// 获取/设置当前出栈指针位置
///
public int Position
{
get
{
return CURRENT_POSITION;
}
set
{
CURRENT_POSITION = value;
}
}
///
/// 获取ByteBuffer所生成的数组
/// 长度必须小于 [MAXSIZE]
///
/// Byte[]
public byte[] ToByteArray()
{
//分配大小
RETURN_ARRAY = new byte[CURRENT_LENGTH];
//调整指针
Array.Copy(TEMP_BYTE_ARRAY, 0, RETURN_ARRAY, 0, CURRENT_LENGTH);
return RETURN_ARRAY;
}
///
/// 初始化ByteBuffer的每一个元素,并把当前指针指向头一位
///
public void Initialize()
{
TEMP_BYTE_ARRAY.Initialize();
CURRENT_LENGTH = 0;
CURRENT_POSITION = 0;
}
///
/// 向ByteBuffer压入一个字节
///
/// 一位字节
public void PushByte(byte by)
{
TEMP_BYTE_ARRAY[CURRENT_LENGTH++] = by;
}
///
/// 向ByteBuffer压入数组
///
/// 数组
public void PushByteArray(byte[] ByteArray)
{
//把自己CopyTo目标数组
ByteArray.CopyTo(TEMP_BYTE_ARRAY, CURRENT_LENGTH);
//调整长度
CURRENT_LENGTH += ByteArray.Length;
}
///
/// 向ByteBuffer压入两字节的Short
///
/// 2字节Short
public void PushUInt16(UInt16 Num)
{
TEMP_BYTE_ARRAY[CURRENT_LENGTH++] = (byte)((Num & 0x00ff) & 0xff);
TEMP_BYTE_ARRAY[CURRENT_LENGTH++] = (byte)(((Num & 0xff00) >> 8) & 0xff);
}
///
/// 向ByteBuffer压入一个无符Int值
///
/// 4字节UInt32
public void PushInt(UInt32 Num)
{
TEMP_BYTE_ARRAY[CURRENT_LENGTH++] = (byte)((Num & 0x000000ff) & 0xff);
TEMP_BYTE_ARRAY[CURRENT_LENGTH++] = (byte)(((Num & 0x0000ff00) >> 8) & 0xff);
TEMP_BYTE_ARRAY[CURRENT_LENGTH++] = (byte)(((Num & 0x00ff0000) >> 16) & 0xff);
TEMP_BYTE_ARRAY[CURRENT_LENGTH++] = (byte)(((Num & 0xff000000) >> 24) & 0xff);
}
///
/// 向ByteBuffer压入一个Long值
///
/// 4字节Long
public void PushLong(long Num)
{
TEMP_BYTE_ARRAY[CURRENT_LENGTH++] = (byte)((Num & 0x000000ff) & 0xff);
TEMP_BYTE_ARRAY[CURRENT_LENGTH++] = (byte)(((Num & 0x0000ff00) >> 8) & 0xff);
TEMP_BYTE_ARRAY[CURRENT_LENGTH++] = (byte)(((Num & 0x00ff0000) >> 16) & 0xff);
TEMP_BYTE_ARRAY[CURRENT_LENGTH++] = (byte)(((Num & 0xff000000) >> 24) & 0xff);
}
///
/// 从ByteBuffer的当前位置弹出一个Byte,并提升一位
///
/// 1字节Byte
public byte PopByte()
{
byte ret = TEMP_BYTE_ARRAY[CURRENT_POSITION++];
return ret;
}
///
/// 从ByteBuffer的当前位置弹出一个Short,并提升两位
///
/// 2字节Short
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]);
UInt16 ret = (UInt16)(TEMP_BYTE_ARRAY[CURRENT_POSITION] | TEMP_BYTE_ARRAY[CURRENT_POSITION + 1] << 8);
CURRENT_POSITION += 2;
return ret;
}
///
/// 从ByteBuffer的当前位置弹出一个uint,并提升4位
///
/// 4字节UInt
public uint PopUInt()
{
if (CURRENT_POSITION + 3 >= CURRENT_LENGTH)
return 0;
uint ret = (uint)(TEMP_BYTE_ARRAY[CURRENT_POSITION] | TEMP_BYTE_ARRAY[CURRENT_POSITION + 1] << 8 | TEMP_BYTE_ARRAY[CURRENT_POSITION + 2] << 16 | TEMP_BYTE_ARRAY[CURRENT_POSITION + 3] << 24);
CURRENT_POSITION += 4;
return ret;
}
///
/// 从ByteBuffer的当前位置弹出一个long,并提升4位
///
/// 4字节Long
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;
}
///
/// 从ByteBuffer的当前位置弹出长度为Length的Byte数组,提升Length位
///
/// 数组长度
/// Length长度的byte数组
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;
}
public byte[] PopByteArray2(int Length)
{
//溢出
if (CURRENT_POSITION <= Length)
{
return new byte[0];
}
byte[] ret = new byte[Length];
Array.Copy(TEMP_BYTE_ARRAY, CURRENT_POSITION - Length, ret, 0, Length);
//提升位置
CURRENT_POSITION -= Length;
return ret;
}
}
}