Skip to content

Commit

Permalink
ch07 refactored common parts, deduped code
Browse files Browse the repository at this point in the history
  • Loading branch information
spamegg1 committed Apr 9, 2024
1 parent c3dd0bb commit 1848bca
Show file tree
Hide file tree
Showing 12 changed files with 295 additions and 480 deletions.
9 changes: 9 additions & 0 deletions src/main/scala/ch07/common/common.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package ch07

import collection.mutable.{Map => MMap}

case class ResponseState(
var code: Int = 200,
var headers: MMap[String, String] = MMap(),
var body: String = ""
)
12 changes: 12 additions & 0 deletions src/main/scala/ch07/common/curl.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ch07

import scalanative.unsafe.Ptr
import scala.scalanative.runtime.{Boxes, Intrinsics}

object Curl:
import LibCurl.*, LibCurlConstants.*
import LibUV.*, LibUVConstants.*

def funcToPtr(f: Object): Ptr[Byte] = Boxes.boxToPtr[Byte](Boxes.unboxToCFuncPtr1(f))
def intToPtr(i: Int): Ptr[Byte] = Boxes.boxToPtr[Byte](Intrinsics.castIntToRawPtr(i))
def longToPtr(l: Long): Ptr[Byte] = Boxes.boxToPtr[Byte](Intrinsics.castLongToRawPtr(l))
6 changes: 5 additions & 1 deletion src/main/scala/ch07/common/libcurl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ object LibCurl:
type Curl = Ptr[Byte]
type CurlBuffer = CStruct2[CString, CSize]
type CurlOption = Int
type CurlAction = CInt
type CurlInfo = CInt
type MultiCurl = Ptr[Byte]
type CurlRequest = CStruct4[Ptr[Byte], Long, Long, Int]
type CurlMessage = CStruct3[Int, Curl, Ptr[Byte]]
type MultiCurl = Ptr[Byte]
type CurlSList = CStruct2[Ptr[Byte], CString]
type CurlDataCallback = CFuncPtr4[Ptr[Byte], CSize, CSize, Ptr[Byte], CSize]
type CurlSocketCallback = CFuncPtr5[Curl, Ptr[Byte], CInt, Ptr[Byte], Ptr[Byte], CInt]
type CurlTimerCallback = CFuncPtr3[MultiCurl, Long, Ptr[Byte], CInt]
type SocketCallback = CFuncPtr5[Curl, Ptr[Byte], CInt, Ptr[Byte], Ptr[Byte], CInt]
type TimerCallback = CFuncPtr3[MultiCurl, Long, Ptr[Byte], CInt]

def curl_easy_strerror(code: Int): CString = extern
@name("curl_global_init") def global_init(flags: Long): Unit = extern
Expand Down
43 changes: 19 additions & 24 deletions src/main/scala/ch07/common/libcurlConstants.scala
Original file line number Diff line number Diff line change
@@ -1,38 +1,33 @@
package ch07

import scalanative.unsafe.{CInt, Ptr, CFuncPtr3, CFuncPtr5}

object LibCurlConstants:
import LibCurl.*

val URL = 10002
val PORT = 10003
val USERPASSWORD = 10005
val URL: CurlOption = 10002
val PORT: CurlOption = 10003
val USERPASSWORD: CurlOption = 10005

val READDATA = 10009
val HEADERDATA = 10029
val WRITEDATA = 10001
val READDATA: CurlOption = 10009
val HEADERDATA: CurlOption = 10029
val WRITEDATA: CurlOption = 10001

val READCALLBACK = 20012
val HEADERCALLBACK = 20079
val WRITECALLBACK = 20011
val READCALLBACK: CurlOption = 20012
val HEADERCALLBACK: CurlOption = 20079
val WRITECALLBACK: CurlOption = 20011

val TIMEOUT = 13
val GET = 80
val POST = 47
val PUT = 54
val CONTENTLENGTHDOWNLOADT = 0x300000 + 15
val HTTPHEADER = 10023
val TIMEOUT: CurlOption = 13
val GET: CurlOption = 80
val POST: CurlOption = 47
val PUT: CurlOption = 54
val CONTENTLENGTHDOWNLOADT: CurlInfo = 0x300000 + 15
val HTTPHEADER: CurlOption = 10023

