LCOV - code coverage report
Current view: top level - jsmods - storage.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 80 91 87.9 %
Date: 2021-04-29 23:48:07 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /*
       2             :  *                      GPAC - Multimedia Framework C SDK
       3             :  *
       4             :  *                      Authors: Jean Le Feuvre
       5             :  *                      Copyright (c) Telecom ParisTech 2007-2019
       6             :  *                      All rights reserved
       7             :  *
       8             :  *  This file is part of GPAC / JavaScript Storage bindings
       9             :  *
      10             :  *  GPAC is free software; you can redistribute it and/or modify
      11             :  *  it under the terms of the GNU Lesser General Public License as published by
      12             :  *  the Free Software Foundation; either version 2, or (at your option)
      13             :  *  any later version.
      14             :  *
      15             :  *  GPAC is distributed in the hope that it will be useful,
      16             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :  *  GNU Lesser General Public License for more details.
      19             :  *
      20             :  *  You should have received a copy of the GNU Lesser General Public
      21             :  *  License along with this library; see the file COPYING.  If not, write to
      22             :  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
      23             :  *
      24             :  */
      25             : 
      26             : /*
      27             :         ANY CHANGE TO THE API MUST BE REFLECTED IN THE DOCUMENTATION IN gpac/share/doc/idl/storage.js
      28             :         (no way to define inline JS doc with doxygen)
      29             : */
      30             : 
      31             : #include <gpac/setup.h>
      32             : 
      33             : #ifdef GPAC_HAS_QJS
      34             : 
      35             : #include <gpac/config_file.h>
      36             : #include "../scenegraph/qjs_common.h"
      37             : 
      38             : 
      39             : static JSClassID storage_class_id = 0;
      40             : GF_List *all_storages = NULL;
      41             : 
      42           9 : static void storage_finalize(JSRuntime *rt, JSValue obj)
      43             : {
      44           9 :         GF_Config *cfg = JS_GetOpaque(obj, storage_class_id);
      45           9 :         if (!cfg) return;
      46           5 :         if (all_storages) {
      47           4 :                 gf_list_del_item(all_storages, cfg);
      48           4 :                 if (!gf_list_count(all_storages)) {
      49           4 :                         gf_list_del(all_storages);
      50           4 :                         all_storages = NULL;
      51             :                 }
      52             :         }
      53           5 :         gf_cfg_del(cfg);
      54             : }
      55             : 
      56             : JSClassDef storageClass = {
      57             :     "Storage",
      58             :     .finalizer = storage_finalize,
      59             : };
      60             : 
      61             : 
      62          13 : static JSValue js_storage_get_option(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
      63             : {
      64             :         const char *opt = NULL;
      65             :         const char *sec_name, *key_name;
      66          13 :         s32 idx = -1;
      67          13 :         GF_Config *config = JS_GetOpaque(this_val, storage_class_id);
      68          13 :         if (!config) return JS_EXCEPTION;
      69          13 :         if (argc < 2) return JS_EXCEPTION;
      70             : 
      71          26 :         if (!JS_IsString(argv[0])) return JS_EXCEPTION;
      72          26 :         if (!JS_IsString(argv[1]) && !JS_IsInteger(argv[1])) return JS_EXCEPTION;
      73             : 
      74             :         sec_name = JS_ToCString(ctx, argv[0]);
      75          13 :         if (!strcmp(sec_name, "GPAC")) {
      76           0 :                 JS_FreeCString(ctx, sec_name);
      77           0 :                 return js_throw_err_msg(ctx, GF_BAD_PARAM, "Cannot access section 'GPAC' from script\n");
      78             :         }
      79             : 
      80             :         key_name = NULL;
      81          26 :         if (JS_IsInteger(argv[1])) {
      82           0 :                 JS_ToInt32(ctx, &idx, argv[1]);
      83          13 :         } else if (JS_IsString(argv[1]) ) {
      84             :                 key_name = JS_ToCString(ctx, argv[1]);
      85             :         }
      86             : 
      87          13 :         if (key_name) {
      88          13 :                 opt = gf_cfg_get_key(config, sec_name, key_name);
      89           0 :         } else if (idx>=0) {
      90           0 :                 opt = gf_cfg_get_key_name(config, sec_name, idx);
      91             :         } else {
      92             :                 opt = NULL;
      93             :         }
      94             : 
      95          13 :         JS_FreeCString(ctx, key_name);
      96          13 :         JS_FreeCString(ctx, sec_name);
      97             : 
      98          13 :         if (opt) {
      99           1 :                 return JS_NewString(ctx, opt);
     100             :         }
     101          12 :         return JS_NULL;
     102             : }
     103             : 
     104          14 : static JSValue js_storage_set_option(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
     105             : {
     106             :         const char *sec_name, *key_name, *key_val;
     107          14 :         GF_Config *config = JS_GetOpaque(this_val, storage_class_id);
     108          14 :         if (!config) return JS_EXCEPTION;
     109          14 :         if (argc < 3) return JS_EXCEPTION;
     110             : 
     111          28 :         if (!JS_IsString(argv[0])) return JS_EXCEPTION;
     112          28 :         if (!JS_IsString(argv[1])) return JS_EXCEPTION;
     113             : 
     114             :         sec_name = JS_ToCString(ctx, argv[0]);
     115          14 :         if (!strcmp(sec_name, "GPAC")) {
     116           0 :                 JS_FreeCString(ctx, sec_name);
     117           0 :                 return js_throw_err_msg(ctx, GF_BAD_PARAM, "Cannot access section 'GPAC' from script\n");
     118             :         }
     119             :         key_name = JS_ToCString(ctx, argv[1]);
     120             :         key_val = NULL;
     121          28 :         if (JS_IsString(argv[2]))
     122             :                 key_val = JS_ToCString(ctx, argv[2]);
     123             : 
     124          14 :         gf_cfg_set_key(config, sec_name, key_name, key_val);
     125             : 
     126          14 :         JS_FreeCString(ctx, sec_name);
     127          14 :         JS_FreeCString(ctx, key_name);
     128          14 :         JS_FreeCString(ctx, key_val);
     129          14 :         return JS_UNDEFINED;
     130             : }
     131             : 
     132          14 : static JSValue js_storage_save(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
     133             : {
     134          14 :         GF_Config *config = JS_GetOpaque(this_val, storage_class_id);
     135          14 :         if (!config) return JS_EXCEPTION;
     136          14 :         gf_cfg_save(config);
     137          14 :         return JS_UNDEFINED;
     138             : }
     139             : 
     140             : static const JSCFunctionListEntry storage_funcs[] = {
     141             :         JS_CFUNC_DEF("get_option", 0, js_storage_get_option),
     142             :         JS_CFUNC_DEF("set_option", 0, js_storage_set_option),
     143             :         JS_CFUNC_DEF("save", 0, js_storage_save),
     144             : };
     145             : 
     146           5 : static JSValue storage_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv)
     147             : {
     148             :         char szFile[GF_MAX_PATH];
     149             :         JSValue anobj;
     150             :         GF_Config *storage = NULL;
     151             :         const char *storage_url = NULL;
     152             :         u32 i, count;
     153             :         u8 hash[20];
     154             :         char temp[3];
     155             : 
     156          10 :         if (!JS_IsString(argv[0]) )
     157           0 :                 return JS_EXCEPTION;
     158             : 
     159             :         storage_url = JS_ToCString(ctx, argv[0]);
     160           5 :         if (!storage_url) return JS_NULL;
     161             : 
     162           5 :         szFile[0]=0;
     163           5 :         gf_sha1_csum((u8 *)storage_url, (u32) strlen(storage_url), hash);
     164         105 :         for (i=0; i<20; i++) {
     165         100 :                 sprintf(temp, "%02X", hash[i]);
     166             :                 strcat(szFile, temp);
     167             :         }
     168             :         strcat(szFile, ".cfg");
     169             : 
     170           5 :         count = gf_list_count(all_storages);
     171           5 :         for (i=0; i<count; i++) {
     172           0 :                 GF_Config *a_cfg = gf_list_get(all_storages, i);
     173           0 :                 const char *cfg_name = gf_cfg_get_filename(a_cfg);
     174             : 
     175           0 :                 if (strstr(cfg_name, szFile)) {
     176             :                         storage = a_cfg;
     177             :                         break;
     178             :                 }
     179             :         }
     180             : 
     181           5 :         if (!storage) {
     182           5 :                 const char *storage_dir = gf_opts_get_key("core", "store-dir");
     183             : 
     184           5 :                 storage = gf_cfg_force_new(storage_dir, szFile);
     185           5 :                 if (storage) {
     186           5 :                         gf_cfg_set_key(storage, "GPAC", "StorageURL", storage_url);
     187           5 :                         gf_list_add(all_storages, storage);
     188             :                 }
     189             :         }
     190             : 
     191           5 :         JS_FreeCString(ctx, storage_url);
     192             : 
     193           5 :         anobj = JS_NewObjectClass(ctx, storage_class_id);
     194           5 :         if (JS_IsException(anobj)) return anobj;
     195           5 :         JS_SetOpaque(anobj, storage);
     196           5 :         return anobj;
     197             : }
     198             : 
     199           4 : static int js_storage_init(JSContext *c, JSModuleDef *m)
     200             : {
     201           4 :         if (!storage_class_id) {
     202           4 :                 JS_NewClassID(&storage_class_id);
     203           4 :                 JS_NewClass(JS_GetRuntime(c), storage_class_id, &storageClass);
     204             : 
     205             :                 assert(!all_storages);
     206           4 :                 all_storages = gf_list_new();
     207             :         }
     208             : 
     209           4 :         JSValue proto = JS_NewObjectClass(c, storage_class_id);
     210           4 :         JS_SetPropertyFunctionList(c, proto, storage_funcs, countof(storage_funcs));
     211           4 :         JS_SetClassProto(c, storage_class_id, proto);
     212             : 
     213           4 :         JSValue ctor = JS_NewCFunction2(c, storage_constructor, "Storage", 1, JS_CFUNC_constructor, 0);
     214           4 :     JS_SetModuleExport(c, m, "Storage", ctor);
     215           4 :         return 0;
     216             : }
     217             : 
     218             : 
     219         468 : void qjs_module_init_storage(JSContext *ctx)
     220             : {
     221             :         JSModuleDef *m;
     222         468 :         m = JS_NewCModule(ctx, "storage", js_storage_init);
     223         468 :         if (!m) return;
     224             : 
     225         468 :         JS_AddModuleExport(ctx, m, "Storage");
     226         468 :         return;
     227             : }
     228             : 
     229             : 
     230             : #endif
     231             : 

Generated by: LCOV version 1.13