From 3f66325c1973e477e27b4d58c205f7c251bfc29d Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Fri, 8 May 2020 17:50:07 +0200 Subject: [PATCH] Add new example for function object, json & algorithms --- example/ex11-algo02.c | 77 ++++++++++++++++++++++++++++++++++++++++ example/ex11-algo02.json | 9 +++++ 2 files changed, 86 insertions(+) create mode 100644 example/ex11-algo02.c create mode 100644 example/ex11-algo02.json diff --git a/example/ex11-algo02.c b/example/ex11-algo02.c new file mode 100644 index 00000000..37e4ae84 --- /dev/null +++ b/example/ex11-algo02.c @@ -0,0 +1,77 @@ +#include "m-tuple.h" +#include "m-array.h" +#include "m-algo.h" +#include "m-funcobj.h" +#include "m-serial-json.h" +#include "m-string.h" + +/* Define the employee */ +TUPLE_DEF2(employee, + (name, string_t), + (age, int), + (idnum, int)) +#define M_OPL_employee_t() TUPLE_OPLIST(employee, STRING_OPLIST, M_DEFAULT_OPLIST, M_DEFAULT_OPLIST) + +/* Define an array of employee and some algorithms on it */ +ARRAY_DEF(vector_employee, employee_t) +#define M_OPL_vector_employee_t() ARRAY_OPLIST(vector_employee, M_OPL_employee_t()) +ALGO_DEF(vector_employee, vector_employee_t) + +/* Define the function object to select the sort order */ +FUNC_OBJ_INS_DEF(compare_by, + vector_employee_cmp_obj, + (a, b), { + if (string_equal_str_p(self->sort_field, "name")) + return string_cmp(a->name, b->name); + else if (string_equal_str_p(self->sort_field, "age")) + return a->age < b->age ? -1 : a->age > b->age; + else + return a->idnum < b->idnum ? -1 : a->idnum > b->idnum; + }, + (sort_field, string_t) ) +#define M_OPL_compare_by_t() FUNC_OBJ_INS_OPLIST(compare_by, STRING_OPLIST) + +// Let's read an array of person from the given JSON file +static void read(vector_employee_t base, const char filename[]) +{ + m_serial_return_code_t ret; + + // Open the file + FILE *f = fopen(filename, "rt"); + if (!f) { + fprintf(stderr, "ERROR: Cannot open file '%s'.\n", filename); + exit(2); + } + // Initialize the JSON serializer with this file + M_LET( (in,f), m_serial_json_read_t) + ret = vector_employee_in_serial(base, in); + // Let's handle errors + if (ret != M_SERIAL_OK_DONE) { + fprintf(stderr, "ERROR: Cannot read JSON data from file '%s'.\nParsing stops at:\n", filename); + while (!feof(f)) { fputc(fgetc(f), stdout); } + fclose(f); + exit(2); + } + fclose(f); +} + +int main(void) +{ + M_LET(emps, vector_employee_t) { + /* Code to populate database from JSON */ + read(emps, "ex11-algo02.json"); + + // Sort the database by employee ID number + M_LET( (cmp, STRING_CTE("idnum")), compare_by_t ) + vector_employee_sort_fo(emps, compare_by_as_interface(cmp)); + printf("Employees sorted by idnum are: "); + vector_employee_out_str(stdout, emps); + + M_LET( (cmp, STRING_CTE("name")), compare_by_t ) + vector_employee_sort_fo(emps, compare_by_as_interface(cmp)); + printf("\nEmployees sorted by name are: "); + vector_employee_out_str(stdout, emps); + printf("\n"); + } + return 0; +} diff --git a/example/ex11-algo02.json b/example/ex11-algo02.json new file mode 100644 index 00000000..222448c4 --- /dev/null +++ b/example/ex11-algo02.json @@ -0,0 +1,9 @@ +[ + { "name": "John Doe", "age": 32, "idnum": 14528}, + { "name": "Clint Smith", "age": 31, "idnum": 14529}, + { "name": "Linda Cameron", "age": 20, "idnum": 14527}, + { "name": "Cameron Carrey", "age": 25, "idnum": 14526}, + { "name": "Marty Brown", "age": 26, "idnum": 14525}, + { "name": "Donald Cow", "age": 45, "idnum": 14520} +] +