X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafm-udb.c;h=7f4a16ea783372a2e0a6188be945f5c3d3a4b7ff;hb=1bb3f2601e862b72cbc6c6dabf515ad9f2f6ad1e;hp=718aa5c3759a48eeda4695ae43e8e56c305fce5b;hpb=1867d049f8a3b181bb920fef6d904cfa67de06f0;p=src%2Fapp-framework-main.git diff --git a/src/afm-udb.c b/src/afm-udb.c index 718aa5c..7f4a16e 100644 --- a/src/afm-udb.c +++ b/src/afm-udb.c @@ -1,5 +1,5 @@ /* - Copyright 2015, 2016, 2017 IoT.bzh + Copyright (C) 2015-2018 IoT.bzh author: José Bollo @@ -78,6 +78,11 @@ struct afm_updt { struct afm_apps applications; }; +/* + * The default language + */ +static char *default_lang; + /* * Release the data of the afm_apps object 'apps'. */ @@ -112,7 +117,7 @@ static int append_field( array = json_object_new_array(); if (!array) goto error; - json_object_array_add(array, item); + json_object_array_add(array, json_object_get(item)); json_object_object_add(object, name, array); } json_object_array_add(array, data); @@ -177,17 +182,25 @@ static int add_fields_of_content( { char *name, *value, *read, *write; - read = strstr(content, x_afm_prefix); - while (read) { + /* start at the beginning */ + read = content; + for (;;) { + /* search the next key */ + read = strstr(read, x_afm_prefix); + if (!read) + return 0; + + /* search to equal */ name = read + x_afm_prefix_length; value = strchr(name, '='); if (value == NULL) - read = strstr(name, x_afm_prefix); + read = name; /* not found */ else { + /* get the value (translate it) */ *value++ = 0; read = write = value; while(*read && *read != '\n') { - if (read[0] != '\\') + if (*read != '\\') *write++ = *read++; else { switch(*++read) { @@ -198,13 +211,14 @@ static int add_fields_of_content( read += !!*read; } } - read = strstr(read, x_afm_prefix); + read += !!*read; *write = 0; + + /* add the found field now */ if (add_field(priv, pub, name, value) < 0) return -1; } } - return 0; } /* @@ -270,64 +284,76 @@ error: } /* - * read a unit file + * Crop and trim unit 'content' of 'length'. Return the new length. */ -static int read_unit_file(const char *path, char **content, size_t *length) +static size_t crop_and_trim_unit_content(char *content, size_t length) { - int rc, st; + int st; char c, *read, *write; - /* read the file */ - rc = getfile(path, content, length); - if (rc >= 0) { - /* removes any comment and join continued lines */ - st = 0; - read = write = *content; - for (;;) { - do { c = *read++; } while (c == '\r'); - if (!c) + /* removes any comment and join continued lines */ + st = 0; + read = write = content; + for (;;) { + do { c = *read++; } while (c == '\r'); + if (!c) + break; + switch (st) { + case 0: + /* state 0: begin of a line */ + if (c == ';' || c == '#') { + st = 3; /* removes lines starting with ; or # */ break; - switch (st) { - case 0: - /* state 0: begin of a line */ - if (c == ';' || c == '#') { - st = 3; /* removes lines starting with ; or # */ - break; - } - if (c == '\n') - break; /* removes empty lines */ + } + if (c == '\n') + break; /* removes empty lines */ enter_state_1: - st = 1; - /*@fallthrough@*/ - case 1: - /* state 1: emitting a normal line */ - if (c == '\\') - st = 2; - else { - *write++ = c; - if (c == '\n') - st = 0; - } - break; - case 2: - /* state 2: character after '\' */ - if (c == '\n') - c = ' '; - else - *write++ = '\\'; - goto enter_state_1; - case 3: - /* state 3: inside a comment, wait its end */ + st = 1; + /*@fallthrough@*/ + case 1: + /* state 1: emitting a normal line */ + if (c == '\\') + st = 2; + else { + *write++ = c; if (c == '\n') st = 0; - break; } + break; + case 2: + /* state 2: character after '\' */ + if (c == '\n') + c = ' '; + else + *write++ = '\\'; + goto enter_state_1; + case 3: + /* state 3: inside a comment, wait its end */ + if (c == '\n') + st = 0; + break; } - if (st == 1) - *write++ = '\n'; - *write = 0; - *length = (size_t)(write - *content); - *content = realloc(*content, *length + 1); + } + if (st == 1) + *write++ = '\n'; + *write = 0; + return (size_t)(write - content); +} + +/* + * read a unit file + */ +static int read_unit_file(const char *path, char **content, size_t *length) +{ + int rc; + size_t nl; + + /* read the file */ + rc = getfile(path, content, length); + if (rc >= 0) { + /* crop and trim it */ + *length = nl = crop_and_trim_unit_content(*content, *length); + *content = realloc(*content, nl + 1); } return rc; } @@ -460,15 +486,25 @@ int afm_udb_update(struct afm_udb *afudb) tmp = afudb->applications; afudb->applications = updt.applications; apps_put(&tmp); - afm_udb_addref(afudb); + afm_udb_unref(afudb); return 0; error: apps_put(&updt.applications); - afm_udb_addref(afudb); + afm_udb_unref(afudb); return -1; } +/* + * set the default language to 'lang' + */ +void afm_udb_set_default_lang(const char *lang) +{ + char *oldval = default_lang; + default_lang = lang ? strdup(lang) : NULL; + free(oldval); +} + /* * Get the list of the applications private data of the afm_udb object 'afudb'. * The list is returned as a JSON-array that must be released using @@ -486,7 +522,7 @@ struct json_object *afm_udb_applications_private(struct afm_udb *afudb, int uid) * 'json_object_put'. * Returns NULL in case of error. */ -struct json_object *afm_udb_applications_public(struct afm_udb *afudb, int uid) +struct json_object *afm_udb_applications_public(struct afm_udb *afudb, int uid, const char *lang) { return json_object_get(afudb->applications.pubarr); } @@ -496,7 +532,7 @@ struct json_object *afm_udb_applications_public(struct afm_udb *afudb, int uid) * It returns a JSON-object that must be released using 'json_object_put'. * Returns NULL in case of error. */ -static struct json_object *get_no_case(struct json_object *object, const char *id, int uid) +static struct json_object *get_no_case(struct json_object *object, const char *id, int uid, const char *lang) { struct json_object *result; struct json_object_iter i; @@ -520,7 +556,7 @@ static struct json_object *get_no_case(struct json_object *object, const char *i */ struct json_object *afm_udb_get_application_private(struct afm_udb *afudb, const char *id, int uid) { - return get_no_case(afudb->applications.prvobj, id, uid); + return get_no_case(afudb->applications.prvobj, id, uid, NULL); } /* @@ -529,9 +565,9 @@ struct json_object *afm_udb_get_application_private(struct afm_udb *afudb, const * Returns NULL in case of error. */ struct json_object *afm_udb_get_application_public(struct afm_udb *afudb, - const char *id, int uid) + const char *id, int uid, const char *lang) { - return get_no_case(afudb->applications.pubobj, id, uid); + return get_no_case(afudb->applications.pubobj, id, uid, lang); }