Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
quelgar committed Dec 29, 2023
1 parent 6fdad24 commit 6d79067
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 105 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
/project/target
/project/project
sbt-launch.jar
src/test/resources/write-test.txt
14 changes: 11 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
scalaVersion := "3.3.1"

enablePlugins(ScalaNativePlugin)
enablePlugins(ScalaNativeJUnitPlugin)

organization := "quelgar.github.com"

Expand All @@ -17,10 +18,17 @@ nativeConfig ~= { c =>
c.withLTO(LTO.none) // thin
.withMode(Mode.debug) // releaseFast
.withGC(GC.immix) // commix
.withTargetTriple("arm64-apple-macosx13.0.0")
}

scalacOptions ++= Seq(
"-new-styntax",
"-no-indent"
"-new-syntax",
"-no-indent",
"-Wvalue-discard",
"-Wunused:all",
"-Werror",
"-deprecation"
)

// libraryDependencies += "dev.zio" %% "zio-test" % "2.0.20" % Test

Test / nativeLinkingOptions += "-luv"
91 changes: 2 additions & 89 deletions src/main/scala/Main.scala
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import scalauv.*

import scala.scalanative.*
import libc.string.*
import unsafe.*
import unsigned.*
import LibUv.*
import UvUtils.*
import java.io.IOException
import java.nio.charset.StandardCharsets
import scala.scalanative.libc.stdlib

object Main {
Expand All @@ -29,97 +26,11 @@ object Main {
} yield (a, b, c, d, e)
println(x)

val filename = c"test.txt"

withZone {
val loop = uv_default_loop()

println("Running!")

val text = c"Hello, world!"

val BufSize: CSize = 1024.toUInt

val buffer = alloc[Byte](BufSize)

println("openning file for write")
val fileHandle = UvUtils.FsReq
.use { openReq =>
uv_fs_open(
loop,
openReq,
filename,
FileOpenFlags.O_WRONLY | FileOpenFlags.O_CREAT | FileOpenFlags.O_TRUNC,
CreateMode.S_IRUSR | CreateMode.S_IWUSR,
null
)
}
.checkErrorThrowIO()

val bytesWritten = UvUtils.FsReq
.use { writeReq =>
strncpy(buffer, text, BufSize)
val iov = IOVector.stackAllocateForBuffer(buffer, strlen(text).toUInt)
uv_fs_write(
loop,
writeReq,
fileHandle,
iov.nativeBuffers,
iov.nativeNumBuffers,
-1,
null
)
}
.checkErrorThrowIO()

println(s"Wrote $bytesWritten bytes")

UvUtils.FsReq
.use { closeReq =>
uv_fs_close(loop, closeReq, fileHandle, null)
}
.checkErrorThrowIO()

val readFileHandle = UvUtils.FsReq
.use { openReq =>
uv_fs_open(
loop,
openReq,
filename,
FileOpenFlags.O_RDONLY,
0,
null
)
}
.checkErrorThrowIO()

val bytesRead = UvUtils.FsReq
.use { readReq =>
val iov = IOVector.stackAllocateForBuffer(buffer, BufSize.toUInt)
uv_fs_read(
loop,
readReq,
readFileHandle,
iov.nativeBuffers,
iov.nativeNumBuffers,
-1,
null
)
}
.checkErrorThrowIO()

println(s"Read $bytesRead bytes")

val readText = fromCString(buffer, StandardCharsets.UTF_8)

println(s"Read text: $readText")

UvUtils.FsReq
.use { closeReq =>
uv_fs_close(loop, closeReq, readFileHandle, null)
}
.checkErrorThrowIO()

def allocBuffer: AllocCallback = CFuncPtr3.fromScalaFunction {
(handle: StreamHandle, suggestedSize: CSize, buf: Buffer) =>
buf.mallocInit(suggestedSize)
Expand Down Expand Up @@ -157,6 +68,7 @@ object Main {
stdlib.free(outBuf.toNative)
stdlib.free(writeReq)
}
()
}
}

Expand Down Expand Up @@ -193,6 +105,7 @@ object Main {

uv_run(loop, RunMode.DEFAULT)

()
}

// val length: unsafe.CUnsignedInt = 200.toUInt
Expand Down
5 changes: 3 additions & 2 deletions src/main/scala/scalauv/Buffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ extension (buffer: Buffer) {
}
}

def +(index: Int): Buffer = buffer + (index * Buffer.structureSize)
def +(index: Int): Buffer =
buffer + (index.toLong * Buffer.structureSize.toLong)

inline def toNative: Ptr[Byte] = buffer

