-
David Sehnal authoredDavid Sehnal authored
string-builder.ts 4.94 KiB
/**
* Copyright (c) 2017 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* Adapted from CIFTools.js (https://github.com/dsehnal/CIFTools.js)
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
interface StringBuilder {
current: string[],
offset: number,
capacity: number,
chunks: string[]
}
namespace StringBuilder {
export function create(chunkCapacity = 512): StringBuilder {
return {
current: [],
offset: 0,
capacity: chunkCapacity,
chunks: []
};
}
export function getString(builder: StringBuilder) {
if (!builder.chunks.length) {
if (builder.current.length === builder.offset) return builder.current.join('');
return builder.current.splice(0, builder.offset).join('');
}
if (builder.offset > 0) {
builder.chunks[builder.chunks.length] = builder.current.length === builder.offset
? builder.current.join('')
: builder.current.slice(0, builder.offset).join('');
}
return builder.chunks.join('');
}
export function getChunks(builder: StringBuilder): string[] {
if (builder.offset > 0) {
if (builder.current.length === builder.offset) builder.chunks[builder.chunks.length] = builder.current.join('');
else builder.chunks[builder.chunks.length] = builder.current.slice(0, builder.offset).join('');
builder.offset = 0;
}
return builder.chunks;
}
const enum PaddingSpaces { Count = 512 }
const __paddingSpaces: string[] = [];
(function () {
let s = '';
for (let i = 0; i < PaddingSpaces.Count; i++) {
__paddingSpaces[i] = s;
s = s + ' ';
}
})();
export function newline(builder: StringBuilder) {
writeSafe(builder, '\n');
}
export function whitespace(builder: StringBuilder, len: number) {
if (len > 0) writeSafe(builder, __paddingSpaces[len]);
}
export function whitespace1(builder: StringBuilder) {
writeSafe(builder, ' ');
}
export function write(builder: StringBuilder, val: string) {
if (!val) return;
if (builder.offset === builder.capacity) {
builder.chunks[builder.chunks.length] = builder.current.join('');
builder.offset = 0;
}
builder.current[builder.offset++] = val;
}
/** Write without check. */
export function writeSafe(builder: StringBuilder, val: string) {
if (builder.offset === builder.capacity) {
builder.chunks[builder.chunks.length] = builder.current.join('');
builder.offset = 0;
}
builder.current[builder.offset++] = val;
}
export function writePadLeft(builder: StringBuilder, val: string, totalWidth: number) {
if (!val) { whitespace(builder, totalWidth); return; }
let padding = totalWidth - val.length;
whitespace(builder, padding);
writeSafe(builder, val);
}
export function writePadRight(builder: StringBuilder, val: string, totalWidth: number) {
if (!val) { whitespace(builder, totalWidth); return; }
let padding = totalWidth - val.length;
writeSafe(builder, val);
whitespace(builder, padding);
}
export function writeInteger(builder: StringBuilder, val: number) {
writeSafe(builder, '' + val);
}
export function writeIntegerAndSpace(builder: StringBuilder, val: number) {
writeSafe(builder, '' + val + ' ');
}
export function writeIntegerPadLeft(builder: StringBuilder, val: number, totalWidth: number) {
let s = '' + val;
let padding = totalWidth - s.length;
whitespace(builder, padding);
writeSafe(builder, s);
}
export function writeIntegerPadRight(builder: StringBuilder, val: number, totalWidth: number) {
let s = '' + val;
let padding = totalWidth - s.length;
writeSafe(builder, s);
whitespace(builder, padding);
}
/**
* @example writeFloat(123.2123, 100) -- 2 decim
*/
export function writeFloat(builder: StringBuilder, val: number, precisionMultiplier: number) {
writeSafe(builder, '' + Math.round(precisionMultiplier * val) / precisionMultiplier)
}
export function writeFloatPadLeft(builder: StringBuilder, val: number, precisionMultiplier: number, totalWidth: number) {
let s = '' + Math.round(precisionMultiplier * val) / precisionMultiplier;
let padding = totalWidth - s.length;
whitespace(builder, padding);
writeSafe(builder, s);
}
export function writeFloatPadRight(builder: StringBuilder, val: number, precisionMultiplier: number, totalWidth: number) {
let s = '' + Math.round(precisionMultiplier * val) / precisionMultiplier;
let padding = totalWidth - s.length;
writeSafe(builder, s);
whitespace(builder, padding);
}
}
export default StringBuilder