[896] | 1 | /* |
---|
| 2 | * ---------------------------------------------------------------------- |
---|
| 3 | * Ruby Rappture Extension Source |
---|
| 4 | * |
---|
| 5 | * ====================================================================== |
---|
| 6 | * AUTHOR: Benjamin Haley, Purdue University |
---|
[3177] | 7 | * Copyright (c) 2004-2012 HUBzero Foundation, LLC |
---|
[896] | 8 | * |
---|
| 9 | * See the file "license.terms" for information on usage and |
---|
| 10 | * redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
---|
| 11 | * ====================================================================== |
---|
| 12 | */ |
---|
| 13 | |
---|
| 14 | /* This file uses Ruby's C API to create a new Ruby class named Rappture |
---|
| 15 | * as a wrapper around the Rappture library C++ API. |
---|
| 16 | * |
---|
| 17 | * Define RAISE_EXCEPTIONS (see Makefile) to raise Ruby Exceptions on errors. |
---|
| 18 | * Without this, those methods which return a Ruby object on success return |
---|
| 19 | * Qnil on errors. For those methods which return Qnil on either success or |
---|
| 20 | * failure, there is no way to check for errors without an Exception. |
---|
| 21 | */ |
---|
| 22 | |
---|
| 23 | #include <string> /* std::string */ |
---|
| 24 | #include <stdlib.h> /* atof() */ |
---|
| 25 | #include "RpLibrary.h" /* RpLibrary, Rappture::Buffer */ |
---|
| 26 | #include "RpUtils.h" /* Rappture::Utils::progress() */ |
---|
| 27 | #include "RpUnits.h" /* RpUnits::convert() */ |
---|
| 28 | #include "ruby.h" /* VALUE, rb_*(), Data_*_Struct(), NUM2INT(), |
---|
| 29 | INT2NUM(), NUM2DBL(), STR2CSTR(), ANYARGS */ |
---|
| 30 | |
---|
| 31 | /****************************************************************************** |
---|
| 32 | * File scope variables |
---|
| 33 | ******************************************************************************/ |
---|
| 34 | |
---|
[1081] | 35 | |
---|
[896] | 36 | /* The new Rappture class */ |
---|
| 37 | VALUE classRappture; |
---|
| 38 | |
---|
| 39 | |
---|
[1081] | 40 | extern "C" void Init_Rappture(void); |
---|
| 41 | |
---|
[896] | 42 | /****************************************************************************** |
---|
| 43 | * RbRp_GetString() |
---|
| 44 | * |
---|
| 45 | * Implement the get() public method of the Rappture class. |
---|
| 46 | * Return a Ruby String from the location path in the Rappture object self. |
---|
| 47 | * |
---|
| 48 | * The original plan was to convert the returned std::string to a Ruby String, |
---|
| 49 | * then try calling the to_f and to_i methods on the Ruby String, to see if |
---|
| 50 | * we should return a Float (double) or a Fixnum (integer). The problem with |
---|
| 51 | * this approach is that these methods (to_f and to_i) return 0.0 and 0, |
---|
| 52 | * respectively, on error, **without raising an Exception**, so there is no |
---|
| 53 | * way to distinguish between an error and legitimate zero values. The user |
---|
| 54 | * will have to call the appropriate Ruby conversion functions on the returned |
---|
| 55 | * String, for now. |
---|
| 56 | ******************************************************************************/ |
---|
| 57 | |
---|
| 58 | static VALUE |
---|
| 59 | RbRp_GetString(VALUE self, VALUE path) |
---|
| 60 | { |
---|
| 61 | RpLibrary *lib; |
---|
| 62 | std::string str; |
---|
| 63 | |
---|
| 64 | /* Extract the pointer to the Rappture object, lib, from the Ruby object, |
---|
| 65 | self */ |
---|
| 66 | Data_Get_Struct(self, RpLibrary, lib); |
---|
| 67 | |
---|
| 68 | /* Read the data from path in lib as a C++ std::string. */ |
---|
| 69 | str = lib->getString(STR2CSTR(path)); |
---|
| 70 | |
---|
| 71 | /* Return a Ruby VALUE */ |
---|
| 72 | return rb_str_new2(str.c_str()); |
---|
| 73 | |
---|
| 74 | } /* end RbRp_GetString */ |
---|
| 75 | |
---|
| 76 | |
---|
| 77 | /****************************************************************************** |
---|
| 78 | * RbRp_GetData() |
---|
| 79 | * |
---|
| 80 | * Implement the getdata() public method of the Rappture class. |
---|
| 81 | * Return a Ruby String from the location path in the Rappture object self. |
---|
| 82 | ******************************************************************************/ |
---|
| 83 | |
---|
| 84 | static VALUE |
---|
| 85 | RbRp_GetData(VALUE self, VALUE path) |
---|
| 86 | { |
---|
| 87 | RpLibrary *lib; |
---|
| 88 | Rappture::Buffer buf; |
---|
| 89 | |
---|
| 90 | /* Extract the pointer to the Rappture object, lib, from the Ruby object, |
---|
| 91 | self */ |
---|
| 92 | Data_Get_Struct(self, RpLibrary, lib); |
---|
| 93 | |
---|
| 94 | /* Read the data from path in lib as a C++ std::string. */ |
---|
| 95 | buf = lib->getData(STR2CSTR(path)); |
---|
| 96 | |
---|
| 97 | /* Return a Ruby VALUE */ |
---|
| 98 | return rb_str_new2(buf.bytes()); |
---|
| 99 | |
---|
| 100 | } /* end RbRp_GetData */ |
---|
| 101 | |
---|
| 102 | |
---|
| 103 | /****************************************************************************** |
---|
| 104 | * RbRp_PutObject() |
---|
| 105 | * |
---|
| 106 | * Implement the put() public method of the Rappture class. |
---|
| 107 | * Put a Ruby String, Float (double), or Fixnum (integer) object into the |
---|
| 108 | * location path in the Rappture object self. |
---|
| 109 | * Return Qnil. |
---|
| 110 | * On error, if RAISE_EXCEPTIONS is defined, raise a Ruby RuntimeError |
---|
| 111 | * Exception. |
---|
| 112 | ******************************************************************************/ |
---|
| 113 | |
---|
| 114 | static VALUE |
---|
| 115 | RbRp_PutObject(VALUE self, VALUE path, VALUE value, VALUE append) |
---|
| 116 | { |
---|
| 117 | #ifdef RAISE_EXCEPTIONS |
---|
| 118 | /* Get the Ruby ID of the "to_s" method. */ |
---|
| 119 | ID id_to_s = rb_intern("to_s"); |
---|
| 120 | |
---|
| 121 | /* Call the "to_s" method on value to get a Ruby String representation of |
---|
| 122 | the value, in case we need to compose an error message below. The final |
---|
| 123 | argument 0 indicates no further arguments.*/ |
---|
| 124 | VALUE rbStrName = rb_funcall(value, id_to_s, 0); |
---|
| 125 | #endif |
---|
| 126 | |
---|
| 127 | RpLibrary *lib; |
---|
| 128 | int intVal; |
---|
| 129 | |
---|
| 130 | /* Extract the pointer to the Rappture object, lib, from the Ruby |
---|
| 131 | object, self */ |
---|
| 132 | Data_Get_Struct(self, RpLibrary, lib); |
---|
| 133 | |
---|
| 134 | /* Check the type of the Ruby object value. If the type if one we are |
---|
| 135 | prepared to handle, call the appropriate put() function. If the type |
---|
| 136 | is unexpected, raise a RuntimeError Exception, if RAISE_EXCEPTIONS is |
---|
| 137 | defined.*/ |
---|
| 138 | switch (TYPE(value)) |
---|
| 139 | { |
---|
| 140 | case T_STRING: |
---|
| 141 | lib->put(STR2CSTR(path), STR2CSTR(value), "", NUM2INT(append)); |
---|
| 142 | break; |
---|
| 143 | case T_FIXNUM: |
---|
| 144 | intVal = NUM2INT(value); |
---|
| 145 | lib->putData(STR2CSTR(path), (const char *)&intVal, sizeof(int), |
---|
| 146 | NUM2INT(append)); |
---|
| 147 | break; |
---|
| 148 | case T_FLOAT: |
---|
| 149 | lib->put(STR2CSTR(path), NUM2DBL(value), "", NUM2INT(append)); |
---|
| 150 | break; |
---|
| 151 | default: |
---|
| 152 | #ifdef RAISE_EXCEPTIONS |
---|
| 153 | rb_raise(rb_eRuntimeError, |
---|
| 154 | "Unable to put object %s to Rappture: unknown type", |
---|
| 155 | STR2CSTR(rbStrName)); |
---|
| 156 | #endif |
---|
| 157 | break; |
---|
| 158 | } /* end switch */ |
---|
| 159 | |
---|
| 160 | /* Return a Ruby VALUE */ |
---|
| 161 | return Qnil; |
---|
| 162 | |
---|
| 163 | } /* end RbRp_PutObject */ |
---|
| 164 | |
---|
| 165 | |
---|
| 166 | /****************************************************************************** |
---|
| 167 | * RbRp_PutData() |
---|
| 168 | * |
---|
| 169 | * Implement the putdata() public method of the Rappture class. |
---|
| 170 | * Put a Ruby String into the location path in the Rappture object self. |
---|
| 171 | * Return Qnil. |
---|
| 172 | * On error, if RAISE_EXCEPTIONS is defined, raise a Ruby RuntimeError |
---|
| 173 | * Exception. |
---|
| 174 | ******************************************************************************/ |
---|
| 175 | |
---|
| 176 | static VALUE |
---|
| 177 | RbRp_PutData(VALUE self, VALUE path, VALUE value, VALUE append) |
---|
| 178 | { |
---|
| 179 | #ifdef RAISE_EXCEPTIONS |
---|
| 180 | /* Get the Ruby ID of the "to_s" method. */ |
---|
| 181 | ID id_to_s = rb_intern("to_s"); |
---|
| 182 | |
---|
| 183 | /* Call the "to_s" method on value to get a Ruby String representation of |
---|
| 184 | the value, in case we need to compose an error message below. The final |
---|
| 185 | argument 0 indicates no further arguments.*/ |
---|
| 186 | VALUE rbStrName = rb_funcall(value, id_to_s, 0); |
---|
| 187 | #endif |
---|
| 188 | |
---|
| 189 | RpLibrary *lib; |
---|
| 190 | |
---|
| 191 | /* Extract the pointer to the Rappture object, lib, from the Ruby |
---|
| 192 | object, self */ |
---|
| 193 | Data_Get_Struct(self, RpLibrary, lib); |
---|
| 194 | |
---|
| 195 | if (T_STRING == TYPE(value)) |
---|
| 196 | { |
---|
| 197 | long int nbytes; |
---|
| 198 | char *bytes = rb_str2cstr(value, &nbytes); |
---|
| 199 | |
---|
| 200 | lib->putData(STR2CSTR(path), bytes, nbytes, NUM2INT(append)); |
---|
| 201 | } |
---|
| 202 | #ifdef RAISE_EXCEPTIONS |
---|
| 203 | else |
---|
| 204 | { |
---|
| 205 | rb_raise(rb_eRuntimeError, |
---|
| 206 | "Unable to put data \"%s\" to Rappture: unknown type", |
---|
| 207 | STR2CSTR(rbStrName)); |
---|
| 208 | } |
---|
| 209 | #endif |
---|
| 210 | |
---|
| 211 | /* Return a Ruby VALUE */ |
---|
| 212 | return Qnil; |
---|
| 213 | |
---|
| 214 | } /* end RbRp_PutData */ |
---|
| 215 | |
---|
| 216 | |
---|
| 217 | /****************************************************************************** |
---|
| 218 | * RbRp_PutFile() |
---|
| 219 | * |
---|
| 220 | * Implement the putfile() public method of the Rappture class. |
---|
| 221 | * Put a file into the location path in the Rappture object self. |
---|
| 222 | * Return Qnil. |
---|
| 223 | * On error, if RAISE_EXCEPTIONS is defined, raise a Ruby RuntimeError |
---|
| 224 | * Exception. |
---|
| 225 | ******************************************************************************/ |
---|
| 226 | |
---|
| 227 | static VALUE |
---|
| 228 | RbRp_PutFile(VALUE self, VALUE path, VALUE filename, VALUE append, |
---|
| 229 | VALUE compress) |
---|
| 230 | { |
---|
| 231 | #ifdef RAISE_EXCEPTIONS |
---|
| 232 | /* Get the Ruby ID of the "to_s" method. */ |
---|
| 233 | ID id_to_s = rb_intern("to_s"); |
---|
| 234 | |
---|
| 235 | /* Call the "to_s" method on value to get a Ruby String representation of |
---|
| 236 | the value, in case we need to compose an error message below. The final |
---|
| 237 | argument 0 indicates no further arguments.*/ |
---|
| 238 | VALUE rbStrName = rb_funcall(filename, id_to_s, 0); |
---|
| 239 | #endif |
---|
| 240 | |
---|
| 241 | RpLibrary *lib; |
---|
| 242 | |
---|
| 243 | /* Extract the pointer to the Rappture object, lib, from the Ruby |
---|
| 244 | object, self */ |
---|
| 245 | Data_Get_Struct(self, RpLibrary, lib); |
---|
| 246 | |
---|
| 247 | if (T_STRING == TYPE(filename)) |
---|
| 248 | { |
---|
[1043] | 249 | VALUE ft = rb_const_get(rb_cObject, rb_intern("FileTest")); |
---|
| 250 | ID id_filetest = rb_intern("file?"); |
---|
[896] | 251 | |
---|
[1043] | 252 | if (Qtrue == rb_funcall(ft, id_filetest, 1, filename)) /* valid filename */ |
---|
[896] | 253 | { |
---|
| 254 | lib->putFile(STR2CSTR(path), STR2CSTR(filename), NUM2INT(compress), |
---|
| 255 | NUM2INT(append)); |
---|
| 256 | } |
---|
| 257 | #ifdef RAISE_EXCEPTIONS |
---|
| 258 | else |
---|
| 259 | { |
---|
| 260 | rb_raise(rb_eRuntimeError, "%s is not a valid file", |
---|
| 261 | STR2CSTR(rbStrName)); |
---|
| 262 | } |
---|
| 263 | #endif |
---|
| 264 | } |
---|
| 265 | #ifdef RAISE_EXCEPTIONS |
---|
| 266 | else |
---|
| 267 | rb_raise(rb_eRuntimeError, "Bad file name: %s", STR2CSTR(rbStrName)); |
---|
| 268 | #endif |
---|
| 269 | |
---|
| 270 | /* Return a Ruby VALUE */ |
---|
| 271 | return Qnil; |
---|
| 272 | |
---|
| 273 | } /* end RbRp_PutFile */ |
---|
| 274 | |
---|
| 275 | |
---|
| 276 | /****************************************************************************** |
---|
| 277 | * RbRp_Result() |
---|
| 278 | * |
---|
| 279 | * Implement the result() public method of the Rappture class. |
---|
| 280 | * Write the XML of the Rappture object self to disk. |
---|
| 281 | * Return Qnil. |
---|
| 282 | ******************************************************************************/ |
---|
| 283 | |
---|
| 284 | static VALUE |
---|
| 285 | RbRp_Result(VALUE self, VALUE status) |
---|
| 286 | { |
---|
| 287 | RpLibrary *lib; |
---|
| 288 | |
---|
| 289 | /* Extract the pointer to the Rappture object, lib, from the Ruby |
---|
| 290 | object, self */ |
---|
| 291 | Data_Get_Struct(self, RpLibrary, lib); |
---|
| 292 | |
---|
| 293 | /* Write the Rappture XML to disk. */ |
---|
| 294 | lib->result(NUM2INT(status)); |
---|
| 295 | |
---|
| 296 | /* Return a Ruby VALUE */ |
---|
| 297 | return Qnil; |
---|
| 298 | |
---|
| 299 | } /* end RbRp_Result */ |
---|
| 300 | |
---|
| 301 | |
---|
| 302 | /****************************************************************************** |
---|
| 303 | * RbRp_Xml() |
---|
| 304 | * |
---|
| 305 | * Impelement the xml() public method of the Rappture class. |
---|
| 306 | * Return a Ruby String with the XML of the Rappture object self. |
---|
| 307 | * Return Qnil on error, or, if RAISE_EXCEPTIONS is defined, raise a |
---|
| 308 | * RuntimeError Exception. |
---|
| 309 | ******************************************************************************/ |
---|
| 310 | |
---|
| 311 | static VALUE |
---|
| 312 | RbRp_Xml(VALUE self) |
---|
| 313 | { |
---|
| 314 | RpLibrary *lib; |
---|
| 315 | std::string str; |
---|
| 316 | |
---|
| 317 | /* Extract the pointer to the Rappture object, lib, from the Ruby |
---|
| 318 | object, self */ |
---|
| 319 | Data_Get_Struct(self, RpLibrary, lib); |
---|
| 320 | |
---|
| 321 | /* Get the Rappture object's XML */ |
---|
| 322 | str = lib->xml(); |
---|
| 323 | |
---|
| 324 | /* Return a Ruby VALUE */ |
---|
| 325 | if (str.empty()) |
---|
| 326 | { |
---|
| 327 | #ifdef RAISE_EXCEPTIONS |
---|
| 328 | rb_raise(rb_eRuntimeError, "Unable to retrieve XML"); |
---|
| 329 | #else |
---|
| 330 | return Qnil; |
---|
| 331 | #endif |
---|
| 332 | } |
---|
| 333 | else |
---|
| 334 | return rb_str_new2(str.c_str()); |
---|
| 335 | |
---|
| 336 | } /* end RbRp_Xml */ |
---|
| 337 | |
---|
| 338 | |
---|
| 339 | /****************************************************************************** |
---|
| 340 | * RbRp_Progress() |
---|
| 341 | * |
---|
| 342 | * Implement the progress() public method for the Rappture class. |
---|
| 343 | * Write a progress message to stdout, using the Ruby Fixnum percent and the |
---|
| 344 | * Ruby String message. |
---|
| 345 | * Return Qnil. |
---|
| 346 | ******************************************************************************/ |
---|
| 347 | |
---|
| 348 | static VALUE |
---|
| 349 | RbRp_Progress(VALUE self, VALUE percent, VALUE message) |
---|
| 350 | { |
---|
| 351 | /* Note: self is a dummy here */ |
---|
| 352 | |
---|
| 353 | /* Write the message */ |
---|
| 354 | (void)Rappture::Utils::progress(NUM2INT(percent), STR2CSTR(message)); |
---|
| 355 | |
---|
| 356 | /* Return a Ruby VALUE */ |
---|
| 357 | return Qnil; |
---|
| 358 | |
---|
| 359 | } /* end RbRp_Progress */ |
---|
| 360 | |
---|
| 361 | |
---|
| 362 | /****************************************************************************** |
---|
| 363 | * RbRp_Convert() |
---|
| 364 | * |
---|
| 365 | * Implement the convert() public method for the Rappture class. |
---|
| 366 | * Convert the Ruby String fromVal, containing a numeric value and optional |
---|
| 367 | * units, to the units specified by the Ruby String toUnitsName. |
---|
| 368 | * If the Ruby Fixnum showUnits is 1, return a Ruby String with units appended, |
---|
| 369 | * else return a Ruby Float (double). |
---|
| 370 | * On error, return Qnil, or, if RAISE_EXCEPTIONS is defined, raise a |
---|
| 371 | * RuntimeError Exception. |
---|
| 372 | ******************************************************************************/ |
---|
| 373 | |
---|
| 374 | static VALUE |
---|
| 375 | RbRp_Convert(VALUE self, VALUE fromVal, VALUE toUnitsName, VALUE showUnits) |
---|
| 376 | { |
---|
| 377 | VALUE retVal = Qnil; |
---|
| 378 | RpLibrary *lib; |
---|
| 379 | std::string strRetVal; |
---|
| 380 | int result; |
---|
| 381 | |
---|
| 382 | /* Extract the pointer to the Rappture object, lib, from the Ruby |
---|
| 383 | object, self */ |
---|
| 384 | Data_Get_Struct(self, RpLibrary, lib); |
---|
| 385 | |
---|
| 386 | /* Convert */ |
---|
| 387 | strRetVal = RpUnits::convert(STR2CSTR(fromVal), STR2CSTR(toUnitsName), |
---|
| 388 | NUM2INT(showUnits), &result); |
---|
| 389 | /* Return value */ |
---|
| 390 | if (0 == result) |
---|
| 391 | { |
---|
| 392 | const char *retCStr = strRetVal.c_str(); |
---|
| 393 | |
---|
| 394 | if (NUM2INT(showUnits)) /* Ruby String */ |
---|
| 395 | retVal = rb_str_new2(retCStr); |
---|
| 396 | else /* Ruby Float */ |
---|
| 397 | retVal = rb_float_new(atof(retCStr)); |
---|
| 398 | } |
---|
| 399 | #ifdef RAISE_EXCEPTIONS |
---|
| 400 | else |
---|
[1100] | 401 | rb_raise(rb_eRuntimeError, "Unable to convert \"%s\" to \"%s\"", |
---|
[896] | 402 | STR2CSTR(fromVal), STR2CSTR(toUnitsName)); |
---|
| 403 | #endif |
---|
| 404 | return retVal; |
---|
| 405 | |
---|
| 406 | } /* end RbRp_Convert */ |
---|
| 407 | |
---|
| 408 | |
---|
| 409 | /****************************************************************************** |
---|
| 410 | * RbRp_Delete() |
---|
| 411 | * |
---|
| 412 | * Implement the destructor for the Rappture class. |
---|
| 413 | * This function is registered with Ruby's garbage collector, which requires |
---|
| 414 | * the void * argument. |
---|
| 415 | ******************************************************************************/ |
---|
| 416 | |
---|
| 417 | static void |
---|
| 418 | RbRp_Delete(void *ptr) |
---|
| 419 | { |
---|
| 420 | delete ((RpLibrary *)ptr); |
---|
| 421 | |
---|
| 422 | } /* end RbRp_Delete */ |
---|
| 423 | |
---|
| 424 | |
---|
| 425 | /****************************************************************************** |
---|
| 426 | * RbRp_Init() |
---|
| 427 | * |
---|
| 428 | * Implement the initialize method, called from the new() method, for the |
---|
| 429 | * Rappture class. |
---|
| 430 | * Set the instance variable @driver (the name of the driver XML file). |
---|
| 431 | * Return self. |
---|
| 432 | ******************************************************************************/ |
---|
| 433 | |
---|
| 434 | static VALUE |
---|
| 435 | RbRp_Init(VALUE self, VALUE driver) |
---|
| 436 | { |
---|
| 437 | /* Set instance variable */ |
---|
| 438 | rb_iv_set(self, "@driver", driver); |
---|
| 439 | |
---|
| 440 | /* Return a Ruby VALUE */ |
---|
| 441 | return self; |
---|
| 442 | |
---|
| 443 | } /* end RbRp_Init */ |
---|
| 444 | |
---|
| 445 | |
---|
| 446 | /****************************************************************************** |
---|
| 447 | * RbRp_New() |
---|
| 448 | * |
---|
| 449 | * Implement the new() method for the Rappture class. |
---|
| 450 | * Create a Rappture I/O object from the XML file driver. |
---|
| 451 | * Create a new Ruby object. |
---|
| 452 | * Associate the Rappture object and the Ruby object with the class value |
---|
| 453 | * classval, and garbage collection functions (mark and sweep). |
---|
| 454 | * Pass driver to the initialize method. |
---|
| 455 | * Return the new Ruby object. |
---|
| 456 | * Note this method is not static. |
---|
| 457 | ******************************************************************************/ |
---|
| 458 | |
---|
| 459 | VALUE |
---|
| 460 | RbRp_New(VALUE classval, VALUE driver) |
---|
| 461 | { |
---|
| 462 | /* Create the Rappture object from the XML driver file. */ |
---|
| 463 | RpLibrary *lib = new RpLibrary(STR2CSTR(driver)); |
---|
| 464 | |
---|
| 465 | /* Data_Wrap_Struct() creates a new Ruby object which associates the |
---|
| 466 | Rappture object, lib, with the class type classval, and registers 0 |
---|
| 467 | as the marking function and RbRp_Delete() as the freeing function for |
---|
| 468 | Ruby's mark and sweep garbage collector. */ |
---|
| 469 | VALUE rbLib = Data_Wrap_Struct(classval, 0, RbRp_Delete, lib); |
---|
| 470 | |
---|
| 471 | /* Call the initialize method; rb_obj_call_init() requires an argument |
---|
| 472 | array. */ |
---|
| 473 | VALUE argv[1] = {driver}; |
---|
| 474 | rb_obj_call_init(rbLib, 1, argv); |
---|
| 475 | |
---|
| 476 | /* Return a Ruby VALUE */ |
---|
| 477 | return rbLib; |
---|
| 478 | |
---|
| 479 | } /* end RbRp_New */ |
---|
| 480 | |
---|
| 481 | |
---|
| 482 | /****************************************************************************** |
---|
| 483 | * Init_Rappture() |
---|
| 484 | * |
---|
| 485 | * This is the first function called when Ruby loads the Rappture extension. |
---|
| 486 | * Create the Rappture class, add constants, and register methods. |
---|
| 487 | ******************************************************************************/ |
---|
| 488 | |
---|
| 489 | void |
---|
| 490 | Init_Rappture(void) |
---|
| 491 | { |
---|
| 492 | /* Create the Rappture class as a sublcass of Ruby's Object class. */ |
---|
| 493 | classRappture = rb_define_class("Rappture", rb_cObject); |
---|
| 494 | |
---|
| 495 | /* Add constants to the Rappture class, accessible via, e.g., |
---|
| 496 | "Rappture::APPEND"*/ |
---|
| 497 | rb_define_const(classRappture, "APPEND", INT2NUM(RPLIB_APPEND)); |
---|
| 498 | rb_define_const(classRappture, "OVERWRITE", INT2NUM(RPLIB_OVERWRITE)); |
---|
| 499 | rb_define_const(classRappture, "UNITS_ON", INT2NUM(RPUNITS_UNITS_ON)); |
---|
| 500 | rb_define_const(classRappture, "UNITS_OFF", INT2NUM(RPUNITS_UNITS_OFF)); |
---|
| 501 | rb_define_const(classRappture, "COMPRESS", INT2NUM(RPLIB_COMPRESS)); |
---|
| 502 | rb_define_const(classRappture, "NO_COMPRESS", INT2NUM(RPLIB_NO_COMPRESS)); |
---|
| 503 | |
---|
| 504 | /* Function pointer cast necessary for C++ (but not C) */ |
---|
| 505 | # define RB_FUNC(func) (VALUE (*)(ANYARGS))func |
---|
| 506 | |
---|
| 507 | /* Register methods; last argument gives the expected number of arguments, |
---|
| 508 | not counting self (i.e. number of arguments from Ruby code) */ |
---|
[1081] | 509 | rb_define_singleton_method(classRappture, "new", RB_FUNC(RbRp_New), 1); |
---|
| 510 | rb_define_method(classRappture, "initialize", RB_FUNC(RbRp_Init), 1); |
---|
| 511 | rb_define_method(classRappture, "get", RB_FUNC(RbRp_GetString), 1); |
---|
| 512 | rb_define_method(classRappture, "getdata", RB_FUNC(RbRp_GetData), 1); |
---|
| 513 | rb_define_method(classRappture, "put", RB_FUNC(RbRp_PutObject), 3); |
---|
| 514 | rb_define_method(classRappture, "putdata", RB_FUNC(RbRp_PutData), 3); |
---|
| 515 | rb_define_method(classRappture, "putfile", RB_FUNC(RbRp_PutFile), 4); |
---|
| 516 | rb_define_method(classRappture, "result", RB_FUNC(RbRp_Result), 1); |
---|
| 517 | rb_define_method(classRappture, "xml", RB_FUNC(RbRp_Xml), 0); |
---|
| 518 | rb_define_method(classRappture, "convert", RB_FUNC(RbRp_Convert), 3); |
---|
| 519 | rb_define_method(classRappture, "progress", RB_FUNC(RbRp_Progress), 2); |
---|
[896] | 520 | |
---|
| 521 | } /* end Init_Rappture */ |
---|
| 522 | |
---|
| 523 | /* TODO rpElement*(), rpChildren*() */ |
---|
| 524 | |
---|