Expand All @@ -50,7 +51,7 @@ object Buffer {

given Tag[Buffer] = Tag.Ptr[Byte](summon[Tag[Byte]])

val structureSize: Long = helpers.uv_scala_buf_struct_size().toLong
val structureSize: CSize = helpers.uv_scala_buf_struct_size()

inline def unsafeFromNative(ptr: Ptr[Byte]): Buffer = ptr

Expand Down
5 changes: 0 additions & 5 deletions src/main/scala/scalauv/LibUv.scala
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package scalauv

import scala.scalanative.unsafe.*
import scala.scalanative.libc.*
import scala.scalanative.unsigned.*
import scala.scalanative.runtime.struct
import java.nio.charset.StandardCharsets
import java.nio

@link("uv")
@extern
Expand Down
2 changes: 0 additions & 2 deletions src/main/scala/scalauv/UvConstants.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package scalauv

import LibUv.*
import scala.scalanative.unsafe.*
import scala.scalanative.libc.*
import scala.scalanative.unsigned.*

type UvBufferSize = Nat.Digit2[Nat._1, Nat._6]

Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/scalauv/UvUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import scala.scalanative.libc.*
import scala.scalanative.unsigned.*
import java.io.IOException
import scala.util.boundary
import scala.concurrent.Future
import scala.concurrent.Promise

inline def withZone[A](f: Zone ?=> A): A = Zone(implicit z => f(using z))

Expand Down Expand Up @@ -313,7 +311,8 @@ object IOVector {
buffers: Seq[(Ptr[Byte], CUnsignedInt)]
): IOVector = {
val uvBufs =
stackalloc[Byte](buffers.size * Buffer.structureSize).asInstanceOf[Buffer]
stackalloc[Byte](buffers.size.toUInt * Buffer.structureSize)
.asInstanceOf[Buffer]
buffers.zipWithIndex.foreach { case ((ptr, size), index) =>
(uvBufs + index).init(ptr, size)
}
Expand All @@ -322,7 +321,8 @@ object IOVector {

def zoneAllocate(bufferSizes: Int*)(using Zone): IOVector = {
val uvBufs =
alloc[Byte](bufferSizes.size * Buffer.structureSize).asInstanceOf[Buffer]
alloc[Byte](bufferSizes.size.toUInt * Buffer.structureSize)
.asInstanceOf[Buffer]
bufferSizes.zipWithIndex.foreach { case (size, index) =>
val base = alloc[Byte](size)
(uvBufs + index).init(base, size.toUInt)
Expand Down
File renamed without changes.
125 changes: 125 additions & 0 deletions src/test/scala/scalauv/FileSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package scalauv

import LibUv.*
import scalanative.unsafe.*
import scalanative.unsigned.*
import java.nio.charset.StandardCharsets

import org.junit.Test
import org.junit.Assert.*
import scala.scalanative.libc.string
import java.nio.file.Files
import java.nio.file.Path

final class FileSpec {

@Test
def readFile(): Unit = {
val expected = "Hello, world!"
val filename = c"src/test/resources/test.txt"

withZone {
val loop = uv_default_loop()

val BufSize: CSize = 1024.toUInt

val buffer = alloc[Byte](BufSize)

val readFileHandle = UvUtils.FsReq
.use { openReq =>
uv_fs_open(
loop,
openReq,
filename,
FileOpenFlags.O_RDONLY,
0,
null
)
}
.checkErrorThrowIO()

val bytesRead = UvUtils.FsReq
.use { readReq =>
val iov = IOVector.stackAllocateForBuffer(buffer, BufSize.toUInt)
uv_fs_read(
loop,
readReq,
readFileHandle,
iov.nativeBuffers,
iov.nativeNumBuffers,
-1,
null
)
}
.checkErrorThrowIO()

val readText = fromCString(buffer, StandardCharsets.UTF_8)

UvUtils.FsReq
.use { closeReq =>
uv_fs_close(loop, closeReq, readFileHandle, null)
}
.checkErrorThrowIO()

assertEquals(13, bytesRead)
assertEquals(expected, readText)
}

}

@Test
def writeNewFile(): Unit = {
val text = "my country is the world, and my religion is to do good"
val filename = "src/test/resources/write-test.txt"

withZone {
val loop = uv_default_loop()

val cText = toCString(text, StandardCharsets.UTF_8)
val cFilename = toCString(filename, StandardCharsets.UTF_8)

val fileHandle = UvUtils.FsReq
.use { openReq =>
uv_fs_open(
loop,
openReq,
cFilename,
FileOpenFlags.O_WRONLY | FileOpenFlags.O_CREAT | FileOpenFlags.O_TRUNC,
CreateMode.S_IRUSR | CreateMode.S_IWUSR,
null
)
}
.checkErrorThrowIO()

val bytesWritten = UvUtils.FsReq
.use { writeReq =>
val iov =
IOVector.stackAllocateForBuffer(cText, string.strlen(cText).toUInt)
uv_fs_write(
loop,
writeReq,
fileHandle,
iov.nativeBuffers,
iov.nativeNumBuffers,
-1,
null
)
}
.checkErrorThrowIO()

UvUtils.FsReq
.use { closeReq =>
uv_fs_close(loop, closeReq, fileHandle, null)
}
.checkErrorThrowIO()

val path = Path.of(filename)
val actualText = Files.readString(path)
Files.delete(path)

assertEquals(text.length(), bytesWritten)
assertEquals(text, actualText)
}
}

}

0 comments on commit 6d79067

Please sign in to comment.