공부/인프런 - Rookiss

Part 4-4-7. 패킷 직렬화 : Packet Generator #2

셩잇님 2023. 12. 18. 19:48
반응형

 

 

패킷 직렬화

 

 지난 시간에는 Packet Generator를 이용하여 패킷 자동화를 어떻게 하면 구성하고, 사용할 수 있는가? 에 대해서 개념 이해를 가지는 시간을 가졌다. Xml 파일에 담긴 데이터를 읽어와 각 타입별로 적합하게 변환하는 작업이 굉장히 유용하여서 추후 다른 프로젝트에서도 필요하다면 사용할 수 있어보인다.

 


 

🫵 GenPackets.cs

 

🧗‍♀️ 파일 생성

using (XmlReader x = XmlReader.Create("PDL.xml", settings))
            {
                x.MoveToContent();
                while (x.Read())
                {
                    if (x.Depth == 1 && x.NodeType == XmlNodeType.Element)
                        ParsePacket(x);
                }
                File.WriteAllText("GenPackets.cs", genPackets);
            }

 

 기존에 using 문을 통해 랩핑해준 영역에  while 반복문이 종료되는 시점에 File.WriteAllText 메서드를 이용하여 GenPackets.cs 스크립트 파일이 컴퓨터에 생성되도록 한다.

 

⏱️ 내용 넣기

 ParsePacket()에서 ParseMembers() 호출 이후의 데이터를 genPackets에 지난 시간에 선언해준 PacketFormat.packetFormat 형식으로 담아준다. 

 

genPackets += string.Format(PacketFormat.packetFormat, packetName, , ,);

 

 

 packetFormat은 총 4개의 값들을 채워줘야하기에 해당 값들은 아래에서 가져와 담아준다. ({0} ~ {3})

 


 

🧦 ParseMembers() - 기본 형태

 

🥙 기본

 기존 void 타입이었던 함수를 Tuple 자료구조를 이용하여 3개의 string을 이용해 선언하여 3개의 값을 리턴 받도록 한다. 왜냐하면 packetname 등의 함수는 이미 만들어 놓았기 때문이다. 😎

 

 따라서 switch 문을 통해 memberType에 따라 동작하는 코드를 구분해 놓은 곳에 각 타입에 맞도록 값을 설정하여 준다.

 

 

 PacketFormat - memberFormat에 필요한 두 가지는 아래와 같이 미리 선언해둔 memberType과 memberName을 넘겨주고, readCode, writeCode 모두 같은 형식으로 담아준다.

 

memberCode += string.Format(PacketFormat.memberFormat, memberType, memberName);

 

 여기에 readCode에 필요한 memberType의 경우는 ToInt16과 같은 변환 타입이 필요한 위치이기에 간단하게 함수를 만들어 해당 값들을 구해주어 처리한다.

 

ToMemberType을 사용하는 doulbe 자료

 

⚜️ ToMemberType(string memberType)

간단하게 각 타입별로 지정된 반환 타입으로 return 값을 보내준다.

 

 


 

🧦 ParseMembers() - string

 string 또한 비슷하지만, 제작하고 사용한 형태가 다르기에 별도의 Format 타입을 작성해주어 그에 맞는 값을 넣어준다. 

 

 


 

🧦 ParseMembers() - list

 string 형태도 별도의 값을 가지는 것처럼, list 형태도 별도의 값을 주어서 처리해야 한다. list 형식은 앞서 사용한 Tuple 리턴 값을 가진 ParseListPacket()을 만들어주고, 값을 받아와 Tuple.Item 1, 2, 3.. 형태로 사용하면 된다.

 

 

💾 ParseListPacket()

 리스트 형식 처리를 위한 함수를 제작한다. 예외 처리를 위해 검사를 먼저 진행하고, Tupble 타입으로 memberCode를 넣기 위한 값을 가져와 담아준다. 나머지 값들은 이름의 대소문자이기에 이를 처리하기 위한 함수를 별도로 제작한다.

 

 

💾 FirstCharToUpper, Lower

간단하게 첫 문자의 값만 대/소 문자로 바꿔주는 기능을 제공한다.

 

public static string FirstCharToUpper(string input)
        {
            if (string.IsNullOrEmpty(input))
                return "";
            return input[0].ToString().ToUpper() + input.Substring(1); // substring은 인자 부터 값 시작
        }

        public static string FirstCharToLower(string input)
        {
            if (string.IsNullOrEmpty(input))
                return "";
            return input[0].ToString().ToLower() + input.Substring(1);
        }
    }

 

 이 뒤로 저장해두었던 Format에 맞춰 값을 넣어주어 처리한다.

 


 

🧦 ParseMembers() - 최종 😎

 이렇게 적용해주었던 함수들과 값을 바탕으로 Format에 맞게 담아주기만 한다면 작업은 끝이난다.

 

 

public static Tuple<string, string, string> ParseMembers(XmlReader x)
        {
        	... 지난 시간 작성한 내용
        
         switch (memberType)
                {
                    case "bool":
                    case "byte":
                    case "short":
                    case "ushort":
                    case "int":
                    case "long":
                    case "float":
                    case "double":
                        memberCode += string.Format(PacketFormat.memberFormat, memberType, memberName);
                        readCode += string.Format(PacketFormat.readFormat, memberName, ToMemberType(memberType), memberType);
                        writeCode += string.Format(PacketFormat.writeFormat, memberName, memberType);
                        break;
                    case "string":
                        memberCode += string.Format(PacketFormat.memberFormat, memberType, memberName);
                        readCode += string.Format(PacketFormat.readStringFormat, memberName);
                        writeCode += string.Format(PacketFormat.writeStringFormat, memberName);
                        break;
                    case "list":
                        Tuple<string, string, string> t = ParseListPacket(x);
                        memberCode += t.Item1;
                        readCode += t.Item2;
                        writeCode += t.Item3;
                        break;
                    default:
                        break;
                }
        }

 


 

😎 실행 결과

 

 

 정상적으로 잘 불러온다. 👀

 

 

반응형