From 34b62886db07b9d44ce1e67950a5598828f9b4da Mon Sep 17 00:00:00 2001 From: Anton Tarasenko Date: Sun, 19 Jun 2022 01:18:47 +0700 Subject: [PATCH] Add more variance to methods that separate by char --- sources/Text/BaseText.uc | 78 ++++++++++++++---- .../FormattingStringParser.uc | 16 ++-- sources/Text/JSON/JSONPointer.uc | 18 ++-- sources/Text/Tests/TEST_Parser.uc | Bin 117808 -> 117712 bytes sources/Text/Tests/TEST_Text.uc | Bin 125080 -> 135698 bytes sources/Text/Tests/TEST_TextAPI.uc | Bin 35902 -> 35896 bytes sources/Text/TextAPI.uc | 31 ++++++- 7 files changed, 110 insertions(+), 33 deletions(-) diff --git a/sources/Text/BaseText.uc b/sources/Text/BaseText.uc index 90e7b48..1c62fde 100644 --- a/sources/Text/BaseText.uc +++ b/sources/Text/BaseText.uc @@ -1332,19 +1332,29 @@ public final function string ToFormattedString( * If `separator` does not match anywhere in the string, method returns a * single-element array containing copy of this `Text`. * - * @param separator Character that separates different parts of this `Text`. - * @param skipEmpty Set this to `true` to filter out empty `MutableText`s - * from the output. - * @return Array of `MutableText`s that contain separated substrings. + * @param separator Character that separates different parts of + * this `Text`. If `separator` is an invalid character, method will do + * nothing and return empty result. + * @param skipEmpty Set this to `true` to filter out empty + * `MutableText`s from the output. + * @param returnMutable Decides whether this method will return + * `Text` (`false`, by default) or `MutableText` (`true`) instances. + * @return Array of `BaseText`s (whether it's `Text` or `MutableText` depends + * on `returnMutable` parameter) that contain separated substrings. + * Always empty if `separator` is an invalid character. */ -public final function array SplitByCharacter( +public final function array SplitByCharacter( Character separator, - optional bool skipEmpty) + optional bool skipEmpty, + optional bool returnMutable) { - local int i, length; - local Character nextCharacter; - local MutableText nextText; - local array result; + local int i, length; + local Character nextCharacter; + local MutableText nextText; + local array result; + if (!_.text.IsValidCharacter(separator)) { + return result; + } length = GetLength(); nextText = _.text.Empty(); i = 0; @@ -1353,8 +1363,14 @@ public final function array SplitByCharacter( nextCharacter = GetCharacter(i); if (_.text.AreEqual(separator, nextCharacter)) { - if (!skipEmpty || !nextText.IsEmpty()) { - result[result.length] = nextText; + if (!skipEmpty || !nextText.IsEmpty()) + { + if (returnMutable) { + result[result.length] = nextText; + } + else { + result[result.length] = nextText.IntoText(); + } } else { _.memory.Free(nextText); @@ -1366,12 +1382,46 @@ public final function array SplitByCharacter( } i += 1; } - if (!skipEmpty || !nextText.IsEmpty()) { - result[result.length] = nextText; + if (!skipEmpty || !nextText.IsEmpty()) + { + if (returnMutable) { + result[result.length] = nextText; + } + else { + result[result.length] = nextText.IntoText(); + } } return result; } +/** + * Splits the string into substrings wherever `separator` occurs, and returns + * array of those strings. + * + * If `separator` does not match anywhere in the string, method returns a + * single-element array containing copy of this `Text`. + * + * @param separatorSource `string`, first character of which will be used as + * a separator. If `separatorSource` is empty, method will do nothing and + * return empty result. + * @param skipEmpty Set this to `true` to filter out empty + * `MutableText`s from the output. + * @param returnMutable Decides whether this method will return + * `Text` (`false`, by default) or `MutableText` (`true`) instances. + * @return Array of `BaseText`s (whether it's `Text` or `MutableText` depends + * on `returnMutable` parameter) that contain separated substrings. + * Always empty if `separatorSource` is empty. + */ +public final function array SplitByCharacterS( + string separatorSource, + optional bool skipEmpty, + optional bool returnMutable) +{ + local Character separator; + separator = _.text.GetCharacter(separatorSource, 0); + return SplitByCharacter(separator, skipEmpty, returnMutable); +} + /** * Returns the index position of the first occurrence of the `otherText` in * the caller `BaseText`, searching forward from index position `fromIndex`. diff --git a/sources/Text/FormattedStrings/FormattingStringParser.uc b/sources/Text/FormattedStrings/FormattingStringParser.uc index 44858b1..791f2df 100644 --- a/sources/Text/FormattedStrings/FormattingStringParser.uc +++ b/sources/Text/FormattedStrings/FormattingStringParser.uc @@ -321,19 +321,19 @@ private final function Color GetColorFor(int index) private final function FormattingInfo ParseFormattingInfo(BaseText colorTag) { - local int i; - local Parser colorParser; - local Color nextColor; - local array specifiedColors; - local array gradientColors; - local array gradientPoints; - local FormattingInfo targetInfo; + local int i; + local Parser colorParser; + local Color nextColor; + local array specifiedColors; + local array gradientColors; + local array gradientPoints; + local FormattingInfo targetInfo; if (colorTag.IsEmpty()) { Report(FSE_EmptyColorTag); return targetInfo; // not colored } - specifiedColors = colorTag.SplitByCharacter(separatorCharacter, true); + specifiedColors = colorTag.SplitByCharacter(separatorCharacter, true, true); for (i = 0; i < specifiedColors.length; i += 1) { colorParser = _.text.Parse(specifiedColors[i]); diff --git a/sources/Text/JSON/JSONPointer.uc b/sources/Text/JSON/JSONPointer.uc index 6e16898..3358714 100644 --- a/sources/Text/JSON/JSONPointer.uc +++ b/sources/Text/JSON/JSONPointer.uc @@ -92,16 +92,17 @@ public final function JSONPointer Empty() */ public final function JSONPointer Set(BaseText pointerAsText) { - local int i; - local bool hasEscapedSequences; - local Component nextComponent; - local array parts; + local int i; + local bool hasEscapedSequences; + local Component nextComponent; + local MutableText nextPart; + local array parts; Empty(); if (pointerAsText == none) { return self; } hasEscapedSequences = (pointerAsText.IndexOf(T(TJSON_ESCAPE)) >= 0); - parts = pointerAsText.SplitByCharacter(T(TSLASH).GetCharacter(0)); + parts = pointerAsText.SplitByCharacter(T(TSLASH).GetCharacter(0),, true); // First element of the array is expected to be empty, so throw it away; // If it is not empty - then `pointerAsText` does not start with "/" and // we will pretend that we have already removed first element, thus @@ -119,13 +120,14 @@ public final function JSONPointer Set(BaseText pointerAsText) // https://tools.ietf.org/html/rfc6901 for (i = 0; i < parts.length; i += 1) { - parts[i].Replace(T(TJSON_ESCAPED_SLASH), T(TSLASH)); - parts[i].Replace(T(TJSON_ESCAPED_ESCAPE), T(TJSON_ESCAPE)); + nextPart = MutableText(parts[i]); + nextPart.Replace(T(TJSON_ESCAPED_SLASH), T(TSLASH)); + nextPart.Replace(T(TJSON_ESCAPED_ESCAPE), T(TJSON_ESCAPE)); } } for (i = 0; i < parts.length; i += 1) { - nextComponent.asText = parts[i]; + nextComponent.asText = MutableText(parts[i]); components[components.length] = nextComponent; } return self; diff --git a/sources/Text/Tests/TEST_Parser.uc b/sources/Text/Tests/TEST_Parser.uc index c04a9ea2dc8b2d9ea4a64d18450d0197299f034c..083a1db7e476be6a69d250251433664e809eed45 100644 GIT binary patch delta 245 zcmdlmgZ;vE_6@9i1)UfY8HyQF8A5=#f}w=LZt{T>(v$z+wwr$5f>CWU|8bS+cgqw%cf_fH*Q!*7bs^qH)TJk!s| lGA;qxJ303n*JR(jNt<8qvtiu4{|XNQM_|#u+4t__cL4nNVh8{L delta 190 zcmcaGoqfX$_6@9iCr_Lv#%#x+FuCDk-9Zy+HKz+H%H4ljYZPO+J5#WAgsv yX`8Jt+c0kCKj6Vel$Oo=k8j|_qEc=0|BEUp7HmF$X$uEYDuGVP+3bI}@f`rELQ%5- diff --git a/sources/Text/Tests/TEST_Text.uc b/sources/Text/Tests/TEST_Text.uc index 8b0502c78b61f55bd188ce28aba3baa717ab9713..ffa7c1346512fe0f78e1e71ddd5145ad23d52932 100644 GIT binary patch delta 1454 zcmc&zT}V@57=Awtf2J#iN&a9vE?ic|v=vGhOY$PN@CO!2VL03TL+8deE9pXrE{ZM! zU+8pK7hQBwD2$SBqM)1dBBHChDd^^`v?^<+#^S$r$KHr_U zMKkw{=V~>pmnP^U4bV7^Qiv7J%W2KR4cZw#sI_yg)>GuCF~p)WR?$h5ltA_ccw|L_ z%dMxl+f&Z3G^ZI$z4ua_RPR0z2RNK6t3H9MI1SQi{4N8-LyG>yxaY?bm$uc20GF-q z<(u<6J0@r!G8Bp-H-Qsl=uv?krYOFrU=P3-!&};yXaq5tF}g8}+VfD@TZ0J6)By^j za1fSEisK!HFRnKf!k4rS&|w@G=Jv%}fyOfZ=8<^raV59hIE+}=&wBOUQQ>6ks^a%k zBkiXEAVL(uF>&)2ABN(f_9P4&k4P@8(^tiqWlTR->ijEH7x$ z^`%tgErmUqy5wxiS-O4BRgqlC*ot$@7k>Vxb#7ng6D5)^2f4_>&0l-1#@7&d57O97 zTLZse?n=5A&lTr{XBN^Qd-jRC9PkLX5XK%{0F|1H>4&|}1hYpEks}#ey;79x{Wr3n zt8ZY}ahn=>A}l=XF5G4?o=tt1BA)JD7h@EQ!$jHjN!^9<UaVgJN;LfitII_hzomNa()9IQ#eCgYa-{N%qC+ZwzB@5_OR7<0% zRD;(=6~CCbfxl~_iJ_SalRzO{>8<1Lm9{LC{hJu<(`{oi-Oe(m=VY1cXM>?W{O6c4 XY@^P@PoMet(3*wqWwvC=+O5&(Y@l5}%!N|2eUxRV+O8|_CCsqIe diff --git a/sources/Text/Tests/TEST_TextAPI.uc b/sources/Text/Tests/TEST_TextAPI.uc index e4b6968e0247a92a7c4ce83345005ea8efc3f1a9..bc339c7291bd9d6f7ebd7dd3d13c6dde40470a15 100644 GIT binary patch delta 20 ccmdltgK5VMrVWwVtWFGx48@yMvTrE>08{`6wg3PC delta 18 acmdlngK6IkrVWwVlMP$NHfLs^R{#J`0|)c~ diff --git a/sources/Text/TextAPI.uc b/sources/Text/TextAPI.uc index e356db2..9c87c53 100644 --- a/sources/Text/TextAPI.uc +++ b/sources/Text/TextAPI.uc @@ -628,12 +628,12 @@ public final function BaseText.Character ToUpper(BaseText.Character character) * @return Separated words. Empty array if passed `source` was empty, * otherwise contains at least one element. */ -public final function array Parts(BaseText source) +public final function array Parts(BaseText source) { - local array result; + local array result; if (source == none) return result; if (source.GetLength() <= 0) return result; - result = source.SplitByCharacter(source.GetCharacter(0)); + result = source.SplitByCharacter(source.GetCharacter(0),, true); // Since we use first character as a separator: // 1. `result` is guaranteed to be non-empty; // 2. We can just drop first (empty) substring. @@ -642,6 +642,31 @@ public final function array Parts(BaseText source) return result; } +/** + * Prepares an array of parts from a given single `BaseText`. + * First character is treated as a separator with which the rest of + * the given `BaseText` is split into parts: + * ~ "/ab/c/d" => ["ab", "c", "d"] + * ~ "zWordzomgzz" => ["Word", "omg", "", ""] + * + * This method is useful to easily prepare array of words for `Parser`'s + * methods. + * + * @param source `string` that contains separator with parts to + * separate and extract. + * @return Separated words. Empty array if passed `source` was empty, + * otherwise contains at least one element. + */ +public final function array PartsS(string source) +{ + local MutableText wrapper; + local array result; + wrapper = _.text.FromStringM(source); + result = Parts(wrapper); + _.memory.Free(wrapper); + return result; +} + /** * Creates a new, empty `MutableText`. *