1/* 2 * Copyright (c) 2021-2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16package std.core; 17 18/** 19 * Performance-oriented class for string construction 20 */ 21export final class StringBuilder { 22 private static readonly INITIAL_BUF_SIZE: int = 16; 23 24 private buf: FixedArray<(Object|undefined)> = new (Object|undefined)[StringBuilder.INITIAL_BUF_SIZE]; // array with pointers to strings or char[] 25 private index: int = 0; // index of the current free element in the buf 26 private length: int = 0; // length of the resulting string 27 private compress: boolean = true; // compress or not the resulting string. 28 29 /** 30 * Construct a new builder instance with the initial buffer of 16 chars 31 */ 32 constructor() {} 33 34 /** 35 * Construct a new builder instance with the provided array of chars 36 * 37 * @param fromChars array that will be used to initialize the builder 38 */ 39 constructor(fromChars: char[]) { 40 let s: String = new String(fromChars); 41 this.buf[this.index++] = s; 42 this.length = s.getLength(); 43 if (!s.isCompressed()) { 44 this.compress = false; 45 } 46 } 47 48 /** 49 * Construct a new builder instance with the provided array of chars 50 * 51 * @param fromChars array that will be used to initialize the builder 52 */ 53 constructor(fromChars: FixedArray<char>) { 54 let s: String = new String(fromChars); 55 this.buf[this.index++] = s; 56 this.length = s.getLength(); 57 if (!s.isCompressed()) { 58 this.compress = false; 59 } 60 } 61 62 /** 63 * Constructs a new builder instance with provided string 64 * 65 * @param s string that will be used to initialize the builder 66 */ 67 public constructor (s: String) { 68 this.buf[this.index++] = s; 69 this.length = s.getLength(); 70 if (!s.isCompressed()) { 71 this.compress = false; 72 } 73 } 74 75 /** 76 * Concatenates two strings and return a result as a new string 77 * 78 * @param lhs left string (prefix) 79 * 80 * @param rhs right string (suffix) 81 * 82 * @returns result of concatenation 83 */ 84 public static native concatStrings(lhs: String, rhs: String): String; 85 86 /** 87 * Appends an object representation as string to the builder's internal buffer 88 * 89 * @param o object that will be converted to a string 90 * 91 * @returns builder with updated internal buffer 92 */ 93 public append(o: Object): StringBuilder { 94 this.append(o.toString()); 95 return this; 96 } 97 98 /** 99 * Appends a string to the builder's internal buffer 100 * 101 * @param s string to be appended 102 * 103 * @returns builder with updated internal buffer 104 */ 105 public native append(s: String): StringBuilder; 106 107 private native append(s0: String, s1: String): StringBuilder; 108 private native append(s0: String, s1: String, s2: String): StringBuilder; 109 private native append(s0: String, s1: String, s2: String, s3: String): StringBuilder; 110 111 /** 112 * Appends a boolean as string to the builder's internal buffer 113 * 114 * @param i value to be appended 115 * 116 * @returns builder with updated internal buffer 117 */ 118 public native append(i: boolean): StringBuilder; 119 120 /** 121 * Appends a byte as string to the builder's internal buffer 122 * 123 * @param i value to be appended 124 * 125 * @returns builder with updated internal buffer 126 */ 127 public native append(i: byte): StringBuilder; 128 129 /** 130 * Appends a short as string to the builder's internal buffer 131 * 132 * @param i value to be appended 133 * 134 * @returns builder with updated internal buffer 135 */ 136 public native append(i: short): StringBuilder; 137 138 /** 139 * Appends a char to the builder's internal buffer 140 * 141 * @param i value to be appended 142 * 143 * @returns builder with updated internal buffer 144 */ 145 public native append(i: char): StringBuilder; 146 147 /** 148 * Appends an int as string to the builder's internal buffer 149 * 150 * @param i value to be appended 151 * 152 * @returns builder with updated internal buffer 153 */ 154 public native append(i: int): StringBuilder; 155 156 /** 157 * Appends a long as string to the builder's internal buffer 158 * 159 * @param i value to be appended 160 * 161 * @returns builder with updated internal buffer 162 */ 163 public native append(i: long): StringBuilder; 164 165 /** 166 * Appends a float as string to the builder's internal buffer 167 * 168 * @param i value to be appended 169 * 170 * @returns builder with updated internal buffer 171 */ 172 public native append(i: float): StringBuilder; 173 174 /** 175 * Appends a double as string to the builder's internal buffer 176 * 177 * @param i value to be appended 178 * 179 * @returns builder with updated internal buffer 180 */ 181 public native append(i: double): StringBuilder; 182 183 /** 184 * Returns the string that was formed as a result of all append operations 185 * 186 * @see append 187 * 188 * @returns String - builder's current buffer as string 189 */ 190 public native override toString(): String; 191 192 /** 193 * Converts the primitive to a string 194 * 195 * @param i value to be converted 196 * 197 * @returns result of the conversion 198 */ 199 public static native toString(i: boolean): String; 200 201 /** 202 * Converts the primitive to a string 203 * 204 * @param i value to be converted 205 * 206 * @returns result of the conversion 207 */ 208 public static native toString(i: byte): String; 209 210 /** 211 * Converts the primitive to a string 212 * 213 * @param i value to be converted 214 * 215 * @returns result of the conversion 216 */ 217 public static native toString(i: short): String; 218 219 /** 220 * Converts the primitive to a string 221 * 222 * @param i value to be converted 223 * 224 * @returns result of the conversion 225 */ 226 public static native toString(i: char): String; 227 228 /** 229 * Converts the primitive to a string 230 * 231 * @param i value to be converted 232 * 233 * @returns result of the conversion 234 */ 235 public static native toString(i: int): String; 236 237 /** 238 * Converts the primitive to a string 239 * 240 * @param i value to be converted 241 * 242 * @returns result of the conversion 243 */ 244 public static native toString(i: long): String; 245 246 /** 247 * Converts the primitive to a string 248 * 249 * @param i value to be converted 250 * 251 * @returns result of the conversion 252 */ 253 public static toString(f: float): String { 254 return Float.toString(f); 255 } 256 257 /** 258 * Converts the primitive to a string 259 * 260 * @param i value to be converted 261 * 262 * @returns result of the conversion 263 */ 264 public static toString(d: double): String { 265 return Double.toString(d); 266 } 267 268} 269 270final class DoubleToStringCacheElement { 271 string: string = ""; 272 // `lock` here and below is internal field used to provide atomicity 273 // and to align `number` by 8 bytes 274 lock: int; 275 number: double; 276} 277 278final class FloatToStringCacheElement { 279 string: string = ""; 280 lock: int; 281 number: float; 282} 283 284final class LongToStringCacheElement { 285 string: string = ""; 286 lock: int; 287 number: long; 288} 289