/* * sablot.c * Sablot module for Ruby * Copyright 2000-2001 TAKAHASHI 'Maki' Masayoshi * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is: Sablotron module for Ruby * * The Developer of the Original Code is * TAKAHASHI 'Maki' Masayoshi. All Rights Reserved. * * Contributor(s): * Takaaki Tateishi (setEncoding support) * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. * $Id: sablot.c,v 1.5 2001/03/04 02:16:50 maki Exp maki $ * */ #include #include "ruby.h" #include "intern.h" #include static VALUE cSablot; static VALUE eSablotError; static ID id_MessageHandlerCode; static ID id_MessageHandlerLog; static ID id_MessageHandlerError; static MessageHandler my_message_handler; typedef struct _sablot_data { SablotHandle processor; } sablot_data; #define GetProcessor(obj, sab) {\ Data_Get_Struct(obj, sablot_data, sab);\ } static void free_sablot(sablot_data *sab) { if (sab->processor) SablotDestroyProcessor(sab->processor); /* sab->processor = NULL; */ } static VALUE rb_sablot_create_processor(int argc, VALUE *argv, VALUE klass) { VALUE obj; int err; sablot_data *sab; obj = Data_Make_Struct(klass, sablot_data, 0, free_sablot, sab); err = SablotCreateProcessor(&(sab->processor)); if (err) { rb_raise(eSablotError, "cannot create a new instance"); } rb_obj_call_init(obj, argc, argv); return obj; } static char** rb_makeparam(VALUE obj) { VALUE keys, key, val; char **namedbuf; long len; long keylen, vallen; char *str; int i; if NIL_P(obj) { namedbuf = ALLOC_N(char*,2); *namedbuf = '\0'; *(namedbuf+1) = '\0'; return namedbuf; } if (TYPE(obj) != T_HASH) rb_raise(eSablotError, "parametar must be a Hash"); keys = rb_funcall(obj, rb_intern("keys"), 0); len = RARRAY(keys)->len; namedbuf = ALLOC_N(char*, len*2+2); for (i = 0; i < len*2; i+=2) { key = rb_ary_pop(keys); val = rb_hash_aref(obj, key); Check_Type(key, T_STRING); Check_Type(val, T_STRING); keylen = RSTRING(key)->len; vallen = RSTRING(val)->len; str = ALLOC_N(char, keylen+vallen+2); *(namedbuf+i) = str; MEMCPY(str, STR2CSTR(key), char, keylen); str += keylen; *str = '\0'; str++; *(namedbuf+i+1) = str; MEMCPY(str, STR2CSTR(val), char, vallen); *(str+vallen) = '\0'; } *(namedbuf+i) = '\0'; *(namedbuf+i+1) = '\0'; /** printf(":%s:\n",*namedbuf); printf(":%s:\n",*(namedbuf+1)); printf(":%s:\n",*(namedbuf+2)); printf(":%s:\n",*(namedbuf+3)); **/ return namedbuf; } static VALUE rb_sablot_run_processor(VALUE self, VALUE sheet, VALUE input, VALUE result, VALUE params, VALUE args) { int err; sablot_data *sab; char *inputURI, *sheetURI, *resultURI; char **params_str; char **args_str; GetProcessor(self, sab); inputURI = STR2CSTR(input); sheetURI = STR2CSTR(sheet); resultURI = STR2CSTR(result); params_str = rb_makeparam(params); args_str = rb_makeparam(args); /* printf("%s:\n%s:\n%s\n",inputURI, sheetURI, resultURI); */ SablotRegHandler(sab->processor, HLR_MESSAGE, (void*)&my_message_handler, (void*)self); err = SablotRunProcessor(sab->processor, sheetURI, inputURI, resultURI, params_str, args_str); SablotUnregHandler(sab->processor, HLR_MESSAGE, NULL, NULL); if (err) { rb_raise(eSablotError, "Sablotron Error"); } return self; } static VALUE rb_sablot_get_result_arg(VALUE self, VALUE result) { char *arg_uri, *arg_val; int err; VALUE ret; sablot_data *sab; if (TYPE(result) != T_STRING) rb_raise(eSablotError, "Sablotron Error"); GetProcessor(self, sab); arg_uri = STR2CSTR(result); arg_val = NULL; err = SablotGetResultArg(sab->processor, arg_uri, &arg_val); if (err) { rb_raise(eSablotError, "Sablotron Error"); SablotFree(arg_val); } else if (arg_val) { ret = rb_tainted_str_new2(arg_val); SablotFree(arg_val); } else { ret = Qnil; } return ret; } static VALUE rb_sablot_set_log(VALUE self, VALUE filename, VALUE level) { char *log; int lev; int err; VALUE ret; sablot_data *sab; Check_Type(level, T_FIXNUM); GetProcessor(self, sab); if NIL_P(filename) { log = NULL; } else { /* Check_Type(filename, T_STRING); */ log = STR2CSTR(filename); } lev = FIX2INT(level); err = SablotSetLog(sab->processor, log, lev); if (err) { rb_raise(eSablotError, "Sablotron Error"); } return self; } static VALUE rb_sablot_set_base(VALUE self, VALUE base) { char *base_uri; int err; VALUE ret; sablot_data *sab; Check_Type(base, T_STRING); GetProcessor(self, sab); base_uri = STR2CSTR(base); err = SablotSetBase(sab->processor, base_uri); if (err) { rb_raise(eSablotError, "Sablotron Error"); } return self; } static VALUE rb_sablot_set_base_for_scheme(VALUE self, VALUE scheme, VALUE base) { char *scheme_name; char *base_uri; int err; VALUE ret; sablot_data *sab; Check_Type(base, T_STRING); Check_Type(scheme, T_STRING); GetProcessor(self, sab); scheme_name = STR2CSTR(scheme); base_uri = STR2CSTR(base); err = SablotSetBaseForScheme(sab->processor, scheme_name, base_uri); if (err) { rb_raise(eSablotError, "Sablotron Error"); } return self; } static VALUE rb_sablot_process_strings(VALUE obj, VALUE xsl, VALUE xml) { VALUE retval; char *templ; char *input; char *result; Check_Type(xsl, T_STRING); Check_Type(xml, T_STRING); input = RSTRING(xml)->ptr; templ = RSTRING(xsl)->ptr; if (SablotProcessStrings(templ, input, &result)) rb_raise(eSablotError, "Sablotron Error"); retval = rb_tainted_str_new2(result); SablotFree(result); return retval; } static VALUE rb_sablot_process_files(VALUE obj, VALUE xsl, VALUE xml, VALUE xml2) { VALUE retval; char *templ; char *input; char *result; Check_Type(xsl, T_STRING); Check_Type(xml, T_STRING); Check_Type(xml2, T_STRING); templ = RSTRING(xsl)->ptr; input = RSTRING(xml)->ptr; result = RSTRING(xml2)->ptr; if (SablotProcessFiles(templ, input, result)) rb_raise(eSablotError, "Sablotron Error"); SablotFree(result); return Qtrue; } static VALUE rb_sablot_set_encoding(VALUE self, VALUE enc) { sablot_data *sab; char *encoding; GetProcessor(self, sab); if (NIL_P(enc)) { encoding = NULL; } else { encoding = STR2CSTR(enc); }; SablotSetEncoding(sab->processor, encoding); return self; } static MH_ERROR my_MessageHandlerCode(void * userData, SablotHandle processor_, int severity, unsigned short facility, unsigned short code) { if (rb_method_boundp(CLASS_OF((VALUE)userData), id_MessageHandlerCode, 0)) { rb_funcall((VALUE)userData, id_MessageHandlerCode, 1, INT2NUM(code)); } } static MH_ERROR my_MessageHandlerLog(void * userData, SablotHandle processor_, MH_ERROR code, MH_LEVEL level, char ** fields) { VALUE log_ary; unsigned long log_len; char *log_str; VALUE log_msg; if (rb_method_boundp(CLASS_OF((VALUE)userData), id_MessageHandlerLog, 0)) { log_ary = rb_ary_new(); if (fields != NULL) { while (*fields != NULL) { log_len = strlen(*fields); log_str = ALLOC_N(char, log_len+1); strncpy(log_str, *fields, log_len+1); log_msg = rb_tainted_str_new2(log_str); rb_ary_push(log_ary, log_msg); fields++; } } rb_funcall((VALUE)userData, id_MessageHandlerLog, 3, INT2NUM(code), INT2NUM(level), log_ary); } } static MH_ERROR my_MessageHandlerError(void *userData, SablotHandle processor_, MH_ERROR code, MH_LEVEL level, char ** fields) { VALUE err_ary; char *err_str; VALUE err_msg; unsigned long err_len; if (rb_method_boundp(CLASS_OF((VALUE)userData), id_MessageHandlerError, 0)) { err_ary = rb_ary_new(); if (fields != NULL) { while (*fields != NULL) { err_len = strlen(*fields); err_str = ALLOC_N(char, err_len+1); strncpy(err_str, *fields, err_len+1); err_msg = rb_tainted_str_new2(err_str); rb_ary_push(err_ary, err_msg); fields++; } } rb_funcall((VALUE)userData, id_MessageHandlerError, 3, INT2NUM(code), INT2NUM(level), err_ary); } } static MessageHandler my_message_handler = { my_MessageHandlerCode, my_MessageHandlerLog, my_MessageHandlerError }; void Init_sablot() { cSablot = rb_define_class("Sablot", rb_cObject); eSablotError = rb_define_class("SablotError", rb_eStandardError); rb_define_singleton_method(cSablot, "createProcessor", rb_sablot_create_processor, -1); rb_define_singleton_method(cSablot, "new", rb_sablot_create_processor, -1); rb_define_method(cSablot, "runProcessor", rb_sablot_run_processor, 5); rb_define_method(cSablot, "resultArg", rb_sablot_get_result_arg, 1); rb_define_method(cSablot, "setLog", rb_sablot_set_log, 2); rb_define_method(cSablot, "setBase", rb_sablot_set_base, 1); rb_define_method(cSablot, "setBaseForScheme", rb_sablot_set_base_for_scheme, 2); rb_define_method(cSablot, "setEncoding", rb_sablot_set_encoding, 1); rb_define_singleton_method(cSablot, "process_strings", rb_sablot_process_strings, 2); rb_define_singleton_method(cSablot, "processStrings", rb_sablot_process_strings, 2); rb_define_singleton_method(cSablot, "process_files", rb_sablot_process_files, 3); rb_define_singleton_method(cSablot, "processFiles", rb_sablot_process_files, 3); rb_define_const(cSablot, "MH_DEBUG", INT2FIX(MH_LEVEL_DEBUG)); rb_define_const(cSablot, "MH_INFO", INT2FIX(MH_LEVEL_INFO)); rb_define_const(cSablot, "MH_WARN", INT2FIX(MH_LEVEL_WARN)); rb_define_const(cSablot, "MH_ERROR", INT2FIX(MH_LEVEL_ERROR)); rb_define_const(cSablot, "MH_CRITICAL", INT2FIX(MH_LEVEL_CRITICAL)); id_MessageHandlerCode = rb_intern("messageCode"); id_MessageHandlerLog = rb_intern("messageLog"); id_MessageHandlerError = rb_intern("messageError"); /* rb_define_const(cSablot, "Sablot_VERSION", rb_str_new2("0.44")); */ }