diff options
author | Marko Kiiskila <marko@runtime.io> | 2016-06-09 16:34:13 -0700 |
---|---|---|
committer | Marko Kiiskila <marko@runtime.io> | 2016-06-09 16:34:13 -0700 |
commit | e25d0688435efb43845dd563c69dbf0d6a417168 (patch) | |
tree | f649dc2679b0d0dae7229bda8524a783f281b372 /sys | |
parent | 4b48c4412643361e0ef25088f43e3c30b6034319 (diff) |
config; configurable number of lines of config before compression.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/config/include/config/config_file.h | 7 | ||||
-rw-r--r-- | sys/config/src/config_file.c | 135 |
2 files changed, 97 insertions, 45 deletions
diff --git a/sys/config/include/config/config_file.h b/sys/config/include/config/config_file.h index 73d4a3ad..aa051a1d 100644 --- a/sys/config/include/config/config_file.h +++ b/sys/config/include/config/config_file.h @@ -21,13 +21,14 @@ #include "config/config.h" -#define CONF_FILE_NAME_MAX 32 /* max length for config filename */ +#define CONF_FILE_NAME_MAX 32 /* max length for config filename */ struct fs_file; struct conf_file { struct conf_store cf_store; - const char *cf_name; - struct fs_file *cf_save_fp; + const char *cf_name; /* filename */ + int cf_maxlines; /* max # of lines before compressing */ + int cf_lines; /* private */ }; int conf_file_src(struct conf_file *); /* register file to be source of cfg */ diff --git a/sys/config/src/config_file.c b/sys/config/src/config_file.c index 850772a6..0012fcab 100644 --- a/sys/config/src/config_file.c +++ b/sys/config/src/config_file.c @@ -63,7 +63,6 @@ conf_file_dst(struct conf_file *cf) if (!cf->cf_name) { return OS_INVALID_PARM; } - cf->cf_save_fp = NULL; cf->cf_store.cs_itf = &conf_file_itf; conf_dst_register(&cf->cf_store); @@ -117,6 +116,7 @@ conf_file_load(struct conf_store *cs, load_cb cb, void *cb_arg) char *name_str; char *val_str; int rc; + int lines; rc = fs_open(cf->cf_name, FS_ACCESS_READ, &file); if (rc != FS_EOK) { @@ -124,6 +124,7 @@ conf_file_load(struct conf_store *cs, load_cb cb, void *cb_arg) } loc = 0; + lines = 0; while (1) { rc = conf_getnext_line(file, tmpbuf, sizeof(tmpbuf), &loc); if (loc == 0) { @@ -136,9 +137,11 @@ conf_file_load(struct conf_store *cs, load_cb cb, void *cb_arg) if (rc != 0) { continue; } + lines++; cb(name_str, val_str, cb_arg); } fs_close(file); + cf->cf_lines = lines; return OS_OK; } @@ -159,21 +162,88 @@ conf_tmpfile(char *dst, const char *src, char *pfx) } /* - * Called to save configuration. + * Try to compress configuration file by keeping unique names only. */ -static int -conf_file_save_start(struct conf_store *cs) +void +conf_file_compress(struct conf_file *cf) { - struct conf_file *cf = (struct conf_file *)cs; - char name[CONF_FILE_NAME_MAX]; + int rc; + struct fs_file *rf; + struct fs_file *wf; + char tmp_file[CONF_FILE_NAME_MAX]; + char buf1[CONF_MAX_NAME_LEN + CONF_MAX_VAL_LEN + 32]; + char buf2[CONF_MAX_NAME_LEN + CONF_MAX_VAL_LEN + 32]; + uint32_t loc1, loc2; + char *name1, *val1; + char *name2, *val2; + int copy; + int len, len2; + int lines; + + if (fs_open(cf->cf_name, FS_ACCESS_READ, &rf) != FS_EOK) { + return; + } + conf_tmpfile(tmp_file, cf->cf_name, ".cmp"); + if (fs_open(tmp_file, FS_ACCESS_WRITE | FS_ACCESS_TRUNCATE, &wf)) { + fs_close(rf); + return; + } - assert(cf->cf_save_fp == NULL); - conf_tmpfile(name, cf->cf_name, ".tmp"); + loc1 = 0; + lines = 0; + while (1) { + len = conf_getnext_line(rf, buf1, sizeof(buf1), &loc1); + if (loc1 == 0 || len < 0) { + break; + } + rc = conf_line_parse(buf1, &name1, &val1); + if (rc) { + continue; + } + loc2 = loc1; + copy = 1; + while ((len2 = conf_getnext_line(rf, buf2, sizeof(buf2), &loc2)) > 0) { + rc = conf_line_parse(buf2, &name2, &val2); + if (rc) { + continue; + } + if (!strcmp(name1, name2)) { + copy = 0; + break; + } + } + if (!copy) { + continue; + } - if (fs_open(name, FS_ACCESS_WRITE | FS_ACCESS_TRUNCATE, &cf->cf_save_fp)) { - return OS_EINVAL; + /* + * Can't find one. Must copy. + */ + len = conf_line_make(buf2, sizeof(buf2), name1, val1); + if (len < 0 || len + 2 > sizeof(buf2)) { + continue; + } + buf2[len++] = '\n'; + fs_write(wf, buf2, len); + lines++; } + fs_close(wf); + fs_close(rf); + fs_unlink(cf->cf_name); + fs_rename(tmp_file, cf->cf_name); + cf->cf_lines = lines; + /* + * XXX at conf_file_load(), look for .cmp if actual file does not + * exist. + */ +} +/* + * Called to save configuration. + */ +static int +conf_file_save_start(struct conf_store *cs) +{ return OS_OK; } @@ -190,56 +260,37 @@ conf_file_save(struct conf_store *cs, const char *name, const char *value) return OS_INVALID_PARM; } + if (cf->cf_maxlines && (cf->cf_lines + 1 >= cf->cf_maxlines)) { + /* + * Compress before config file size exceeds the max number of lines. + */ + conf_file_compress(cf); + } len = conf_line_make(buf, sizeof(buf), name, value); if (len < 0 || len + 2 > sizeof(buf)) { return OS_INVALID_PARM; } buf[len++] = '\n'; - if (cf->cf_save_fp) { - file = cf->cf_save_fp; - } else { - /* - * Open the file to add this one value. - */ - if (fs_open(cf->cf_name, FS_ACCESS_WRITE | FS_ACCESS_APPEND, &file)) { - return OS_EINVAL; - } + /* + * Open the file to add this one value. + */ + if (fs_open(cf->cf_name, FS_ACCESS_WRITE | FS_ACCESS_APPEND, &file)) { + return OS_EINVAL; } if (fs_write(file, buf, len)) { rc = OS_EINVAL; } else { rc = 0; + cf->cf_lines++; } - if (!cf->cf_save_fp) { - fs_close(file); - } + fs_close(file); return rc; } static int conf_file_save_end(struct conf_store *cs) { - struct conf_file *cf = (struct conf_file *)cs; - char tmp_name[CONF_FILE_NAME_MAX]; - int rc; - - fs_close(cf->cf_save_fp); - cf->cf_save_fp = NULL; - - fs_unlink(cf->cf_name); - - conf_tmpfile(tmp_name, cf->cf_name, ".tmp"); - - rc = fs_rename(tmp_name, cf->cf_name); - if (rc && rc != FS_ENOENT) { - return OS_EINVAL; - } - - /* - * XXX at conf_file_load(), look for .tmp if actual file does not - * exist. - */ return OS_OK; } |