/* * Sary::Builder - a builder class for Sary * * $Id: builder.c,v 1.1.1.1 2004/09/18 00:26:46 satoru-t Exp $ * * Copyright (C) 2000 TAKAOKA Kazuma * All right reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA */ #include #include #include "sary.h" #include "ruby.h" #include "version.h" #define GET_Builder(obj, dat) Data_Get_Struct(obj, SaryBuilder, dat) static VALUE BuilderClass; /* For SaryBuilder class. */ static VALUE rsbuilder_s_new(int argc, VALUE *argv, VALUE klass); static void rsbuilder_destroy(SaryBuilder *builder); static VALUE rsbuilder_sort(int argc, VALUE *argv, VALUE klass); static VALUE rsbuilder_block_sort(int argc, VALUE *argv, VALUE klass); static VALUE rsbuilder_set_block_size(VALUE klass, VALUE size); static VALUE rsbuilder_set_nthreads(VALUE klass, VALUE nthreads); static void dummy_progress(SaryProgress *progress); static void progress(SaryProgress *progress); static VALUE rsbuilder_s_new(int argc, VALUE *argv, VALUE klass) { NEWOBJ(data, struct RData); OBJSETUP(data, klass, T_DATA); rb_obj_call_init((VALUE)data, argc, argv); return (VALUE)data; } static VALUE rsbuilder_initialize(int argc, VALUE *argv, VALUE klass) { SaryBuilder *builder; char *file_name_ptr; char *array_name_ptr; VALUE file_name, array_name; rb_scan_args(argc, argv, "11", &file_name, &array_name); Check_SafeStr(file_name); #if RUBY_VERSION_CODE >= 180 file_name_ptr = StringValuePtr(file_name); #else file_name_ptr = STR2CSTR(file_name); #endif if (array_name == Qnil) builder = sary_builder_new(file_name_ptr); else { Check_SafeStr(array_name); #if RUBY_VERSION_CODE >= 180 array_name_ptr = StringValuePtr(array_name); #else array_name_ptr = STR2CSTR(array_name); #endif builder = sary_builder_new2(file_name_ptr, array_name_ptr); } if (builder == NULL) rb_raise(rb_eIOError, g_strerror(errno)); Check_Type(klass, T_DATA); RDATA(klass)->dfree = (RUBY_DATA_FUNC)rsbuilder_destroy; RDATA(klass)->dmark = (RUBY_DATA_FUNC)0; DATA_PTR(klass) = builder; return klass; } static void rsbuilder_destroy(SaryBuilder *builder) { sary_builder_destroy(builder); } static VALUE rsb_sort(int argc, VALUE *argv, VALUE klass, gboolean (*func)(SaryBuilder*)) { SaryBuilder *builder; VALUE block; rb_scan_args(argc, argv, "00&", &block); GET_Builder(klass, builder); if (block == Qnil) { sary_builder_connect_progress(builder, dummy_progress, NULL); } else { sary_builder_connect_progress(builder, progress, NULL); } if (func(builder) == FALSE) { rb_raise(rb_eRuntimeError, g_strerror(errno)); } return klass; } static VALUE rsbuilder_sort(int argc, VALUE *argv, VALUE klass) { return rsb_sort(argc, argv, klass, sary_builder_sort); } static VALUE rsbuilder_block_sort(int argc, VALUE *argv, VALUE klass) { return rsb_sort(argc, argv, klass, sary_builder_block_sort); } static VALUE rsbuilder_set_block_size(VALUE klass, VALUE size) { SaryBuilder *builder; GET_Builder(klass, builder); sary_builder_set_block_size(builder, NUM2INT(size)); return klass; } static void dummy_progress(SaryProgress *progress) { /* do nothing */ } static void progress(SaryProgress *progress) { VALUE args; SaryInt cur_percentage, prev_percentage; gint current = progress->current + 1; gint previous = progress->previous + 1; gint total = progress->total + 1; cur_percentage = (gint)((gdouble)current * 100 / total); prev_percentage = (gint)((gdouble)previous * 100 / total); if (cur_percentage > prev_percentage || progress->is_finished) { args = rb_ary_new3(4, rb_str_new2(progress->task), INT2NUM(current), INT2NUM(total), (progress->is_finished) ? Qtrue : Qfalse); rb_yield(args); } } static VALUE rsbuilder_set_nthreads(VALUE klass, VALUE nthreads) { SaryBuilder *builder; GET_Builder(klass, builder); sary_builder_set_nthreads(builder, NUM2INT(nthreads)); return klass; } /* * Initialize class */ void Init_sarybuilder(VALUE module) { BuilderClass = rb_define_class_under(module, "Builder", rb_cObject); rb_define_singleton_method(BuilderClass, "new", rsbuilder_s_new, -1); rb_define_method(BuilderClass, "initialize", rsbuilder_initialize, -1); rb_define_method(BuilderClass, "sort", rsbuilder_sort, -1); rb_define_method(BuilderClass, "block_sort", rsbuilder_block_sort, -1); rb_define_method(BuilderClass, "set_block_size", rsbuilder_set_block_size, 1); rb_define_method(BuilderClass, "set_nthreads", rsbuilder_set_nthreads, 1); }