90 lines
2.4 KiB
C#
90 lines
2.4 KiB
C#
using Qrakhen.Qamp.Core.Collections;
|
|
using System.Text;
|
|
|
|
namespace Qrakhen.Qamp.Core.Values.Objects;
|
|
|
|
public class String(string? value) : Obj(ValueType.String)
|
|
{
|
|
private static readonly Register<uint, String> _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<String>()!.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<byte> 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();
|
|
}
|
|
} |