PacketByte Support 라이브러리

이 부분 때문에 우선은 Append의 메인 메서드 선정 상관없이 사용할 수 있게 해놨습니다.

투표 마치는대로 적용작업을.!


5개의 좋아요

@jrchs
전체 패킷이 다 적용 되는건가요? 아니면 선언한 일부에서만 적용이되는건가요?

3개의 좋아요

주로 패킷의 Body 부분만 적용이 되는데, 전체 다 적용도 되었으면 좋겠습니다.

4개의 좋아요

부분만 적용된다고 하더라도 AppendClass 개념이 있기 때문에 부분적으로 패킷을 나눠 제작할 수 있기 때문에 전체 만 적용하면 되겠네요! :slight_smile:

3개의 좋아요

BIGBYTESWAP과 LITTLEBYTESWAP 기능 추가 한 유닛테스트 샘플코드와 결과입니다.

[Fact]
public void TestShort()
{
    var test1 = new PacketBuilder (new PacketBuilderConfiguration ()
    {
        DefaultEndian = BytePacketSupport.Enums.Endian.BIG
    }).@short (0x1234)
                  .Build ();
    var test2 = new PacketBuilder (new PacketBuilderConfiguration ()
    {
        DefaultEndian = BytePacketSupport.Enums.Endian.LITTLE
    }).@short (0x1234)
                  .Build ();
    var test3 = new PacketBuilder (new PacketBuilderConfiguration ()
    {
        DefaultEndian = BytePacketSupport.Enums.Endian.BIGBYTESWAP
    }).@short (0x1234)
                  .Build ();
    var test4 = new PacketBuilder (new PacketBuilderConfiguration ()
    {
        DefaultEndian = BytePacketSupport.Enums.Endian.LITTLEBYTESWAP
    }).@short (0x1234)
                  .Build ();

    _testOutputHelper.WriteLine (test1.ToHexString ());
    _testOutputHelper.WriteLine (test2.ToHexString ());
    _testOutputHelper.WriteLine (test3.ToHexString ());
    _testOutputHelper.WriteLine (test4.ToHexString ());
}

결과
image

 [Fact]
 public void Testint()
 {
     var test1 = new PacketBuilder (new PacketBuilderConfiguration ()
     {
         DefaultEndian = BytePacketSupport.Enums.Endian.BIG
     }).@int (0x12345678)
                   .Build ();
     var test2 = new PacketBuilder (new PacketBuilderConfiguration ()
     {
         DefaultEndian = BytePacketSupport.Enums.Endian.LITTLE
     }).@int (0x12345678)
                   .Build ();
     var test3 = new PacketBuilder (new PacketBuilderConfiguration ()
     {
         DefaultEndian = BytePacketSupport.Enums.Endian.BIGBYTESWAP
     }).@int (0x12345678)
                   .Build ();
     var test4 = new PacketBuilder (new PacketBuilderConfiguration ()
     {
         DefaultEndian = BytePacketSupport.Enums.Endian.LITTLEBYTESWAP
     }).@int (0x12345678)
                   .Build ();

     _testOutputHelper.WriteLine (test1.ToHexString ());
     _testOutputHelper.WriteLine (test2.ToHexString ());
     _testOutputHelper.WriteLine (test3.ToHexString ());
     _testOutputHelper.WriteLine (test4.ToHexString ());
 }

결과
image

[Fact]
public void Testlong()
{
    var test1 = new PacketBuilder (new PacketBuilderConfiguration ()
    {
        DefaultEndian = BytePacketSupport.Enums.Endian.BIG
    }).@long (0x123456789ABCDEF0)
                  .Build ();
    var test2 = new PacketBuilder (new PacketBuilderConfiguration ()
    {
        DefaultEndian = BytePacketSupport.Enums.Endian.LITTLE
    }).@long (0x123456789ABCDEF0)
                  .Build ();
    var test3 = new PacketBuilder (new PacketBuilderConfiguration ()
    {
        DefaultEndian = BytePacketSupport.Enums.Endian.BIGBYTESWAP
    }).@long (0x123456789ABCDEF0)
                  .Build ();
    var test4 = new PacketBuilder (new PacketBuilderConfiguration ()
    {
        DefaultEndian = BytePacketSupport.Enums.Endian.LITTLEBYTESWAP
    }).@long (0x123456789ABCDEF0)
                  .Build ();

    _testOutputHelper.WriteLine (test1.ToHexString ());
    _testOutputHelper.WriteLine (test2.ToHexString ());
    _testOutputHelper.WriteLine (test3.ToHexString ());
    _testOutputHelper.WriteLine (test4.ToHexString ());
}

