diff -r 92e482410453 -r d345541018fa src/properties.c --- a/src/properties.c Mon Dec 30 09:54:10 2019 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,264 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "ucx/properties.h" - -#include -#include -#include - -UcxProperties *ucx_properties_new() { - UcxProperties *parser = (UcxProperties*)malloc( - sizeof(UcxProperties)); - if(!parser) { - return NULL; - } - - parser->buffer = NULL; - parser->buflen = 0; - parser->pos = 0; - parser->tmp = NULL; - parser->tmplen = 0; - parser->tmpcap = 0; - parser->error = 0; - parser->delimiter = '='; - parser->comment1 = '#'; - parser->comment2 = 0; - parser->comment3 = 0; - - return parser; -} - -void ucx_properties_free(UcxProperties *parser) { - if(parser->tmp) { - free(parser->tmp); - } - free(parser); -} - -void ucx_properties_fill(UcxProperties *parser, char *buf, size_t len) { - parser->buffer = buf; - parser->buflen = len; - parser->pos = 0; -} - -static void parser_tmp_append(UcxProperties *parser, char *buf, size_t len) { - if(parser->tmpcap - parser->tmplen < len) { - size_t newcap = parser->tmpcap + len + 64; - parser->tmp = (char*)realloc(parser->tmp, newcap); - parser->tmpcap = newcap; - } - memcpy(parser->tmp + parser->tmplen, buf, len); - parser->tmplen += len; -} - -int ucx_properties_next(UcxProperties *parser, sstr_t *name, sstr_t *value) { - if(parser->tmplen > 0) { - char *buf = parser->buffer + parser->pos; - size_t len = parser->buflen - parser->pos; - sstr_t str = sstrn(buf, len); - sstr_t nl = sstrchr(str, '\n'); - if(nl.ptr) { - size_t newlen = (size_t)(nl.ptr - buf) + 1; - parser_tmp_append(parser, buf, newlen); - // the tmp buffer contains exactly one line now - - char *orig_buf = parser->buffer; - size_t orig_len = parser->buflen; - - parser->buffer = parser->tmp; - parser->buflen = parser->tmplen; - parser->pos = 0; - parser->tmp = NULL; - parser->tmpcap = 0; - parser->tmplen = 0; - // run ucx_properties_next with the tmp buffer as main buffer - int ret = ucx_properties_next(parser, name, value); - - // restore original buffer - parser->tmp = parser->buffer; - parser->buffer = orig_buf; - parser->buflen = orig_len; - parser->pos = newlen; - - /* - * if ret == 0 the tmp buffer contained just space or a comment - * we parse again with the original buffer to get a name/value - * or a new tmp buffer - */ - return ret ? ret : ucx_properties_next(parser, name, value); - } else { - parser_tmp_append(parser, buf, len); - return 0; - } - } else if(parser->tmp) { - free(parser->tmp); - parser->tmp = NULL; - } - - char comment1 = parser->comment1; - char comment2 = parser->comment2; - char comment3 = parser->comment3; - char delimiter = parser->delimiter; - - // get one line and parse it - while(parser->pos < parser->buflen) { - char *buf = parser->buffer + parser->pos; - size_t len = parser->buflen - parser->pos; - - /* - * First we check if we have at least one line. We also get indices of - * delimiter and comment chars - */ - size_t delimiter_index = 0; - size_t comment_index = 0; - int has_comment = 0; - - size_t i = 0; - char c = 0; - for(;itmpcap = len + 128; - parser->tmp = (char*)malloc(parser->tmpcap); - parser->tmplen = len; - memcpy(parser->tmp, buf, len); - return 0; - } - - sstr_t line = has_comment ? sstrn(buf, comment_index) : sstrn(buf, i); - // check line - if(delimiter_index == 0) { - line = sstrtrim(line); - if(line.length != 0) { - parser->error = 1; - } - } else { - sstr_t n = sstrn(buf, delimiter_index); - sstr_t v = sstrn( - buf + delimiter_index + 1, - line.length - delimiter_index - 1); - n = sstrtrim(n); - v = sstrtrim(v); - if(n.length != 0 || v.length != 0) { - *name = n; - *value = v; - parser->pos += i + 1; - return 1; - } else { - parser->error = 1; - } - } - - parser->pos += i + 1; - } - - return 0; -} - -int ucx_properties2map(UcxProperties *parser, UcxMap *map) { - sstr_t name; - sstr_t value; - while(ucx_properties_next(parser, &name, &value)) { - value = sstrdup_a(map->allocator, value); - if(!value.ptr) { - return 1; - } - if(ucx_map_sstr_put(map, name, value.ptr)) { - alfree(map->allocator, value.ptr); - return 1; - } - } - if (parser->error) { - return parser->error; - } else { - return 0; - } -} - -// buffer size is documented - change doc, when you change bufsize! -#define UCX_PROPLOAD_BUFSIZE 1024 -int ucx_properties_load(UcxMap *map, FILE *file) { - UcxProperties *parser = ucx_properties_new(); - if(!(parser && map && file)) { - return 1; - } - - int error = 0; - size_t r; - char buf[UCX_PROPLOAD_BUFSIZE]; - while((r = fread(buf, 1, UCX_PROPLOAD_BUFSIZE, file)) != 0) { - ucx_properties_fill(parser, buf, r); - error = ucx_properties2map(parser, map); - if (error) { - break; - } - } - ucx_properties_free(parser); - return error; -} - -int ucx_properties_store(UcxMap *map, FILE *file) { - UcxMapIterator iter = ucx_map_iterator(map); - void *v; - sstr_t value; - size_t written; - - UCX_MAP_FOREACH(k, v, iter) { - value = sstr((char*)v); - - written = 0; - written += fwrite(k.data, 1, k.len, file); - written += fwrite(" = ", 1, 3, file); - written += fwrite(value.ptr, 1, value.length, file); - written += fwrite("\n", 1, 1, file); - - if (written != k.len + value.length + 4) { - return 1; - } - } - - return 0; -} -