1 /* 2 * Geario - A cross-platform abstraction library with asynchronous I/O. 3 * 4 * Copyright (C) 2021-2022 Kerisy.com 5 * 6 * Website: https://www.kerisy.com 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module geario.util.StringBuilder; 13 14 import geario.util.Appendable; 15 16 import std.ascii; 17 import std.algorithm; 18 import std.array; 19 import std.exception; 20 import std.conv; 21 import std.string; 22 import std.uni; 23 24 /** 25 * 26 */ 27 class StringBuilder : Appendable { 28 Appender!(byte[]) _buffer; 29 30 this(size_t capacity = 16) { 31 _buffer.reserve(capacity); 32 } 33 34 this(string data, size_t capacity = 16) { 35 _buffer.reserve(capacity); 36 this.Append(data); 37 } 38 39 // void Append(in char[] s) 40 // { 41 // _buffer.put(cast(string) s); 42 // } 43 44 void Reset() { 45 _buffer.clear(); 46 } 47 48 StringBuilder SetCharAt(int index, char c) { 49 _buffer.data[index] = c; 50 return this; 51 } 52 53 StringBuilder Append(char s) { 54 _buffer.put(s); 55 return this; 56 } 57 58 StringBuilder Append(bool s) { 59 Append(s.to!string()); 60 return this; 61 } 62 63 StringBuilder Append(int i) { 64 _buffer.put(cast(byte[])(to!(string)(i))); 65 return this; 66 } 67 68 StringBuilder Append(float f) { 69 _buffer.put(cast(byte[])(to!(string)(f))); 70 return this; 71 } 72 73 StringBuilder Append(const(char)[] s) { 74 _buffer.put(cast(byte[]) s); 75 return this; 76 } 77 78 StringBuilder Append(const(char)[] s, int start, int end) { 79 _buffer.put(cast(byte[]) s[start .. end]); 80 return this; 81 } 82 83 // StringBuilder Append(byte[] s, int start, int end) 84 // { 85 // _buffer.put(s[start..end]); 86 // return this; 87 // } 88 89 /// Warning: It's different from the previous one. 90 StringBuilder Append(byte[] str, int offset, int len) { 91 _buffer.put(str[offset .. offset + len]); 92 return this; 93 } 94 95 StringBuilder Append(Object obj) { 96 _buffer.put(cast(byte[])(obj.toString)); 97 return this; 98 } 99 100 int Length() { 101 return cast(int) _buffer.data.length; 102 } 103 104 void SetLength(int newLength) { 105 _buffer.shrinkTo(newLength); 106 // if (newLength < 0) 107 // throw new StringIndexOutOfBoundsException(to!string(newLength)); 108 // EnsureCapacityInternal(newLength); 109 110 // if (count < newLength) { 111 // Arrays.fill(value, count, newLength, '\0'); 112 // } 113 114 // count = newLength; 115 } 116 117 private void EnsureCapacityInternal(size_t minimumCapacity) { 118 // overflow-conscious code 119 // if (minimumCapacity > value.length) { 120 // value = Arrays.copyOf(value, 121 // newCapacity(minimumCapacity)); 122 // } 123 } 124 125 int LastIndexOf(string s) { 126 string source = cast(string) _buffer.data; 127 return cast(int) source.lastIndexOf(s); 128 } 129 130 char CharAt(int idx) { 131 if (Length() > idx) 132 return _buffer.data[idx]; 133 else 134 return ' '; 135 } 136 137 StringBuilder DeleteCharAt(int index) { 138 if (index < Length()) { 139 auto data = _buffer.data.idup; 140 for (int i = index + 1; i < data.length; i++) { 141 _buffer.data[i - 1] = data[i]; 142 } 143 SetLength(cast(int)(data.length - 1)); 144 } 145 return this; 146 } 147 148 StringBuilder Insert(int index, char c) { 149 if (index <= Length()) { 150 auto data = _buffer.data.idup; 151 for (int i = index; i < data.length; i++) { 152 _buffer.data[i + 1] = data[i]; 153 } 154 _buffer.data[index] = c; 155 SetLength(cast(int)(data.length + 1)); 156 } 157 return this; 158 } 159 160 StringBuilder Insert(int index, long data) { 161 auto bytes = cast(byte[])(to!string(data)); 162 auto start = index; 163 foreach (b; bytes) { 164 Insert(start, cast(char) b); 165 start++; 166 } 167 return this; 168 } 169 170 StringBuilder Replace(int start, int end, string str) { 171 if (start <= end && start < Length() && end < Length()) { 172 if (str.length >= end) 173 _buffer.data[start .. end] = cast(byte[])(str[start .. end]); 174 } 175 return this; 176 } 177 178 void Clear() { 179 _buffer = Appender!(byte[]).init; 180 } 181 182 override string toString() { 183 string s = cast(string) _buffer.data.idup; 184 if (s is null) 185 return ""; 186 else 187 return s; 188 } 189 }