Files
crtr/Assets/SystemExtensions/gstring.cs
2022-09-30 17:32:21 +08:00

1063 lines
40 KiB
C#

using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
//#define DBG
// gstring (gcfreestring) is a string wrapper that uses pointers to mutate the string when performing misc string operations
// the purpose is to be able to perform most the common operations we do no strings (concat, format, replace, etc)
// without any allocation.
// gstring is not meant to be stored as member variables, but to quickly declare them in a 'gstring block', use them
// for whatever string operation you want, then dispose of them.
// The nice thing is that you don't have to manually dispose of gstrings, once you're in a block all assignments are
// registered so that when the block/scope ends all used gstrings are disposed.
//
// But what if you wanted to keep/store the result you calculated and not dispose of them?
// Well this is where 'intern' comes in - basically there's a runtime intern (cache) table
// of strings (similar to .NET's string const intern table).
// string str = result.Intern();
// Which basically says, if the string is in the intern (cache) table, return it
// otherwise allocate new memory for it and store it in the table, next time we ask for it, it's there.
// The nice thing about interning is that you could pre-intern your strings via the static method gstring.Intern
//
// NOTES:
// 1- The class is not designed with concurrency/threading in mind, it's meant to be used in Unity
// 2- Cultural stuff I did not consider as well
// 3- Again, you shouldn't have gstring members in your class. All gstring instances are meant to be disposed.
// You just quickly open up a gstring.Block() and use gstrings in it, if you want to store a result you get
// back from a gstring operation use Intern
namespace System {
public class gstring {
static Dictionary<int, Stack<gstring>> g_cache;
static Stack<gstring_block> g_blocks;
static List<string> g_intern_table;
static gstring_block g_current_block;
static List<int> g_finds;
static gstring[] g_format_args;
const int INITIAL_BLOCK_CAPACITY = 32;
const int INITIAL_CACHE_CAPACITY = 128;
const int INITIAL_STACK_CAPACITY = 48;
const int INITIAL_INTERN_CAPACITY = 256;
const char NEW_ALLOC_CHAR = 'X';
[NonSerialized] string _value;
[NonSerialized] bool _disposed;
internal gstring() {
throw new NotSupportedException();
}
internal gstring(int length) {
_value = new string(NEW_ALLOC_CHAR, length);
}
static gstring() {
Initialize(INITIAL_CACHE_CAPACITY,
INITIAL_STACK_CAPACITY,
INITIAL_BLOCK_CAPACITY,
INITIAL_INTERN_CAPACITY);
g_finds = new List<int>(10);
g_format_args = new gstring[10];
}
internal void dispose() {
if (_disposed)
throw new ObjectDisposedException(this);
// At this point there *must* be a stack whose length is equal to ours
// otherwise we wouldn't exist
var stack = g_cache[Length];
stack.Push(this);
#if DBG
if (log != null)
log("Disposed: " + _value + " Length=" + Length + " Stack=" + stack.Count);
#endif
memcpy(_value, NEW_ALLOC_CHAR);
_disposed = true;
}
internal static gstring get(string value) {
if (value == null)
return null;
#if DBG
if (log != null)
log("Getting: " + value);
#endif
var result = get(value.Length);
memcpy(dst: result, src: value);
return result;
}
internal static string __intern(string value) {
int idx = g_intern_table.IndexOf(value);
if (idx != -1)
return g_intern_table[idx];
string interned = new string(NEW_ALLOC_CHAR, value.Length);
memcpy(interned, value);
g_intern_table.Add(interned);
#if DBG
if (log != null)
log("Interned: " + value);
#endif
return interned;
}
internal static gstring get(int length) {
if (g_current_block == null)
throw new InvalidOperationException("Getting gstrings must be done in a gstring_block. Make sure you do a using(gstring.block())");
if (length <= 0)
throw new InvalidOperationException("Invalid length: " + length);
gstring result;
Stack<gstring> stack;
if (!g_cache.TryGetValue(length, out stack)) {
stack = new Stack<gstring>(INITIAL_STACK_CAPACITY);
for (int i = 0; i < INITIAL_STACK_CAPACITY; i++)
stack.Push(new gstring(length));
g_cache[length] = stack;
result = stack.Pop();
}
else {
if (stack.Count == 0) {
if (Log != null)
Log("Stack=0 Allocating new gstring Length=" + length);
result = new gstring(length);
}
else {
result = stack.Pop();
#if DBG
if (log != null)
log("Popped Length=" + length + " Stack=" + stack.Count);
#endif
}
}
result._disposed = false;
g_current_block.push(result);
return result;
}
internal static int get_digit_count(int value) {
int cnt;
for (cnt = 1; (value /= 10) > 0; cnt++) ;
return cnt;
}
internal static int internal_index_of(string input, char value, int start) {
return internal_index_of(input, value, start, input.Length - start);
}
internal static int internal_index_of(string input, string value) {
return internal_index_of(input, value, 0, input.Length);
}
internal static int internal_index_of(string input, string value, int start) {
return internal_index_of(input, value, start, input.Length - start);
}
internal unsafe static gstring internal_format(string input, int num_args) {
// "{0} {1}", "Hello", "World" ->
// "xxxxxxxxxxx"
// "Helloxxxxxx"
// "Hello xxxxx"
// "Hello World"
// "Player={0} Id={1}", "Jon", 10 ->
// "xxxxxxxxxxxxxxxx"
// "Player=xxxxxxxxx"
// "Player=Jonxxxxxx"
// "Player=Jon Id=xx"
// "Player=Jon Id=10"
if (input == null)
throw new ArgumentNullException("value");
int new_len = input.Length - 3 * num_args;
for (int i = 0; i < num_args; i++) {
gstring arg = g_format_args[i];
new_len += arg.Length;
}
gstring result = get(new_len);
string res_value = result._value;
int brace_idx = -3;
for (int i = 0, j = 0, x = 0; x < num_args; x++) {
string arg = g_format_args[x]._value;
brace_idx = internal_index_of(input, '{', brace_idx + 3);
if (brace_idx == -1)
throw new InvalidOperationException("Couldn't find open brace for argument " + arg);
if (brace_idx + 2 >= input.Length || input[brace_idx + 2] != '}')
throw new InvalidOperationException("Couldn't find close brace for argument " + arg);
fixed (char* ptr_input = input) {
fixed (char* ptr_result = res_value) {
for (int k = 0; i < new_len;) {
if (j < brace_idx)
ptr_result[i++] = ptr_input[j++];
else {
ptr_result[i++] = arg[k++];
if (k == arg.Length) {
j += 3;
break;
}
}
}
}
}
}
return result;
}
internal unsafe static int internal_index_of(string input, char value, int start, int count) {
if (start < 0 || start >= input.Length)
throw new ArgumentOutOfRangeException("start");
if (start + count > input.Length)
throw new ArgumentOutOfRangeException("count=" + count + " start+count=" + start + count);
fixed (char* ptr_this = input) {
int end = start + count;
for (int i = start; i < end; i++)
if (ptr_this[i] == value)
return i;
return -1;
}
}
internal unsafe static int internal_index_of(string input, string value, int start, int count) {
int input_len = input.Length;
if (start < 0 || start >= input_len)
throw new ArgumentOutOfRangeException("start");
if (count < 0 || start + count > input_len)
throw new ArgumentOutOfRangeException("count=" + count + " start+count=" + (start + count));
if (count == 0)
return -1;
fixed (char* ptr_input = input) {
fixed (char* ptr_value = value) {
int found = 0;
int end = start + count;
for (int i = start; i < end; i++) {
for (int j = 0; j < value.Length && i + j < input_len; j++) {
if (ptr_input[i + j] == ptr_value[j]) {
found++;
if (found == value.Length)
return i;
continue;
}
if (found > 0)
break;
}
}
return -1;
}
}
}
internal unsafe static gstring internal_remove(string input, int start, int count) {
if (start < 0 || start >= input.Length)
throw new ArgumentOutOfRangeException("start=" + start + " Length=" + input.Length);
if (count < 0 || start + count > input.Length)
throw new ArgumentOutOfRangeException("count=" + count + " start+count=" + (start + count) + " Length=" + input.Length);
if (count == 0)
return input;
gstring result = get(input.Length - count);
internal_remove(result, input, start, count);
return result;
}
internal unsafe static void internal_remove(string dst, string src, int start, int count) {
fixed (char* src_ptr = src) {
fixed (char* dst_ptr = dst) {
for (int i = 0, j = 0; i < dst.Length; i++) {
if (i >= start && i < start + count) // within removal range
continue;
dst_ptr[j++] = src_ptr[i];
}
}
}
}
internal unsafe static gstring internal_replace(string value, string old_value, string new_value) {
// "Hello, World. There World" | World->Jon =
// "000000000000000000000" (len = orig - 2 * (world-jon) = orig - 4
// "Hello, 00000000000000"
// "Hello, Jon00000000000"
// "Hello, Jon. There 000"
// "Hello, Jon. There Jon"
// "Hello, World. There World" | World->Alexander =
// "000000000000000000000000000000000" (len = orig + 2 * (alexander-world) = orig + 8
// "Hello, 00000000000000000000000000"
// "Hello, Alexander00000000000000000"
// "Hello, Alexander. There 000000000"
// "Hello, Alexander. There Alexander"
if (old_value == null)
throw new ArgumentNullException("old_value");
if (new_value == null)
throw new ArgumentNullException("new_value");
int idx = internal_index_of(value, old_value);
if (idx == -1)
return value;
g_finds.Clear();
g_finds.Add(idx);
// find all the indicies beforehand
while (idx + old_value.Length < value.Length) {
idx = internal_index_of(value, old_value, idx + old_value.Length);
if (idx == -1)
break;
g_finds.Add(idx);
}
// calc the right new total length
int new_len;
int dif = old_value.Length - new_value.Length;
if (dif > 0)
new_len = value.Length - (g_finds.Count * dif);
else
new_len = value.Length + (g_finds.Count * -dif);
gstring result = get(new_len);
fixed (char* ptr_this = value) {
fixed (char* ptr_result = result._value) {
for (int i = 0, x = 0, j = 0; i < new_len;) {
if (x == g_finds.Count || g_finds[x] != j) {
ptr_result[i++] = ptr_this[j++];
}
else {
for (int n = 0; n < new_value.Length; n++)
ptr_result[i + n] = new_value[n];
x++;
i += new_value.Length;
j += old_value.Length;
}
}
}
}
return result;
}
internal unsafe static gstring internal_insert(string value, char to_insert, int start, int count) {
// "HelloWorld" (to_insert=x, start=5, count=3) -> "HelloxxxWorld"
if (start < 0 || start >= value.Length)
throw new ArgumentOutOfRangeException("start=" + start + " Length=" + value.Length);
if (count < 0)
throw new ArgumentOutOfRangeException("count=" + count);
if (count == 0)
return get(value);
int new_len = value.Length + count;
gstring result = get(new_len);
fixed (char* ptr_value = value) {
fixed (char* ptr_result = result._value) {
for (int i = 0, j = 0; i < new_len; i++) {
if (i >= start && i < start + count)
ptr_result[i] = to_insert;
else
ptr_result[i] = ptr_value[j++];
}
}
}
return result;
}
internal unsafe static gstring internal_insert(string input, string to_insert, int start) {
if (input == null)
throw new ArgumentNullException("input");
if (to_insert == null)
throw new ArgumentNullException("to_insert");
if (start < 0 || start >= input.Length)
throw new ArgumentOutOfRangeException("start=" + start + " Length=" + input.Length);
if (to_insert.Length == 0)
return get(input);
int new_len = input.Length + to_insert.Length;
gstring result = get(new_len);
internal_insert(result, input, to_insert, start);
return result;
}
internal unsafe static gstring internal_concat(string s1, string s2) {
int total_length = s1.Length + s2.Length;
gstring result = get(total_length);
fixed (char* ptr_result = result._value) {
fixed (char* ptr_s1 = s1) {
fixed (char* ptr_s2 = s2) {
memcpy(dst: ptr_result, src: ptr_s1, length: s1.Length, src_offset: 0);
memcpy(dst: ptr_result, src: ptr_s2, length: s2.Length, src_offset: s1.Length);
}
}
}
return result;
}
internal unsafe static void internal_insert(string dst, string src, string to_insert, int start) {
fixed (char* ptr_src = src) {
fixed (char* ptr_dst = dst) {
fixed (char* ptr_to_insert = to_insert) {
for (int i = 0, j = 0, k = 0; i < dst.Length; i++) {
if (i >= start && i < start + to_insert.Length)
ptr_dst[i] = ptr_to_insert[k++];
else
ptr_dst[i] = ptr_src[j++];
}
}
}
}
}
internal unsafe static void intcpy(char* dst, int value, int start, int count) {
int end = start + count;
for (int i = end - 1; i >= start; i--, value /= 10)
*(dst + i) = (char)(value % 10 + 48);
}
internal unsafe static void memcpy(char* dst, char* src, int count) {
for (int i = 0; i < count; i++)
*(dst++) = *(src++);
}
internal unsafe static void memcpy(string dst, char src) {
fixed (char* ptr_dst = dst) {
int len = dst.Length;
for (int i = 0; i < len; i++)
ptr_dst[i] = src;
}
}
internal unsafe static void memcpy(string dst, char src, int index) {
fixed (char* ptr = dst)
ptr[index] = src;
}
internal unsafe static void memcpy(string dst, string src) {
if (dst.Length != src.Length)
throw new InvalidOperationException("Length mismatch");
memcpy(dst, src, dst.Length, 0);
}
internal unsafe static void memcpy(char* dst, char* src, int length, int src_offset) {
for (int i = 0; i < length; i++)
*(dst + i + src_offset) = *(src + i);
}
internal unsafe static void memcpy(string dst, string src, int length, int src_offset) {
fixed (char* ptr_dst = dst) {
fixed (char* ptr_src = src) {
for (int i = 0; i < length; i++)
ptr_dst[i + src_offset] = ptr_src[i];
}
}
}
internal class gstring_block : IDisposable {
readonly Stack<gstring> stack;
internal gstring_block(int capacity) {
stack = new Stack<gstring>(capacity);
}
internal void push(gstring str) {
stack.Push(str);
}
internal IDisposable begin() {
#if DBG
if (log != null)
log("Began block");
#endif
return this;
}
void IDisposable.Dispose() {
#if DBG
if (log != null)
log("Disposing block");
#endif
while (stack.Count > 0) {
var str = stack.Pop();
str.dispose();
}
gstring.g_blocks.Push(this);
}
}
// Public API
#region
public static Action<string> Log = null;
public static int DecimalAccuracy = 3; // digits after the decimal point
public int Length {
get { return _value.Length; }
}
public static void Initialize(int cache_capacity, int stack_capacity, int block_capacity, int intern_capacity) {
g_cache = new Dictionary<int, Stack<gstring>>(cache_capacity);
g_blocks = new Stack<gstring_block>(block_capacity);
g_intern_table = new List<string>(intern_capacity);
for (int c = 1; c < cache_capacity; c++) {
var stack = new Stack<gstring>(stack_capacity);
for (int j = 0; j < stack_capacity; j++)
stack.Push(new gstring(c));
g_cache[c] = stack;
}
for (int i = 0; i < block_capacity; i++) {
var block = new gstring_block(block_capacity * 2);
g_blocks.Push(block);
}
}
public static IDisposable Block() {
if (g_blocks.Count == 0)
g_current_block = new gstring_block(INITIAL_BLOCK_CAPACITY * 2);
else
g_current_block = g_blocks.Pop();
return g_current_block.begin();
}
public string Intern() {
return __intern(_value);
}
public static string Intern(string value) {
return __intern(value);
}
public static void Intern(string[] values) {
for (int i = 0; i < values.Length; i++)
__intern(values[i]);
}
public char this[int i] {
get { return _value[i]; }
set { memcpy(this, value, i); }
}
public override int GetHashCode() {
return RuntimeHelpers.GetHashCode(_value);
}
public override bool Equals(object obj) {
if (obj == null)
return ReferenceEquals(this, null);
var gstr = obj as gstring;
if (gstr != null)
return gstr._value == this._value;
var str = obj as string;
if (str != null)
return str == this._value;
return false;
}
public override string ToString() {
return _value;
}
public static implicit operator gstring(bool value) {
return get(value ? "True" : "False");
}
public unsafe static implicit operator gstring(int value) {
// e.g. 125
// first pass: count the number of digits
// then: get a gstring with length = num digits
// finally: iterate again, get the char of each digit, memcpy char to result
bool negative = value < 0;
value = Math.Abs(value);
int num_digits = get_digit_count(value);
gstring result;
if (negative) {
result = get(num_digits + 1);
fixed (char* ptr = result._value) {
*ptr = '-';
intcpy(ptr, value, 1, num_digits);
}
}
else {
result = get(num_digits);
fixed (char* ptr = result._value)
intcpy(ptr, value, 0, num_digits);
}
return result;
}
public unsafe static implicit operator gstring(float value) {
// e.g. 3.148
bool negative = value < 0;
if (negative) value = -value;
int mul = (int)Math.Pow(10, DecimalAccuracy);
int number = (int)(value * mul); // gets the number as a whole, e.g. 3148
int left_num = number / mul; // left part of the decimal point, e.g. 3
int right_num = number % mul; // right part of the decimal pnt, e.g. 148
int left_digit_count = get_digit_count(left_num); // e.g. 1
int right_digit_count = get_digit_count(right_num); // e.g. 3
int total = left_digit_count + right_digit_count + 1; // +1 for '.'
gstring result;
if (negative) {
result = get(total + 1); // +1 for '-'
fixed (char* ptr = result._value) {
*ptr = '-';
intcpy(ptr, left_num, 1, left_digit_count);
*(ptr + left_digit_count + 1) = '.';
intcpy(ptr, right_num, left_digit_count + 2, right_digit_count);
}
}
else {
result = get(total);
fixed (char* ptr = result._value) {
intcpy(ptr, left_num, 0, left_digit_count);
*(ptr + left_digit_count) = '.';
intcpy(ptr, right_num, left_digit_count + 1, right_digit_count);
}
}
return result;
}
public static implicit operator gstring(string value) {
return get(value);
}
public static implicit operator string(gstring value) {
return value._value;
}
public static gstring operator +(gstring left, gstring right) {
return internal_concat(left, right);
}
public static bool operator ==(gstring left, gstring right) {
if (ReferenceEquals(left, null))
return ReferenceEquals(right, null);
if (ReferenceEquals(right, null))
return false;
return left._value == right._value;
}
public static bool operator !=(gstring left, gstring right) {
return !(left._value == right._value);
}
public unsafe gstring ToUpper() {
var result = get(Length);
fixed (char* ptr_this = this._value) {
fixed (char* ptr_result = result._value) {
for (int i = 0; i < _value.Length; i++) {
var ch = ptr_this[i];
if (char.IsLower(ch))
ptr_result[i] = char.ToUpper(ch);
else
ptr_result[i] = ptr_this[i];
}
}
}
return result;
}
public unsafe gstring ToLower() {
var result = get(Length);
fixed (char* ptr_this = this._value) {
fixed (char* ptr_result = result._value) {
for (int i = 0; i < _value.Length; i++) {
var ch = ptr_this[i];
if (char.IsUpper(ch))
ptr_result[i] = char.ToLower(ch);
else
ptr_result[i] = ptr_this[i];
}
}
}
return result;
}
public gstring Remove(int start) {
return Remove(start, Length - start);
}
public gstring Remove(int start, int count) {
return internal_remove(this._value, start, count);
}
public gstring Insert(char value, int start, int count) {
return internal_insert(this._value, value, start, count);
}
public gstring Insert(string value, int start) {
return internal_insert(this._value, value, start);
}
public unsafe gstring Replace(char old_value, char new_value) {
gstring result = get(Length);
fixed (char* ptr_this = this._value) {
fixed (char* ptr_result = result._value) {
for (int i = 0; i < Length; i++) {
if (ptr_this[i] == old_value)
ptr_result[i] = new_value;
else
ptr_result[i] = ptr_this[i];
}
}
}
return result;
}
public gstring Replace(string old_value, string new_value) {
return internal_replace(this._value, old_value, new_value);
}
public gstring Substring(int start) {
return Substring(start, Length - start);
}
public unsafe gstring Substring(int start, int count) {
if (start < 0 || start >= Length)
throw new ArgumentOutOfRangeException("start");
if (count > Length)
throw new ArgumentOutOfRangeException("count");
gstring result = get(count);
fixed (char* src = this._value)
fixed (char* dst = result._value)
memcpy(dst, src + start, count);
return result;
}
public bool Contains(string value) {
return IndexOf(value) != -1;
}
public bool Contains(char value) {
return IndexOf(value) != -1;
}
public int LastIndexOf(string value) {
int idx = -1;
int last_find = -1;
while (true) {
idx = internal_index_of(this._value, value, idx + value.Length);
last_find = idx;
if (idx == -1 || idx + value.Length >= this._value.Length)
break;
}
return last_find;
}
public int LastIndexOf(char value) {
int idx = -1;
int last_find = -1;
while (true) {
idx = internal_index_of(this._value, value, idx + 1);
last_find = idx;
if (idx == -1 || idx + 1 >= this._value.Length)
break;
}
return last_find;
}
public int IndexOf(char value) {
return IndexOf(value, 0, Length);
}
public int IndexOf(char value, int start) {
return internal_index_of(this._value, value, start);
}
public int IndexOf(char value, int start, int count) {
return internal_index_of(this._value, value, start, count);
}
public int IndexOf(string value) {
return IndexOf(value, 0, Length);
}
public int IndexOf(string value, int start) {
return IndexOf(value, start, Length - start);
}
public int IndexOf(string value, int start, int count) {
return internal_index_of(this._value, value, start, count);
}
public unsafe bool EndsWith(string postfix) {
if (postfix == null)
throw new ArgumentNullException("postfix");
if (this.Length < postfix.Length)
return false;
fixed (char* ptr_this = this._value) {
fixed (char* ptr_postfix = postfix) {
for (int i = this._value.Length - 1, j = postfix.Length - 1; j >= 0; i--, j--)
if (ptr_this[i] != ptr_postfix[j])
return false;
}
}
return true;
}
public unsafe bool StartsWith(string prefix) {
if (prefix == null)
throw new ArgumentNullException("prefix");
if (this.Length < prefix.Length)
return false;
fixed (char* ptr_this = this._value) {
fixed (char* ptr_prefix = prefix) {
for (int i = 0; i < prefix.Length; i++)
if (ptr_this[i] != ptr_prefix[i])
return false;
}
}
return true;
}
public static int GetCacheCount(int length) {
Stack<gstring> stack;
if (!g_cache.TryGetValue(length, out stack))
return -1;
return stack.Count;
}
public gstring Concat(gstring value) {
return internal_concat(this, value);
}
public static gstring Concat(gstring s0, gstring s1) { return s0 + s1; }
public static gstring Concat(gstring s0, gstring s1, gstring s2) { return s0 + s1 + s2; }
public static gstring Concat(gstring s0, gstring s1, gstring s2, gstring s3) { return s0 + s1 + s2 + s3; }
public static gstring Concat(gstring s0, gstring s1, gstring s2, gstring s3, gstring s4) { return s0 + s1 + s2 + s3 + s4; }
public static gstring Concat(gstring s0, gstring s1, gstring s2, gstring s3, gstring s4, gstring s5) { return s0 + s1 + s2 + s3 + s4 + s5; }
public static gstring Concat(gstring s0, gstring s1, gstring s2, gstring s3, gstring s4, gstring s5, gstring s6) { return s0 + s1 + s2 + s3 + s4 + s5 + s6; }
public static gstring Concat(gstring s0, gstring s1, gstring s2, gstring s3, gstring s4, gstring s5, gstring s6, gstring s7) { return s0 + s1 + s2 + s3 + s4 + s5 + s6 + s7; }
public static gstring Concat(gstring s0, gstring s1, gstring s2, gstring s3, gstring s4, gstring s5, gstring s6, gstring s7, gstring s8) { return s0 + s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8; }
public static gstring Concat(gstring s0, gstring s1, gstring s2, gstring s3, gstring s4, gstring s5, gstring s6, gstring s7, gstring s8, gstring s9) { return s0 + s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9; }
public static gstring Format(string input, gstring arg0, gstring arg1, gstring arg2, gstring arg3, gstring arg4, gstring arg5, gstring arg6, gstring arg7, gstring arg8, gstring arg9) {
if (arg0 == null) throw new ArgumentNullException("arg0");
if (arg1 == null) throw new ArgumentNullException("arg1");
if (arg2 == null) throw new ArgumentNullException("arg2");
if (arg3 == null) throw new ArgumentNullException("arg3");
if (arg4 == null) throw new ArgumentNullException("arg4");
if (arg5 == null) throw new ArgumentNullException("arg5");
if (arg6 == null) throw new ArgumentNullException("arg6");
if (arg7 == null) throw new ArgumentNullException("arg7");
if (arg8 == null) throw new ArgumentNullException("arg8");
if (arg9 == null) throw new ArgumentNullException("arg9");
g_format_args[0] = arg0;
g_format_args[1] = arg1;
g_format_args[2] = arg2;
g_format_args[3] = arg3;
g_format_args[4] = arg4;
g_format_args[5] = arg5;
g_format_args[6] = arg6;
g_format_args[7] = arg7;
g_format_args[8] = arg8;
g_format_args[9] = arg9;
return internal_format(input, 10);
}
public static gstring Format(string input, gstring arg0, gstring arg1, gstring arg2, gstring arg3, gstring arg4, gstring arg5, gstring arg6, gstring arg7, gstring arg8) {
if (arg0 == null) throw new ArgumentNullException("arg0");
if (arg1 == null) throw new ArgumentNullException("arg1");
if (arg2 == null) throw new ArgumentNullException("arg2");
if (arg3 == null) throw new ArgumentNullException("arg3");
if (arg4 == null) throw new ArgumentNullException("arg4");
if (arg5 == null) throw new ArgumentNullException("arg5");
if (arg6 == null) throw new ArgumentNullException("arg6");
if (arg7 == null) throw new ArgumentNullException("arg7");
if (arg8 == null) throw new ArgumentNullException("arg8");
g_format_args[0] = arg0;
g_format_args[1] = arg1;
g_format_args[2] = arg2;
g_format_args[3] = arg3;
g_format_args[4] = arg4;
g_format_args[5] = arg5;
g_format_args[6] = arg6;
g_format_args[7] = arg7;
g_format_args[8] = arg8;
return internal_format(input, 9);
}
public static gstring Format(string input, gstring arg0, gstring arg1, gstring arg2, gstring arg3, gstring arg4, gstring arg5, gstring arg6, gstring arg7) {
if (arg0 == null) throw new ArgumentNullException("arg0");
if (arg1 == null) throw new ArgumentNullException("arg1");
if (arg2 == null) throw new ArgumentNullException("arg2");
if (arg3 == null) throw new ArgumentNullException("arg3");
if (arg4 == null) throw new ArgumentNullException("arg4");
if (arg5 == null) throw new ArgumentNullException("arg5");
if (arg6 == null) throw new ArgumentNullException("arg6");
if (arg7 == null) throw new ArgumentNullException("arg7");
g_format_args[0] = arg0;
g_format_args[1] = arg1;
g_format_args[2] = arg2;
g_format_args[3] = arg3;
g_format_args[4] = arg4;
g_format_args[5] = arg5;
g_format_args[6] = arg6;
g_format_args[7] = arg7;
return internal_format(input, 8);
}
public static gstring Format(string input, gstring arg0, gstring arg1, gstring arg2, gstring arg3, gstring arg4, gstring arg5, gstring arg6) {
if (arg0 == null) throw new ArgumentNullException("arg0");
if (arg1 == null) throw new ArgumentNullException("arg1");
if (arg2 == null) throw new ArgumentNullException("arg2");
if (arg3 == null) throw new ArgumentNullException("arg3");
if (arg4 == null) throw new ArgumentNullException("arg4");
if (arg5 == null) throw new ArgumentNullException("arg5");
if (arg6 == null) throw new ArgumentNullException("arg6");
g_format_args[0] = arg0;
g_format_args[1] = arg1;
g_format_args[2] = arg2;
g_format_args[3] = arg3;
g_format_args[4] = arg4;
g_format_args[5] = arg5;
g_format_args[6] = arg6;
return internal_format(input, 7);
}
public static gstring Format(string input, gstring arg0, gstring arg1, gstring arg2, gstring arg3, gstring arg4, gstring arg5) {
if (arg0 == null) throw new ArgumentNullException("arg0");
if (arg1 == null) throw new ArgumentNullException("arg1");
if (arg2 == null) throw new ArgumentNullException("arg2");
if (arg3 == null) throw new ArgumentNullException("arg3");
if (arg4 == null) throw new ArgumentNullException("arg4");
if (arg5 == null) throw new ArgumentNullException("arg5");
g_format_args[0] = arg0;
g_format_args[1] = arg1;
g_format_args[2] = arg2;
g_format_args[3] = arg3;
g_format_args[4] = arg4;
g_format_args[5] = arg5;
return internal_format(input, 6);
}
public static gstring Format(string input, gstring arg0, gstring arg1, gstring arg2, gstring arg3, gstring arg4) {
if (arg0 == null) throw new ArgumentNullException("arg0");
if (arg1 == null) throw new ArgumentNullException("arg1");
if (arg2 == null) throw new ArgumentNullException("arg2");
if (arg3 == null) throw new ArgumentNullException("arg3");
if (arg4 == null) throw new ArgumentNullException("arg4");
g_format_args[0] = arg0;
g_format_args[1] = arg1;
g_format_args[2] = arg2;
g_format_args[3] = arg3;
g_format_args[4] = arg4;
return internal_format(input, 5);
}
public static gstring Format(string input, gstring arg0, gstring arg1, gstring arg2, gstring arg3) {
if (arg0 == null) throw new ArgumentNullException("arg0");
if (arg1 == null) throw new ArgumentNullException("arg1");
if (arg2 == null) throw new ArgumentNullException("arg2");
if (arg3 == null) throw new ArgumentNullException("arg3");
g_format_args[0] = arg0;
g_format_args[1] = arg1;
g_format_args[2] = arg2;
g_format_args[3] = arg3;
return internal_format(input, 4);
}
public static gstring Format(string input, gstring arg0, gstring arg1, gstring arg2) {
if (arg0 == null) throw new ArgumentNullException("arg0");
if (arg1 == null) throw new ArgumentNullException("arg1");
if (arg2 == null) throw new ArgumentNullException("arg2");
g_format_args[0] = arg0;
g_format_args[1] = arg1;
g_format_args[2] = arg2;
return internal_format(input, 3);
}
public static gstring Format(string input, gstring arg0, gstring arg1) {
if (arg0 == null) throw new ArgumentNullException("arg0");
if (arg1 == null) throw new ArgumentNullException("arg1");
g_format_args[0] = arg0;
g_format_args[1] = arg1;
return internal_format(input, 2);
}
public static gstring Format(string input, gstring arg0) {
if (arg0 == null) throw new ArgumentNullException("arg0");
g_format_args[0] = arg0;
return internal_format(input, 1);
}
#endregion
}
public static class GStringExtensions {
public static bool IsNullOrEmpty(this gstring str) {
return str == null || str.Length == 0;
}
public static bool IsPrefix(this gstring str, string value) {
return str.StartsWith(value);
}
public static bool ispostfix(this gstring str, string postfix) {
return str.EndsWith(postfix);
}
}
}