val PRIVATEDATA = 10103
val GET_PRIVATEDATA = 0x100000 + 21
val PRIVATEDATA: CurlOption = 10103
val GET_PRIVATEDATA: CurlInfo = 0x100000 + 21

val SOCKETFUNCTION = 20001
type SocketCallback = CFuncPtr5[Curl, Ptr[Byte], CInt, Ptr[Byte], Ptr[Byte], CInt]
val TIMERFUNCTION = 20004
type TimerCallback = CFuncPtr3[MultiCurl, Long, Ptr[Byte], CInt]
val SOCKETFUNCTION: CurlOption = 20001
val TIMERFUNCTION: CurlOption = 20004

type CurlAction = CInt
val POLL_NONE: CurlAction = 0
val POLL_IN: CurlAction = 1
val POLL_OUT: CurlAction = 2
Expand Down
107 changes: 107 additions & 0 deletions src/main/scala/ch07/common/libuv.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package ch07

import scalanative.unsafe.*

@link("uv")
@extern
object LibUV:
type PipeHandle = Ptr[Byte]
type PollHandle = Ptr[Ptr[Byte]]
type TCPHandle = Ptr[Byte]
type TTYHandle = Ptr[Byte]
type Loop = Ptr[Byte]
type Buffer = CStruct2[Ptr[Byte], CSize]
type WriteReq = Ptr[Ptr[Byte]]
type ShutdownReq = Ptr[Ptr[Byte]]
type Connection = Ptr[Byte]
type ConnectionCB = CFuncPtr2[TCPHandle, Int, Unit]
type AllocCB = CFuncPtr3[TCPHandle, CSize, Ptr[Buffer], Unit]
type ReadCB = CFuncPtr3[TCPHandle, CSSize, Ptr[Buffer], Unit]
type WriteCB = CFuncPtr2[WriteReq, Int, Unit]
type ShutdownCB = CFuncPtr2[ShutdownReq, Int, Unit]
type CloseCB = CFuncPtr1[TCPHandle, Unit]
type PollCB = CFuncPtr3[PollHandle, Int, Int, Unit]
type PrepareHandle = Ptr[Byte]
type TimerHandle = Ptr[Byte]
type PrepareCB = CFuncPtr1[PrepareHandle, Unit]
type TimerCB = CFuncPtr1[TimerHandle, Unit]
type FSReq = Ptr[Ptr[Byte]]
type FSCB = CFuncPtr1[FSReq, Unit]

