• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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