我看到这个家伙为Tag-Length-Value做了一些不同的事情,他允许存储大长度>正如我们在TLV示例中看到的,它是这样工作的:
我需要存储我的ID + Name
标签1,长度5,值(ID) = 12345,等等
回到我需要的,这个家伙/TlvEncoding如何压缩长度以允许存储超过4个字节。例如:
假设我有一个长度为1000的字符串,超过1字节。
备注:0xffff = 65,535UInt16
或ushort
的最大值。我想这条线上长度达到1000的条件。流将写入2字节的长度。但当他读到这个值时,他会做更多的逻辑操作。我已经泄露了。(
/// <summary>
/// Write TLV length to stream
/// </summary>
/// <param name="stream">stream to write to</param>
/// <param name="length">length to write or null to write indefinite length</param>
public static void WriteLength(Stream stream, int? length)
{
if (length == null)
{
stream.WriteByte(0x80); // indefinite form
return;
}
if (length < 0 || length > 0xffffffff)
throw new TlvException(string.Format("Invalid length value: {0}", length));
if (length <= 0x7f) // use short form if possible
{
stream.WriteByte(checked((byte)length));
return;
}
byte lengthBytes;
// use minimum number of octets
if (length <= 0xff)
lengthBytes = 1;
else if (length <= 0xffff)
lengthBytes = 2;
else if (length <= 0xffffff)
lengthBytes = 3;
else if (length <= 0xffffffff)
lengthBytes = 4;
else
throw new TlvException(string.Format("Length value too big: {0}", length));
stream.WriteByte((byte)(lengthBytes | 0x80));
// shift out the bytes
for (var i = lengthBytes - 1; i >= 0; i--)
{
var data = (byte)(length >> (8 * i));
stream.WriteByte(data);
}
}
在读取操作他做:(我认为条件将满足这里0x7f; // remove 0x80 bit
)我不知道他为什么选择等于127的0x7f,而去掉等于128的0x80。
/// <summary>
/// Read TLV length from stream
/// </summary>
/// <param name="stream">Stream to read</param>
/// <returns>length or null to indicate indefinite length</returns>
public static int? ReadLength(Stream stream)
{
var readByte = stream.ReadByte();
if (readByte == -1)
throw new TlvException("Unexpected end of stream while reading length");
if ((readByte & 0x80) == 0)
return (int)readByte; // length is in first byte
int length = 0;
var lengthBytes = readByte & 0x7f; // remove 0x80 bit
if (lengthBytes == 0)
return null; // indefinite form
if (lengthBytes > 4)
throw new TlvException($"Unsupported length: {lengthBytes} bytes");
for (var i = 0; i < lengthBytes; i++)
{
readByte = stream.ReadByte();
if (readByte == -1)
throw new TlvException("Unexpected end of stream while reading length");
length <<= 8;
length |= (int)readByte;
}
return length;
}
请我只需要了解事情是如何发生的,因为我需要在字节数组中应用相同的方法。我需要存储即:1500长度的字符串,日期时间,一些整数,作为(tlv)。但是我只知道如何应用1字节长度(255)。
所以我只能读取1字节的长度,因为我不知道如何告诉数组我需要寻找3字节的长度?还是2个字节?然后我必须用2或3字节存储所有tlv。那是浪费空间。
- 整数存储为4字节(OK),所以我可以写长度是
(byte) 4
(注意字节转换) - 字符串只能存储在255中但是怎么像上面那个人那样做呢?1500长度在3字节?
我简单地解释一下,他允许存储1字节作为长度,有时存储3字节作为长度。我甚至不知道他如何告诉编译器/流从接下来的3个字节读取这个标签长度。或者接下来的2个字节。或1个字节
从WriteLength
来看,它看起来相当简单。
0到0x7F之间的值仅用该值的单个字节表示。例如,如果你想写入值5
,你写一个值5
的字节。
For values>0 x7f:
- 第一个字节是表示值所需的字节数,设置最高位(以便您可以区分它与保存0-127之间值的简单字节之间的区别)
- 下一个字节保留实际值。