note description: "RRD wrapper" author: "Patrick Ruckstuhl " date: "$Date$" revision: "$Revision$" class RRD create make feature {NONE} -- Initialization make -- Create. do create lock.make end feature rrd_create (an_arguments: DS_ARRAYED_LIST [STRING]) -- Create a new rrd file. require arguments_valid: an_arguments /= Void and then not an_arguments.is_empty local l_strings: SPECIAL [C_STRING] l_strings_c: SPECIAL [POINTER] l_locked: BOOLEAN do -- we need to do this in two steps as otherwise the C_STRINGS would -- be unreferenced and therefore open to garbage collection which -- would make the pointer to them invalid l_strings := list_to_c_string_array (an_arguments) l_strings_c := c_string_array_to_c (l_strings) lock.lock l_locked := True c_rrd_create (l_strings_c.count, $l_strings_c) lock.unlock rescue if l_locked then lock.unlock end end rrd_update (an_arguments: DS_ARRAYED_LIST [STRING]) -- Update a rrd file. require arguments_valid: an_arguments /= Void and then not an_arguments.is_empty local l_strings: SPECIAL [C_STRING] l_strings_c: SPECIAL [POINTER] l_locked: BOOLEAN do -- we need to do this in two steps as otherwise the C_STRINGS would -- be unreferenced and therefore open to garbage collection which -- would make the pointer to them invalid l_strings := list_to_c_string_array (an_arguments) l_strings_c := c_string_array_to_c (l_strings) lock.lock l_locked := True c_rrd_update (l_strings_c.count, $l_strings_c) lock.unlock rescue if l_locked then lock.unlock end end rrd_graph (an_arguments: DS_ARRAYED_LIST [STRING]) -- Generate a graph. require arguments_valid: an_arguments /= Void and then not an_arguments.is_empty local l_strings: SPECIAL [C_STRING] l_strings_c: SPECIAL [POINTER] l_locked: BOOLEAN do -- we need to do this in two steps as otherwise the C_STRINGS would -- be unreferenced and therefore open to garbage collection which -- would make the pointer to them invalid l_strings := list_to_c_string_array (an_arguments) l_strings_c := c_string_array_to_c (l_strings) lock.lock l_locked := True c_rrd_graph (l_strings_c.count, $l_strings_c) lock.unlock rescue if l_locked then lock.unlock end end rrd_fetch (an_arguments: DS_ARRAYED_LIST [STRING]): RRD_VALUES -- Retrieve data from an rrd. require arguments_valid: an_arguments /= Void and then not an_arguments.is_empty local l_strings: SPECIAL [C_STRING] l_strings_c: SPECIAL [POINTER] l_start_time, l_end_time: NATURAL_64 l_step, l_ds_count: NATURAL_64 l_np: POINTER l_vp: POINTER l_locked: BOOLEAN do -- we need to do this in two steps as otherwise the C_STRINGS would -- be unreferenced and therefore open to garbage collection which -- would make the pointer to them invalid l_strings := list_to_c_string_array (an_arguments) l_strings_c := c_string_array_to_c (l_strings) lock.lock l_locked := True c_rrd_fetch (l_strings_c.count, $l_strings_c, $l_start_time, $l_end_time, $l_step, $l_ds_count, $l_np, $l_vp) lock.unlock create Result.make (l_start_time, l_end_time, l_step, l_ds_count, l_np, l_vp) ensure Result_ok: Result /= Void rescue if l_locked then lock.unlock end end feature {NONE} -- Implementation lock: MUTEX -- Protection for non threadsafe methods. list_to_c_string_array (an_array: DS_ARRAYED_LIST[STRING]): SPECIAL[C_STRING] -- Convert from a list of strings into a list of c_strings. local i: INTEGER l_c_string: C_STRING do create Result.make (an_array.count) from i := 0 an_array.start until an_array.after loop create l_c_string.make (an_array.item_for_iteration) Result.put (l_c_string, i) i := i + 1 an_array.forth end end c_string_array_to_c (an_array: SPECIAL [C_STRING]): SPECIAL [POINTER] -- Convert from an an eiffel c_string to something that corresponds to char** on the c side. local i: INTEGER do create Result.make (an_array.count) from i := 0 until i >= an_array.count loop Result.put (an_array.item (i).item , i) i := i + 1 end end feature {NONE} -- C externals c_rrd_create (an_argc: INTEGER; an_arguments: POINTER) -- RRD create external "C inline use " alias "[ int rrd_argc = $an_argc; char** rrd_argv = (char**) $an_arguments; rrd_clear_error(); rrd_create(rrd_argc, rrd_argv); if( rrd_test_error() != 0 ){ eraise (rrd_get_error(), EN_PROG); } ]" end c_rrd_update (an_argc: INTEGER; an_arguments: POINTER) -- RRD update external "C inline use " alias "[ int rrd_argc = $an_argc; char** rrd_argv = (char**) $an_arguments; rrd_clear_error(); rrd_update(rrd_argc, rrd_argv); if( rrd_test_error() != 0 ){ eraise (rrd_get_error(), EN_PROG); } ]" end c_rrd_graph (an_argc: INTEGER; an_arguments: POINTER) -- RRD graph external "C inline use " alias "[ int rrd_argc = $an_argc; char** rrd_argv = (char**) $an_arguments; // some dummy return variables, needed by the method call char **calcpr = NULL; int xsize, ysize; double ymin, ymax; rrd_clear_error(); rrd_graph(rrd_argc, rrd_argv, &calcpr, &xsize, &ysize, NULL, &ymin, &ymax); if( rrd_test_error() != 0 ){ eraise (rrd_get_error(), EN_PROG); } if (calcpr) { int i; for(i = 0; calcpr[i]; i++){ free(calcpr[i]); } free(calcpr); } ]" end c_rrd_fetch (an_argc: INTEGER; an_arguments: POINTER; a_start_time: TYPED_POINTER[NATURAL_64]; an_end_time: TYPED_POINTER[NATURAL_64]; a_step: TYPED_POINTER[NATURAL_64]; a_ds_count: TYPED_POINTER[NATURAL_64]; a_ds_names: POINTER; a_values: POINTER) -- RRD fetch external "C inline use " alias "[ int rrd_argc = $an_argc; char** rrd_argv = (char**) $an_arguments; rrd_clear_error(); rrd_fetch(rrd_argc, rrd_argv, $a_start_time, $an_end_time, $a_step, $a_ds_count, $a_ds_names, $a_values); if( rrd_test_error() != 0 ){ eraise (rrd_get_error(), EN_PROG); } ]" end invariant lock_not_void: lock /= Void end