Ejemplo n.º 1
0
        public void UnpackListStr()
        {
            void Template(string listStr, string delimiter, List <string> compList)
            {
                List <string> destList = StringEscaper.UnpackListStr(listStr, delimiter);

                Assert.AreEqual(compList.Count, destList.Count);
                for (int i = 0; i < destList.Count; i++)
                {
                    Assert.IsTrue(destList[i].Equals(compList[i], StringComparison.Ordinal));
                }
            }

            Template("1|2|3|4|5", "|", new List <string>
            {
                "1",
                "2",
                "3",
                "4",
                "5"
            });
            Template("1|2|3|4|5", "3", new List <string>
            {
                "1|2|",
                "|4|5"
            });
            Template("1|2|3|4|5", "$", new List <string>
            {
                "1|2|3|4|5"
            });
            Template("1|2|3|4|5", "|3|", new List <string>
            {
                "1|2",
                "4|5"
            });

            Template("|a", "|", new List <string>
            {
                string.Empty,
                "a",
            });
            Template("a|", "|", new List <string>
            {
                "a",
                string.Empty,
            });
            Template("|10|98||50|32||0|1|5|2|4|3|", "|", new List <string>
            {
                string.Empty,
                "10",
                "98",
                string.Empty,
                "50",
                "32",
                string.Empty,
                "0",
                "1",
                "5",
                "2",
                "4",
                "3",
                string.Empty,
            });
        }
Ejemplo n.º 2
0
        /// <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);
        }