shake it all up
[tripe-android] / util.scala
index 8eba6f8..79ac861 100644 (file)
@@ -45,17 +45,16 @@ def unreachable(msg: String): Nothing = throw new AssertionError(msg);
 /*----- Various pieces of implicit magic ----------------------------------*/
 
 class InvalidCStringException(msg: String) extends Exception(msg);
-type CString = Array[Byte];
 
-object Magic {
+object Implicits {
 
   /* --- Syntactic sugar for locks --- */
 
   implicit class LockOps(lk: Lock) {
     /* LK withLock { BODY }
      * LK.withLock(INTERRUPT) { BODY }
-     * LK.withLock(DUR, [INTERRUPT]) { BODY } orelse { ALT }
-     * LK.withLock(DL, [INTERRUPT]) { BODY } orelse { ALT }
+     * LK.withLock(DUR, [INTERRUPT]) { BODY } orElse { ALT }
+     * LK.withLock(DL, [INTERRUPT]) { BODY } orElse { ALT }
      *
      * Acquire a lock while executing a BODY.  If a duration or deadline is
      * given then wait so long for the lock, and then give up and run ALT
@@ -81,12 +80,12 @@ object Magic {
     def withLock[T](body: => T): T = withLock(true)(body);
   }
 
-  class PendingLock[T] private[Magic]
+  class PendingLock[T] private[Implicits]
          (val lk: Lock, val dur: Duration,
           val interrupt: Boolean, body: => T) {
-    /* An auxiliary class for LockOps; provides the `orelse' qualifier. */
+    /* An auxiliary class for LockOps; provides the `orElse' qualifier. */
 
-    def orelse(alt: => T): T = {
+    def orElse(alt: => T): T = {
       val locked = (dur, interrupt) match {
        case (Duration.Inf, true) => lk.lockInterruptibly(); true
        case (Duration.Inf, false) => lk.lock(); true
@@ -98,86 +97,6 @@ object Magic {
       else try { body; } finally lk.unlock();
     }
   }
-
-  /* --- Conversion to/from C strings --- */
-
-  implicit class ConvertJStringToCString(s: String) {
-    /* Magic to convert a string into a C string (null-terminated bytes). */
-
-    def toCString: CString = {
-      /* Convert the receiver to a C string.
-       *
-       * We do this by hand, rather than relying on the JNI's built-in
-       * conversions, because we use the default encoding taken from the
-       * locale settings, rather than the ridiculous `modified UTF-8' which
-       * is (a) insensitive to the user's chosen locale and (b) not actually
-       * UTF-8 either.
-       */
-
-      val enc = Charset.defaultCharset.newEncoder;
-      val in = CharBuffer.wrap(s);
-      var sz: Int = (s.length*enc.averageBytesPerChar + 1).toInt;
-      var out = ByteBuffer.allocate(sz);
-
-      while (true) {
-       /* If there's still stuff to encode, then encode it.  Otherwise,
-        * there must be some dregs left in the encoder, so flush them out.
-        */
-       val r = if (in.hasRemaining) enc.encode(in, out, true)
-               else enc.flush(out);
-
-       /* Sift through the wreckage to figure out what to do. */
-       if (r.isError) r.throwException();
-       else if (r.isOverflow) {
-         /* No space in the buffer.  Make it bigger. */
-
-         sz *= 2;
-         val newout = ByteBuffer.allocate(sz);
-         out.flip(); newout.put(out);
-         out = newout;
-       } else if (r.isUnderflow) {
-         /* All done.  Check that there are no unexpected zero bytes -- so
-          * this will indeed be a valid C string -- and convert into a byte
-          * array that the C code will be able to pick apart.
-          */
-
-         out.flip(); val n = out.limit; val u = out.array;
-         if ({val z = u.indexOf(0); 0 <= z && z < n})
-           throw new InvalidCStringException("null byte in encoding");
-         val v = new Array[Byte](n + 1);
-         out.array.copyToArray(v, 0, n);
-         v(n) = 0;
-         return v;
-       }
-      }
-
-      /* Placate the type checker. */
-      unreachable("unreachable");
-    }
-  }
-
-  implicit class ConvertCStringToJString(v: CString) {
-    /* Magic to convert a C string into a `proper' string. */
-
-    def toJString: String = {
-      /* Convert the receiver to a C string.
-       *
-       * We do this by hand, rather than relying on the JNI's built-in
-       * conversions, because we use the default encoding taken from the
-       * locale settings, rather than the ridiculous `modified UTF-8' which
-       * is (a) insensitive to the user's chosen locale and (b) not actually
-       * UTF-8 either.
-       */
-
-      val inlen = v.indexOf(0) match {
-       case -1 => v.length
-       case n => n
-      }
-      val dec = Charset.defaultCharset.newDecoder;
-      val in = ByteBuffer.wrap(v, 0, inlen);
-      dec.decode(in).toString
-    }
-  }
 }
 
 /*----- Cleanup assistant -------------------------------------------------*/