about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2011-01-31 18:39:31 -0800
committerEric Wong <normalperson@yhbt.net>2011-01-31 18:46:20 -0800
commit36f69750cd69cbf892580da04be6675e23d92f6f (patch)
treea04e2574c0de5e1ebdcaa2ff8c9683c7a4ff6fdf
parent37e50a9a5fcd45242373379c0dc61ebf8ff609af (diff)
downloadkgio-36f69750cd69cbf892580da04be6675e23d92f6f.tar.gz
This allows people to more easily use Kgio in existing apps.
-rw-r--r--ext/kgio/read_write.c41
-rw-r--r--test/test_singleton_read_write.rb21
2 files changed, 62 insertions, 0 deletions
diff --git a/ext/kgio/read_write.c b/ext/kgio/read_write.c
index 224497e..8960035 100644
--- a/ext/kgio/read_write.c
+++ b/ext/kgio/read_write.c
@@ -350,6 +350,44 @@ static VALUE kgio_trysend(VALUE io, VALUE str)
 #  define kgio_trysend kgio_trywrite
 #endif /* ! USE_MSG_DONTWAIT */
 
+/*
+ * call-seq:
+ *
+ *        Kgio.tryread(io, maxlen)           ->  buffer
+ *        Kgio.tryread(io, maxlen, buffer)   ->  buffer
+ *
+ * Returns nil on EOF.
+ * Returns :wait_readable if EAGAIN is encountered.
+ *
+ * Maybe used in place of PipeMethods#kgio_tryread for non-Kgio objects
+ */
+static VALUE s_tryread(int argc, VALUE *argv, VALUE mod)
+{
+        if (argc <= 1)
+                rb_raise(rb_eArgError, "wrong number of arguments");
+        return my_read(0, argc - 1, &argv[1], argv[0]);
+}
+
+/*
+ * call-seq:
+ *
+ *        Kgio.trywrite(io, str)    -> nil or :wait_writable
+ *
+ * Returns nil if the write was completed in full.
+ *
+ * Returns a String containing the unwritten portion if EAGAIN
+ * was encountered, but some portion was successfully written.
+ *
+ * Returns :wait_writable if EAGAIN is encountered and nothing
+ * was written.
+ *
+ * Maybe used in place of PipeMethods#kgio_trywrite for non-Kgio objects
+ */
+static VALUE s_trywrite(VALUE mod, VALUE io, VALUE str)
+{
+        return my_write(io, str, 0);
+}
+
 void init_kgio_read_write(void)
 {
         VALUE mPipeMethods, mSocketMethods;
@@ -359,6 +397,9 @@ void init_kgio_read_write(void)
         sym_wait_readable = ID2SYM(rb_intern("wait_readable"));
         sym_wait_writable = ID2SYM(rb_intern("wait_writable"));
 
+        rb_define_singleton_method(mKgio, "tryread", s_tryread, -1);
+        rb_define_singleton_method(mKgio, "trywrite", s_trywrite, 2);
+
         /*
          * Document-module: Kgio::PipeMethods
          *
diff --git a/test/test_singleton_read_write.rb b/test/test_singleton_read_write.rb
new file mode 100644
index 0000000..5abbf00
--- /dev/null
+++ b/test/test_singleton_read_write.rb
@@ -0,0 +1,21 @@
+require 'test/unit'
+$-w = true
+require 'kgio'
+
+class TestSingletonReadWrite < Test::Unit::TestCase
+
+  def test_unix_socketpair
+    a, b = UNIXSocket.pair
+    assert_nothing_raised { Kgio.trywrite(a, "HELLO") }
+    buf = ""
+    assert_equal "HELLO", Kgio.tryread(b, 5, buf)
+    assert_equal "HELLO", buf
+    assert_equal :wait_readable, Kgio.tryread(b, 5)
+  end
+
+  def test_arg_error
+    assert_raises(ArgumentError) { Kgio.tryread }
+    assert_raises(ArgumentError) { Kgio.tryread($stdin) }
+    assert_raises(ArgumentError) { Kgio.trywrite($stdout) }
+  end
+end