public void PackListStr() { void Template(List <string> list, string delimiter, string comp) { string dest = StringEscaper.PackListStr(list, delimiter); Assert.IsTrue(dest.Equals(comp, StringComparison.Ordinal)); } Template(new List <string> { "1", "2", "3", "4", "5" }, "|", "1|2|3|4|5"); Template(new List <string> { "1", "2", "3", "4", "5" }, "$", "1$2$3$4$5"); Template(new List <string> { "1", "2", "3", "4", "5" }, "12", "1122123124125"); }
public static List <LogInfo> IniReadSection(EngineState s, CodeCommand cmd) { List <LogInfo> logs = new List <LogInfo>(); CodeInfo_IniReadSection info = cmd.Info.Cast <CodeInfo_IniReadSection>(); string fileName = StringEscaper.Preprocess(s, info.FileName); string section = StringEscaper.Preprocess(s, info.Section); string delim = "|"; if (info.Delim != null) { delim = StringEscaper.Preprocess(s, info.Delim); } Debug.Assert(fileName != null, $"{nameof(fileName)} != null"); Debug.Assert(section != null, $"{nameof(section)} != null"); if (section.Length == 0) { return(LogInfo.LogErrorMessage(logs, "Section name cannot be empty")); } IniKey[] keys = IniReadWriter.ReadSection(fileName, section); if (keys != null) { List <string> kvList = new List <string>(keys.Length * 2); foreach (IniKey k in keys) { kvList.Add(k.Key); kvList.Add(k.Value); } string destStr = StringEscaper.PackListStr(kvList, delim); logs.Add(new LogInfo(LogState.Success, $"Section [{section}] read from [{fileName}]")); string escapedValue = StringEscaper.Escape(destStr, false, true); List <LogInfo> varLogs = Variables.SetVariable(s, info.DestVar, escapedValue, false, false, false); logs.AddRange(varLogs); } else { logs.Add(new LogInfo(LogState.Ignore, $"Section [{section}] does not exist in [{fileName}]")); List <LogInfo> varLogs = Variables.SetVariable(s, info.DestVar, string.Empty, false, false, false); logs.AddRange(varLogs); } return(logs); }
/// <summary> /// PEBakery uses 1-based index for concated list /// </summary> /// <param name="s"></param> /// <param name="cmd"></param> /// <returns></returns> public static List <LogInfo> List(EngineState s, CodeCommand cmd) { List <LogInfo> logs = new List <LogInfo>(); CodeInfo_List info = cmd.Info.Cast <CodeInfo_List>(); string listStr = string.Empty; string listVar = info.SubInfo.ListVar; if (Variables.ContainsKey(s, listVar) == true) { listStr = StringEscaper.Preprocess(s, listVar); } ListType type = info.Type; string delimiter = "|"; switch (type) { case ListType.Get: { ListInfo_Get subInfo = info.SubInfo.Cast <ListInfo_Get>(); string indexStr = StringEscaper.Preprocess(s, subInfo.Index); if (!NumberHelper.ParseInt32(indexStr, out int index)) { return(LogInfo.LogErrorMessage(logs, $"[{indexStr}] is not a valid positive integer")); } if (index <= 0) { return(LogInfo.LogErrorMessage(logs, $"[{indexStr}] is not a valid positive integer")); } if (subInfo.Delim != null) { delimiter = StringEscaper.Preprocess(s, subInfo.Delim); } List <string> list = StringEscaper.UnpackListStr(listStr, delimiter); string destStr = list[index - 1]; List <LogInfo> varLogs = Variables.SetVariable(s, subInfo.DestVar, destStr); logs.AddRange(varLogs); } break; case ListType.Set: { ListInfo_Set subInfo = info.SubInfo.Cast <ListInfo_Set>(); string indexStr = StringEscaper.Preprocess(s, subInfo.Index); string item = StringEscaper.Preprocess(s, subInfo.Item); if (!NumberHelper.ParseInt32(indexStr, out int index)) { return(LogInfo.LogErrorMessage(logs, $"[{indexStr}] is not a valid positive integer")); } if (index <= 0) { return(LogInfo.LogErrorMessage(logs, $"[{indexStr}] is not a valid positive integer")); } if (subInfo.Delim != null) { delimiter = StringEscaper.Preprocess(s, subInfo.Delim); } List <string> list = StringEscaper.UnpackListStr(listStr, delimiter); list[index - 1] = item; listStr = StringEscaper.PackListStr(list, delimiter); List <LogInfo> varLogs = Variables.SetVariable(s, subInfo.ListVar, listStr); logs.AddRange(varLogs); } break; case ListType.Append: { ListInfo_Append subInfo = info.SubInfo.Cast <ListInfo_Append>(); string item = StringEscaper.Preprocess(s, subInfo.Item); if (subInfo.Delim != null) { delimiter = StringEscaper.Preprocess(s, subInfo.Delim); } List <string> list = StringEscaper.UnpackListStr(listStr, delimiter); list.Add(item); listStr = StringEscaper.PackListStr(list, delimiter); List <LogInfo> varLogs = Variables.SetVariable(s, subInfo.ListVar, listStr); logs.AddRange(varLogs); } break; case ListType.Insert: { ListInfo_Insert subInfo = info.SubInfo.Cast <ListInfo_Insert>(); string indexStr = StringEscaper.Preprocess(s, subInfo.Index); string item = StringEscaper.Preprocess(s, subInfo.Item); if (!NumberHelper.ParseInt32(indexStr, out int index)) { return(LogInfo.LogErrorMessage(logs, $"[{indexStr}] is not a valid positive integer")); } if (index <= 0) { return(LogInfo.LogErrorMessage(logs, $"[{indexStr}] is not a valid positive integer")); } if (subInfo.Delim != null) { delimiter = StringEscaper.Preprocess(s, subInfo.Delim); } List <string> list = StringEscaper.UnpackListStr(listStr, delimiter); list.Insert(index - 1, item); listStr = StringEscaper.PackListStr(list, delimiter); List <LogInfo> varLogs = Variables.SetVariable(s, subInfo.ListVar, listStr); logs.AddRange(varLogs); } break; case ListType.Remove: case ListType.RemoveX: { ListInfo_Remove subInfo = info.SubInfo.Cast <ListInfo_Remove>(); string item = StringEscaper.Preprocess(s, subInfo.Item); if (subInfo.Delim != null) { delimiter = StringEscaper.Preprocess(s, subInfo.Delim); } List <string> list = StringEscaper.UnpackListStr(listStr, delimiter); StringComparison comp; switch (type) { case ListType.Remove: comp = StringComparison.OrdinalIgnoreCase; break; case ListType.RemoveX: comp = StringComparison.Ordinal; break; default: throw new InternalException("Internal Logic Error at CommandList"); } int deletedItemCount = list.RemoveAll(x => x.Equals(item, comp)); if (0 < deletedItemCount) { logs.Add(new LogInfo(LogState.Success, $"[{deletedItemCount}] items were deleted")); listStr = StringEscaper.PackListStr(list, delimiter); List <LogInfo> varLogs = Variables.SetVariable(s, subInfo.ListVar, listStr); logs.AddRange(varLogs); } else { logs.Add(new LogInfo(LogState.Ignore, "No items were deleted")); } } break; case ListType.RemoveAt: { ListInfo_RemoveAt subInfo = info.SubInfo.Cast <ListInfo_RemoveAt>(); string indexStr = StringEscaper.Preprocess(s, subInfo.Index); if (subInfo.Delim != null) { delimiter = StringEscaper.Preprocess(s, subInfo.Delim); } if (!NumberHelper.ParseInt32(indexStr, out int index)) { return(LogInfo.LogErrorMessage(logs, $"[{indexStr}] is not a valid positive integer")); } if (index <= 0) { return(LogInfo.LogErrorMessage(logs, $"[{indexStr}] is not a valid positive integer")); } List <string> list = StringEscaper.UnpackListStr(listStr, delimiter); list.RemoveAt(index - 1); listStr = StringEscaper.PackListStr(list, delimiter); List <LogInfo> varLogs = Variables.SetVariable(s, subInfo.ListVar, listStr); logs.AddRange(varLogs); } break; case ListType.Count: { ListInfo_Count subInfo = info.SubInfo.Cast <ListInfo_Count>(); if (subInfo.Delim != null) { delimiter = StringEscaper.Preprocess(s, subInfo.Delim); } List <string> list = StringEscaper.UnpackListStr(listStr, delimiter); int destInt = list.Count; List <LogInfo> varLogs = Variables.SetVariable(s, subInfo.DestVar, destInt.ToString()); logs.AddRange(varLogs); } break; case ListType.Pos: case ListType.PosX: case ListType.LastPos: case ListType.LastPosX: { ListInfo_Pos subInfo = info.SubInfo.Cast <ListInfo_Pos>(); string item = StringEscaper.Preprocess(s, subInfo.Item); if (subInfo.Delim != null) { delimiter = StringEscaper.Preprocess(s, subInfo.Delim); } List <string> list = StringEscaper.UnpackListStr(listStr, delimiter); int destInt; switch (type) { case ListType.Pos: destInt = list.FindIndex(x => x.Equals(item, StringComparison.OrdinalIgnoreCase)); break; case ListType.PosX: destInt = list.FindIndex(x => x.Equals(item, StringComparison.Ordinal)); break; case ListType.LastPos: destInt = list.FindLastIndex(x => x.Equals(item, StringComparison.OrdinalIgnoreCase)); break; case ListType.LastPosX: destInt = list.FindLastIndex(x => x.Equals(item, StringComparison.Ordinal)); break; default: throw new InternalException("Internal Logic Error at CommandList"); } destInt += 1; List <LogInfo> varLogs = Variables.SetVariable(s, subInfo.DestVar, destInt.ToString()); logs.AddRange(varLogs); } break; case ListType.Sort: case ListType.SortX: case ListType.SortN: case ListType.SortNX: { ListInfo_Sort subInfo = info.SubInfo.Cast <ListInfo_Sort>(); string order = StringEscaper.Preprocess(s, subInfo.Order); if (subInfo.Delim != null) { delimiter = StringEscaper.Preprocess(s, subInfo.Delim); } bool reverse; if (order.Equals("ASC", StringComparison.OrdinalIgnoreCase)) { reverse = false; } else if (order.Equals("DESC", StringComparison.OrdinalIgnoreCase)) { reverse = true; } else { return(LogInfo.LogErrorMessage(logs, "Order must be [ASC] or [DESC]")); } List <string> list = StringEscaper.UnpackListStr(listStr, delimiter); switch (type) { case ListType.Sort: list = list .OrderBy(x => x, StringComparer.OrdinalIgnoreCase) .ThenBy(x => x, StringComparer.Ordinal) .ToList(); break; case ListType.SortX: list.Sort(StringComparer.Ordinal); break; case ListType.SortN: list = list .OrderBy(x => x, StringComparer.OrdinalIgnoreCase.WithNaturalSort()) .ThenBy(x => x, StringComparer.Ordinal.WithNaturalSort()) .ToList(); break; case ListType.SortNX: list.Sort(StringComparer.Ordinal.WithNaturalSort()); break; default: throw new InternalException("Internal Logic Error at CommandList"); } if (reverse) { list.Reverse(); } listStr = StringEscaper.PackListStr(list, delimiter); List <LogInfo> varLogs = Variables.SetVariable(s, subInfo.ListVar, listStr); logs.AddRange(varLogs); } break; default: // Error throw new InternalException("Internal Logic Error at CommandList"); } return(logs); }
public static List <LogInfo> IniReadSectionOp(EngineState s, CodeCommand cmd) { List <LogInfo> logs = new List <LogInfo>(); CodeInfo_IniReadSectionOp infoOp = cmd.Info.Cast <CodeInfo_IniReadSectionOp>(); string fileName = StringEscaper.Preprocess(s, infoOp.Infos[0].FileName); Debug.Assert(fileName != null, $"{nameof(fileName)} != null"); string[] sections = new string[infoOp.Cmds.Count]; string[] destVars = new string[infoOp.Cmds.Count]; string[] delims = new string[infoOp.Cmds.Count]; for (int i = 0; i < sections.Length; i++) { CodeInfo_IniReadSection info = infoOp.Infos[i]; string section = StringEscaper.Preprocess(s, info.Section); if (section.Length == 0) { return(LogInfo.LogErrorMessage(logs, "Section name cannot be empty")); } sections[i] = section; destVars[i] = info.DestVar; delims[i] = "|"; if (info.Delim != null) { delims[i] = StringEscaper.Preprocess(s, info.Delim); } } Dictionary <string, IniKey[]> keyDict = IniReadWriter.ReadSections(fileName, sections); int successCount = 0; for (int i = 0; i < sections.Length; i++) { string section = sections[i]; string delim = delims[i]; IniKey[] keys = keyDict[section]; CodeCommand subCmd = infoOp.Cmds[i]; if (keys != null) { List <string> kvList = new List <string>(keys.Length * 2); foreach (IniKey k in keys) { kvList.Add(k.Key); kvList.Add(k.Value); } string destStr = StringEscaper.PackListStr(kvList, delim); logs.Add(new LogInfo(LogState.Success, $"Section [{section}] read", subCmd)); string escapedValue = StringEscaper.Escape(destStr, false, true); List <LogInfo> varLogs = Variables.SetVariable(s, destVars[i], escapedValue, false, false, false); LogInfo.AddCommand(varLogs, subCmd); logs.AddRange(varLogs); } else { logs.Add(new LogInfo(LogState.Ignore, $"Section [{section}] does not exist", subCmd)); List <LogInfo> varLogs = Variables.SetVariable(s, destVars[i], string.Empty, false, false, false); LogInfo.AddCommand(varLogs, subCmd); logs.AddRange(varLogs); } } logs.Add(new LogInfo(LogState.Success, $"Read [{successCount}] sections from [{fileName}]", cmd)); return(logs); }