def uv_prepare_init(loop: Loop, handle: PrepareHandle): Int = extern
def uv_prepare_start(handle: PrepareHandle, cb: PrepareCB): Int = extern
def uv_prepare_stop(handle: PrepareHandle): Unit = extern
def uv_default_loop(): Loop = extern
def uv_loop_size(): CSize = extern
def uv_is_active(handle: Ptr[Byte]): Int = extern
def uv_handle_size(h_type: Int): CSize = extern
def uv_req_size(r_type: Int): CSize = extern
def uv_tty_init(loop: Loop, handle: TTYHandle, fd: Int, readable: Int): Int = extern
def uv_tcp_init(loop: Loop, tcp_handle: TCPHandle): Int = extern
def uv_tcp_bind(tcp_handle: TCPHandle, address: Ptr[Byte], flags: Int): Int = extern
def uv_ip4_addr(address: CString, port: Int, out_addr: Ptr[Byte]): Int = extern
def uv_ip4_name(address: Ptr[Byte], s: CString, size: Int): Int = extern
def uv_pipe_init(loop: Loop, handle: PipeHandle, ipc: Int): Int = extern
def uv_pipe_open(handle: PipeHandle, fd: Int): Int = extern
def uv_pipe_bind(handle: PipeHandle, socketName: CString): Int = extern
def uv_poll_init_socket(loop: Loop, handle: PollHandle, socket: Ptr[Byte]): Int = extern
def uv_poll_start(handle: PollHandle, events: Int, cb: PollCB): Int = extern
def uv_poll_stop(handle: PollHandle): Int = extern
def uv_timer_init(loop: Loop, handle: TimerHandle): Int = extern
def uv_timer_start(handle: TimerHandle, cb: TimerCB, timeout: Long, repeat: Long): Int =
extern
def uv_timer_stop(handle: TimerHandle): Int = extern
def uv_listen(handle: PipeHandle, backlog: Int, callback: ConnectionCB): Int = extern
def uv_accept(server: PipeHandle, client: PipeHandle): Int = extern
def uv_read_start(client: PipeHandle, allocCB: AllocCB, readCB: ReadCB): Int = extern
def uv_write(
writeReq: WriteReq,
client: PipeHandle,
bufs: Ptr[Buffer],
numBufs: Int,
writeCB: WriteCB
): Int = extern
def uv_read_stop(client: PipeHandle): Int = extern
def uv_shutdown(
shutdownReq: ShutdownReq,
client: PipeHandle,
shutdownCB: ShutdownCB
): Int = extern
def uv_close(handle: PipeHandle, closeCB: CloseCB): Unit = extern
def uv_is_closing(handle: PipeHandle): Int = extern
def uv_run(loop: Loop, runMode: Int): Int = extern
def uv_strerror(err: Int): CString = extern
def uv_err_name(err: Int): CString = extern
def uv_fileno(handle: TTYHandle, fileno: Ptr[Int]): Int = extern
def uv_handle_type_name(handle: TTYHandle): Int = extern
def uv_guess_handle(fd: Int): Int = extern
def uv_fs_open(
loop: Loop,
req: FSReq,
path: CString,
flags: Int,
mode: Int,
cb: FSCB
): Int = extern
def uv_fs_read(
loop: Loop,
req: FSReq,
fd: Int,
bufs: Ptr[Buffer],
numBufs: Int,
offset: Long,
fsCB: FSCB
): Int = extern
def uv_fs_write(
loop: Loop,
req: FSReq,
fd: Int,
bufs: Ptr[Buffer],
numBufs: Int,
offset: Long,
fsCB: FSCB
): Int = extern
def uv_fs_close(loop: Loop, req: FSReq, fd: Int, fsCB: FSCB): Int = extern
def uv_req_cleanup(req: FSReq): Unit = extern
def uv_fs_get_result(req: FSReq): Int = extern
def uv_fs_get_ptr(req: FSReq): Ptr[Byte] = extern
48 changes: 48 additions & 0 deletions src/main/scala/ch07/common/libuvConstants.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package ch07

import scalanative.unsafe.fromCString

object LibUVConstants:
import LibUV.*

// uv_run_mode
val UV_RUN_DEFAULT = 0
val UV_RUN_ONCE = 1
val UV_RUN_NOWAIT = 2

// UV_HANDLE_T
val UV_PIPE_T = 7
val UV_POLL_T = 8
val UV_PREPARE_T = 9
val UV_PROCESS_T = 10
val UV_TCP_T = 12
val UV_TIMER_T = 13
val UV_TTY_T = 14
val UV_UDP_T = 15

// UV_REQ_T
val UV_WRITE_REQ_T = 3
val UV_SHUTDOWN_REQ_T = 4
val UV_FS_REQ_T = 6

val UV_READABLE = 1
val UV_WRITABLE = 2
val UV_DISCONNECT = 4
val UV_PRIORITIZED = 8

val O_RDWR = 2
val O_CREAT = sys.props("os.name") match
case "Mac OS X" => 512
case _ => 64

val default_permissions = 420 // octal 0644

def checkError(v: Int, label: String): Int =
if v == 0 then
println(s"$label returned $v")
v
else
val error = fromCString(uv_err_name(v))
val message = fromCString(uv_strerror(v))
println(s"$label returned $v: $error: $message")
v
Loading

0 comments on commit 1848bca

Please sign in to comment.