X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fappfwk.c;h=0ede96aa0c5579c8c5bae272acb1dd19781c5f08;hb=6c6177fcf8fdcc62c42a18407e95c7577897e10c;hp=6dc7182fbc8f1a709ffed77eaa5e65c61473399b;hpb=f3d64b7c741677cd28e2a11deed67196cd02b46a;p=src%2Fapp-framework-main.git diff --git a/src/appfwk.c b/src/appfwk.c index 6dc7182..0ede96a 100644 --- a/src/appfwk.c +++ b/src/appfwk.c @@ -23,17 +23,21 @@ #include #include -#include +#include -struct stringset { - int count; - char **strings; +#include + +struct afapps { + struct json_object *pubarr; + struct json_object *direct; + struct json_object *byapp; }; - struct appfwk { int refcount; - struct stringset paths; + int nrroots; + char **roots; + struct afapps applications; }; struct appfwk *appfwk_create() @@ -43,8 +47,11 @@ struct appfwk *appfwk_create() errno = ENOMEM; else { appfwk->refcount = 1; - appfwk->paths.count = 0; - appfwk->paths.strings = NULL; + appfwk->nrroots = 0; + appfwk->roots = NULL; + appfwk->applications.pubarr = NULL; + appfwk->applications.direct = NULL; + appfwk->applications.byapp = NULL; } return appfwk; } @@ -59,8 +66,9 @@ void appfwk_unref(struct appfwk *appfwk) { assert(appfwk); if (!--appfwk->refcount) { - while (appfwk->paths.count) - free(appfwk->paths.strings[--appfwk->paths.count]); + while (appfwk->nrroots) + free(appfwk->roots[--appfwk->nrroots]); + free(appfwk->roots); free(appfwk); } } @@ -69,19 +77,23 @@ int appfwk_add_root(struct appfwk *appfwk, const char *path) { int i, n; char *r, **roots; + assert(appfwk); + + /* don't depend on the cwd and unique name */ r = realpath(path, NULL); if (!r) return -1; /* avoiding duplications */ - n = appfwk->paths.count; - roots = appfwk->paths.strings; - for (i = 0 ; i < n ; i++) + n = appfwk->nrroots; + roots = appfwk->roots; + for (i = 0 ; i < n ; i++) { if (!strcmp(r, roots[i])) { free(r); return 0; } + } /* add */ roots = realloc(roots, (n + 1) * sizeof(roots[0])); @@ -91,92 +103,165 @@ int appfwk_add_root(struct appfwk *appfwk, const char *path) return -1; } roots[n++] = r; - appfwk->paths.strings = roots; - appfwk->paths.count = n; + appfwk->roots = roots; + appfwk->nrroots = n; return 0; } -struct aea { - char *path; - char *appver; - char *ver; - const char *root; - const char *appid; - const char *version; - int (*callback)(struct wgt *wgt, void *data); - void *data; -}; - -struct appfwk_enumerate_applications_context { - const char *dirpath; - const char *appid; - const char *version; - - void *data; -}; +static int json_add(struct json_object *obj, const char *key, struct json_object *val) +{ + json_object_object_add(obj, key, val); + return 0; +} -inline int testd(int dirfd, struct dirent *e) +static int json_add_str(struct json_object *obj, const char *key, const char *val) { - return e->d_name[0] != '.' || (e->d_name[1] && (e->d_name[1] != '.' || e->d_name[2])); + struct json_object *str = json_object_new_string (val ? val : ""); + return str ? json_add(obj, key, str) : -1; } -#include -static int aea3(int dirfd, struct aea *aea) +static int json_add_int(struct json_object *obj, const char *key, int val) { - printf("aea3 %s *** %s *** %s\n", aea->path, aea->appver, aea->ver); - return 0; + struct json_object *v = json_object_new_int (val); + return v ? json_add(obj, key, v) : -1; } -static int aea2(int dirfd, struct aea *aea) +static int addapp(struct afapps *apps, const char *path) { - DIR *dir; - int rc, fd; - struct dirent entry, *e; + struct wgt_info *info; + const struct wgt_desc *desc; + const struct wgt_desc_feature *feat; + struct json_object *priv = NULL, *pub, *bya, *plugs, *str; + char *appid, *end; - dir = fdopendir(dirfd); - if (!dir) - return -1; + /* connect to the widget */ + info = wgt_info_createat(AT_FDCWD, path, 0, 1, 0); + if (info == NULL) + goto error; + desc = wgt_info_desc(info); - aea->version = entry.d_name; + /* create the application id */ + appid = alloca(2 + strlen(desc->id) + strlen(desc->version)); + end = stpcpy(appid, desc->id); + *end++ = '@'; + strcpy(end, desc->version); - rc = readdir_r(dir, &entry, &e); - while (!rc && e) { - if (testd(dirfd, &entry)) { - fd = openat(dirfd, entry.d_name, O_DIRECTORY|O_RDONLY); - if (fd >= 0) { - strcpy(aea->ver, entry.d_name); - rc = aea3(fd, aea); - close(fd); + /* create the application structure */ + priv = json_object_new_object(); + if (!priv) + goto error2; + + pub = json_object_new_object(); + if (!priv) + goto error2; + + if (json_add(priv, "public", pub)) { + json_object_put(pub); + goto error2; + } + + plugs = json_object_new_array(); + if (!priv) + goto error2; + + if (json_add(priv, "plugins", plugs)) { + json_object_put(plugs); + goto error2; + } + + if(json_add_str(pub, "id", appid) + || json_add_str(priv, "id", desc->id) + || json_add_str(pub, "version", desc->version) + || json_add_str(priv, "path", path) + || json_add_int(pub, "width", desc->width) + || json_add_int(pub, "height", desc->height) + || json_add_str(pub, "name", desc->name) + || json_add_str(pub, "description", desc->description) + || json_add_str(pub, "shortname", desc->name_short) + || json_add_str(pub, "author", desc->author)) + goto error2; + + feat = desc->features; + while (feat) { + static const char prefix[] = FWK_PREFIX_PLUGIN; + if (!memcmp(feat->name, prefix, sizeof prefix - 1)) { + str = json_object_new_string (feat->name + sizeof prefix - 1); + if (str == NULL) + goto error2; + if (json_object_array_add(plugs, str)) { + json_object_put(str); + goto error2; } - } - rc = readdir_r(dir, &entry, &e); + } + feat = feat->next; } - closedir(dir); - return rc; + + /* record the application structure */ + if (!json_object_object_get_ex(apps->byapp, desc->id, &bya)) { + bya = json_object_new_object(); + if (!bya) + goto error2; + if (json_add(apps->byapp, desc->id, bya)) { + json_object_put(bya); + goto error2; + } + } + + if (json_add(apps->direct, appid, priv)) + goto error2; + json_object_get(priv); + + if (json_add(bya, desc->version, priv)) { + json_object_put(priv); + goto error2; + } + + if (json_object_array_add(apps->pubarr, pub)) + goto error2; + + wgt_info_unref(info); + return 0; + +error2: + json_object_put(priv); + wgt_info_unref(info); +error: + return -1; } -static int aea1(int dirfd, struct aea *aea) +struct enumdata { + char path[PATH_MAX]; + int length; + struct afapps apps; +}; + +static int enumentries(struct enumdata *data, int (*callto)(struct enumdata *)) { DIR *dir; - int rc, fd; + int rc; + char *beg, *end; struct dirent entry, *e; - dir = fdopendir(dirfd); + /* opens the directory */ + dir = opendir(data->path); if (!dir) return -1; - aea->appid = entry.d_name; + /* prepare appending entry names */ + beg = data->path + data->length; + *beg++ = '/'; + /* enumerate entries */ rc = readdir_r(dir, &entry, &e); while (!rc && e) { - if (testd(dirfd, &entry)) { - fd = openat(dirfd, entry.d_name, O_DIRECTORY|O_RDONLY); - if (fd >= 0) { - aea->ver = stpcpy(aea->appver, entry.d_name); - *aea->ver++ = '/'; - rc = aea2(fd, aea); - close(fd); - } + if (entry.d_name[0] != '.' || (entry.d_name[1] && (entry.d_name[1] != '.' || entry.d_name[2]))) { + /* prepare callto */ + end = stpcpy(beg, entry.d_name); + data->length = end - data->path; + /* call the function */ + rc = callto(data); + if (rc) + break; } rc = readdir_r(dir, &entry, &e); } @@ -184,41 +269,77 @@ static int aea1(int dirfd, struct aea *aea) return rc; } -int appfwk_enumerate_applications(struct appfwk *appfwk, int (*callback)(struct wgt *wgt, void *data), void *data) +static int recordapp(struct enumdata *data) { - int rc, iroot, nroots; - char **roots; - int fd; - char buffer[PATH_MAX]; - struct aea aea; - - aea.callback = callback; - aea.data = data; - aea.path = buffer; - - nroots = appfwk->paths.count; - roots = appfwk->paths.strings; - for (iroot = 0 ; iroot < nroots ; iroot++) { - aea.root = roots[iroot]; - fd = openat(AT_FDCWD, aea.root, O_DIRECTORY|O_RDONLY); - if (fd >= 0) { - aea.appver = stpcpy(buffer, aea.root); - *aea.appver++ = '/'; - rc = aea1(fd, &aea); - close(fd); - } + return addapp(&data->apps, data->path); +} + +/* enumerate the versions */ +static int enumvers(struct enumdata *data) +{ + int rc = enumentries(data, recordapp); + return !rc || errno != ENOTDIR ? 0 : rc; +} + +/* regenerate the list of applications */ +int appfwk_update_applications(struct appfwk *af) +{ + int rc, iroot; + struct enumdata edata; + struct afapps oldapps; + + /* create the result */ + edata.apps.pubarr = json_object_new_array(); + edata.apps.direct = json_object_new_object(); + edata.apps.byapp = json_object_new_object(); + if (edata.apps.pubarr == NULL || edata.apps.direct == NULL || edata.apps.byapp == NULL) { + errno = ENOMEM; + goto error; } + /* for each root */ + for (iroot = 0 ; iroot < af->nrroots ; iroot++) { + edata.length = stpcpy(edata.path, af->roots[iroot]) - edata.path; + assert(edata.length < sizeof edata.path); + /* enumerate the applications */ + rc = enumentries(&edata, enumvers); + if (rc) + goto error; + } + /* commit the result */ + oldapps = af->applications; + af->applications = edata.apps; + json_object_put(oldapps.pubarr); + json_object_put(oldapps.direct); + json_object_put(oldapps.byapp); return 0; + +error: + json_object_put(edata.apps.pubarr); + json_object_put(edata.apps.direct); + json_object_put(edata.apps.byapp); + return -1; +} + +int appfwk_ensure_applications(struct appfwk *af) +{ + return af->applications.pubarr ? 0 : appfwk_update_applications(af); +} + +/* regenerate the list of applications */ +struct json_object *appfwk_application_list(struct appfwk *af) +{ + return appfwk_ensure_applications(af) ? NULL : af->applications.pubarr; +} + +#include +int main() +{ +struct appfwk *af = appfwk_create(); +appfwk_add_root(af,FWK_APP_DIR); +appfwk_update_applications(af); +printf("array = %s\n", json_object_to_json_string_ext(af->applications.pubarr, 3)); +printf("direct = %s\n", json_object_to_json_string_ext(af->applications.direct, 3)); +printf("byapp = %s\n", json_object_to_json_string_ext(af->applications.byapp, 3)); +return 0; } -/* - struct wgt *wgt; - wgt = wgt_create(); - if (!wgt) - return -1; - wgt_unref(wgt); - - rfd = AT_FDCWD; - if (pathname) { - rfd = openat(rfd, pathname, O_PATH|O_DIRECTORY); -*/