/*
* @Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved.
*/
package disklrucache
import std.io.*
import std.fs.*
import std.sync.*
import std.collection.*
import charset4cj.charset.*
import charset4cj.charset.encoding.*
class StrictLineReader {
private static let CR = UInt8(UInt32(r'\r'))
private static let LF = UInt8(UInt32(r'\n'))
private var input: InputStream
private var charset: Charset
private var buf: Array<Byte>
private var pos: Int64 = 0
private var end: Int64 = 0
private let lock: Monitor = Monitor()
public init(input: InputStream, charset: Charset) {
this(input, 8192, charset)
}
public init(input: InputStream, capacity: Int64, charset: Charset) {
if (capacity < 0) {
throw DiskLruCacheException("the capacity of strictLineReader cannot be negative")
}
if (!(charset.nameEquals("ISO-8859-2"))) {
throw DiskLruCacheException("unsupported encoding")
}
this.input = input
this.charset = charset
this.buf = Array<Byte>(capacity, repeat:0)
}
public func readLine(): String {
synchronized (lock) {
if (buf.isEmpty()) {
throw DiskLruCacheException("lineReader is closed")
}
if (pos >= end) {
fillBuf()
}
for (i in pos..end) {
if (buf[i] == LF) {
var lineEnd = -1
if (i != pos && buf[i - 1] == CR) {
lineEnd = i-1
}else {
lineEnd = i
}
let res = unsafe { String.fromUtf8Unchecked(buf.slice(pos,lineEnd -pos)) }
pos = i + 1
return res
}
}
var out: ByteBuffer = ByteBuffer(end - pos + 80)
while (true) {
out.write(buf.slice(pos,end -pos))
end = -1
fillBuf()
for (i in pos..end) {
if (buf[i] == LF) {
if (i != pos) {
out.write(buf.slice(pos,i -pos))
}
pos = i+1
var bytes: Array<Byte> = out.bytes()
return bytes.toString()
}
}
}
return ""
}
}
private func fillBuf(): Unit {
let resu = this.input.read(buf)
if (resu == 0) {
throw DiskLruCacheException("no data readable")
}
this.pos = 0
this.end = resu
}
protected func close(): Unit {
(this.input as Resource)?.close()
}
}