096111e983
.claude/ 제외(.gitignore 추가). 기존 초기커밋(5a96a69) 위에 신규·수정·이동분 커밋.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
57 lines
1.8 KiB
C#
57 lines
1.8 KiB
C#
namespace CvnetPacketProgram;
|
|
|
|
/// <summary>
|
|
/// 수신 바이트 스트림에서 0xF7 0x32 로 시작하는 완전한 프레임을 추출한다.
|
|
/// 프레임 길이 = 5(Header~Len) + Len + 2(XOR,ADD).
|
|
/// </summary>
|
|
public sealed class FrameParser
|
|
{
|
|
private readonly List<byte> _buf = new();
|
|
|
|
public void Append(byte[] data, int len)
|
|
{
|
|
for (int i = 0; i < len; i++) _buf.Add(data[i]);
|
|
}
|
|
|
|
/// <summary>버퍼에서 추출 가능한 모든 완전 프레임을 반환한다.</summary>
|
|
public List<byte[]> Extract()
|
|
{
|
|
var result = new List<byte[]>();
|
|
|
|
while (true)
|
|
{
|
|
// Header(0xF7) + Device(0x32) 동기화
|
|
int sync = FindSync();
|
|
if (sync < 0)
|
|
{
|
|
// 동기 패턴 없음 — 마지막 1바이트(0xF7 가능성)만 남기고 버림
|
|
if (_buf.Count > 1) _buf.RemoveRange(0, _buf.Count - 1);
|
|
break;
|
|
}
|
|
if (sync > 0) _buf.RemoveRange(0, sync); // 앞쪽 쓰레기 제거
|
|
|
|
if (_buf.Count < 5) break; // Len 까지 못 받음
|
|
int len = _buf[4];
|
|
int frameLen = 5 + len + 2;
|
|
if (_buf.Count < frameLen) break; // 프레임 미완성
|
|
|
|
var frame = _buf.GetRange(0, frameLen).ToArray();
|
|
_buf.RemoveRange(0, frameLen);
|
|
result.Add(frame);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private int FindSync()
|
|
{
|
|
for (int i = 0; i + 1 < _buf.Count; i++)
|
|
if (_buf[i] == Cvnet.Header && _buf[i + 1] == Cvnet.Device)
|
|
return i;
|
|
// 마지막 바이트가 Header 면 다음 바이트 대기
|
|
if (_buf.Count > 0 && _buf[^1] == Cvnet.Header) return _buf.Count - 1;
|
|
return -1;
|
|
}
|
|
|
|
public void Clear() => _buf.Clear();
|
|
}
|