ruby/trema/error.c in trema-0.2.2.1 vs ruby/trema/error.c in trema-0.2.3
- old
+ new
@@ -1,8 +1,6 @@
/*
- * Author: Nick Karanatsios <nickkaranatsios@gmail.com>
- *
* Copyright (C) 2008-2012 NEC Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
* published by the Free Software Foundation.
@@ -16,115 +14,120 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "trema.h"
#include "ruby.h"
+#include "trema-ruby-utils.h"
+#include "trema.h"
extern VALUE mTrema;
VALUE cError;
+static VALUE
+error_alloc( VALUE klass ) {
+ buffer *error = create_error( 0, 0, 0, NULL );
+ return Data_Wrap_Struct( klass, NULL, free_buffer, error );
+}
+
+
/*
- * @overload initialize(options={})
+ * @overload initialize(options)
* @example
* Error.new(
- * :type => Error::OFPET_BAD_REQUEST,
- * :code => Error::OFPBRC_BAD_TYPE,
+ * :type => OFPET_BAD_REQUEST,
+ * :code => OFPBRC_BAD_TYPE,
* )
* Error.new(
- * :type => Errr::OFPET_BAD_REQUEST,
- * :code => Error::OFPBRC_BAD_TYPE,
+ * :type => OFPET_BAD_REQUEST,
+ * :code => OFPBRC_BAD_TYPE,
* :transcation_id => 123
* )
* Error.new(
- * :type => Errr::OFPET_BAD_REQUEST,
- * :code => Error::OFPBRC_BAD_TYPE,
+ * :type => OFPET_BAD_REQUEST,
+ * :code => OFPBRC_BAD_TYPE,
* :transcation_id => 123
- * :user_data => "Error!!"
+ * :data => "Error!!"
* )
- *
- * @param [Hash] options
+ * @param [Hash] options
* the options to create a message with.
- *
* @option options [Number] :type
* a command or action that failed.
- *
* @option options [Number] :code
* the reason of the failed type error.
- *
+ * @option options [String] :data
+ * a more user friendly explanation of the error. Defaults to nil
+ * if not specified.
+ * @option options [Number] :xid
* @option options [Number] :transaction_id
- * a positive number, not recently attached to any previous pending commands to
- * guarantee message integrity auto-generated if not specified.
- *
- * @option options [String] :user_data
- * a more user friendly explanation of the error. Defaults to nil if not
- * specified.
- *
- * @raise [ArgumentError] if transaction_id is not an unsigned 32bit integer.
+ * An unsigned 32bit integer number associated with this message.
+ * If not specified, an auto-generated value is set.
+ * @raise [ArgumentError] if transaction ID is not an unsigned 32bit integer.
* @raise [ArgumentError] if type and code are not supplied.
* @raise [ArgumentError] if user data is not a string.
* @raise [TypeError] if options is not a hash.
- *
* @return [Error]
- * an object that encapsulates the +OFPT_ERROR+ OpenFlow message.
*/
static VALUE
-error_new( int argc, VALUE *argv, VALUE klass ) {
- buffer *data = NULL;
- uint32_t xid;
- uint16_t type;
- uint16_t code;
+error_init( int argc, VALUE *argv, VALUE self ) {
+ buffer *error = NULL;
+ Data_Get_Struct( self, buffer, error );
VALUE options;
if ( rb_scan_args( argc, argv, "01", &options ) == 1 ) {
Check_Type( options, T_HASH );
- VALUE type_r;
- if ( ( type_r = rb_hash_aref( options, ID2SYM( rb_intern( "type" ) ) ) ) != Qnil ) {
- type = ( uint16_t ) NUM2UINT( type_r );
+ VALUE tmp = Qnil;
+
+ tmp = rb_hash_aref( options, ID2SYM( rb_intern( "type" ) ) );
+ if ( tmp != Qnil ) {
+ ( ( struct ofp_error_msg * ) error->data )->type = htons( ( uint16_t ) NUM2UINT( tmp ) );
}
else {
rb_raise( rb_eArgError, "Type is a mandatory option" );
}
- VALUE code_r;
- if ( ( code_r = rb_hash_aref( options, ID2SYM( rb_intern( "code" ) ) ) ) != Qnil ) {
- code = ( uint16_t ) NUM2UINT( code_r );
+
+ tmp = rb_hash_aref( options, ID2SYM( rb_intern( "code" ) ) );
+ if ( tmp != Qnil ) {
+ ( ( struct ofp_error_msg * ) error->data )->code = htons( ( uint16_t ) NUM2UINT( tmp ) );
}
else {
rb_raise( rb_eArgError, "Code is a mandatory option" );
}
- VALUE xid_r;
- if ( ( xid_r = rb_hash_aref( options, ID2SYM( rb_intern( "transaction_id" ) ) ) ) != Qnil ) {
- if ( rb_funcall( xid_r, rb_intern( "unsigned_32bit?" ), 0 ) == Qfalse ) {
- rb_raise( rb_eArgError, "Transaction ID must be an unsigned 32-bit integer" );
- }
- xid = ( uint32_t ) NUM2UINT( xid_r );
+
+ VALUE xid = Qnil;
+ tmp = rb_hash_aref( options, ID2SYM( rb_intern( "transaction_id" ) ) );
+ if ( tmp != Qnil ) {
+ xid = tmp;
}
+ tmp = rb_hash_aref( options, ID2SYM( rb_intern( "xid" ) ) );
+ if ( tmp != Qnil ) {
+ xid = tmp;
+ }
+ if ( xid != Qnil ) {
+ validate_xid( xid );
+ set_xid( error, ( uint32_t ) NUM2UINT( xid ) );
+ }
else {
- xid = get_transaction_id();
+ set_xid( error, get_transaction_id() );
}
- VALUE user_data;
- if ( ( user_data = rb_hash_aref( options, ID2SYM( rb_intern( "user_data" ) ) ) ) != Qnil ) {
- if ( rb_obj_is_kind_of( user_data, rb_cString ) == Qfalse ) {
- rb_raise( rb_eArgError, "User data must be a string" );
- }
- uint16_t length = ( u_int16_t ) RSTRING_LEN( user_data );
- data = alloc_buffer_with_length( length );
- void *p = append_back_buffer( data, length );
- memcpy( p, RSTRING_PTR( user_data ), length );
+
+ VALUE data = rb_hash_aref( options, ID2SYM( rb_intern( "data" ) ) );
+ if ( data != Qnil ) {
+ Check_Type( data, T_STRING );
+ uint16_t length = ( u_int16_t ) RSTRING_LEN( data );
+ append_back_buffer( error, length );
+ ( ( struct ofp_header * ) ( error->data ) )->length = htons( ( uint16_t ) ( offsetof( struct ofp_error_msg, data ) + length ) );
+ memcpy( ( char * ) error->data + offsetof( struct ofp_error_msg, data ), RSTRING_PTR( data ), length );
}
}
else {
rb_raise( rb_eArgError, "Type and code are mandatory options" );
}
- buffer *error = create_error( xid, type, code, data );
- if ( data != NULL ) {
- free_buffer( data );
- }
- return Data_Wrap_Struct( klass, NULL, free_buffer, error );
+
+ return self;
}
static struct ofp_error_msg *
get_error( VALUE self ) {
@@ -152,11 +155,11 @@
*
* @return [String] user data payload is set.
* @return [nil] user data payload is not set.
*/
static VALUE
-error_user_data( VALUE self ) {
+error_data( VALUE self ) {
struct ofp_error_msg *error = get_error( self );
long length = ( long ) ( ntohs( error->header.length ) - sizeof( struct ofp_error_msg ) );
if ( length > 0 ) {
return rb_str_new( ( char * ) error->data, length );
}
@@ -190,57 +193,59 @@
}
void
Init_error() {
- cError = rb_define_class_under( mTrema, "Error", rb_cObject );
- rb_define_singleton_method( cError, "new", error_new, -1 );
- rb_define_const( cError, "OFPET_HELLO_FAILED", INT2NUM( OFPET_HELLO_FAILED ) );
- rb_define_const( cError, "OFPET_BAD_REQUEST", INT2NUM( OFPET_BAD_REQUEST ) );
- rb_define_const( cError, "OFPET_BAD_ACTION", INT2NUM( OFPET_BAD_ACTION ) );
- rb_define_const( cError, "OFPET_FLOW_MOD_FAILED", INT2NUM( OFPET_FLOW_MOD_FAILED ) );
- rb_define_const( cError, "OFPET_PORT_MOD_FAILED", INT2NUM( OFPET_PORT_MOD_FAILED ) );
- rb_define_const( cError, "OFPET_QUEUE_OP_FAILED", INT2NUM( OFPET_QUEUE_OP_FAILED ) );
+ rb_define_const( mTrema, "OFPET_HELLO_FAILED", INT2NUM( OFPET_HELLO_FAILED ) );
+ rb_define_const( mTrema, "OFPHFC_INCOMPATIBLE", INT2NUM( OFPHFC_INCOMPATIBLE ) );
+ rb_define_const( mTrema, "OFPHFC_EPERM", INT2NUM( OFPHFC_EPERM ) );
- rb_define_const( cError, "OFPHFC_INCOMPATIBLE", INT2NUM( OFPHFC_INCOMPATIBLE ) );
- rb_define_const( cError, "OFPHFC_EPERM", INT2NUM( OFPHFC_EPERM ) );
+ rb_define_const( mTrema, "OFPET_BAD_REQUEST", INT2NUM( OFPET_BAD_REQUEST ) );
+ rb_define_const( mTrema, "OFPBRC_BAD_VERSION", INT2NUM( OFPBRC_BAD_VERSION ) );
+ rb_define_const( mTrema, "OFPBRC_BAD_TYPE", INT2NUM( OFPBRC_BAD_TYPE ) );
+ rb_define_const( mTrema, "OFPBRC_BAD_STAT", INT2NUM( OFPBRC_BAD_STAT ) );
+ rb_define_const( mTrema, "OFPBRC_BAD_VENDOR", INT2NUM( OFPBRC_BAD_VENDOR ) );
+ rb_define_const( mTrema, "OFPBRC_BAD_SUBTYPE", INT2NUM( OFPBRC_BAD_SUBTYPE ) );
+ rb_define_const( mTrema, "OFPBRC_EPERM", INT2NUM( OFPBRC_EPERM ) );
+ rb_define_const( mTrema, "OFPBRC_BAD_LEN", INT2NUM( OFPBRC_BAD_LEN ) );
+ rb_define_const( mTrema, "OFPBRC_BUFFER_EMPTY", INT2NUM( OFPBRC_BUFFER_EMPTY ) );
+ rb_define_const( mTrema, "OFPBRC_BUFFER_UNKNOWN", INT2NUM( OFPBRC_BUFFER_UNKNOWN ) );
- rb_define_const( cError, "OFPBRC_BAD_VERSION", INT2NUM( OFPBRC_BAD_VERSION ) );
- rb_define_const( cError, "OFPBRC_BAD_TYPE", INT2NUM( OFPBRC_BAD_TYPE ) );
- rb_define_const( cError, "OFPBRC_BAD_STAT", INT2NUM( OFPBRC_BAD_STAT ) );
- rb_define_const( cError, "OFPBRC_BAD_VENDOR", INT2NUM( OFPBRC_BAD_VENDOR ) );
- rb_define_const( cError, "OFPBRC_BAD_SUBTYPE", INT2NUM( OFPBRC_BAD_SUBTYPE ) );
- rb_define_const( cError, "OFPBRC_EPERM", INT2NUM( OFPBRC_EPERM ) );
- rb_define_const( cError, "OFPBRC_BAD_LEN", INT2NUM( OFPBRC_BAD_LEN ) );
- rb_define_const( cError, "OFPBRC_BUFFER_EMPTY", INT2NUM( OFPBRC_BUFFER_EMPTY ) );
- rb_define_const( cError, "OFPBRC_BUFFER_UNKNOWN", INT2NUM( OFPBRC_BUFFER_UNKNOWN ) );
+ rb_define_const( mTrema, "OFPET_BAD_ACTION", INT2NUM( OFPET_BAD_ACTION ) );
+ rb_define_const( mTrema, "OFPBAC_BAD_TYPE", INT2NUM( OFPBAC_BAD_TYPE ) );
+ rb_define_const( mTrema, "OFPBAC_BAD_LEN", INT2NUM( OFPBAC_BAD_LEN ) );
+ rb_define_const( mTrema, "OFPBAC_BAD_VENDOR", INT2NUM( OFPBAC_BAD_VENDOR ) );
+ rb_define_const( mTrema, "OFPBAC_BAD_VENDOR_TYPE", INT2NUM( OFPBAC_BAD_VENDOR_TYPE ) );
+ rb_define_const( mTrema, "OFPBAC_BAD_OUT_PORT", INT2NUM( OFPBAC_BAD_OUT_PORT ) );
+ rb_define_const( mTrema, "OFPBAC_BAD_ARGUMENT", INT2NUM( OFPBAC_BAD_ARGUMENT ) );
+ rb_define_const( mTrema, "OFPBAC_EPERM", INT2NUM( OFPBAC_EPERM ) );
+ rb_define_const( mTrema, "OFPBAC_TOO_MANY", INT2NUM( OFPBAC_TOO_MANY ) );
+ rb_define_const( mTrema, "OFPBAC_BAD_QUEUE", INT2NUM( OFPBAC_BAD_QUEUE ) );
- rb_define_const( cError, "OFPBAC_BAD_TYPE", INT2NUM( OFPBAC_BAD_TYPE ) );
- rb_define_const( cError, "OFPBAC_BAD_LEN", INT2NUM( OFPBAC_BAD_LEN ) );
- rb_define_const( cError, "OFPBAC_BAD_VENDOR", INT2NUM( OFPBAC_BAD_VENDOR ) );
- rb_define_const( cError, "OFPBAC_BAD_VENDOR_TYPE", INT2NUM( OFPBAC_BAD_VENDOR_TYPE ) );
- rb_define_const( cError, "OFPBAC_BAD_OUT_PORT", INT2NUM( OFPBAC_BAD_OUT_PORT ) );
- rb_define_const( cError, "OFPBAC_BAD_ARGUMENT", INT2NUM( OFPBAC_BAD_ARGUMENT ) );
- rb_define_const( cError, "OFPBAC_EPERM", INT2NUM( OFPBAC_EPERM ) );
- rb_define_const( cError, "OFPBAC_TOO_MANY", INT2NUM( OFPBAC_TOO_MANY ) );
- rb_define_const( cError, "OFPBAC_BAD_QUEUE", INT2NUM( OFPBAC_BAD_QUEUE ) );
+ rb_define_const( mTrema, "OFPET_FLOW_MOD_FAILED", INT2NUM( OFPET_FLOW_MOD_FAILED ) );
+ rb_define_const( mTrema, "OFPFMFC_ALL_TABLES_FULL", INT2NUM( OFPFMFC_ALL_TABLES_FULL ) );
+ rb_define_const( mTrema, "OFPFMFC_OVERLAP", INT2NUM( OFPFMFC_OVERLAP ) );
+ rb_define_const( mTrema, "OFPFMFC_EPERM", INT2NUM( OFPFMFC_EPERM ) );
+ rb_define_const( mTrema, "OFPFMFC_BAD_EMERG_TIMEOUT", INT2NUM( OFPFMFC_BAD_EMERG_TIMEOUT ) );
+ rb_define_const( mTrema, "OFPFMFC_BAD_COMMAND", INT2NUM( OFPFMFC_BAD_COMMAND ) );
+ rb_define_const( mTrema, "OFPFMFC_UNSUPPORTED", INT2NUM( OFPFMFC_UNSUPPORTED ) );
- rb_define_const( cError, "OFPFMFC_ALL_TABLES_FULL", INT2NUM( OFPFMFC_ALL_TABLES_FULL ) );
- rb_define_const( cError, "OFPFMFC_OVERLAP", INT2NUM( OFPFMFC_OVERLAP ) );
- rb_define_const( cError, "OFPFMFC_EPERM", INT2NUM( OFPFMFC_EPERM ) );
- rb_define_const( cError, "OFPFMFC_BAD_EMERG_TIMEOUT", INT2NUM( OFPFMFC_BAD_EMERG_TIMEOUT ) );
- rb_define_const( cError, "OFPFMFC_BAD_COMMAND", INT2NUM( OFPFMFC_BAD_COMMAND ) );
- rb_define_const( cError, "OFPFMFC_UNSUPPORTED", INT2NUM( OFPFMFC_UNSUPPORTED ) );
+ rb_define_const( mTrema, "OFPET_PORT_MOD_FAILED", INT2NUM( OFPET_PORT_MOD_FAILED ) );
+ rb_define_const( mTrema, "OFPPMFC_BAD_PORT", INT2NUM( OFPPMFC_BAD_PORT ) );
+ rb_define_const( mTrema, "OFPPMFC_BAD_HW_ADDR", INT2NUM( OFPPMFC_BAD_HW_ADDR ) );
- rb_define_const( cError, "OFPPMFC_BAD_PORT", INT2NUM( OFPPMFC_BAD_PORT ) );
- rb_define_const( cError, "OFPPMFC_BAD_HW_ADDR", INT2NUM( OFPPMFC_BAD_HW_ADDR ) );
+ rb_define_const( mTrema, "OFPET_QUEUE_OP_FAILED", INT2NUM( OFPET_QUEUE_OP_FAILED ) );
+ rb_define_const( mTrema, "OFPQOFC_BAD_PORT", INT2NUM(OFPQOFC_BAD_PORT));
+ rb_define_const( mTrema, "OFPQOFC_BAD_QUEUE", INT2NUM(OFPQOFC_BAD_QUEUE));
+ rb_define_const( mTrema, "OFPQOFC_EPERM", INT2NUM(OFPQOFC_EPERM));
- rb_define_const( cError, "OFPQOFC_BAD_PORT", INT2NUM(OFPQOFC_BAD_PORT));
- rb_define_const( cError, "OFPQOFC_BAD_QUEUE", INT2NUM(OFPQOFC_BAD_QUEUE));
- rb_define_const( cError, "OFPQOFC_EPERM", INT2NUM(OFPQOFC_EPERM));
+ cError = rb_define_class_under( mTrema, "Error", rb_cObject );
+ rb_define_alloc_func( cError, error_alloc );
+ rb_define_method( cError, "initialize", error_init, -1 );
rb_define_method( cError, "transaction_id", error_transaction_id, 0 );
- rb_define_method( cError, "user_data", error_user_data, 0 );
+ rb_alias( cError, rb_intern( "xid" ), rb_intern( "transaction_id" ) );
+ rb_define_method( cError, "data", error_data, 0 );
rb_define_method( cError, "error_type", error_type, 0 );
rb_define_method( cError, "code", error_code, 0 );
}