class StringBuffer(var buf: Array[Byte], var length: Int) { @static fun empty() -> StringBuffer = StringBuffer(Array[Byte](0), 0); fun length() -> Int { return self.length; } fun capacity() -> Int { return self.buf.length(); } // reserve `elements` bytes // (capacity - length >= elements) fun reserve(elements: Int) { if self.capacity() - self.length() >= elements { return; } let newcap = self.newCapacity(elements); let newbuf = Array[Byte](newcap); var i = 0; while i < self.buf.length() { newbuf.set(i, self.buf.get(i)); i = i + 1; } self.buf = newbuf; } fun newCapacity(reserve: Int) -> Int { var len = self.length; if len == 0 { len = 4; } let c1 = (len + reserve + 7) & !8; let c2 = len * 2; if c1 > c2 { return c1; } else if c2 - c1 > 32 { return c1; } else { return c2; } } fun appendChar(ch: Char) -> StringBuffer { let chLen = ch.lenUtf8(); self.reserve(chLen); ch.encodeUtf8(self.buf, self.length); self.length = self.length + chLen; return self; } fun append(value: String) -> StringBuffer { self.reserve(value.length()); var i = 0; while i < value.length() { self.buf.set(self.length + i, value.getByte(i)); i = i + 1; } self.length = self.length + value.length(); return self; } fun toString() -> String = try! String::fromBytesPart(self.buf, 0, self.length()); }