Skip to content

Commit

Permalink
Add missing functionality.
Browse files Browse the repository at this point in the history
  • Loading branch information
quelgar committed Feb 20, 2024
1 parent 548e4de commit 6a795d6
Show file tree
Hide file tree
Showing 11 changed files with 352 additions and 143 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ organization := "io.github.quelgar"

name := "scala-uv"

version := "0.0.2"
version := "0.0.3-SNAPSHOT"

ThisBuild / versionScheme := Some("early-semver")

Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/scala-native/helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
#include <netinet/in.h>
#endif

uv_loop_t *scala_uv_fs_req_get_loop(const uv_fs_t *req)
{
return req->loop;
}

void scala_uv_buf_init(char *base, unsigned int len, uv_buf_t *buffer)
{
uv_buf_t buf = uv_buf_init(base, len);
Expand Down
49 changes: 38 additions & 11 deletions src/main/scala/scalauv/Buffer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,26 @@ object Buffer {

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

// to avoid compiler bug where same name is used in inline methods in different files
private val h = scalauv.helpers

extension (buffer: Buffer) {

/** Pointer to the actual content.
*/
def base: Ptr[Byte] = helpers.scala_uv_buf_base(buffer)
inline def base: Ptr[Byte] = h.scala_uv_buf_base(buffer)

def base_=(ptr: Ptr[Byte]): Unit =
helpers.scala_uv_buf_base_set(buffer, ptr)
inline def base_=(ptr: Ptr[Byte]): Unit =
h.scala_uv_buf_base_set(buffer, ptr)

/** The number of bytes (starting from `base`) that should be considered
* part of this buffer. When reading, you probably want to set this to the
* number of bytes read.
*/
def length: Int = helpers.scala_uv_buf_len(buffer).toInt
inline def length: Int = h.scala_uv_buf_len(buffer).toInt

def length_=(len: Int): Unit =
helpers.scala_uv_buf_len_set(buffer, len.toUInt)
inline def length_=(len: Int): Unit =
h.scala_uv_buf_len_set(buffer, len.toUInt)

/** Gets the byte at the specified index.
*
Expand Down Expand Up @@ -93,23 +96,47 @@ object Buffer {
* `length`.
*/
inline def init(base: Ptr[Byte], length: CSize): Unit =
helpers.scala_uv_buf_init(base, length.toUInt, buffer)
h.scala_uv_buf_init(base, length.toUInt, buffer)

/** Allocates a new native byte array of `size` bytes, and uses it to
* initialize this buffer structure. `base` is set to the newly allocated
* array, and `length` is set to `size`.
*/
inline def mallocInit(size: CSize): Unit =
helpers.scala_uv_buf_init(stdlib.malloc(size), size.toUInt, buffer)
h.scala_uv_buf_init(stdlib.malloc(size), size.toUInt, buffer)

/** Frees this boffer structure. **Note:** does not free the `base` pointer.
*/
inline def free(): Unit = stdlib.free(buffer)

/** Perform an operation using this buffer with the length temporarily
* changed. This can be useful after a read that only partially filled the
* buffer.
*/
inline def withLength[A](tempLength: Int)(f: Buffer => A): A = {
val oldLength = length
length = tempLength
val result = f(buffer)
length = oldLength
result
}

inline def withOffset[A](offset: Int)(f: Buffer => A): A = {
val origBase = base
val origLength = length
base += offset
length -= offset
val result = f(buffer)
length = origLength
base = origBase
result
}

}

/** The size of the `uv_buf_t` structure. Useful for manual allocation.
*/
val structureSize: CSize = helpers.scala_uv_buf_struct_size()
val structureSize: CSize = h.scala_uv_buf_struct_size()

/** Cast a native pointer to a buffer structure pointer.
*/
Expand Down Expand Up @@ -166,7 +193,7 @@ object Buffer {
*/
def malloc(base: Ptr[Byte], size: CSize): Buffer = {
val uvBuf = stdlib.malloc(structureSize.toULong)
helpers.scala_uv_buf_init(base, size.toUInt, uvBuf)
h.scala_uv_buf_init(base, size.toUInt, uvBuf)
uvBuf
}

Expand All @@ -176,7 +203,7 @@ object Buffer {
*/
def malloc(array: Array[Byte], index: Int = 0): Buffer = {
val uvBuf = stdlib.malloc(structureSize.toULong)
helpers.scala_uv_buf_init(
h.scala_uv_buf_init(
array.at(index),
(array.length - index).toUInt,
uvBuf
Expand Down
14 changes: 14 additions & 0 deletions src/main/scala/scalauv/Handle.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ object Handle {

extension (h: Handle) {

inline def loop: Loop = LibUv.uv_handle_get_loop(h)

inline def handleType: HandleType = LibUv.uv_handle_get_type(h)

inline def data: Ptr[Byte] = LibUv.uv_handle_get_data(h)

inline def data_=(data: Ptr[Byte]): Unit = LibUv.uv_handle_set_data(h, data)

/** Extract the underlying native pointer for this handle.
*/
inline def toPtr: Ptr[Byte] = h
Expand Down Expand Up @@ -230,6 +238,12 @@ object StreamHandle {

given Tag[StreamHandle] = Tag.Ptr(Tag.Byte)

extension (h: StreamHandle) {

inline def writeQueueSize: CSize = LibUv.uv_stream_get_write_queue_size(h)

}

}

/** The `uv_tcp_t*` type.
Expand Down
71 changes: 1 addition & 70 deletions src/main/scala/scalauv/LibUv.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1599,82 +1599,13 @@ object LibUv {
// =========================================================
// File system operations

/** Pointer to time strucutre.
*
* @see
* [[https://docs.libuv.org/en/v1.x/fs.html#c.uv_timespec_t LibUv docs]]
* @group fs
*/
type TimeSpec = Ptr[CStruct2[CLong, CLong]]

/** Pointer to file `stat` strcture.
*
* @see
* [[https://docs.libuv.org/en/v1.x/fs.html#c.uv_stat_t LibUv docs]]
* @group fs
*/
type Stat = Ptr[CStruct16[
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong,
TimeSpec,
TimeSpec,
TimeSpec,
TimeSpec
]]

/** Pointer to `struct statfs`.
*
* @see
* [[https://docs.libuv.org/en/v1.x/fs.html#c.uv_statfs_t LibUv docs]]
* @group fs
*/
type StatFs = Ptr[CStruct11[
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong,
CUnsignedLongLong
]]

/** Pointer to directory entry structure.
*
* @see
* [[https://docs.libuv.org/en/v1.x/fs.html#c.uv_dirent_t LibUv docs]]
* @group fs
*/
type DirEnt = Ptr[CStruct2[CString, DirEntType]]

/** Pointer to directory structure.
*
* @see
* [[https://docs.libuv.org/en/v1.x/fs.html#c.uv_dir_t LibUv docs]]
* @group fs
*/
type Dir = Ptr[CStruct2[DirEnt, CSize]]

/** Callback for file system requests.
*
* @see
* [[https://docs.libuv.org/en/v1.x/fs.html#c.uv_fs_cb LibUv docs]]
* @group fs
*/
type FsCallback = CFuncPtr1[Req, Unit]
type FsCallback = CFuncPtr1[FileReq, Unit]

/** Cleans up a file system request.
*
Expand Down
54 changes: 54 additions & 0 deletions src/main/scala/scalauv/Req.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ object Req {

extension (r: Req) {

inline def data: Ptr[Byte] = LibUv.uv_req_get_data(r)

inline def data_=(data: Ptr[Byte]): Unit = LibUv.uv_req_set_data(r, data)

inline def reqType: RequestType = LibUv.uv_req_get_type(r)

inline def cancel(): ErrorCode = LibUv.uv_cancel(r)

/** Casts this request to a native pointer.
*/
inline def toPtr: Ptr[Byte] = r
Expand All @@ -62,6 +70,13 @@ opaque type RequestType = CInt
/** Constants for all the request types supported by libuv.
*/
object RequestType {

extension (rt: RequestType) {

inline def size: CSize = LibUv.uv_req_size(rt)

}

val UNKNOWN_REQ: RequestType = 0
val REQ: RequestType = 1
val CONNECT: RequestType = 2
Expand Down Expand Up @@ -114,6 +129,13 @@ object ShutdownReq {
inline def malloc(): ShutdownReq =
Req.malloc(RequestType.SHUTDOWN)

extension (r: ShutdownReq) {

inline def shutdownReqStreamHandle: StreamHandle =
helpers.scala_uv_shutdown_stream_handle(r)

}

}

opaque type WriteReq <: Req = Ptr[Byte]
Expand All @@ -131,6 +153,16 @@ object WriteReq {
inline def malloc(): WriteReq =
Req.malloc(RequestType.WRITE)

extension (r: WriteReq) {

inline def writeReqStreamHandle: StreamHandle =
helpers.scala_uv_write_stream_handle(r)

inline def writeReqSendStreamHandle: StreamHandle =
helpers.scala_uv_send_stream_handle(r)

}

}

opaque type UdpSendReq <: Req = Ptr[Byte]
Expand All @@ -154,6 +186,28 @@ opaque type FileReq <: Req = Ptr[Byte]

object FileReq {

given Tag[FileReq] = Tag.Ptr(Tag.Byte)

extension (req: FileReq) {

inline def loop: Loop = helpers.scala_uv_fs_req_get_loop(req)

inline def fsType: FsType = LibUv.uv_fs_get_type(req)

inline def result: CSSize = LibUv.uv_fs_get_result(req)

inline def systemError: CInt = LibUv.uv_fs_get_system_error(req)

inline def ptr: Ptr[Byte] = LibUv.uv_fs_get_ptr(req)

inline def path: CString = LibUv.uv_fs_get_path(req)

inline def statBuf: Stat = LibUv.uv_fs_get_statbuf(req)

inline def cleanup(): Unit = LibUv.uv_fs_req_cleanup(req)

}

inline def stackAllocate(): FileReq =
Req.stackAllocate(RequestType.FS)

Expand Down
Loading

0 comments on commit 6a795d6

Please sign in to comment.