Skip to content
This repository has been archived by the owner on Oct 19, 2020. It is now read-only.

Commit

Permalink
Add decent rdoc documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Floppy committed Aug 21, 2008
1 parent 3ce9ed0 commit efb83dc
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 40 deletions.
15 changes: 8 additions & 7 deletions README
Expand Up @@ -45,10 +45,11 @@ You can provide alternative settings when you create a new port:
:parity => true,
:stop_bits => 2)

If you are using a simple text protocol over RS232, you can use the TextProtocol
class to help you out. It automatically monitors the port and splits messages
up by detecting separator characters. See examples/listen.rb for an example of
how to use this class.

See http://github.com/Floppy/rb232/tree/master/spec/port_spec.rb for more
details.
See http://github.com/Floppy/rb232/tree/master/spec/port_spec.rb or RB232::Port
documentation for more details.

If you are using a simple text protocol over RS232, you can use the
RB232::TextProtocol class to help you out. It automatically monitors the port
and splits messages up by detecting separator characters. See
http://github.com/Floppy/rb232/tree/master/examples/listen.rb for an example of
how to use this class.
18 changes: 18 additions & 0 deletions lib/rb232/text_protocol.rb
Expand Up @@ -3,18 +3,35 @@

module RB232

# A helper class for RB232::Port which implements a simple text-based
# protocol on top of a serial port. Data is read from the serial port and split
# into individual messages based on a separator character.
#
# This class is Observable. Client code should implement an update(string) function
# add call TextProtocol#add_observer(self). When a complete message is received,
# the update() function will be called with the message string.
class TextProtocol

include Observable

# Create a protocol object. _port_ should be a RB232::Port object.
# _separator_ is the character which separates messages in the text protocol,
# "\n" by default.
def initialize(port, separator = "\n")
@port = port
@separator = separator
end

# Separator character, as specified in TextProtocol#new
attr_reader :separator

# Port object, as specified in TextProtocol#new
attr_reader :port

# Begin processing incoming data from the serial port.
# A thread is started which monitors the port for data and detects
# complete messages.
# Call TextProtocol#stop to halt this process.
def start
@stop = false
@reader_thread = Thread.new {
Expand All @@ -31,6 +48,7 @@ def start
}
end

# Stop processing incoming data from the serial port.
def stop
@stop = true
@reader_thread.join
Expand Down
4 changes: 2 additions & 2 deletions rb232.gemspec
@@ -1,7 +1,7 @@
Gem::Specification.new do |s|
s.name = "rb232"
s.version = "0.2.1"
s.date = "2008-08-20"
s.version = "0.2.2"
s.date = "2008-08-21"
s.summary = "A simple serial port library for Ruby"
s.email = "james@floppy.org.uk"
s.homepage = "http://github.com/Floppy/rb232"
Expand Down
52 changes: 40 additions & 12 deletions src/port.c
Expand Up @@ -169,10 +169,14 @@ VALUE rb232_port_initialize_with_options(VALUE self, VALUE port, VALUE options)
}

