1 /* 2 * Copyright 2001-2004 Brandon Long 3 * All Rights Reserved. 4 * 5 * ClearSilver Templating System 6 * 7 * This code is made available under the terms of the ClearSilver License. 8 * http://www.clearsilver.net/license.hdf 9 * 10 */ 11 12 #include <ruby.h> 13 #include <version.h> 14 #include "ClearSilver.h" 15 #include "neo_ruby.h" 16 17 VALUE mNeotonic; 18 static VALUE cHdf; 19 VALUE eHdfError; 20 static ID id_to_s; 21 22 #define Srb_raise(val) rb_raise(eHdfError, "%s/%d %s",__FILE__,__LINE__,RSTRING(val)->ptr) 23 24 VALUE r_neo_error (NEOERR *err) 25 { 26 STRING str; 27 VALUE errstr; 28 29 string_init (&str); 30 nerr_error_string (err, &str); 31 errstr = rb_str_new2(str.buf); 32 /* 33 if (nerr_match(err, NERR_PARSE)) { 34 } 35 else { 36 } 37 */ 38 string_clear (&str); 39 return errstr; 40 } 41 42 static void h_free2(t_hdfh *hdfh) { 43 #ifdef DEBUG 44 fprintf(stderr,"freeing hdf 0x%x\n",hdfh); 45 #endif 46 hdf_destroy(&(hdfh->hdf)); 47 free(hdfh); 48 } 49 static void h_free(t_hdfh *hdfh) { 50 #ifdef DEBUG 51 fprintf(stderr,"freeing hdf holder 0x%x of 0x%x\n",hdfh,hdfh->parent); 52 #endif 53 free(hdfh); 54 } 55 static void h_mark(t_hdfh *hdfh) { 56 /* Only mark the array if this is the top node, only the original node should 57 set up the marker. 58 */ 59 #ifdef DEBUG 60 fprintf(stderr,"marking 0x%x\n",hdfh); 61 #endif 62 if ( ! NIL_P(hdfh->top) ) 63 rb_gc_mark(hdfh->top); 64 else 65 fprintf(stderr,"mark top 0x%x\n",hdfh); 66 } 67 68 static VALUE h_init (VALUE self) 69 { 70 return self; 71 } 72 73 VALUE h_new(VALUE class) 74 { 75 t_hdfh *hdfh; 76 NEOERR *err; 77 VALUE obj; 78 79 obj=Data_Make_Struct(class,t_hdfh,0,h_free2,hdfh); 80 err = hdf_init (&(hdfh->hdf)); 81 if (err) Srb_raise(r_neo_error(err)); 82 #ifdef DEBUG 83 fprintf(stderr,"allocated 0x%x\n",(void *)hdfh); 84 #endif 85 hdfh->top=Qnil; 86 rb_obj_call_init(obj, 0, NULL); 87 return obj; 88 } 89 90 static VALUE h_get_attr (VALUE self, VALUE oName) 91 { 92 t_hdfh *hdfh; 93 char *name; 94 HDF_ATTR *attr; 95 VALUE k,v; 96 VALUE rv; 97 98 Data_Get_Struct(self, t_hdfh, hdfh); 99 name = STR2CSTR(oName); 100 101 rv = rb_hash_new(); 102 103 attr = hdf_get_attr(hdfh->hdf, name); 104 while ( attr != NULL ) { 105 k=rb_str_new2(attr->key); 106 v=rb_str_new2(attr->value); 107 rb_hash_aset(rv, k, v); 108 attr = attr->next; 109 } 110 return rv; 111 } 112 113 static VALUE h_set_attr(VALUE self, VALUE oName, VALUE oKey, VALUE oValue) 114 { 115 t_hdfh *hdfh; 116 char *name, *key, *value; 117 NEOERR *err; 118 119 Data_Get_Struct(self, t_hdfh, hdfh); 120 121 name = STR2CSTR(oName); 122 key = STR2CSTR(oKey); 123 if ( NIL_P(oValue) ) 124 value = NULL; 125 else 126 value = STR2CSTR(oValue); 127 128 err = hdf_set_attr(hdfh->hdf, name, key, value); 129 if (err) Srb_raise(r_neo_error(err)); 130 131 return self; 132 } 133 134 static VALUE h_set_value (VALUE self, VALUE oName, VALUE oValue) 135 { 136 t_hdfh *hdfh; 137 char *name, *value; 138 NEOERR *err; 139 140 Data_Get_Struct(self, t_hdfh, hdfh); 141 142 if ( TYPE(oName) == T_STRING ) 143 name=STR2CSTR(oName); 144 else 145 name=STR2CSTR(rb_funcall(oName,id_to_s,0)); 146 147 if ( TYPE(oValue) == T_STRING ) 148 value=STR2CSTR(oValue); 149 else 150 value=STR2CSTR(rb_funcall(oValue,id_to_s,0)); 151 152 err = hdf_set_value (hdfh->hdf, name, value); 153 154 if (err) Srb_raise(r_neo_error(err)); 155 156 return self; 157 } 158 159 static VALUE h_get_int_value (VALUE self, VALUE oName, VALUE oDefault) 160 { 161 t_hdfh *hdfh; 162 char *name; 163 int r, d = 0; 164 VALUE rv; 165 166 Data_Get_Struct(self, t_hdfh, hdfh); 167 168 name=STR2CSTR(oName); 169 d=NUM2INT(oDefault); 170 171 r = hdf_get_int_value (hdfh->hdf, name, d); 172 rv = INT2NUM(r); 173 return rv; 174 } 175 176 static VALUE h_get_value (VALUE self, VALUE oName, VALUE oDefault) 177 { 178 t_hdfh *hdfh; 179 char *name; 180 char *r, *d = NULL; 181 VALUE rv; 182 183 Data_Get_Struct(self, t_hdfh, hdfh); 184 name=STR2CSTR(oName); 185 d=STR2CSTR(oDefault); 186 187 r = hdf_get_value (hdfh->hdf, name, d); 188 rv = rb_str_new2(r); 189 return rv; 190 } 191 192 static VALUE h_get_child (VALUE self, VALUE oName) 193 { 194 t_hdfh *hdfh,*hdfh_new; 195 HDF *r; 196 VALUE rv; 197 char *name; 198 199 Data_Get_Struct(self, t_hdfh, hdfh); 200 name=STR2CSTR(oName); 201 202 r = hdf_get_child (hdfh->hdf, name); 203 if (r == NULL) { 204 return Qnil; 205 } 206 rv=Data_Make_Struct(cHdf,t_hdfh,h_mark,h_free,hdfh_new); 207 hdfh_new->top=self; 208 hdfh_new->hdf=r; 209 hdfh_new->parent=hdfh; 210 211 return rv; 212 } 213 214 static VALUE h_get_obj (VALUE self, VALUE oName) 215 { 216 t_hdfh *hdfh,*hdfh_new; 217 HDF *r; 218 VALUE rv; 219 char *name; 220 221 Data_Get_Struct(self, t_hdfh, hdfh); 222 name=STR2CSTR(oName); 223 224 r = hdf_get_obj (hdfh->hdf, name); 225 if (r == NULL) { 226 return Qnil; 227 } 228 229 rv=Data_Make_Struct(cHdf,t_hdfh,h_mark,h_free,hdfh_new); 230 hdfh_new->top=self; 231 hdfh_new->hdf=r; 232 hdfh_new->parent=hdfh; 233 234 return rv; 235 } 236 237 static VALUE h_get_node (VALUE self, VALUE oName) 238 { 239 t_hdfh *hdfh,*hdfh_new; 240 HDF *r; 241 VALUE rv; 242 char *name; 243 NEOERR *err; 244 245 Data_Get_Struct(self, t_hdfh, hdfh); 246 name=STR2CSTR(oName); 247 248 err = hdf_get_node (hdfh->hdf, name, &r); 249 if (err) 250 Srb_raise(r_neo_error(err)); 251 252 rv=Data_Make_Struct(cHdf,t_hdfh,h_mark,h_free,hdfh_new); 253 hdfh_new->top=self; 254 hdfh_new->hdf=r; 255 hdfh_new->parent=hdfh; 256 257 return rv; 258 } 259 260 261 static VALUE h_obj_child (VALUE self) 262 { 263 t_hdfh *hdfh,*hdfh_new; 264 HDF *r = NULL; 265 VALUE rv; 266 267 Data_Get_Struct(self, t_hdfh, hdfh); 268 269 r = hdf_obj_child (hdfh->hdf); 270 if (r == NULL) { 271 return Qnil; 272 } 273 274 rv=Data_Make_Struct(cHdf,t_hdfh,h_mark,h_free,hdfh_new); 275 hdfh_new->top=self; 276 hdfh_new->hdf=r; 277 hdfh_new->parent=hdfh; 278 279 return rv; 280 } 281 282 static VALUE h_obj_next (VALUE self) 283 { 284 t_hdfh *hdfh,*hdfh_new; 285 HDF *r = NULL; 286 VALUE rv; 287 288 Data_Get_Struct(self, t_hdfh, hdfh); 289 290 r = hdf_obj_next (hdfh->hdf); 291 if (r == NULL) { 292 return Qnil; 293 } 294 295 rv=Data_Make_Struct(cHdf,t_hdfh,h_mark,h_free,hdfh_new); 296 hdfh_new->top=self; 297 hdfh_new->hdf=r; 298 hdfh_new->parent=hdfh; 299 300 return rv; 301 } 302 303 static VALUE h_obj_top (VALUE self) 304 { 305 t_hdfh *hdfh,*hdfh_new; 306 HDF *r = NULL; 307 VALUE rv; 308 309 Data_Get_Struct(self, t_hdfh, hdfh); 310 311 r = hdf_obj_top (hdfh->hdf); 312 if (r == NULL) { 313 return Qnil; 314 } 315 316 rv=Data_Make_Struct(cHdf,t_hdfh,h_mark,h_free,hdfh_new); 317 hdfh_new->top=self; 318 hdfh_new->hdf=r; 319 hdfh_new->parent=hdfh; 320 321 return rv; 322 } 323 324 static VALUE h_obj_name (VALUE self) 325 { 326 t_hdfh *hdfh; 327 VALUE rv; 328 char *r; 329 330 Data_Get_Struct(self, t_hdfh, hdfh); 331 332 r = hdf_obj_name (hdfh->hdf); 333 if (r == NULL) { 334 return Qnil; 335 } 336 337 rv = rb_str_new2(r); 338 return rv; 339 } 340 341 static VALUE h_obj_attr (VALUE self) 342 { 343 t_hdfh *hdfh; 344 HDF_ATTR *attr; 345 VALUE k,v; 346 VALUE rv; 347 348 Data_Get_Struct(self, t_hdfh, hdfh); 349 rv = rb_hash_new(); 350 351 attr = hdf_obj_attr(hdfh->hdf); 352 while ( attr != NULL ) { 353 k=rb_str_new2(attr->key); 354 v=rb_str_new2(attr->value); 355 rb_hash_aset(rv, k, v); 356 attr = attr->next; 357 } 358 return rv; 359 } 360 361 362 static VALUE h_obj_value (VALUE self) 363 { 364 t_hdfh *hdfh; 365 VALUE rv; 366 char *r; 367 368 Data_Get_Struct(self, t_hdfh, hdfh); 369 370 r = hdf_obj_value (hdfh->hdf); 371 if (r == NULL) { 372 return Qnil; 373 } 374 375 rv = rb_str_new2(r); 376 return rv; 377 } 378 379 static VALUE h_read_file (VALUE self, VALUE oPath) 380 { 381 t_hdfh *hdfh; 382 char *path; 383 NEOERR *err; 384 385 Data_Get_Struct(self, t_hdfh, hdfh); 386 387 path=STR2CSTR(oPath); 388 389 err = hdf_read_file (hdfh->hdf, path); 390 if (err) Srb_raise(r_neo_error(err)); 391 392 return self; 393 } 394 395 static VALUE h_write_file (VALUE self, VALUE oPath) 396 { 397 t_hdfh *hdfh; 398 char *path; 399 NEOERR *err; 400 401 Data_Get_Struct(self, t_hdfh, hdfh); 402 403 path=STR2CSTR(oPath); 404 405 err = hdf_write_file (hdfh->hdf, path); 406 407 if (err) Srb_raise(r_neo_error(err)); 408 409 return self; 410 } 411 412 static VALUE h_write_file_atomic (VALUE self, VALUE oPath) 413 { 414 t_hdfh *hdfh; 415 char *path; 416 NEOERR *err; 417 418 Data_Get_Struct(self, t_hdfh, hdfh); 419 420 path=STR2CSTR(oPath); 421 422 err = hdf_write_file_atomic (hdfh->hdf, path); 423 if (err) Srb_raise(r_neo_error(err)); 424 425 return self; 426 } 427 428 static VALUE h_remove_tree (VALUE self, VALUE oName) 429 { 430 t_hdfh *hdfh; 431 char *name; 432 NEOERR *err; 433 434 Data_Get_Struct(self, t_hdfh, hdfh); 435 name = STR2CSTR(oName); 436 437 err = hdf_remove_tree (hdfh->hdf, name); 438 if (err) Srb_raise(r_neo_error(err)); 439 440 return self; 441 } 442 443 static VALUE h_dump (VALUE self) 444 { 445 t_hdfh *hdfh; 446 VALUE rv; 447 NEOERR *err; 448 STRING str; 449 450 string_init (&str); 451 452 Data_Get_Struct(self, t_hdfh, hdfh); 453 454 err = hdf_dump_str (hdfh->hdf, NULL, 0, &str); 455 if (err) Srb_raise(r_neo_error(err)); 456 457 if (str.len==0) 458 return Qnil; 459 460 rv = rb_str_new2(str.buf); 461 string_clear (&str); 462 return rv; 463 } 464 465 static VALUE h_write_string (VALUE self) 466 { 467 t_hdfh *hdfh; 468 VALUE rv; 469 NEOERR *err; 470 char *s = NULL; 471 472 Data_Get_Struct(self, t_hdfh, hdfh); 473 474 err = hdf_write_string (hdfh->hdf, &s); 475 476 if (err) Srb_raise(r_neo_error(err)); 477 478 rv = rb_str_new2(s); 479 if (s) free(s); 480 return rv; 481 } 482 483 static VALUE h_read_string (VALUE self, VALUE oString, VALUE oIgnore) 484 { 485 t_hdfh *hdfh; 486 NEOERR *err; 487 char *s = NULL; 488 int ignore = 0; 489 490 Data_Get_Struct(self, t_hdfh, hdfh); 491 492 s = STR2CSTR(oString); 493 ignore = NUM2INT(oIgnore); 494 495 err = hdf_read_string_ignore (hdfh->hdf, s, ignore); 496 497 if (err) Srb_raise(r_neo_error(err)); 498 499 return self; 500 } 501 502 static VALUE h_copy (VALUE self, VALUE oName, VALUE oHdfSrc) 503 { 504 t_hdfh *hdfh, *hdfh_src; 505 char *name; 506 NEOERR *err; 507 508 Data_Get_Struct(self, t_hdfh, hdfh); 509 Data_Get_Struct(oHdfSrc, t_hdfh, hdfh_src); 510 511 name = STR2CSTR(oName); 512 513 if (hdfh_src == NULL) rb_raise(eHdfError, "second argument must be an Hdf object"); 514 515 err = hdf_copy (hdfh->hdf, name, hdfh_src->hdf); 516 if (err) Srb_raise(r_neo_error(err)); 517 518 return self; 519 } 520 521 static VALUE h_set_symlink (VALUE self, VALUE oSrc, VALUE oDest) 522 { 523 t_hdfh *hdfh; 524 char *src; 525 char *dest; 526 NEOERR *err; 527 528 Data_Get_Struct(self, t_hdfh, hdfh); 529 src = STR2CSTR(oSrc); 530 dest = STR2CSTR(oDest); 531 532 err = hdf_set_symlink (hdfh->hdf, src, dest); 533 if (err) Srb_raise(r_neo_error(err)); 534 535 return self; 536 } 537 538 static VALUE h_escape (VALUE self, VALUE oString, VALUE oEsc_char, VALUE oEsc) 539 { 540 VALUE rv; 541 char *s; 542 char *escape; 543 char *esc_char; 544 long buflen; 545 char *ret = NULL; 546 NEOERR *err; 547 548 s = rb_str2cstr(oString,&buflen); 549 esc_char = STR2CSTR(oEsc_char); 550 escape = STR2CSTR(oEsc); 551 552 err = neos_escape((UINT8*)s, buflen, esc_char[0], escape, &ret); 553 554 if (err) Srb_raise(r_neo_error(err)); 555 556 rv = rb_str_new2(ret); 557 free(ret); 558 return rv; 559 } 560 561 static VALUE h_unescape (VALUE self, VALUE oString, VALUE oEsc_char) 562 { 563 VALUE rv; 564 char *s; 565 char *copy; 566 char *esc_char; 567 long buflen; 568 569 s = rb_str2cstr(oString,&buflen); 570 esc_char = STR2CSTR(oEsc_char); 571 572 /* This should be changed to use memory from the gc */ 573 copy = strdup(s); 574 if (copy == NULL) rb_raise(rb_eNoMemError, "out of memory"); 575 576 neos_unescape((UINT8*)copy, buflen, esc_char[0]); 577 578 rv = rb_str_new2(copy); 579 free(copy); 580 return rv; 581 } 582 583 void Init_cs(); 584 585 void Init_hdf() { 586 587 id_to_s=rb_intern("to_s"); 588 589 mNeotonic = rb_define_module("Neo"); 590 cHdf = rb_define_class_under(mNeotonic, "Hdf", rb_cObject); 591 592 rb_define_singleton_method(cHdf, "new", h_new, 0); 593 rb_define_method(cHdf, "initialize", h_init, 0); 594 rb_define_method(cHdf, "get_attr", h_get_attr, 1); 595 rb_define_method(cHdf, "set_attr", h_set_attr, 3); 596 rb_define_method(cHdf, "set_value", h_set_value, 2); 597 rb_define_method(cHdf, "put", h_set_value, 2); 598 rb_define_method(cHdf, "get_int_value", h_get_int_value, 2); 599 rb_define_method(cHdf, "get_value", h_get_value, 2); 600 rb_define_method(cHdf, "get_child", h_get_child, 1); 601 rb_define_method(cHdf, "get_obj", h_get_obj, 1); 602 rb_define_method(cHdf, "get_node", h_get_node, 1); 603 rb_define_method(cHdf, "obj_child", h_obj_child, 0); 604 rb_define_method(cHdf, "obj_next", h_obj_next, 0); 605 rb_define_method(cHdf, "obj_top", h_obj_top, 0); 606 rb_define_method(cHdf, "obj_name", h_obj_name, 0); 607 rb_define_method(cHdf, "obj_attr", h_obj_attr, 0); 608 rb_define_method(cHdf, "obj_value", h_obj_value, 0); 609 rb_define_method(cHdf, "read_file", h_read_file, 1); 610 rb_define_method(cHdf, "write_file", h_write_file, 1); 611 rb_define_method(cHdf, "write_file_atomic", h_write_file_atomic, 1); 612 rb_define_method(cHdf, "remove_tree", h_remove_tree, 1); 613 rb_define_method(cHdf, "dump", h_dump, 0); 614 rb_define_method(cHdf, "write_string", h_write_string, 0); 615 rb_define_method(cHdf, "read_string", h_read_string, 2); 616 rb_define_method(cHdf, "copy", h_copy, 2); 617 rb_define_method(cHdf, "set_symlink", h_set_symlink, 2); 618 619 rb_define_singleton_method(cHdf, "escape", h_escape, 3); 620 rb_define_singleton_method(cHdf, "unescape", h_unescape, 3); 621 622 eHdfError = rb_define_class_under(mNeotonic, "HdfError", 623 #if RUBY_VERSION_MINOR >= 6 624 rb_eStandardError); 625 #else 626 rb_eException); 627 #endif 628 629 Init_cs(); 630 } 631