commonMain.org.jetbrains.skia.Data.kt Maven / Gradle / Ivy
package org.jetbrains.skia
import org.jetbrains.skia.impl.*
import org.jetbrains.skia.impl.Library.Companion.staticLoad
/**
* Data holds an immutable data buffer.
*/
class Data internal constructor(ptr: NativePointer) : Managed(ptr, _FinalizerHolder.PTR) {
/**
* A reference to the underlying memory owner to prevent it from being cleaned by GC until Data instance finalization.
* It's used in [makeWithoutCopy].
*/
private var underlyingMemoryOwner: Managed? = null
companion object {
fun makeFromBytes(bytes: ByteArray, offset: Int = 0, length: Int = bytes.size): Data {
Stats.onNativeCall()
return Data(
interopScope {
_nMakeFromBytes(toInterop(bytes), offset, length)
}
)
}
/**
* makeWithoutCopy uses NoopReleaseProc as a ReleaseProc, therefore memory needs to be cleaned up by caller side
* (or by [underlyingMemoryOwner] if provided).
*
* @param underlyingMemoryOwner - is stored in Data instance to prevent underlying memory getting cleaned by GC in cases when
* [underlyingMemoryOwner] doesn't have any other references.
*/
fun makeWithoutCopy(memoryAddr: NativePointer, length: Int, underlyingMemoryOwner: Managed): Data {
Stats.onNativeCall()
return Data(
interopScope {
_nMakeWithoutCopy(memoryAddr, length)
}
).also {
it.underlyingMemoryOwner = underlyingMemoryOwner
}
}
/**
* Returns a new empty dataref (or a reference to a shared empty dataref).
* New or shared, the caller must see that [.close] is eventually called.
*/
fun makeEmpty(): Data {
Stats.onNativeCall()
return Data(_nMakeEmpty())
}
fun makeUninitialized(length: Int): Data {
Stats.onNativeCall()
return Data(_nMakeUninitialized(length))
}
init {
staticLoad()
}
}
val size: Int
get() = try {
Stats.onNativeCall()
_nSize(_ptr)
} finally {
reachabilityBarrier(this)
}
val bytes: ByteArray
get() = getBytes(0, size)
fun getBytes(offset: Int, length: Int): ByteArray {
return try {
Stats.onNativeCall()
check(_nSize(_ptr) >= offset + length) {
"Data=${_ptr}: Can't getBytes with offset=$offset and length=$length"
}
withResult(ByteArray(length)) {
_nBytes(_ptr, offset, length, it)
}
} finally {
reachabilityBarrier(this)
}
}
override fun equals(other: Any?): Boolean {
val otherData = other as? Data ?: return false
return _nativeEquals(otherData)
}
/**
* Returns true if these two objects have the same length and contents,
* effectively returning 0 == memcmp(...)
*/
override fun _nativeEquals(other: Native?): Boolean {
return try {
Stats.onNativeCall()
_nEquals(_ptr, getPtr(other))
} finally {
reachabilityBarrier(this)
reachabilityBarrier(other)
}
}
/**
* Create a new dataref using a subset of the data in the specified
* src dataref.
*/
fun makeSubset(offset: Int, length: Int): Data {
return try {
Stats.onNativeCall()
Data(_nMakeSubset(_ptr, offset, length))
} finally {
reachabilityBarrier(this)
}
}
fun makeCopy(): Data {
return try {
Stats.onNativeCall()
Data(_nMakeSubset(_ptr, 0, size))
} finally {
reachabilityBarrier(this)
}
}
fun writableData(): NativePointer {
return try {
Stats.onNativeCall()
_nWritableData(_ptr)
} finally {
reachabilityBarrier(this)
}
}
private object _FinalizerHolder {
val PTR = Data_nGetFinalizer()
}
}
@ExternalSymbolName("org_jetbrains_skia_Data__1nGetFinalizer")
private external fun Data_nGetFinalizer(): NativePointer
@ExternalSymbolName("org_jetbrains_skia_Data__1nSize")
private external fun _nSize(ptr: NativePointer): Int
@ExternalSymbolName("org_jetbrains_skia_Data__1nBytes")
private external fun _nBytes(ptr: NativePointer, offset: Int, length: Int, destBytes: InteropPointer)
@ExternalSymbolName("org_jetbrains_skia_Data__1nEquals")
private external fun _nEquals(ptr: NativePointer, otherPtr: NativePointer): Boolean
@ExternalSymbolName("org_jetbrains_skia_Data__1nMakeFromBytes")
private external fun _nMakeFromBytes(bytes: InteropPointer, offset: Int, length: Int): NativePointer
@ExternalSymbolName("org_jetbrains_skia_Data__1nMakeWithoutCopy")
private external fun _nMakeWithoutCopy(memoryAddr: NativePointer, length: Int): NativePointer
@ExternalSymbolName("org_jetbrains_skia_Data__1nMakeFromFileName")
internal external fun _nMakeFromFileName(path: InteropPointer): NativePointer
@ExternalSymbolName("org_jetbrains_skia_Data__1nMakeSubset")
private external fun _nMakeSubset(ptr: NativePointer, offset: Int, length: Int): NativePointer
@ExternalSymbolName("org_jetbrains_skia_Data__1nMakeEmpty")
private external fun _nMakeEmpty(): NativePointer
@ExternalSymbolName("org_jetbrains_skia_Data__1nMakeUninitialized")
private external fun _nMakeUninitialized(length: Int): NativePointer
@ExternalSymbolName("org_jetbrains_skia_Data__1nWritableData")
private external fun _nWritableData(dataPtr: NativePointer): NativePointer