Skip to content

Commit

Permalink
Add UnsafeRichArray#at syntax extension (#2888)
Browse files Browse the repository at this point in the history
* Add `UnsafeRichArray#at` syntax extension

* Use it more
  • Loading branch information
armanbilge committed Oct 10, 2022
1 parent 8a15c88 commit d350595
Show file tree
Hide file tree
Showing 12 changed files with 29 additions and 26 deletions.
4 changes: 1 addition & 3 deletions javalib/src/main/scala/java/lang/String.scala
Expand Up @@ -252,12 +252,10 @@ final class _String()
} else {
val data1 =
value
.asInstanceOf[CharArray]
.at(offset)
.asInstanceOf[Ptr[scala.Byte]]
val data2 =
s.value
.asInstanceOf[CharArray]
.at(s.offset)
.asInstanceOf[Ptr[scala.Byte]]
memcmp(data1, data2, (count * 2).toUInt) == 0
Expand Down Expand Up @@ -362,7 +360,7 @@ final class _String()
if (count == 0) {
0
} else {
val data = value.asInstanceOf[CharArray].at(offset)
val data = value.at(offset)
var hash = 0
var i = 0
while (i < count) {
Expand Down
4 changes: 2 additions & 2 deletions javalib/src/main/scala/java/net/AbstractPlainSocketImpl.scala
Expand Up @@ -295,7 +295,7 @@ private[net] abstract class AbstractPlainSocketImpl extends SocketImpl {
} else if (isClosed) {
0
} else {
val cArr = buffer.asInstanceOf[ByteArray].at(offset)
val cArr = buffer.at(offset)
var sent = 0
while (sent < count) {
val ret = socket
Expand All @@ -314,7 +314,7 @@ private[net] abstract class AbstractPlainSocketImpl extends SocketImpl {
if (shutInput) -1
else {
val bytesNum = socket
.recv(fd.fd, buffer.asInstanceOf[ByteArray].at(offset), count.toUInt, 0)
.recv(fd.fd, buffer.at(offset), count.toUInt, 0)
.toInt

def timeoutDetected = mapLastError(
Expand Down
4 changes: 2 additions & 2 deletions javalib/src/main/scala/java/nio/GenHeapBufferView.scala
@@ -1,6 +1,6 @@
package java.nio

import scala.scalanative.runtime.ByteArray
import scala.scalanative.unsafe._

// Ported from Scala.js
private[nio] object GenHeapBufferView {
Expand Down Expand Up @@ -129,7 +129,7 @@ private[nio] final class GenHeapBufferView[B <: Buffer](val self: B)
newHeapBufferView: NewThisHeapBufferView
): ByteArrayBits = {
ByteArrayBits(
_byteArray.asInstanceOf[ByteArray].at(0),
_byteArray.at(0),
_byteArrayOffset,
isBigEndian,
newHeapBufferView.bytesPerElem
Expand Down
4 changes: 2 additions & 2 deletions javalib/src/main/scala/java/nio/HeapByteBuffer.scala
@@ -1,6 +1,6 @@
package java.nio

import scala.scalanative.runtime.ByteArray
import scala.scalanative.unsafe._

// Ported from Scala.js

Expand Down Expand Up @@ -70,7 +70,7 @@ private[nio] class HeapByteBuffer(

@inline private def arrayBits: ByteArrayBits =
ByteArrayBits(
_array.asInstanceOf[ByteArray].at(0),
_array.at(0),
_arrayOffset,
isBigEndian
)
Expand Down
Expand Up @@ -213,7 +213,7 @@ private[java] final class FileChannelImpl(

// we use the runtime knowledge of the array layout to avoid
// intermediate buffer, and write straight into the array memory
val buf = buffer.asInstanceOf[runtime.ByteArray].at(offset)
val buf = buffer.at(offset)
if (isWindows) {
def fail() = throw WindowsException.onPath(file.fold("")(_.toString))

Expand Down Expand Up @@ -373,7 +373,7 @@ private[java] final class FileChannelImpl(

// we use the runtime knowledge of the array layout to avoid
// intermediate buffer, and read straight from the array memory
val buf = buffer.asInstanceOf[runtime.ByteArray].at(offset)
val buf = buffer.at(offset)
if (isWindows) {
val hasSucceded =
WriteFile(fd.handle, buf, count.toUInt, null, null)
Expand Down
2 changes: 1 addition & 1 deletion javalib/src/main/scala/java/util/zip/Adler32.scala
Expand Up @@ -39,7 +39,7 @@ class Adler32 extends Checksum {
zlib
.adler32(
adler1.toULong,
buf.asInstanceOf[ByteArray].at(off),
buf.at(off),
nbytes.toUInt
)
.toLong
Expand Down
2 changes: 1 addition & 1 deletion javalib/src/main/scala/java/util/zip/CRC32.scala
Expand Up @@ -42,6 +42,6 @@ class CRC32 extends Checksum {
crc1: Long
): Long =
zlib
.crc32(crc1.toULong, buf.asInstanceOf[ByteArray].at(off), nbytes.toUInt)
.crc32(crc1.toULong, buf.at(off), nbytes.toUInt)
.toLong
}
10 changes: 5 additions & 5 deletions javalib/src/main/scala/java/util/zip/Deflater.scala
Expand Up @@ -58,9 +58,9 @@ class Deflater(private var compressLevel: Int, noHeader: Boolean) {
val sin = stream.totalIn.toInt
val sout = stream.totalOut.toInt
if (buf.length == 0) {
stream.nextOut = Deflater.empty.asInstanceOf[ByteArray].at(off)
stream.nextOut = Deflater.empty.at(off)
} else {
stream.nextOut = buf.asInstanceOf[ByteArray].at(off)
stream.nextOut = buf.at(off)
}
val err = zlib.deflate(stream, flushParm)

Expand Down Expand Up @@ -139,7 +139,7 @@ class Deflater(private var compressLevel: Int, noHeader: Boolean) {
if (stream == null) {
throw new IllegalStateException()
} else if (off <= buf.length && nbytes >= 0 && off >= 0 && buf.length - off >= nbytes) {
val bytes = buf.asInstanceOf[ByteArray].at(off)
val bytes = buf.at(off)
val err = zlib.deflateSetDictionary(stream, bytes, nbytes.toUInt)
if (err != zlib.Z_OK) {
throw new IllegalArgumentException(err.toString)
Expand All @@ -166,9 +166,9 @@ class Deflater(private var compressLevel: Int, noHeader: Boolean) {
}
inputBuffer = buf
if (buf.length == 0) {
stream.nextIn = Deflater.empty.asInstanceOf[ByteArray].at(off)
stream.nextIn = Deflater.empty.at(off)
} else {
stream.nextIn = buf.asInstanceOf[ByteArray].at(off)
stream.nextIn = buf.at(off)
}
stream.availableIn = nbytes.toUInt
} else {
Expand Down
10 changes: 5 additions & 5 deletions javalib/src/main/scala/java/util/zip/Inflater.scala
Expand Up @@ -128,7 +128,7 @@ class Inflater(noHeader: Boolean) {
if (stream == null) {
throw new NullPointerException()
} else {
val bytes = buf.asInstanceOf[ByteArray].at(off)
val bytes = buf.at(off)
val err = zlib.inflateSetDictionary(stream, bytes, nbytes.toUInt)
if (err != zlib.Z_OK) {
throw new IllegalArgumentException(err.toString)
Expand All @@ -146,9 +146,9 @@ class Inflater(noHeader: Boolean) {
inRead = 0
inLength = nbytes
if (buf.length == 0) {
stream.nextIn = Inflater.empty.asInstanceOf[ByteArray].at(off)
stream.nextIn = Inflater.empty.at(off)
} else {
stream.nextIn = buf.asInstanceOf[ByteArray].at(off)
stream.nextIn = buf.at(off)
}
stream.availableIn = nbytes.toUInt
} else {
Expand All @@ -160,9 +160,9 @@ class Inflater(noHeader: Boolean) {
val sin = stream.totalIn
val sout = stream.totalOut
if (buf.length == 0) {
stream.nextOut = Inflater.empty.asInstanceOf[ByteArray].at(off)
stream.nextOut = Inflater.empty.at(off)
} else {
stream.nextOut = buf.asInstanceOf[ByteArray].at(off)
stream.nextOut = buf.at(off)
}
val err = zlib.inflate(stream, zlib.Z_SYNC_FLUSH)

Expand Down
Expand Up @@ -101,7 +101,7 @@ object CVarArgList {
val count =
((sizeof(tag) + sizeof[Long] - 1.toULong) / sizeof[Long]).toInt
val words = new Array[Long](count)
val start = words.asInstanceOf[LongArray].at(0).asInstanceOf[Ptr[T]]
val start = words.at(0).asInstanceOf[Ptr[T]]
tag.store(start, value)
words
}
Expand Down Expand Up @@ -151,7 +151,7 @@ object CVarArgList {
}
val resultStorage =
z.alloc(sizeof[Long] * storage.size.toULong).asInstanceOf[Ptr[Long]]
val storageStart = storage.asInstanceOf[LongArray].at(0)
val storageStart = storage.at(0)
libc.memcpy(
toRawPtr(resultStorage),
toRawPtr(storageStart),
Expand Down
Expand Up @@ -124,6 +124,11 @@ package object unsafe extends unsafe.UnsafePackageCompat {
@inline def toPtr[T]: Ptr[T] = fromRawPtr[T](castLongToRawPtr(value))
}

/** Scala Native unsafe extensions to Arrays */
implicit class UnsafeRichArray[T](val value: Array[T]) extends AnyVal {
@inline def at(i: Int): Ptr[T] = value.asInstanceOf[runtime.Array[T]].at(i)
}

/** Convert a CString to a String using given charset. */
def fromCString(
cstr: CString,
Expand Down
Expand Up @@ -217,7 +217,7 @@ class IssuesTest {
val bytes = new Array[Byte](2)
bytes(0) = 'b'.toByte
bytes(1) = 'a'.toByte
val p: Ptr[Byte] = bytes.asInstanceOf[ByteArray].at(0)
val p: Ptr[Byte] = bytes.at(0)
assertEquals('b'.toByte, !p)
assertEquals('a'.toByte, !(p + 1))
}
Expand Down

0 comments on commit d350595

Please sign in to comment.