• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
r_neo_error(NEOERR * err)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 
h_free2(t_hdfh * hdfh)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 }
h_free(t_hdfh * hdfh)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 }
h_mark(t_hdfh * hdfh)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 
h_init(VALUE self)68 static VALUE h_init (VALUE self)
69 {
70   return self;
71 }
72 
h_new(VALUE class)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 
h_get_attr(VALUE self,VALUE oName)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 
h_set_attr(VALUE self,VALUE oName,VALUE oKey,VALUE oValue)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 
h_set_value(VALUE self,VALUE oName,VALUE oValue)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 
h_get_int_value(VALUE self,VALUE oName,VALUE oDefault)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 
h_get_value(VALUE self,VALUE oName,VALUE oDefault)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 
h_get_child(VALUE self,VALUE oName)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 
h_get_obj(VALUE self,VALUE oName)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 
h_get_node(VALUE self,VALUE oName)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 
h_obj_child(VALUE self)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 
h_obj_next(VALUE self)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 
h_obj_top(VALUE self)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 
h_obj_name(VALUE self)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 
h_obj_attr(VALUE self)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 
h_obj_value(VALUE self)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 
h_read_file(VALUE self,VALUE oPath)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 
h_write_file(VALUE self,VALUE oPath)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 
h_write_file_atomic(VALUE self,VALUE oPath)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 
h_remove_tree(VALUE self,VALUE oName)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 
h_dump(VALUE self)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 
h_write_string(VALUE self)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 
h_read_string(VALUE self,VALUE oString,VALUE oIgnore)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 
h_copy(VALUE self,VALUE oName,VALUE oHdfSrc)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 
h_set_symlink(VALUE self,VALUE oSrc,VALUE oDest)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 
h_escape(VALUE self,VALUE oString,VALUE oEsc_char,VALUE oEsc)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 
h_unescape(VALUE self,VALUE oString,VALUE oEsc_char)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 
Init_hdf()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