Home | History | Annotate | Download | only in hdf
      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