/**
 * call-seq:
 *  read(device=nil)
 * 
 * Read the disc ID from the given device.
 * 
 * If no device is given the default device of the platform will be used.
 * Throws an _Exception_ if the CD's TOC can not be read.
 *
 * Raises:: ArgumentError, TypeError, Exception
 */
static VALUE mb_discid_read(int argc, VALUE *argv, VALUE self)
{
        DiscId *disc;        /* Pointer to the disc struct */
        VALUE device = Qnil; /* The device string as a Ruby string */
        char* cdevice;       /* The device string as a C string */
        
        Data_Get_Struct(self, DiscId, disc);
        
        /* Check the number and types of arguments */
        rb_scan_args(argc, argv, "01", &device);

        /* Use the default device if none was given. */
        if (device == Qnil)
                cdevice = discid_get_default_device();
        else if (rb_respond_to(device, rb_intern("to_s")))
        {
                device = rb_funcall(device, rb_intern("to_s"), 0, 0);
                cdevice = StringValuePtr(device);
        }
        else
                rb_raise(rb_eTypeError, "wrong argument type (expected String)");
        
        /* Mark the disc id as unread in case something goes wrong. */
        rb_iv_set(self, "@read", Qfalse);
        
        /* Read the discid */
        if (discid_read(disc, cdevice) == 0)
                rb_raise(rb_eException, "%s", discid_get_error_msg(disc));
        else /* Remember that we already read the ID. */
                rb_iv_set(self, "@read", Qtrue);
        
        return Qnil;
}