/*
* 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.
*/
package std.core
@Frozen
public func print(str: String, flush!: Bool = false): Unit {
unsafe {
var cp = acquireArrayRawData(str.rawData())
let ret = CJ_CORE_PrintUTF8(cp.pointer, str.size, false, flush)
releaseArrayRawData(cp)
if (ret == -1) {
throw OutOfMemoryError()
}
}
}
@Frozen
public func println(): Unit {
unsafe {
CJ_CORE_PrintChar(UInt32(r'\n'), false, false)
}
}
@Frozen
public func println(str: String): Unit {
unsafe {
var cp = acquireArrayRawData(str.rawData())
let ret = CJ_CORE_PrintUTF8(cp.pointer, str.size, true, false)
releaseArrayRawData(cp)
if (ret == -1) {
throw OutOfMemoryError()
}
}
}
// The `eprint` is used to print error message, such as exception throwing.
// The message will be printed to standard error text stream rather than standard output.
@Frozen
public func eprint(str: String, flush!: Bool = true): Unit {
unsafe {
var cp = acquireArrayRawData(str.rawData())
let ret = CJ_CORE_ErrorPrintUTF8(cp.pointer, str.size, false, flush)
releaseArrayRawData(cp)
if (ret == -1) {
throw OutOfMemoryError()
}
}
}
// The `eprintln` is used to print error message, such as exception throwing.
// The message will be printed to standard error text stream rather than standard output.
@Frozen
public func eprintln(str: String): Unit {
unsafe {
var cp = acquireArrayRawData(str.rawData())
let ret = CJ_CORE_ErrorPrintUTF8(cp.pointer, str.size, true, true)
releaseArrayRawData(cp)
if (ret == -1) {
throw OutOfMemoryError()
}
}
}
@Frozen
public func eprint<T>(arg: T, flush!: Bool = false): Unit where T <: ToString {
eprint(arg.toString(), flush: flush)
}
@Frozen
public func eprintln<T>(arg: T): Unit where T <: ToString {
eprintln(arg.toString())
}
@Frozen
public func print<T>(arg: T, flush!: Bool = false): Unit where T <: ToString {
print(arg.toString(), flush: flush)
}
@Frozen
public func println<T>(arg: T): Unit where T <: ToString {
println(arg.toString())
}
public func readln(): String {
let ln = readFromConsole()
if (ln.endsWith("\r\n")) {
return ln[..ln.size - 2]
} else if (ln.endsWith('\n')) {
return ln[..ln.size - 1]
}
return ln
}
private func readFromConsole(): String {
let build: StringBuilder = StringBuilder()
let line: CPointer<StructureString> = unsafe { CJ_CONSOLE_Readline() }
if (line.isNull()) {
unsafe { CJ_CONSOLE_ClearstdInerr() }
throw IllegalStateException("Failed to read from console: I/O error or EOF.")
}
let str = unsafe { line.read() }
var itemLen = Int64(str.length)
try {
var buffer: Array<Byte> = Array<Byte>(itemLen, repeat: 0)
var i: Int64 = 0
while (i < itemLen) {
var c = unsafe { str.buffer.read(i) }
buffer[i] = c
i++
}
build.appendFromUtf8(buffer)
} finally {
unsafe {
LibC.free(str.buffer)
LibC.free(line)
}
}
return build.toString()
}
/**
* overload primitive types for performance optimization
* For example, when using `Bool` type as the argument of `print` function, there are two steps:
* 1. call `toString()` method to create a String
* 2. call `print(String)` function to do the printing
* A few temporary objects like `Array<UInt8>` and `String` are created in above process.
* If we provide a few overloaded `print` function below, these temporary objects can be avoided.
*/
@Frozen
public func print(b: Bool, flush!: Bool = false): Unit {
unsafe { CJ_CORE_PrintBool(b, false, flush) }
}
@Frozen
public func println(b: Bool): Unit {
unsafe { CJ_CORE_PrintBool(b, true, false) }
}
@Frozen
public func print(c: Rune, flush!: Bool = false): Unit {
unsafe { CJ_CORE_PrintChar(UInt32(c), false, flush) }
}
@Frozen
public func println(c: Rune): Unit {
unsafe { CJ_CORE_PrintChar(UInt32(c), true, false) }
}
@Frozen
public func print(f: Float16, flush!: Bool = false): Unit {
unsafe { CJ_CORE_PrintFloat(Float64(f), false, flush) }
}
@Frozen
public func println(f: Float16): Unit {
unsafe { CJ_CORE_PrintFloat(Float64(f), true, false) }
}
@Frozen
public func print(f: Float32, flush!: Bool = false): Unit {
unsafe { CJ_CORE_PrintFloat(Float64(f), false, flush) }
}
@Frozen
public func println(f: Float32): Unit {
unsafe { CJ_CORE_PrintFloat(Float64(f), true, false) }
}
@Frozen
public func print(f: Float64, flush!: Bool = false): Unit {
unsafe { CJ_CORE_PrintFloat(f, false, flush) }
}
@Frozen
public func println(f: Float64): Unit {
unsafe { CJ_CORE_PrintFloat(f, true, false) }
}
@Frozen
public func print(i: Int8, flush!: Bool = false): Unit {
unsafe { CJ_CORE_PrintSigned(Int64(i), false, flush) }
}
@Frozen
public func print(i: Int16, flush!: Bool = false): Unit {
unsafe { CJ_CORE_PrintSigned(Int64(i), false, flush) }
}
@Frozen
public func print(i: Int32, flush!: Bool = false): Unit {
unsafe { CJ_CORE_PrintSigned(Int64(i), false, flush) }
}
@Frozen
public func print(i: Int64, flush!: Bool = false): Unit {
unsafe { CJ_CORE_PrintSigned(i, false, flush) }
}
@Frozen
public func print(i: UInt8, flush!: Bool = false): Unit {
unsafe { CJ_CORE_PrintUnsigned(UInt64(i), false, flush) }
}
@Frozen
public func print(i: UInt16, flush!: Bool = false): Unit {
unsafe { CJ_CORE_PrintUnsigned(UInt64(i), false, flush) }
}
@Frozen
public func print(i: UInt32, flush!: Bool = false): Unit {
unsafe { CJ_CORE_PrintUnsigned(UInt64(i), false, flush) }
}
@Frozen
public func print(i: UInt64, flush!: Bool = false): Unit {
unsafe { CJ_CORE_PrintUnsigned(i, false, flush) }
}
@Frozen
public func println(i: Int8): Unit {
unsafe { CJ_CORE_PrintSigned(Int64(i), true, false) }
}
@Frozen
public func println(i: Int16): Unit {
unsafe { CJ_CORE_PrintSigned(Int64(i), true, false) }
}
@Frozen
public func println(i: Int32): Unit {
unsafe { CJ_CORE_PrintSigned(Int64(i), true, false) }
}
@Frozen
public func println(i: Int64): Unit {
unsafe { CJ_CORE_PrintSigned(i, true, false) }
}
@Frozen
public func println(i: UInt8): Unit {
unsafe { CJ_CORE_PrintUnsigned(UInt64(i), true, false) }
}
@Frozen
public func println(i: UInt16): Unit {
unsafe { CJ_CORE_PrintUnsigned(UInt64(i), true, false) }
}
@Frozen
public func println(i: UInt32): Unit {
unsafe { CJ_CORE_PrintUnsigned(UInt64(i), true, false) }
}
@Frozen
public func println(i: UInt64): Unit {
unsafe { CJ_CORE_PrintUnsigned(i, true, false) }
}