Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions OpenDreamRuntime/Procs/Native/DreamProcNative.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public static void SetupNativeProcs(DreamObjectTree objectTree) {
objectTree.SetGlobalNativeProc(DreamProcNativeRoot.NativeProc_splicetext);
objectTree.SetGlobalNativeProc(DreamProcNativeRoot.NativeProc_splicetext_char);
objectTree.SetGlobalNativeProc(DreamProcNativeRoot.NativeProc_splittext);
objectTree.SetGlobalNativeProc(DreamProcNativeRoot.NativeProc_splittext_char);
objectTree.SetGlobalNativeProc(DreamProcNativeRoot.NativeProc_stat);
objectTree.SetGlobalNativeProc(DreamProcNativeRoot.NativeProc_statpanel);
objectTree.SetGlobalNativeProc(DreamProcNativeRoot.NativeProc_text2ascii);
Expand Down
42 changes: 29 additions & 13 deletions OpenDreamRuntime/Procs/Native/DreamProcNativeRoot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1594,7 +1594,7 @@

public static DreamValue _length(DreamValue value, bool countBytes) {
if (value.TryGetValueAsString(out var str)) {
return new DreamValue(countBytes ? str.Length : str.EnumerateRunes().Count());
return new DreamValue(countBytes ? Encoding.UTF8.GetByteCount(str) : str.EnumerateRunes().Count());
} else if (value.TryGetValueAsDreamList(out var list)) {
return new DreamValue(list.GetLength());
} else if (value.Type is DreamValueType.Float or DreamValueType.DreamObject or DreamValueType.DreamType) {
Expand Down Expand Up @@ -2779,30 +2779,46 @@
[DreamProcParameter("End", Type = DreamValueTypeFlag.Float, DefaultValue = 0)]
[DreamProcParameter("include_delimiters", Type = DreamValueTypeFlag.Float, DefaultValue = 0)]
public static DreamValue NativeProc_splittext(NativeProc.Bundle bundle, DreamObject? src, DreamObject? usr) {
return SplitText(bundle, src, usr, true);
}

[DreamProc("splittext_char")]
[DreamProcParameter("Text", Type = DreamValueTypeFlag.String)]
[DreamProcParameter("Delimiter", Type = DreamValueTypeFlag.String)]
[DreamProcParameter("Start", Type = DreamValueTypeFlag.Float, DefaultValue = 1)]
[DreamProcParameter("End", Type = DreamValueTypeFlag.Float, DefaultValue = 0)]
[DreamProcParameter("include_delimiters", Type = DreamValueTypeFlag.Float, DefaultValue = 0)]
public static DreamValue NativeProc_splittext_char(NativeProc.Bundle bundle, DreamObject? src, DreamObject? usr) {
return SplitText(bundle, src, usr, false);
}

private static DreamValue SplitText(NativeProc.Bundle bundle, DreamObject? src, DreamObject? usr, bool useByteLength) {

Check warning

Code scanning / InspectCode

Unused parameter: Private accessibility Warning

Parameter 'src' is never used

Check warning

Code scanning / InspectCode

Unused parameter: Private accessibility Warning

Parameter 'usr' is never used
if (!bundle.GetArgument(0, "Text").TryGetValueAsString(out var text)) {
return new DreamValue(bundle.ObjectTree.CreateList());
}

int consideredLength = useByteLength ? Encoding.UTF8.GetByteCount(text) : text.EnumerateRunes().Count();
int start = 0;
int end = 0;
if(bundle.GetArgument(2, "Start").TryGetValueAsInteger(out start))
if (bundle.GetArgument(2, "Start").TryGetValueAsInteger(out start))
start -= 1; //1-indexed
if(bundle.GetArgument(3, "End").TryGetValueAsInteger(out end))
if(end == 0)
end = text.Length;
if (bundle.GetArgument(3, "End").TryGetValueAsInteger(out end))
if (end == 0)
end = consideredLength;
else
end -= 1; //1-indexed

bool includeDelimiters = false;
if(bundle.GetArgument(4, "include_delimiters").TryGetValueAsInteger(out var includeDelimitersInt))
if (bundle.GetArgument(4, "include_delimiters").TryGetValueAsInteger(out var includeDelimitersInt))
includeDelimiters = includeDelimitersInt != 0; //idk why BYOND doesn't just use truthiness, but it doesn't, so...

if(start > 0 || end < text.Length)
text = text[Math.Max(start,0)..Math.Min(end, text.Length)];
if (start > 0 || end < consideredLength)
text = text[Math.Max(start, 0)..Math.Min(end, consideredLength)];

var delim = bundle.GetArgument(1, "Delimiter"); //can either be a regex or string

if (delim.TryGetValueAsDreamObject<DreamObjectRegex>(out var regexObject)) {
if(includeDelimiters) {
if (includeDelimiters) {
var values = new List<string>();
int pos = 0;
foreach (Match m in regexObject.Regex.Matches(text)) {
Expand All @@ -2818,13 +2834,13 @@
}
} else if (delim.TryGetValueAsString(out var delimiter)) {
string[] splitText;
if(includeDelimiters) {
if (includeDelimiters) {
//basically split on delimeter, and then add the delimiter back in after each split (except the last one)
splitText= text.Split(delimiter);
splitText = text.Split(delimiter);
string[] longerSplitText = new string[splitText.Length * 2 - 1];
for(int i = 0; i < splitText.Length; i++) {
for (int i = 0; i < splitText.Length; i++) {
longerSplitText[i * 2] = splitText[i];
if(i < splitText.Length - 1)
if (i < splitText.Length - 1)
longerSplitText[i * 2 + 1] = delimiter;
}

Expand Down
Loading