using Qrakhen.Qamp.Core.Collections; using System.Text; namespace Qrakhen.Qamp.Core.Values.Objects; public class String(string? value) : Obj(ValueType.String) { // yea that's quite temporary private static readonly Register _strings = new(); public string? Value = value; public override string ToString() => Value ?? "null"; public Value SubString(Value start, Value length) { if (Value == null) throw new RuntimeException($"Can not call substring on an empty string."); int index = start.IsInteger ? (int)start.Signed : throw new RuntimeException($"{nameof(String)}.{nameof(SubString)} requires first parameter 'start' to be an integer."); if (index < 0 || index >= Value.Length) throw new RuntimeException($"Parameter 'start' {start} was out of bounds."); if (length.IsVoid) return String.Make(Value.Substring(index)); int _length = length.IsInteger ? (int)length.Signed : throw new RuntimeException($"{nameof(String)}.{nameof(SubString)} requires second parameter 'length' to be an integer."); return String.Make(Value.Substring(index, _length)); } public Value IndexOf(Value needle) { if (!needle.IsString) throw new RuntimeException($"Parameter 'needle' is expected to be of type string, got {needle} instead."); return new Value(Value?.IndexOf(needle.Ptr.As()!.Value!) ?? -1L); } public Value Split(Value delimiter) { return Values.Value.Void; } public Value Length() { return new Value(Value?.Length ?? 0L); } public uint GetHash() { if (string.IsNullOrEmpty(Value)) return 0; return Value?.GetHash() ?? 0; } public static Value Make(string? value) { String? str; var hash = value?.GetHash() ?? 0; if (!_strings.TryGet(hash, out str)) { str = new String(value); _strings.Add(hash, str); } return Create(str); } public static byte[] SerializeStrings() { List result = new(); foreach (var pair in _strings) { String str = pair.Value; if (str == null || str.__GC_Marked) continue; byte[] bytes; bytes = Encoding.ASCII.GetBytes(str.Value!); result.AddRange(pair.Key.GetBytes()); result.AddRange(bytes.Length.GetBytes()); result.AddRange(bytes); result.Add(0); } return result.ToArray(); } }