/*
* This function implements a default argument for initialize().
* Equivalent Ruby would be def initialize(port, options = {}).
* This function calls the _with_options version, providing an empty
* hash if one is not passed in.
* Create a Port object, using the port filename specified in _port_ (e.g. '/dev/ttyS0' or 'COM1').
*
* Valid options are :baud_rate (integer), :data_bits (integer), :parity
* (boolean), and :stop_bits (integer). Default values are 9600, 8, false, and 1 respectively.
*
* call-seq:
* new(port, options = {})
*
*/
VALUE rb232_port_initialize(int argc, VALUE* argv, VALUE self) {
/* Only allow 1 or 2 arguments */
Expand All @@ -193,25 +197,33 @@ VALUE rb232_port_initialize(int argc, VALUE* argv, VALUE self) {
return rb232_port_initialize_with_options(self, port, options);
}

/* def port_name */
/*
* Get the port name (for instance, '/dev/ttyS0' or 'COM1'), as set in Port#new.
*/
VALUE rb232_port_get_port_name(VALUE self) {
/* Return baud rate */
return rb_str_new2(get_port_data(self)->port_name);
}

/* def baud_rate */
/*
* Get the baud rate, as set in the _options_ argument to Port#new.
*/
VALUE rb232_port_get_baud_rate(VALUE self) {
/* Return baud rate */
return rb_uint_new(get_port_data(self)->baud_rate);
}

/* def data_bits */
/*
* Get the number of data bits, as set in the _options_ argument to Port#new.
*/
VALUE rb232_port_get_data_bits(VALUE self) {
/* Return baud rate */
return rb_uint_new(get_port_data(self)->data_bits);
}

/* def parity */
/*
* Get the parity setting, as set in the _options_ argument to Port#new.
*/
VALUE rb232_port_get_parity(VALUE self) {
/* Return baud rate */
if (get_port_data(self)->parity == TRUE)
Expand All @@ -220,21 +232,31 @@ VALUE rb232_port_get_parity(VALUE self) {
return Qfalse;
}

/* def stop_bits */
/*
* Get the number of stop bits, as set in the _options_ argument to Port#new.
*/
VALUE rb232_port_get_stop_bits(VALUE self) {
/* Return baud rate */
return rb_uint_new(get_port_data(self)->stop_bits);
}

/* Read raw data from port */
/*
* Read raw data from port
*/
int rb232_port_read(VALUE self, char* buffer, VALUE count) {
int bytes_to_read = NUM2INT(count);
if (bytes_to_read > 255)
rb_raise(rb_eArgError, "can't read more than 255 bytes at once");
return read(get_port_data(self)->port_handle, buffer, bytes_to_read);
}

/* def read_bytes(count) */
/*
* Read _count_ raw byte values from the port.
* Returns an array of values. Useful for binary protocols.
* call-seq:
* read_bytes(count)
*
*/
VALUE rb232_port_read_bytes(VALUE self, VALUE count) {
char buffer[256];
int bytes_read = rb232_port_read(self, buffer, count);
Expand All @@ -245,7 +267,13 @@ VALUE rb232_port_read_bytes(VALUE self, VALUE count) {
}
}

/* def read_string(count) */
/*
* Read _count_ characters from the port.
* Returns a string. Useful for text-based protocols.
* call-seq:
* read_string(count)
*
*/
VALUE rb232_port_read_string(VALUE self, VALUE count) {
char buffer[256];
int bytes_read = rb232_port_read(self, buffer, count);
Expand Down
47 changes: 39 additions & 8 deletions src/port.h
Expand Up @@ -9,26 +9,57 @@ extern VALUE RB232_Port;
/* Allocator for Port class */
VALUE rb232_port_alloc(VALUE klass);

/* def initialize(options = {}) */
/*
* Create a Port object, using the port filename specified in _port_ (e.g. '/dev/ttyS0' or 'COM1').
*
* Valid options are :baud_rate (integer), :data_bits (integer), :parity
* (boolean), and :stop_bits (integer). Default values are 9600, 8, false, and 1 respectively.
*
* call-seq:
* new(port, options = {})
*
*/
VALUE rb232_port_initialize(int argc, VALUE* argv, VALUE self);

/* def port_name */
/*
* Get the port name (for instance, '/dev/ttyS0' or 'COM1'), as set in Port#new.
*/
VALUE rb232_port_get_port_name(VALUE self);

/* def baud_rate */
/*
* Get the baud rate, as set in the _options_ argument to Port#new.
*/
VALUE rb232_port_get_baud_rate(VALUE self);

/* def data_bits */
/*
* Get the number of data bits, as set in the _options_ argument to Port#new.
*/
VALUE rb232_port_get_data_bits(VALUE self);

/* def parity */
/*
* Get the parity setting, as set in the _options_ argument to Port#new.
*/
VALUE rb232_port_get_parity(VALUE self);

/* def stop_bits */
/*
* Get the number of stop bits, as set in the _options_ argument to Port#new.
*/
VALUE rb232_port_get_stop_bits(VALUE self);

/* def read_bytes(count) */
/*
* Read _count_ raw byte values from the port.
* Returns an array of values. Useful for binary protocols.
* call-seq:
* read_bytes(count)
*
*/
VALUE rb232_port_read_bytes(VALUE self, VALUE count);

/* def read_string(count) */
/*
* Read _count_ characters from the port.
* Returns a string. Useful for text-based protocols.
* call-seq:
* read_string(count)
*
*/
VALUE rb232_port_read_string(VALUE self, VALUE count);
21 changes: 10 additions & 11 deletions src/rb232.c
Expand Up @@ -2,20 +2,19 @@
#include "port.h"

/*
* Library initialization.
* Registers all classes and methods with the Ruby interpreter.
* Called automatically on require 'rb232'.
* Serial port communications. The class RB232::Port provides access to a hardware
* port on the local machine. Currently only Linux systems are supported.
*/
void Init_rb232() {
RB232 = rb_define_module("RB232");
RB232_Port = rb_define_class_under(RB232, "Port", rb_cObject);
rb_define_alloc_func(RB232_Port, rb232_port_alloc);
rb_define_method(RB232_Port, "initialize", rb232_port_initialize, -1);
rb_define_method(RB232_Port, "port_name", rb232_port_get_port_name, 0);
rb_define_method(RB232_Port, "baud_rate", rb232_port_get_baud_rate, 0);
rb_define_method(RB232_Port, "data_bits", rb232_port_get_data_bits, 0);
rb_define_method(RB232_Port, "parity", rb232_port_get_parity, 0);
rb_define_method(RB232_Port, "stop_bits", rb232_port_get_stop_bits, 0);
rb_define_method(RB232_Port, "read_bytes", rb232_port_read_bytes, 1);
rb_define_method(RB232_Port, "read_string", rb232_port_read_string, 1);
rb_define_method(RB232_Port, "initialize", rb232_port_initialize, -1); /* in port.c */
rb_define_method(RB232_Port, "port_name", rb232_port_get_port_name, 0); /* in port.c */
rb_define_method(RB232_Port, "baud_rate", rb232_port_get_baud_rate, 0); /* in port.c */
rb_define_method(RB232_Port, "data_bits", rb232_port_get_data_bits, 0); /* in port.c */
rb_define_method(RB232_Port, "parity", rb232_port_get_parity, 0); /* in port.c */
rb_define_method(RB232_Port, "stop_bits", rb232_port_get_stop_bits, 0); /* in port.c */
rb_define_method(RB232_Port, "read_bytes", rb232_port_read_bytes, 1); /* in port.c */
rb_define_method(RB232_Port, "read_string", rb232_port_read_string, 1); /* in port.c */
}
10 changes: 10 additions & 0 deletions src/utility.c
@@ -1,5 +1,10 @@
#include "utility.h"

/*
* Get a key from a hash, or if it's not there, use the default.
* A bit like doing hash[key] || default_val in Ruby.
* Integer version.
*/
int rbx_int_from_hash_or_default(VALUE hash, VALUE key, int default_val) {
VALUE data = (rb_hash_aref(hash, key));
if (data == Qnil)
Expand All @@ -8,6 +13,11 @@ int rbx_int_from_hash_or_default(VALUE hash, VALUE key, int default_val) {
return NUM2INT(data);
}

/*
* Get a key from a hash, or if it's not there, use the default.
* A bit like doing hash[key] || default_val in Ruby.
* Boolean version.
*/
BOOL rbx_bool_from_hash_or_default(VALUE hash, VALUE key, BOOL default_val) {
VALUE data = (rb_hash_aref(hash, key));
if (data == Qnil)
Expand Down

0 comments on commit efb83dc

Please sign in to comment.