2.1이 되면 Framework 호환성은 떨어져 나가겠네요!
음, 사실상 레거시라 상관없겠지만요… 쬐끔 아쉽!ㅠㅠ
프로젝트에 참여하고 싶은데 어느 범위로 참여해야 할지가 고민됩니다. 일감이 있으면 알려주세요!
사실…말은 단순히 한줄 요약했지만…
고민을 좀 했었습니다
0.1 버전 차이로
그대로 쓰으윽 긁어올까 나쁜생각(?)을 했지만
개발해주신 분의 시간과 노력을 존중하기 위해 선택한 결정이였습니다
p.s 가장 큰 버그 나오면 그대로 클론해서 수정 계획을 가지고 있긴합니다…!
해당 라이브러리는 컨셉만 잡아놓은 상태이기때문에 아이디어만 있다면 언제든지 클론해서 pr로올려주세요!
PacketSupport 1.2.0 1.2.1 업데이트 되었습니다.
- PacketBuilder의 LinkedList → List로 변경
LinkedList 보다 List가 성능이 좋을 것 같습니다. · Issue #5 · lukewire129/BytePacketSupport · GitHub - PacketBuilder의 Endian 로직 변경
엔디안 적용시점 · Issue #2 · lukewire129/BytePacketSupport · GitHub
엔디안 Reverse 적용 대상 · Issue #3 · lukewire129/BytePacketSupport · GitHub
엔디안의 동작성은 시스템의 엔디안에 따라 달라야 할 것 같습니다. · Issue #4 · lukewire129/BytePacketSupport · GitHub
기본적으로 IntelCPU의 경우 LittleEndian으로 동작됩니다.
아래 코드들은 PacketBuilder와 Append Extentions의
Endian의 테스트 코드샘플들입니다!
short test = 0x0102;
short testAdd = 0x0304;
var littlEndianType = new PacketBuilder ();
var bigEndianType = new PacketBuilder (new PacketBuilderConfiguration ()
{
DefaultEndian = BytePacketSupport.Enums.Endian.BIG
});
var display1 = littlEndianType.Append (test)
.Append (testAdd)
.Build ();
var display2 = bigEndianType.Append (test)
.Append (testAdd)
.Build ();
Console.WriteLine ("display1 {0}", display1.Display ());
Console.WriteLine ("display2 {0}", display2.Display ());
// output
// display1 02010403
// display2 01020304
int test = 1;
int testAdd = 2;
var littlEndianType = new PacketBuilder ();
var bigEndianType = new PacketBuilder (new PacketBuilderConfiguration ()
{
DefaultEndian = BytePacketSupport.Enums.Endian.BIG
});
var display1 = littlEndianType.Append (test)
.Append (testAdd)
.Build ();
var display2 = bigEndianType.Append (test)
.Append (testAdd)
.Build ();
Console.WriteLine ("display1 {0}", display1.Display ());
Console.WriteLine ("display2 {0}", display2.Display ());
// output
// 보기좋게 띄어쓰기를..!
// display1 01000000 00000000 02000000 00000000
// display2 00000000 00000001 00000000 00000002
아래 코드 동작 시 Little Endian 처리가 되지 않는 이슈로
1.2.1로 업데이트 하였습니다.
// Extentions 활용 시
short test = 0x0102;
byte[] abclittle = new byte[] { 0x01, 0x02 };
byte[] abcBig = new byte[] { 0x01, 0x02 };
// 정수형 Append 메서드 기본적으로 isLittleEndian는 기본적으로 true 입니다.
// Append (int intByte, bool isLittleEndian = true)
abclittle = abclittle.Append (test);
abcBig = abcBig.Append (test, false);
Console.WriteLine ("display1 {0}", abclittle.Display ());
Console.WriteLine ("display2 {0}", abcBig.Display ());
// output
// display1 01020201
// display2 01020102
이슈로 등록할까 하다가 개인적인 의견이므로 댓글로 남깁니다
심각한 이슈는 샘플 코드를 실행하면 README와 다른 결과가 나옵니다.
var builder = new PacketBuilder()
.Append(0x40)
.Append(0x41)
.Append(0x42)
.Append(0x43)
.Append(0x44)
.Append(0x45)
.Build();
결과
400000004100000042000000430000004400000045000000
Append
함수의 오버로드 설계 때문인데요, 이 부분은 고민이 필요해 보입니다.
아래는 명명 규칙이나 사용성에 대한 검토입니다. (함수 인자까지는 아직 못봤네요)
일반
- 클래스 이름은 명사 또는 명사구를 사용해야 합니다.
- 메서드 이름은 동사 또는 동사구를 사용해야 합니다.
- 일반 명명 규칙 - Framework Design Guidelines | Microsoft Learn
- 클래스, 구조체 및 인터페이스의 이름 - Framework Design Guidelines | Microsoft Learn
- 형식 멤버의 이름 - Framework Design Guidelines | Microsoft Learn
PacketParse
- 클래스 이름은 명사형으로 지정해야 합니다.
Serialization<T>
- 함수의 이름은 동사형이어야 하므로
Serialize<T>
가 되어야 합니다.
DeserializeObject<T>
Serialize
함수와 짝을 이루므로Deserialize<T>
가 되어야 합니다.
GetFieldType<T>
- 해당 함수는
object
형식을 제시된 제네릭 형식으로 형 변환하므로Cast<T>
등이 더 나은 명명입니다.
ByteConverter
GetByte()
- 해당 함수는
byte[]
을 반환하므로GetBytes()
가 되어야 합니다.
PacketBuilder
/ AppendHelper
Append()
- 해당 함수의 오버로드들은 사용성에 있어 의도치 않은 동작을 할 가능성 있습니다. README.md의 예제에서
Append(0x40)
은 1바이트 값0x40
이 버퍼에 추가되기를 기대하지만 코드에서0x40
은int
형식의 값이므로 4바이트0x00000040
이 버퍼에 추가됩니다. - 위와 같이 의도치 않은 형 변환을 피하려면 사용자는
Append((byte)0x40)
과 같은 명시적인 형 변환을 사용해야 합니다. AppendInt32()
,AppendByte()
와 같이 형식 이름을 접미사로 하는 함수 이름을 고려해 볼 필요가 있습니다.
PacketBuilder
PointSaveStart()
/ PointSaveEnd()
/ GetSavePoint()
~~Start()
/~~End()
보다는 목적어가 뒤에 오는Start~~()
/End~~()
가 일반적입니다.Start~~()
/End~~()
보다는Begin~()
/End~()
패턴이 더 적합해 보입니다.SavePoint
보다는BeginSection()
/EndSection()
등이 적합할 것 같습니다.
ErrorDetection()
- 함수 이름은 동사형이어야 합니다.
DisplayHelper
Display()
- 해당 함수는 입력된 값에 대한 문자열 값을 반환하므로 '표시하다’라는 의미을 가지는 동사 'Display’의 동작에 부합하지 않습니다.
- BCL의
Convert.ToHexString()
과 같은 이름을 고려해 볼 수 있습니다.
DisplayAscii()
- 위와 동일합니다.
- BCL의
Encoding.GetString()
과 같이GetString()
이라는 이름을 고려해 볼 수 있고, 인코딩을 제공하면 아래와 같은 오버로드를 제공하는 것을 고려할 수 있습니다.public static string GetString(this byte[] bytes) => GetString(bytes, Encoding.ASCII); public static string GetString(this byte[] bytes, Encoding encoding) { ... }
지극히 개인적인 리뷰이지만 짚고 넘어가면 좋을 것 같아 참고 부탁드립니다ㅎ
감사합니다
상세한 의견 감사합니다.
아마도 수정하는 과정에서 생긴게 아닐까…싶네요 이 부분은 바로 확인하고 수정하겠습니다.
확인해보니… 기존 Append(정수형 타입) 삽입 시엔 삽입하려는 값과 Enum.Endian두 개의 파라미터 값을 넣어 처리를 했었는데 Endian의 기본값 설정과 현재 버전에선 불필요 요소로 삭제 처리로 인해 변화가 되었네요…
어쩔 수 없이 정수형의 경우는
AppendInt, Appendlong, AppendShort 등 과 같이 표기를 해야할 것 같네요 :)*
나머지 부분은 전부 맞는 말씀이셔서…말씀하신부분처럼 바꾸는게 맞을것 같네요
Append
관련 다른 의견으로…
이렇게 사용하는 것은 어떨까 하는데요, 한번 보시죠.
var builder = new PacketBuilder()
.@byte (0x41)
.@bytes [0x42, 0x43, 0x44] // 또는 bytes (0x42, 0x43, 0x44)
.@int (312)
.@long (312312312)
.@string ("Test")
.Build();
흠…
var builder = new PacketBuilder()
[0x01]
[0x02, 0x03]
[0x04]
.Build();
처럼 너무 갔나요? ^^;
보기에는 이쁜데… ㅎㅎ
@byte, @bytes 는 어떤문법인가요…!?
아 그냥 메소드명을 그렇게 한거에요. byte
, int
등은 예약어니까요. 앞에 골뱅이 넣어주면 메소드 명으로 쓸 수 있습니다.
아 @는…무조건 넣어야겠는데요…? 나쁘지않을꺼같은데요?
저는 일감으로 소스 생성기를 이용해 ToPacket()
및 FromPacket()
메서드를 생성해주는 걸 해봐야겠습니다. 괜찮으시죠?
적극 환영합니다.
우선 전체적으로 Append 대신 @로 가는걸로 가보겠습니다
2024년도 뜨거운 감자이군요.
자 이것으로 .NET Conf 발표를
Serialization, DeserializeObject 메서드명 변경
→ Serialize, Deserialize 메서드명 변경 완료GetFieldType 메서드명 변경
→ Cast 메서드명 변경 완료GetByte 메서드명 변경
→ GetBytes 메서드명 변경 완료Append메서드 검토
→@예약어
로 메서드명 변경 완료PointSave~ 메서드명 변경
→ ~Section 메서드명 변경 완료ErrorDetection 메서드명 변경
→ Compute 메서드명 변경 완료Display, DisplayAscii 메서드명 변경
→ Display → ToHexString, DisplayAscii → GetString
parameter Indexer .net standard 2.1에서 가능한 방식인가요?!
바로 2.0으로 올라가야할 것 같네요.
간단하게 변경 예정인것만
- unsigned Type 추가 (ushort, uint, ulong)
- 기존 컨셉의 Append 대신
@예약어
로 변경
// 샘플
byte[] samplebyte = new byte[]{0x01, 0x02};
samplebyte = samplebyte
.@int(1)
.@int(1, false)
.@uint(1)
.@uint(1, false)
.@bytes(new byte[]
{
0x03,
0x04,
0x05
})
.@byte(0x06);
var pb = new PacketBuilder()
.@bytes(new byte[]
{
0x03,
0x04,
0x05
})
.@byte(0x06)
.Build();
- Serialize, Deserialize의 정수형의 EndianType 설정할 수 있게 CustomAttribute 추가
public class Test3Packet
{
[Endian (Endian.BIG)]
public int Value;
[Endian (Endian.LITTLE)]
public int Value1;
[ByteSize (3)]
public string Value3;
}
[Fact]
public void DeserializeEndianAttribute()
{
var test = new byte[] { 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x61, 0x62, 0x63 };
var aaa = PacketParse.Deserialize<Test3Packet> (test);
}
[Fact]
public void SerializeEndianAttribute()
{
var aaa = new Test3Packet ()
{
Value = 1,
Value1 = 1,
Value3 = "abc",
};
var abc = PacketParse.Serialize (aaa);
}
To Be Continue…
params 인덱서 파라미터는 아마 다 될텐데 bytes는 메서드가 아니라 속성이 되어야 하고 구현이 조금 복잡할 듯 하니 params byte[] ...
가 구현하기 쉽겠습니다. ([…,…] 방식이 올바른지도 모르겠고요 ^^)
PacketBuilder @bytes(byte[] datas)
와
PacketBuilder @bytes(List<byte> datas)
를
PacketBuilder @bytes(IEnumerable<byte> datas)
로 통일하고 나니
자연스럽게 아래 코드처럼 되어버렸네요
var pb = new PacketBuilder ();
List<byte> abcBig2 = new List<byte> () { 0x01, 0x02 };
var result = pb.@bytes ([0x01, 0x02])
.@bytes (new byte[] { 0x02, 0x03 })
.@bytes(abcBig2)
.Build ();
Console.WriteLine ("result {0}", result.ToHexString ());
PR한번 해봤습니다. 내용 살펴봐주세요~ ^^
아 PR 잘못했네요 ㅎㅎ; 처음 하는 PR이라…