결과
image

6개의 좋아요

bit단위기능적용에 대한 기능 설명을 좀 간략해주실수있나요?

  • byte position, bit position, bit size도 같이요!
3개의 좋아요

제가 설명하는 덴 조금 부족해서…
말씀드리자면,

2개의 상태 또는 4개의 상태를 나타내는 항목이 있다면,
메모리 사용량이 제한적인 경우,
비트 1개, 2개면 표현이 충분하거든요…
그래서 바이트 하나를 비트 쪼개서 사용할 경우가 꽤 많습니다.

이런 경우 사용할 수 있는 기능이 있으면 좋겠다라는… 의견이었습니다.
position, size 이런 것들은
위 기능 구현할 때 필요한 요소들에 포함되지 않을까 해서 한번 적어본 것이었어요

4개의 좋아요

Enum의 Flag값 같은 걸 말씀하시는 것과도 비슷한 것 같네요!

3개의 좋아요

감사합니다!
@BOBx5 님이 개발해주실거에요 하하하하!

3개의 좋아요

와… 레전드…

실행력이 다들 대단하시네요 :scream:

4개의 좋아요

같이 참여하시죠…!

3개의 좋아요

약간 요련 느낌인가보네요 :slight_smile:

2개의 좋아요

맞습니다! 저도 종종 응용하는 방법이에요.

2개의 좋아요

2.2.0 업데이트

첫번째 사진의 Compute 메소드는 Mythosia.Integrity의 라이브러리를 사용하여 처리했을 때고,
두번째 사진은 Compute 메소드는 Mythosia.Integrity 라이브러리를 개선한 현재 버전입니다.

7개의 좋아요

훌륭한결과네요!

3개의 좋아요

오랜만에 다시 찔끔찔끔 개발을 해볼까합니다.

Bit를 가지고 Byte확장하는것으로…?! 라고 생각했지만 (BitArray이라는 클래스가 너무 잘만들었는걸…) 예제

이번 개발 주제 컨셉

Byte 값을 사용자가 지정해놓은 Enum에 맵핑과
사용자가 지정해놓은 Enum 기반으로 Byte를 만들어주는 그런기능을요…!


예상 컨셉

public enum MACHINESTATE
{
  POWER,
  LEFT,
  RIGHT
 . 
 .
 .
}

new EnumByteConverter(0x05, typeof(MACHINESTATE))
// Result : POWER, RIGHT

new ByteEnumConverter(MACHINESTATE.POWER | MACHINESTATE.LEFT, typeof(MACHINESTATE))
// Result : 0x03

PacketSupoort 연동

new PacketBuilder ()
    .AppdenByte(new ByteEnumConverter(MACHINESTATE.POWER | MACHINESTATE.LEFT, typeof(MACHINESTATE)))
    .
    .
    .
    .
    .Build();

p.s 이번에도 역시 다 같이 이해하고 만들었으면 합니다. 어떠한 훈수든 다 받아들이고 소통하고싶어요!

6개의 좋아요

ENUM에 초기값을 넣지 않으니 여러 변수상황이 빵빵터져나오네요…

public enum MACHINE
{
     POWER,
     RIGHT,
     TOP,
     LIGHT,
     TEMP,
     RUN,
     SOUND,
     ETC
}

Enum은 위 와 같은 형태로 만들어줍니다.
ENUM의 값은 1,2,4,8,10,20,40,80 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80을 의미 합니다.
image

  1. Enum을 통한 Byte 출력하기
public void EnumToByteTest1()
{
    var rest = EnumHelper.Byte (MACHINE.POWER, MACHINE.TOP);

    // Result : 0x05;
}

public void EnumToByteTest2()
{
    var rest = EnumHelper.Byte (MACHINE.POWER, MACHINE.RIGHT);

    // Result : 0x03;
}
  1. Byte를 통한 EnumString 값 얻기
public void EnumString1()
{
    byte data = 0x05;
    var enums = data.ToEnumString<MACHINE> ();

    // Result :  [POWER, TOP]
}
public void EnumString2()
{
    byte data = 0x0A;
    var enums = data.ToEnumString<MACHINE> ();

    // Result :  [RIGHT, LIGHT]
}

