/*
* Copyright (c) Huawei Technologies Co., Ltd. 2022-2025. All rights reserved.
*/
/**
* @file
*
* Define commonly used streaming types for compression
*/
package cangjie_tpc::zlib4cj
import std.io.*
sealed abstract class CompressOutputStream <: OutputStream & Resource {
let out : OutputStream
let deflater: Deflate
var buf: Array<Byte>
var closed: Bool
var syncFlush: Bool
var ownDeflate: Bool
var aotuOutClose: Bool
protected var error: Int32
@Frozen
protected init(out: OutputStream, deflater: Deflate, bufferSize: Int64,
ownDeflate: Bool, aotuOutClose: Bool) {
let bufsize = if (bufferSize <= 0) {
1024
} else {
bufferSize
}
this.out = out
this.deflater = deflater
this.buf = Array<Byte>(bufsize, repeat: 0)
this.closed = false
this.error = 0
this.syncFlush = false
this.ownDeflate = ownDeflate
this.aotuOutClose = aotuOutClose
}
@Frozen
public open func setDictionary(dict: Array<UInt8>): Int32
@Frozen
public func write(buffer: Array<Byte>): Unit {
if (this.deflater.finished) {
return
}
else if (buffer.size == 0) {
return
}
let flush = if (this.syncFlush) {
Z_SYNC_FLUSH
} else {
Z_NO_FLUSH
}
this.deflater.setInBuf(buffer)
while(this.deflater.avail_in > 0) {
this.deflater.setOutBuf(this.buf)
this.error = this.deflater.deflate(flush)
let len = this.deflater.pos_out
if (len > 0) {
this.out.write(this.buf[0..len])
this.deflater.resetOutBuf()
}
if (this.error == Z_OK) {}
else if (this.error == Z_STREAM_END) {
break
}
else if (this.error == Z_BUF_ERROR) {
if (this.deflater.avail_out <= 0 && flush != Z_FINISH) {
break
}
}
else {
throw IOException(deflater.message) // cjlint-ignore !G.ERR.02 description
}
}
}
@Frozen
public func getErrorCode(): Int32 {
return this.error
}
@Frozen
public func flush(): Unit {
if (this.closed) {
return
}
if (syncFlush && !deflater.finished) {
while (true) {
this.deflater.setOutBuf(this.buf)
this.error = this.deflater.deflate(Z_SYNC_FLUSH)
let len = this.deflater.pos_out
if (len > 0) {
this.out.write(this.buf[0..len])
this.deflater.resetOutBuf()
}
if (this.error == Z_OK) {}
else if (this.error == Z_STREAM_END) {
break
}
else if (this.error == Z_BUF_ERROR) {
if (this.deflater.avail_out <= 0 && Z_SYNC_FLUSH != Z_FINISH) {
break
}
}
else {
throw IOException(deflater.message) // cjlint-ignore !G.ERR.02 description
}
if (this.deflater.pos_out < this.buf.size) {
break
}
if (this.error == Z_STREAM_END) {
break
}
}
}
this.out.flush()
}
@Frozen
public func close(): Unit {
if (this.closed) {
return
}
this.finish()
if (this.aotuOutClose) {
if (let Some(v) <- (this.out as Resource)) {
v.close()
}
}
if (this.ownDeflate) {
this.deflater.deflateEnd()
}
}
@Frozen
public func finish(): Unit {
if (this.closed) {
return
}
this.deflater.setOutBuf(this.buf)
while (true) {
this.error = this.deflater.deflate(Z_FINISH)
let len = this.deflater.pos_out
if (len > 0) {
this.out.write(this.buf[0..len])
this.deflater.resetOutBuf()
}
if (this.error == Z_OK) {}
else if (this.error == Z_STREAM_END) {
break
}
else if (this.error == Z_BUF_ERROR) {
if (this.deflater.avail_out <= 0 && Z_FINISH != Z_FINISH) {
break
}
}
else {
throw IOException(deflater.message) // cjlint-ignore !G.ERR.02 description
}
}
}
@Frozen
public open func getTotalIn(): Int64 {
return this.deflater.getTotalIn()
}
@Frozen
public open func getTotalOut(): Int64 {
return this.deflater.getTotalOut()
}
@Frozen
public open func getAvailIn(): Int64 {
return this.deflater.avail_in
}
@Frozen
public open func getPositionOut(): Int64 {
return this.deflater.getOutDataLength()
}
@Frozen
public open func getDeflater(): Deflate {
return this.deflater
}
@Frozen
public open func isClosed(): Bool{
return this.closed
}
}
public class DeflaterOutputStream <: CompressOutputStream {
@Frozen
public init(out: OutputStream,
bufferSize!: Int64 = 1024,
level!: Int64 = 6,
memLevel!: UInt32 = DEF_MEM_LEVEL,
strategy!: UInt32 = Z_DEFAULT_STRATEGY) {
super(out, Deflate(), bufferSize, true, true)
let lev = if (level < 0 || level > 9) {
6
} else {
level
}
let mem = if (memLevel < 1 || memLevel > 9) {
DEF_MEM_LEVEL
} else {
memLevel
}
let str = if (strategy < 0 || strategy > 4) {
Z_DEFAULT_STRATEGY
} else {
strategy
}
this.deflater.deflateInit2(lev, -15, mem, str)
}
@Frozen
public func setDictionary(dict: Array<UInt8>): Int32 {
return this.deflater.setDictionary(dict)
}
}
public class GzipOutputStream <: CompressOutputStream {
@Frozen
public init(out: OutputStream,
bufferSize!: Int64 = 1024,
level!: Int64 = 6,
memLevel!: UInt32 = DEF_MEM_LEVEL,
strategy!: UInt32 = Z_DEFAULT_STRATEGY) {
super(out, Deflate(), bufferSize, true, true)
let lev = if (level < 0 || level > 9) {
6
} else {
level
}
let mem = if (memLevel < 1 || memLevel > 9) {
DEF_MEM_LEVEL
} else {
memLevel
}
let str = if (strategy < 0 || strategy > 4) {
Z_DEFAULT_STRATEGY
} else {
strategy
}
this.deflater.deflateInit2(lev, 15 + 16, mem, str)
}
@Frozen
public func setDictionary(dict: Array<UInt8>): Int32 { // cjlint-ignore !G.FUN.02 description
throw Zlib4cjException("GzipOutputStream does not support setDictionary")
}
}
public class ZlibOutputStream <: CompressOutputStream {
@Frozen
public init(out: OutputStream,
bufferSize!: Int64 = 1024,
level!: Int64 = 6,
memLevel!: UInt32 = DEF_MEM_LEVEL,
strategy!: UInt32 = Z_DEFAULT_STRATEGY) {
super(out, Deflate(), bufferSize, true, true)
let lev = if (level < 0 || level > 9) {
6
} else {
level
}
let mem = if (memLevel < 1 || memLevel > 9) {
DEF_MEM_LEVEL
} else {
memLevel
}
let str = if (strategy < 0 || strategy > 4) {
Z_DEFAULT_STRATEGY
} else {
strategy
}
this.deflater.deflateInit2(lev, 15, mem, str)
}
@Frozen
public func setDictionary(dict: Array<UInt8>): Int32 {
return this.deflater.setDictionary(dict)
}
}
sealed abstract class CompressInputStream <: InputStream {
let input: InputStream
//从输入流中读取数据,存在 this.buf 中,用于后续压缩。
var inbuf: Array<Byte>
//let out: ByteArrayStream
let deflater: Deflate
var buf: Array<Byte>
var closed: Bool
var syncFlush: Bool
var ownDeflate: Bool
var aotuOutClose: Bool
var totalread: Int64
//已到达基础输入流的末尾。
private var reachEOF: Bool = false
//读取到的压缩好的数据长度
var cnt: Int64 = 0
//需要读取的压缩好的数据长度
var sum: Int64 = 0
@Frozen
protected init(input: InputStream, deflater: Deflate, size: Int64,
ownDeflate: Bool, aotuOutClose: Bool) {
let bufsize = if (size <= 0) {
1024
} else {
size
}
this.input = input
//this.out = ByteArrayStream()
this.deflater = deflater
//从输入流中读取数据,存在 this.buf 中,用于后续压缩。
this.inbuf = Array<Byte>(bufsize, repeat: 0)
this.buf = NULL_ARR_UINT8
this.closed = false
this.syncFlush = false
this.ownDeflate = ownDeflate
this.aotuOutClose = aotuOutClose
this.totalread = 0
}
@Frozen
public func setDictionary(dict: Array<UInt8>): Int32
@Frozen
public func read(buffer: Array<Byte>): Int64 {
if (this.deflater.finished) {
return -1
}
else if (buffer.size == 0) {
return 0
}
let flush = if (this.syncFlush) {
Z_SYNC_FLUSH
} else {
Z_NO_FLUSH
}
this.buf = buffer
var off: Int64 = 0
var len: Int64 = buffer.size
this.cnt = 0
this.sum = buffer.size
while(cnt < sum && len > 0 && !this.deflater.finished) {
var n: Int64 = 0
if (this.deflater.avail_in <= 0) {
n = this.input.read(this.inbuf)
this.totalread += n
if (n <= 0 && this.totalread > 0) {
//已到达输入流的末尾
this.finish()
} else if (n > 0) {
this.deflater.setInBuf(this.inbuf, 0, n)
} else if (n <= 0) {//从 arkts 流端多次向 InputStream 中写入待压缩数据
return cnt
}
}
while(cnt < sum && this.deflater.avail_in > 0) {
this.deflater.setOutBuf(this.buf, cnt, sum - cnt)
let err = this.deflater.deflate(flush)
n = this.deflater.pos_out - cnt
if (n > 0) {
cnt += n
off += n
len -= n
this.deflater.resetOutBuf()
}
if (err == Z_OK) {}
else if (err == Z_OK && n <= 0) {//从 arkts 流端多次向 InputStream 中写入待压缩数据
return cnt
}
else if (err == Z_STREAM_END) {
break
}
else if (err == Z_BUF_ERROR) {
if (this.deflater.avail_out <= 0 && flush != Z_FINISH) {
break
}
}
else {
throw IOException(deflater.message) // cjlint-ignore !G.ERR.02 description
}
}
}
if (cnt == 0 && this.deflater.finished) {
reachEOF = true
cnt = -1
}
return cnt
}
@Frozen
public func close(): Unit {
if (this.closed) {
return
}
// this.finish()
if (this.ownDeflate) {
this.deflater.deflateEnd()
}
}
func finish(): Unit {
if (this.closed) {
return
}
this.deflater.setOutBuf(this.buf, cnt, sum - cnt)
while (cnt < sum) {
let err = this.deflater.deflate(Z_FINISH)
let len = this.deflater.pos_out - cnt
if (len > 0) {
cnt += len
this.deflater.resetOutBuf()
}
if (err == Z_OK) {}
else if (err == Z_STREAM_END) {
break
}
else if (err == Z_BUF_ERROR) {
if (this.deflater.avail_out <= 0 && Z_FINISH != Z_FINISH) {
break
}
}
else {
throw IOException(deflater.message) // cjlint-ignore !G.ERR.02 description
}
}
}
public open func getTotalIn(): Int64 {
return this.deflater.getTotalIn()
}
public open func getTotalOut(): Int64 {
return this.deflater.getTotalOut()
}
public open func getAvailIn(): Int64 {
return this.deflater.avail_in
}
public open func getPositionOut(): Int64 {
return this.deflater.getOutDataLength()
}
public open func getDeflater(): Deflate {
return this.deflater
}
public open func isClosed(): Bool{
return this.closed
}
}
public class DeflaterInputStream <: CompressInputStream {
public init(in_: InputStream,
bufferSize!: Int64 = 1024,
level!: Int64 = 6,
memLevel!: UInt32 = DEF_MEM_LEVEL,
strategy!: UInt32 = Z_DEFAULT_STRATEGY) {
super(in_, Deflate(), bufferSize, true, true)
let lev = if (level < 0 || level > 9) {
6
} else {
level
}
let mem = if (memLevel < 1 || memLevel > 9) {
DEF_MEM_LEVEL
} else {
memLevel
}
let str = if (strategy < 0 || strategy > 4) {
Z_DEFAULT_STRATEGY
} else {
strategy
}
this.deflater.deflateInit2(lev, -15, mem, str)
}
@Frozen
public func setDictionary(dict: Array<UInt8>): Int32 {
return this.deflater.setDictionary(dict)
}
}
public class GzipInputStream <: CompressInputStream {
public init(in_: InputStream,
bufferSize!: Int64 = 1024,
level!: Int64 = 6,
memLevel!: UInt32 = DEF_MEM_LEVEL,
strategy!: UInt32 = Z_DEFAULT_STRATEGY) {
super(in_, Deflate(), bufferSize, true, true)
let lev = if (level < 0 || level > 9) {
6
} else {
level
}
let mem = if (memLevel < 1 || memLevel > 9) {
DEF_MEM_LEVEL
} else {
memLevel
}
let str = if (strategy < 0 || strategy > 4) {
Z_DEFAULT_STRATEGY
} else {
strategy
}
this.deflater.deflateInit2(lev, 15 + 16, mem, str)
}
@Frozen
public func setDictionary(dict: Array<UInt8>): Int32 { // cjlint-ignore !G.FUN.02 description
throw Zlib4cjException("GzipInputStream does not support setDictionary")
}
}
public class ZlibInputStream <: CompressInputStream {
public init(in_: InputStream,
bufferSize!: Int64 = 1024,
level!: Int64 = 6,
memLevel!: UInt32 = DEF_MEM_LEVEL,
strategy!: UInt32 = Z_DEFAULT_STRATEGY) {
super(in_, Deflate(), bufferSize, true, true)
let lev = if (level < 0 || level > 9) {
6
} else {
level
}
let mem = if (memLevel < 1 || memLevel > 9) {
DEF_MEM_LEVEL
} else {
memLevel
}
let str = if (strategy < 0 || strategy > 4) {
Z_DEFAULT_STRATEGY
} else {
strategy
}
this.deflater.deflateInit2(lev, 15, mem, str)
}
@Frozen
public func setDictionary(dict: Array<UInt8>): Int32 {
return this.deflater.setDictionary(dict)
}
}