Skip to content
This repository was archived by the owner on Jul 30, 2024. It is now read-only.

Overhaul dgram module #76

Merged
merged 2 commits into from
Sep 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ The following core Node.js modules (v8.7.0+) have been implemented:
| [cluster](https://nodejs.org/api/cluster.html) | :heavy_check_mark: |
| [console](https://nodejs.org/api/console.html) | :heavy_check_mark: |
| [crypto](https://nodejs.org/api/crypto.html) | :heavy_check_mark: |
| [dgram](https://nodejs.org/api/dgram.html) | |
| [dgram](https://nodejs.org/api/dgram.html) | :heavy_check_mark: |
| [dns](https://nodejs.org/api/dns.html) | :heavy_check_mark: |
| [events](https://nodejs.org/api/events.html) | :heavy_check_mark: |
| [fs](https://nodejs.org/api/fs.html) | :heavy_check_mark: |
Expand Down
24 changes: 24 additions & 0 deletions app/current/src/main/scala/io/scalajs/nodejs/dgram/Dgram.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.scalajs.nodejs.dgram

import scala.scalajs.js
import scala.scalajs.js.annotation.JSImport

@js.native
trait Dgram extends js.Object {
def createSocket(options: SocketOptions, callback: js.Function = js.native): Socket = js.native
def createSocket(`type`: String, callback: js.Function): Socket = js.native
def createSocket(`type`: String): Socket = js.native
}

class SocketOptions(
var `type`: String,
var reuseAddr: js.UndefOr[Boolean] = js.undefined,
var ipv6Only: js.UndefOr[Boolean] = js.undefined,
var recvBufferSize: js.UndefOr[Int] = js.undefined,
var sendBufferSize: js.UndefOr[Int] = js.undefined,
var lookup: js.UndefOr[js.Function1[String, Any]] = js.undefined
) extends js.Object

@js.native
@JSImport("dgram", JSImport.Namespace)
object Dgram extends Dgram
104 changes: 66 additions & 38 deletions app/current/src/main/scala/io/scalajs/nodejs/dgram/Socket.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package io.scalajs.nodejs
package dgram

import io.scalajs.RawOptions
import io.scalajs.nodejs.buffer.Buffer
import com.thoughtworks.enableIf
import io.scalajs.nodejs.events.IEventEmitter
import io.scalajs.nodejs.net.Address

import scala.scalajs.js
import scala.scalajs.js.annotation.JSImport
import scala.scalajs.js.|

/**
* The dgram.Socket object is an EventEmitter that encapsulates the datagram functionality.
Expand All @@ -18,7 +16,7 @@ import scala.scalajs.js.|
*/
@js.native
@JSImport("dgram", "Socket")
class Socket extends IEventEmitter {
class Socket private[this] () extends IEventEmitter {

/**
* Tells the kernel to join a multicast group at the given multicastAddress and multicastInterface using the
Expand Down Expand Up @@ -48,7 +46,13 @@ class Socket extends IEventEmitter {
* @param callback the callback
* @example bind([port][, address][, callback])
*/
def bind(port: Int, address: String, callback: js.Function): Unit = js.native
def bind(port: Int, address: String, callback: js.Function0[Any]): Unit = js.native
def bind(port: Int, address: String): Unit = js.native
def bind(port: Int, callback: js.Function0[Any]): Unit = js.native
def bind(address: String, callback: js.Function0[Any]): Unit = js.native
def bind(port: Int): Unit = js.native
def bind(callback: js.Function0[Any]): Unit = js.native
def bind(address: String): Unit = js.native

/**
* For UDP sockets, causes the dgram.Socket to listen for datagram messages on a named port and optional address.
Expand All @@ -59,41 +63,44 @@ class Socket extends IEventEmitter {
* @param callback the callback
* @example bind(options[, callback])
*/
def bind(options: RawOptions, callback: js.Function): Unit = js.native
def bind(options: BindOptions, callback: js.Function = js.native): Unit = js.native

/**
* For UDP sockets, causes the dgram.Socket to listen for datagram messages on a named port and optional address.
* If port is not specified or is 0, the operating system will attempt to bind to a random port. If address is not
* specified, the operating system will attempt to listen on all addresses. Once binding is complete, a 'listening'
* event is emitted and the optional callback function is called.
* @param options the optional settings
* @example bind(options[, callback])
*/
def bind(options: RawOptions): Unit = js.native
def close(callback: js.Function = js.native): Unit = js.native

/**
* Broadcasts a datagram on the socket. The destination port and address must be specified.
*
* The msg argument contains the message to be sent. Depending on its type, different behavior can apply.
* If msg is a Buffer, the offset and length specify the offset within the Buffer where the message begins
* and the number of bytes in the message, respectively. If msg is a String, then it is automatically converted
* to a Buffer with 'utf8' encoding. With messages that contain multi-byte characters, offset and length will
* be calculated with respect to byte length and not the character position. If msg is an array, offset and
* length must not be specified.
* @param msg Message to be sent (<Buffer> | <String> | <Array>)
* @param offset Optional. Offset in the buffer where the message starts.
* @param length Optional. Number of bytes in the message.
* @param port Destination port.
* @param address Destination hostname or IP address.
* @param callback Optional. Called when the message has been sent.
* @example send(msg, [offset, length,] port, address[, callback])
*/
def send(msg: Buffer | String | js.Array[Buffer] | js.Array[String],
offset: Int = js.native,
length: Int = js.native,
port: Int,
address: String,
callback: js.Function): Unit = js.native
@enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs12)
def connect(port: Int, address: String = js.native, callback: js.Function0[Any] = js.native): Unit = js.native

@enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs12)
def disconnect(): Unit = js.native

def dropMembership(multicastAddress: String, multicastInterface: String = js.native): Unit = js.native

def getRecvBufferSize(): Int = js.native
def getSendBufferSize(): Int = js.native

def ref(): this.type = js.native

@enableIf(io.scalajs.nodejs.CompilerSwitches.gteNodeJs12)
def remoteAddress(): RemoteAddress = js.native

def send(msg: BufferMessage, offset: Int, length: Int, port: Int, address: String, callback: js.Function): Unit =
js.native
def send(msg: BufferMessage, offset: Int, length: Int, port: Int, address: String): Unit = js.native
def send(msg: BufferMessage, offset: Int, length: Int, port: Int, callback: js.Function): Unit = js.native
def send(msg: BufferMessage, offset: Int, length: Int, address: String, callback: js.Function): Unit = js.native
def send(msg: BufferMessage, offset: Int, length: Int, port: Int): Unit = js.native
def send(msg: BufferMessage, offset: Int, length: Int, address: String): Unit = js.native
def send(msg: BufferMessage, offset: Int, length: Int, callback: js.Function): Unit = js.native
def send(msg: BufferMessage, offset: Int, length: Int): Unit = js.native

def send(msg: Message, port: Int, address: String, callback: js.Function): Unit = js.native
def send(msg: Message, address: String, callback: js.Function): Unit = js.native
def send(msg: Message, port: Int, callback: js.Function): Unit = js.native
def send(msg: Message, port: Int, address: String): Unit = js.native
def send(msg: Message, callback: js.Function): Unit = js.native
def send(msg: Message, port: Int): Unit = js.native
def send(msg: Message, address: String): Unit = js.native
def send(msg: Message): Unit = js.native

/**
* Sets or clears the SO_BROADCAST socket option. When set to true, UDP packets may be sent to a
Expand All @@ -102,4 +109,25 @@ class Socket extends IEventEmitter {
*/
def setBroadcast(flag: Boolean): Unit = js.native

def setMulticastInterface(multicastInterface: String): Unit = js.native
def setMulticastLoopback(flag: Boolean): Unit = js.native
def setMulticastTTL(ttl: Int): Unit = js.native
def setRecvBufferSize(size: Int): Unit = js.native
def setSendBufferSize(size: Int): Unit = js.native
def setTTL(ttl: Int): Unit = js.native
def unref(): this.type = js.native
}

class BindOptions(
var port: js.UndefOr[Int] = js.undefined,
var address: js.UndefOr[String] = js.undefined,
var exclusive: js.UndefOr[Boolean] = js.undefined,
var fd: js.UndefOr[Int] = js.undefined
) extends js.Object {}

@js.native
trait RemoteAddress extends js.Object {
var address: String = js.native
var family: String = js.native
var port: Int = js.native
}
11 changes: 11 additions & 0 deletions app/current/src/main/scala/io/scalajs/nodejs/dgram/package.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.scalajs.nodejs

import scala.scalajs.js
import scala.scalajs.js.typedarray.Uint8Array
import scala.scalajs.js.|

package object dgram {
type StringMessage = String | js.Array[String]
type Message = BufferMessage | StringMessage
type BufferMessage = Uint8Array | js.Array[Uint8Array]
}
2 changes: 1 addition & 1 deletion core/src/main/scala/io/scalajs/util/PromiseHelper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ object PromiseHelper {
case Success(_) =>
val elapsedTime = System.currentTimeMillis - startTime
println(f"$action took $elapsedTime msecs")
case Failure(e) =>
case Failure(_) =>
val elapsedTime = System.currentTimeMillis - startTime
println(f"$action took $elapsedTime msecs")
}
Expand Down
37 changes: 34 additions & 3 deletions project/MySettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,46 @@ import sbtrelease.ReleaseStateTransformations._

object MySettings {

private val lintSettings = Def.setting({
val isScala212 = scalaVersion.value.startsWith("2.12")
val lints = (Seq(
"adapted-args",
"nullary-unit",
"inaccessible",
"nullary-override",
"infer-any",
"missing-interpolator",
"doc-detached",
"private-shadow",
"type-parameter-shadow",
"poly-implicit-overload",
"option-implicit",
"delayedinit-select",
"package-object-classes",
"stars-align",
"constant"
) ++ Seq(
"nonlocal-return",
"implicit-not-found",
"serial",
"valpattern",
"eta-zero",
"eta-sam",
"deprecation"
).filter(_ => !isScala212)).map(s => s"-Xlint:${s}")
// no privates to allow private constructor
val unused = Seq("imports", "implicits", "locals", "patvars").filter(_ => !isScala212).map(s => s"-Wunused:${s}")
lints ++ unused
})

lazy val commonSettings = Seq(
autoCompilerPlugins := true,
scalacOptions ++= Seq(
"-deprecation",
"-unchecked",
"-feature",
"-language:implicitConversions",
"-Xlint"
),
"-language:implicitConversions"
) ++ lintSettings.value,
scalacOptions in Compile in compile ++= Seq(
"-Xfatal-warnings"
),
Expand Down