public void EnumNull()
{
    byte data = 0x00;
    var enums = data.ToEnumString<MACHINE> ();

    // Result null
}
  1. Byte를 통한 Enum 값 얻기
public void ToEnumTest1()
{
    byte data = 0x10;
    var enums = data.ToEnum<MACHINE> ();

    // Result : Temp
}
 public void ToEnumTest2()
 {
     byte data = 0x05;
     var enums = data.ToEnum<MACHINE> ();

     // Result : POWER, TOP
 }
public void ToEnumTest3()
{
    byte data = 0x00;
    var enums = data.ToEnum<MACHINE> ();

    // Result : NULL
}
2개의 좋아요

제 경험에 enum에 [Flags] Attribute를 붙여주셔야 각 enum 값 별로 비트단위 연산이
원활히 잘 되었던 걸로 기억중입니다.

오잉, 그나저나
1 2 4 8 다음에 10 20 40 80인가요?

2개의 좋아요

네 그거를 봤는데…
개발자가 일일이 Value값을 넣는게 맞나 싶기도해서…
최대한 생략 해볼려고 하다보니 저런결과물이 하핫…

이론적으론 1, 2, 4, 8,16, 32, 64, 128이 맞습니다.


제가 말한 의도는 비트 플래그 사용 개념을 얘기하고자 했던거였습니다.
자세한건
CHATGPT 답변으로…

enum 값을 읽는 이유는 각 상수에 **비트 플래그(Bit Flags)**를 할당하기 위해서입니다. 이 방식은 비트 연산을 통해 여러 값을 동시에 저장하거나 비교할 수 있게 해줍니다. 주로 비트마스크(Bitmask) 방식으로 사용됩니다.

이유: 비트 플래그 (Bit Flags) 사용

각 상수는 2의 제곱수를 값으로 가지는데, 이는 이진수로 표현될 때 각 비트가 고유한 위치를 가질 수 있게 합니다. 이렇게 하면 상수들을 **OR 연산 (|)**으로 결합하여 하나의 값으로 여러 상태를 동시에 표현할 수 있습니다.

예시:

csharp

코드 복사

public enum MACHINE
{
    POWER = 0x01,   // 0000 0001
    RIGHT = 0x02,   // 0000 0010
    TOP   = 0x04,   // 0000 0100
    LIGHT = 0x08,   // 0000 1000
    TEMP  = 0x10,   // 0001 0000
    RUN   = 0x20,   // 0010 0000
    SOUND = 0x40,   // 0100 0000
    ETC   = 0x80    // 1000 0000
}

특징

  1. 2의 제곱수로 값을 설정하면 각 상수는 이진수에서 하나의 비트만 차지하게 됩니다.
  • POWER = 0x01은 이진수 0000 0001이고, 첫 번째 비트를 사용합니다.
  • RIGHT = 0x02는 이진수 0000 0010이고, 두 번째 비트를 사용합니다.
  • TOP = 0x04는 이진수 0000 0100이고, 세 번째 비트를 사용합니다.
  1. **비트 OR 연산 (|)**을 사용하면 여러 상수를 결합하여 하나의 값으로 만들 수 있습니다.
  • 예를 들어, POWER | TOP0000 0001 | 0000 0100으로 결과는 0000 0101이 되어 값은 0x05입니다.
  1. **비트 AND 연산 (&)**을 사용하면 특정 플래그가 설정되었는지 확인할 수 있습니다.
  • 예를 들어, value & MACHINE.POWER == MACHINE.POWERPOWER 플래그가 설정되었는지 확인할 수 있습니다.

활용 예시

csharp

코드 복사

MACHINE settings = MACHINE.POWER | MACHINE.TOP;  // OR 연산으로 두 플래그를 결합
Console.WriteLine(settings);  // 출력: POWER, TOP

bool hasPower = (settings & MACHINE.POWER) == MACHINE.POWER;
Console.WriteLine(hasPower);  // 출력: True

이 방식은 효율적으로 여러 상태를 관리할 수 있게 해주기 때문에 플래그 기반 설정에서 자주 사용됩니다.


다시 보니 1,2,4,8,16,32,64,128 든 0x01, 0x02,0x04,0x08, 0x10,0x20,0x40,0x80이든 같은 값이에요

2개의 좋아요

아 그렇지요! 16진수 표기 0x10이면 맞는 표현이 맞습니다!!
저도 눈이 침침했나 봅니다 (머쓱)

2개의 좋아요