public static List <CPacketItem> CodeToItems(String str) { List <CPacketItem> items = new List <CPacketItem>(); /* * names.Clear(); * types.Clear(); * sizes.Clear(); * initStr.Clear(); * initValues.Clear(); */ String[] lines = str.Split(";".ToCharArray()); //각 라인으로 나누어서 String[] initValues; for (int i = 0; i < lines.Length; i++) {//각 라인들 String line = lines[i]; line = removeOuterWhiteSpace(line); if (line.Length == 0) { continue; } int firstSpace = -1; int secondSpace = -1; int thirdSpace = -1; int typeSpace = -1; try { firstSpace = line.IndexOf(' '); secondSpace = line.IndexOf(' ', firstSpace + 1); thirdSpace = line.IndexOf(' ', secondSpace + 1); } catch { } if (firstSpace < 0) { firstSpace = line.IndexOf('['); } if (firstSpace < 0) { firstSpace = line.IndexOf('='); } if (firstSpace < 0) { firstSpace = line.Length; } String type = line.Substring(0, firstSpace); if (TypeHandling.getTypeFromTypeName(type) == null) {//첫번째 토큰에서 제대로된 타입이 검출안되면 if (secondSpace > 0) { type = line.Substring(0, secondSpace); //두번째 검색 } else { setError("타입정의가 맞지 않습니다.", i, line); //두번째 스페이스가 없으면 에러 return(null); } if (TypeHandling.getTypeFromTypeName(type) == null) {//두번째 토큰에서 타입틀리면 if (thirdSpace > 0) { type = line.Substring(0, thirdSpace); //세번째 검색 } else { setError("타입정의가 맞지 않습니다.", i, line);//세번째 스페이스 없으면 에러 return(null); } if (TypeHandling.getTypeFromTypeName(type) == null) { //세번째 토큰에서도 타입이 틀리다면 setError("타입정의가 맞지 않습니다.", i, line); //무조건 에러 return(null); } else { typeSpace = thirdSpace; } } else { typeSpace = secondSpace; } } else { typeSpace = firstSpace; } type = type.ToLower(); String rest = line.Substring(typeSpace); if (type.ToLower().Equals("string") == false) { rest = rest.Trim(); // rest.Replace(" ", ""); //string이 아니라면 나머지에서는 빈칸이 필요없다. } //초기값 입력받기 bool isSwap = false; if (rest.Length > 5 && rest.Substring(0, 5).ToLower().Equals("swap@")) //swap명령어. { rest = rest.Substring(5); //명령어 삭제. isSwap = true; //값을 핸들링할 때 swap한다. } String initValue = "0"; //기본값은 0이다. String[] token = rest.Split("=".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); int openBracket; int closeBracket; if (token.Length == 2) { token[0] = token[0].Trim(); token[1] = token[1].Trim(); initValue = token[1]; } else if (token.Length > 2) { setError("= 이 2번 이상 들어갑니다.", i, line); return(null); } rest = token[0]; //=오른쪽의 값은 잘라버림. //배열검사 openBracket = rest.IndexOf('['); closeBracket = rest.IndexOf(']'); int arrSize = 1; //arrSize가 1이면 단순값이다. if (openBracket > 0 || closeBracket > 0) //배열인지 검사하여 { if (openBracket < 0 || closeBracket < 0) { setError("배열을 나타내는 [,] 기호 둘 중 하나가 없습니다", i, line); return(null); } String numStr = rest.Substring(openBracket + 1, closeBracket - openBracket - 1); if (numStr.Length == 0) { arrSize = initValue.Split(",".ToCharArray()).Length; rest = rest.Substring(0, openBracket); //배열 크기를 가져왔으므로 배열기호그룹 삭제 } else { int num = -1; if (Int32.TryParse(numStr, out num) == false) { setError("배열기호[] 안에는 정수가 와야합니다.", i, line); return(null); } else { if (num <= 0) { setError("배열의 크기는 1보다 작을 수 없습니다.", i, line); return(null); } else { arrSize = num; rest = rest.Substring(0, openBracket); //배열 크기를 가져왔으므로 배열기호그룹 삭제 } } } } //배열검사 끝. //초기값 검사 openBracket = initValue.IndexOf('{'); closeBracket = initValue.IndexOf('}'); //initValues.Add(new object[arrSize]);//값 배열을 만들어줌 initValues = new String[arrSize]; if (openBracket >= 0 || closeBracket >= 0 || initValue.IndexOf(',') >= 0) //배열형식의 초기값이라면 { if (openBracket < 0 || closeBracket < 0) { setError("{ 나 } 중에서 하나가 없습니다.", i, line); return(null); } String numStr = initValue.Substring(openBracket + 1, closeBracket - openBracket - 1); //브래킷 내부의 내용 가져옴 token = numStr.Split(",".ToCharArray()); if (token.Length > arrSize) //배열의 크기보다 클 때 { setError("배열의 크기를 넘어서 초기화를 시도했습니다. size:" + arrSize + " this:" + token.Length, i, line); return(null); } string newInitStr = ""; for (int j = 0; j < token.Length; j++) //초기값들의 타입을 검사한다. { Int64 intValue = 0; Double doubleValue = 0.0; String strValue = ""; initValues[j] = token[j]; TypeHandling.getValueAndType(token[j], ref intValue, ref doubleValue, ref strValue); /* * switch (TypeHandling.getValueAndType(token[j], ref intValue, ref doubleValue, ref strValue)) * {//hex나 oct형식등을 모두 숫자형으로 먼저 치환한다. * case TypeHandling.TypeName.Integer: * if (isSwap) * { * if (TypeHandling.getTypeFromTypeName(type) == typeof(byte)) initValues[j] = Swaper.swap<byte>((byte)intValue).ToString(); * else if (TypeHandling.getTypeFromTypeName(type) == typeof(short)) initValues[j] = Swaper.swap<short>((short)intValue).ToString(); * else if (TypeHandling.getTypeFromTypeName(type) == typeof(int)) initValues[j] = Swaper.swap<int>((int)intValue).ToString(); * else if (TypeHandling.getTypeFromTypeName(type) == typeof(long)) initValues[j] = Swaper.swap<long>((long)intValue).ToString(); * else if (TypeHandling.getTypeFromTypeName(type) == typeof(ushort)) initValues[j] = Swaper.swap<ushort>((ushort)intValue).ToString(); * else if (TypeHandling.getTypeFromTypeName(type) == typeof(uint)) initValues[j] = Swaper.swap<uint>((uint)intValue).ToString(); * else if (TypeHandling.getTypeFromTypeName(type) == typeof(ulong)) initValues[j] = Swaper.swap<ulong>((ulong)intValue).ToString(); * } * else * { * initValues[j] = intValue.ToString(); * } * break; * case TypeHandling.TypeName.Float: * initValues[j] = doubleValue.ToString(); * break; * case TypeHandling.TypeName.String: * initValues[j] = strValue; * break; * } */ if (j != 0) { newInitStr += ","; } newInitStr += initValues[j].ToString(); if (TypeHandling.isValidType(initValues[j].ToString(), type) == false) { setError("초기값이 타입과 다릅니다.Type:" + type + " value:" + token[j], i, line); return(null); } } initValue = newInitStr; } else //배열형식이 아니라 단순값일 때 { if (initValue[0] != '-' && Char.IsDigit(initValue[0]) == false && initValue[0] != '\"')//첫글자가 문자로 시작하고, 따옴표(")로시작하지 않으면 함수나 변수이거나 문자열이다. { int argstart = initValue.IndexOf("("); int argend = initValue.LastIndexOf(")"); if (argstart < 0 && argend < 0 && initValue.IndexOf("@") == 0)//변수임. { items[i].Var = new VariableInfo(initValue); } else if (argstart > 1 && argend == initValue.Length - 1) {//함수임. String funcName = initValue.Substring(0, argstart); String[] args = initValue.Substring(argstart + 1, argend - 1 - argstart).Split(",".ToCharArray()); if (FunctionsList.ContainsKey(funcName)) { items[i].Function = new FunctionInfo(FunctionsList[funcName], args); } else { items[i].Function = new FunctionInfo(funcName, null, args); } } else if (type.Equals("string")) { initValue = initValue.Replace("\\\"", "@'aAiIOo~{|\\]~"); //\"를 구분하기 위해 모두 특수한 문자로 바꾸어준다. initValue = initValue.Replace("\"", ""); initValue = initValue.Replace("@'aAiIOo~{|\\]~", "\\\""); //\"를 다시 복구한다. initValues[0] = initValue; //따옴표를 지우고 넣어준다. } else { setError("함수정의가 맞지 않습니다. 괄호가 완성되지 않았습니다.", i, line); return(null); } } else { if (type.Equals("sring")) { initValue = initValue.Replace("\\\"", "@'aAiIOo~{|\\]~"); //\"를 구분하기 위해 모두 특수한 문자로 바꾸어준다. initValue = initValue.Replace("\"", ""); initValue = initValue.Replace("@'aAiIOo~{|\\]~", "\\\""); //\"를 다시 복구한다. initValues[0] = initValue; //따옴표를 지우고 넣어준다. } else if (initValue.Length == 0) { initValues = new String[] { "0" } } ; else { for (int initc = 0; initc < arrSize; initc++) { initValues[initc] = initValue; //모두 같은 값으로 채워줌. } } } #region old /* * switch (TypeHandling.getValueAndType(initValue, ref intValue, ref doubleValue, ref strValue)) * {//hex나 oct형식등을 모두 숫자형으로 먼저 치환한다. * case TypeHandling.TypeName.Integer: * //initValues[i][0] = intValue; * if (isSwap) * { * if (TypeHandling.getTypeFromTypeName(type) == typeof(byte)) initValues[0] = Swaper.swap<byte>((byte)intValue).ToString(); * else if (TypeHandling.getTypeFromTypeName(type) == typeof(short)) initValues[0] = Swaper.swap<short>((short)intValue).ToString(); * else if (TypeHandling.getTypeFromTypeName(type) == typeof(int)) initValues[0] = Swaper.swap<int>((int)intValue).ToString(); * else if (TypeHandling.getTypeFromTypeName(type) == typeof(long)) initValues[0] = Swaper.swap<long>((long)intValue).ToString(); * else if (TypeHandling.getTypeFromTypeName(type) == typeof(ushort)) initValues[0] = Swaper.swap<ushort>((ushort)intValue).ToString(); * else if (TypeHandling.getTypeFromTypeName(type) == typeof(uint)) initValues[0] = Swaper.swap<uint>((uint)intValue).ToString(); * else if (TypeHandling.getTypeFromTypeName(type) == typeof(ulong)) initValues[0] = Swaper.swap<ulong>((ulong)intValue).ToString(); * } * else * { * initValues[0] = intValue.ToString(); * } * break; * case TypeHandling.TypeName.Float: * initValues[0] = doubleValue.ToString(); * break; * case TypeHandling.TypeName.String: * initValues[0] = strValue; * break; * } * */ #endregion if (TypeHandling.isValidType(initValues[0].ToString(), type) == false) { String error = "초기값이 타입과 다릅니다."; if (TypeHandling.getTypeKind(initValue) == TypeHandling.TypeName.HexString) { error += " hex값을 넣어주실 때는 unsigned 타입으로 지정하십시오."; } setError(error, i, line); return(null); } initValue = initValues[0].ToString(); } //초기값 검사 끝 rest = rest.Replace(" ", ""); //변수명검사 for (int j = 0; j < rest.Length; j++) //변수명 검사 { if ((Char.IsLetterOrDigit(rest[j]) == false) && rest[j].Equals('_') == false) { setError("변수명에는 기호가 들어갈 수 없습니다.", i, line); return(null); } else if (j == 0 && Char.IsDigit(rest[j])) { setError("변수명의 첫번째에는 숫자가 들어갈 수 없습니다.", i, line); return(null); } }//변수명 검사 끝 if (rest.Length == 0) { rest = "var" + i; } CPacketItem item = new CPacketItem(rest, type, arrSize, initValues); item.IsSwap = isSwap; //item.InitString = initValue; items.Add(item); /* * ns.names.Add(rest); * ns.sizes.Add(arrSize); * ns.types.Add(type); * ns.isSwap.Add(isSwap); * ns.initStr.Add(initValue); */ }//각 라인들 검색 끝 return(items); }
public NetStruct parsing(String str = null) { if (str == null || str.Length == 0) { str = nativeText; } else { nativeText = str; } NetStruct ns = new NetStruct(); String[] lines = str.Split(";".ToCharArray()); //각 라인으로 나누어서 for (int i = 0; i < lines.Length; i++) {//각 라인들 String line = lines[i]; line = removeWhiteSpace(line); if (line.Length == 0) { continue; } int firstSpace = -1; int secondSpace = -1; int thirdSpace = -1; int typeSpace = -1; try { firstSpace = line.IndexOf(' '); secondSpace = line.IndexOf(' ', firstSpace); thirdSpace = line.IndexOf(' ', secondSpace); } catch { } if (firstSpace < 0) { firstSpace = line.IndexOf('['); } if (firstSpace < 0) { firstSpace = line.IndexOf('='); } if (firstSpace < 0) { firstSpace = line.Length; } String type = line.Substring(0, firstSpace); if (TypeHandling.getTypeFromTypeName(type) == null) {//첫번째 토큰에서 제대로된 타입이 검출안되면 if (secondSpace > 0) { type = line.Substring(0, secondSpace); //두번째 검색 } else { setError("타입정의가 맞지 않습니다.", i, line); //두번째 스페이스가 없으면 에러 return(null); } if (TypeHandling.getTypeFromTypeName(type) == null) {//두번째 토큰에서 타입틀리면 if (thirdSpace > 0) { type = line.Substring(0, thirdSpace); //세번째 검색 } else { setError("타입정의가 맞지 않습니다.", i, line);//세번째 스페이스 없으면 에러 return(null); } if (TypeHandling.getTypeFromTypeName(type) == null) { //세번째 토큰에서도 타입이 틀리다면 setError("타입정의가 맞지 않습니다.", i, line); //무조건 에러 return(null); } else { typeSpace = thirdSpace; } } else { typeSpace = secondSpace; } } else { typeSpace = firstSpace; } String rest = line.Substring(typeSpace); rest = rest.Replace(" ", ""); //나머지에서는 빈칸이 필요없다. //초기값 입력받기 String initValue = "0"; //기본값은 0이다. String[] token = rest.Split("=".ToCharArray()); int openBracket; int closeBracket; if (token.Length == 2) { initValue = token[1]; } else if (token.Length > 2) { setError("= 이 2번 이상 들어갑니다.", i, line); return(null); } rest = token[0]; //=오른쪽의 값은 잘라버림. //배열검사 openBracket = rest.IndexOf('['); closeBracket = rest.IndexOf(']'); int arrSize = 1; if (openBracket > 0 || closeBracket > 0) //배열인지 검사하여 { if (openBracket < 0 || closeBracket < 0) { setError("배열을 나타내는 [,] 기호 둘 중 하나가 없습니다", i, line); return(null); } String numStr = rest.Substring(openBracket + 1, closeBracket - openBracket - 1); if (numStr.Length == 0) { arrSize = initValue.Split(",".ToCharArray()).Length; rest = rest.Substring(0, openBracket); //배열 크기를 가져왔으므로 배열기호그룹 삭제 } else { int num = -1; if (Int32.TryParse(numStr, out num) == false) { setError("배열기호[] 안에는 정수가 와야합니다.", i, line); return(null); } else { if (num <= 0) { setError("배열의 크기는 1보다 작을 수 없습니다.", i, line); return(null); } else { arrSize = num; rest = rest.Substring(0, openBracket); //배열 크기를 가져왔으므로 배열기호그룹 삭제 } } } } //배열검사 끝. //초기값 검사 openBracket = initValue.IndexOf('{'); closeBracket = initValue.IndexOf('}'); if (openBracket >= 0 || closeBracket >= 0 || initValue.IndexOf(',') >= 0) //배열형식의 초기값이라면 { if (openBracket < 0 || closeBracket < 0) { setError("{ 나 } 중에서 하나가 없습니다.", i, line); return(null); } String numStr = initValue.Substring(openBracket + 1, closeBracket - openBracket - 1); //브래킷 내부의 내용 가져옴 token = numStr.Split(",".ToCharArray()); if (token.Length > arrSize) //배열의 크기보다 클 때 { setError("배열의 크기를 넘어서 초기화를 시도했습니다. size:" + arrSize + " this:" + token.Length, i, line); return(null); } for (int j = 0; j < token.Length; j++) //초기값들의 타입을 검사한다. { if (TypeHandling.isValidType(token[j], type) == false) { setError("초기값이 타입과 다릅니다.Type:" + type + " value:" + token[j], i, line); return(null); } } } else if (TypeHandling.isValidType(initValue, type) == false) //배열형식이 아니라 단순값일 때 { setError("초기값이 타입과 다릅니다.", i, line); return(null); } //초기값 검사 끝 //변수명검사 for (int j = 0; j < rest.Length; j++) //변수명 검사 { if (Char.IsLetterOrDigit(rest[j]) == false) { setError("변수명에는 기호가 들어갈 수 없습니다.", i, line); return(null); } else if (j == 0 && Char.IsDigit(rest[j])) { setError("변수명의 첫번째에는 숫자가 들어갈 수 없습니다.", i, line); return(null); } }//변수명 검사 끝 if (rest.Length == 0) { rest = "var" + i; } ns.names.Add(rest); ns.sizes.Add(arrSize); ns.types.Add(type); ns.init.Add(initValue); }//각 라인들 검색 끝 this.names.Clear();; this.sizes.Clear(); this.types.Clear(); this.init.Clear(); this.names = ns.names; this.sizes = ns.sizes; this.types = ns.types; this.init = ns.init; return(ns); }