| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- using System;
- namespace Base
- {
- internal enum ParserState
- {
- PacketSize,
- PacketBody
- }
- internal class PacketParser
- {
- private readonly TBuffer buffer;
- private uint packetSize;
- private readonly byte[] packetSizeBuffer = new byte[4];
- private ParserState state;
- private byte[] packet;
- private bool isOK;
- public PacketParser(TBuffer buffer)
- {
- this.buffer = buffer;
- }
- private void Parse()
- {
- if (this.isOK)
- {
- return;
- }
- bool finish = false;
- while (!finish)
- {
- switch (this.state)
- {
- case ParserState.PacketSize:
- if (this.buffer.Count < 4)
- {
- finish = true;
- }
- else
- {
- this.buffer.RecvFrom(this.packetSizeBuffer);
- this.packetSize = BitConverter.ToUInt32(this.packetSizeBuffer, 0);
- if (packetSize > 1024 * 1024)
- {
- throw new Exception($"packet too large, size: {this.packetSize}");
- }
- this.state = ParserState.PacketBody;
- }
- break;
- case ParserState.PacketBody:
- if (this.buffer.Count < this.packetSize)
- {
- finish = true;
- }
- else
- {
- this.packet = new byte[this.packetSize];
- this.buffer.RecvFrom(this.packet);
- this.isOK = true;
- this.state = ParserState.PacketSize;
- finish = true;
- }
- break;
- }
- }
- }
- public byte[] GetPacket()
- {
- this.Parse();
- if (!this.isOK)
- {
- return null;
- }
- byte[] result = this.packet;
- this.isOK = false;
- return result;
- }
- }
- }
|