aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/com/github/jodersky/flow/Serial.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/com/github/jodersky/flow/Serial.scala')
-rw-r--r--src/main/scala/com/github/jodersky/flow/Serial.scala63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/main/scala/com/github/jodersky/flow/Serial.scala b/src/main/scala/com/github/jodersky/flow/Serial.scala
new file mode 100644
index 0000000..7565cbd
--- /dev/null
+++ b/src/main/scala/com/github/jodersky/flow/Serial.scala
@@ -0,0 +1,63 @@
+package com.github.jodersky.flow
+
+import scala.concurrent._
+import scala.concurrent.ExecutionContext.Implicits._
+import java.io.IOException
+
+class Serial private (val port: String, private val pointer: Long, reader: Array[Byte] => Unit) {
+ future {
+ var n = 0
+ val buffer = new Array[Byte](100)
+ while (n >= 0) {
+ n = NativeSerial.read(pointer, buffer)
+ import NativeSerial._
+ n match {
+ case E_POINTER => throw new NullPointerException("pointer to native serial")
+ case E_POLL => throw new IOException(port + ": polling")
+ case E_IO => throw new IOException(port + ": reading")
+ case E_CLOSE => println("close request")
+ case x if x > 0 => reader(buffer.take(n))
+ }
+ }
+ }
+
+ private def writeBlock(data: Array[Byte]) = synchronized {
+ import NativeSerial._
+ NativeSerial.write(pointer, data) match {
+ case E_POINTER => throw new NullPointerException("pointer to native serial")
+ case E_IO => throw new IOException(port + ": writing")
+ case r => data.take(r)
+ }
+ }
+
+ def write(data: Array[Byte]) = future { writeBlock(data) }
+
+ def close() = synchronized {
+ NativeSerial.close(pointer)
+ }
+
+}
+
+object Serial {
+
+ def open(port: String, baud: Int)(reader: Array[Byte] => Unit) = synchronized {
+ val pointer = new Array[Long](1)
+ val result = NativeSerial.open(port, baud, pointer)
+
+ import NativeSerial._
+ result match {
+ case E_PERMISSION => throw new AccessDeniedException(port)
+ case E_OPEN => throw new NoSuchPortException(port)
+ case E_BUSY => throw new PortInUseException(port)
+ case E_BAUD => throw new IllegalArgumentException(
+ s"invalid baudrate ${baud}, use standard unix values")
+ case E_PIPE => throw new IOException("cannot create pipe")
+ case E_MALLOC => throw new IOException("cannot allocate memory")
+ case 0 => new Serial(port, pointer(0), reader)
+ case _ => throw new Exception("cannot open port")
+ }
+ }
+
+ def debug(value: Boolean) = NativeSerial.debug(value)
+
+} \ No newline at end of file