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