/*
* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
* This source file is part of the Cangjie project, licensed under Apache-2.0
* with Runtime Library Exception.
*
* See https://cangjie-lang.cn/pages/LICENSE for license information.
*/
/**
* @file
*
* This file defines some utility functions.
*/
package std.io
let BLOCK_SIZE = 4096
/**
* SeekPosition is the position of the cursor in the file.
*/
public enum SeekPosition {
| Current(Int64) /* < current position. */
| Begin(Int64) /* < begin position of the file. */
| End(Int64) /* < end position of the file. */
}
public func readString<T>(from: T): String where T <: InputStream & Seekable {
var data = Array<Byte>(from.remainLength, repeat: 0)
return try {
from.read(data)
String.fromUtf8(data)
} catch (e: IllegalArgumentException) {
throw ContentFormatException(e.message)
}
}
public unsafe func readStringUnchecked<T>(from: T): String where T <: InputStream & Seekable {
var data = Array<Byte>(from.remainLength, repeat: 0)
from.read(data)
String.fromUtf8Unchecked(data)
}
public func readToEnd<T>(from: T): Array<Byte> where T <: InputStream & Seekable {
let sum = from.length
const MAX_DIRECT_ALLOC_SIZE: Int64 = 1 << 30 // 1 GB
if (sum <= 0 || sum > MAX_DIRECT_ALLOC_SIZE) {
let tempSize: Int64 = BLOCK_SIZE
let temp: Array<Byte> = Array<Byte>(tempSize, repeat: 0)
var buffer: ByteBuffer = ByteBuffer(tempSize)
while (true) {
let readLen = from.read(temp)
if (readLen == 0) {
break
} else if (readLen == tempSize) {
buffer.write(temp)
} else {
buffer.write(temp.slice(0, readLen))
}
}
var res: Array<Byte> = Array<Byte>(buffer.length, repeat: 0)
buffer.read(res)
return res
}
let arr: Array<Byte> = Array<Byte>(sum, repeat: 0)
let onceMax = 1 << 30
var readSize = 0
var emptySize = arr.size
while (readSize < sum) {
let oneSize = if (emptySize > onceMax) {
onceMax
} else {
emptySize
}
let len = from.read(arr.slice(readSize, oneSize))
if (len == 0) {
break
}
readSize += len
emptySize -= len
}
arr.slice(0, readSize)
}
public func copy(from: InputStream, to!: OutputStream): Int64 {
let tempArr = Array<Byte>(BLOCK_SIZE, repeat: 0)
var readCount = 0
while (true) {
let readRet = from.read(tempArr)
if (readRet > 0) {
to.write(tempArr.slice(0, readRet))
} else {
break
}
readCount += readRet
}
readCount
}