1.1 --- a/src/properties.c Mon Dec 30 09:54:10 2019 +0100 1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 @@ -1,264 +0,0 @@ 1.4 -/* 1.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 1.6 - * 1.7 - * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved. 1.8 - * 1.9 - * Redistribution and use in source and binary forms, with or without 1.10 - * modification, are permitted provided that the following conditions are met: 1.11 - * 1.12 - * 1. Redistributions of source code must retain the above copyright 1.13 - * notice, this list of conditions and the following disclaimer. 1.14 - * 1.15 - * 2. Redistributions in binary form must reproduce the above copyright 1.16 - * notice, this list of conditions and the following disclaimer in the 1.17 - * documentation and/or other materials provided with the distribution. 1.18 - * 1.19 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1.20 - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1.21 - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.22 - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 1.23 - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1.24 - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1.25 - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1.26 - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 1.27 - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.28 - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 1.29 - * POSSIBILITY OF SUCH DAMAGE. 1.30 - */ 1.31 - 1.32 -#include "ucx/properties.h" 1.33 - 1.34 -#include <stdio.h> 1.35 -#include <stdlib.h> 1.36 -#include <string.h> 1.37 - 1.38 -UcxProperties *ucx_properties_new() { 1.39 - UcxProperties *parser = (UcxProperties*)malloc( 1.40 - sizeof(UcxProperties)); 1.41 - if(!parser) { 1.42 - return NULL; 1.43 - } 1.44 - 1.45 - parser->buffer = NULL; 1.46 - parser->buflen = 0; 1.47 - parser->pos = 0; 1.48 - parser->tmp = NULL; 1.49 - parser->tmplen = 0; 1.50 - parser->tmpcap = 0; 1.51 - parser->error = 0; 1.52 - parser->delimiter = '='; 1.53 - parser->comment1 = '#'; 1.54 - parser->comment2 = 0; 1.55 - parser->comment3 = 0; 1.56 - 1.57 - return parser; 1.58 -} 1.59 - 1.60 -void ucx_properties_free(UcxProperties *parser) { 1.61 - if(parser->tmp) { 1.62 - free(parser->tmp); 1.63 - } 1.64 - free(parser); 1.65 -} 1.66 - 1.67 -void ucx_properties_fill(UcxProperties *parser, char *buf, size_t len) { 1.68 - parser->buffer = buf; 1.69 - parser->buflen = len; 1.70 - parser->pos = 0; 1.71 -} 1.72 - 1.73 -static void parser_tmp_append(UcxProperties *parser, char *buf, size_t len) { 1.74 - if(parser->tmpcap - parser->tmplen < len) { 1.75 - size_t newcap = parser->tmpcap + len + 64; 1.76 - parser->tmp = (char*)realloc(parser->tmp, newcap); 1.77 - parser->tmpcap = newcap; 1.78 - } 1.79 - memcpy(parser->tmp + parser->tmplen, buf, len); 1.80 - parser->tmplen += len; 1.81 -} 1.82 - 1.83 -int ucx_properties_next(UcxProperties *parser, sstr_t *name, sstr_t *value) { 1.84 - if(parser->tmplen > 0) { 1.85 - char *buf = parser->buffer + parser->pos; 1.86 - size_t len = parser->buflen - parser->pos; 1.87 - sstr_t str = sstrn(buf, len); 1.88 - sstr_t nl = sstrchr(str, '\n'); 1.89 - if(nl.ptr) { 1.90 - size_t newlen = (size_t)(nl.ptr - buf) + 1; 1.91 - parser_tmp_append(parser, buf, newlen); 1.92 - // the tmp buffer contains exactly one line now 1.93 - 1.94 - char *orig_buf = parser->buffer; 1.95 - size_t orig_len = parser->buflen; 1.96 - 1.97 - parser->buffer = parser->tmp; 1.98 - parser->buflen = parser->tmplen; 1.99 - parser->pos = 0; 1.100 - parser->tmp = NULL; 1.101 - parser->tmpcap = 0; 1.102 - parser->tmplen = 0; 1.103 - // run ucx_properties_next with the tmp buffer as main buffer 1.104 - int ret = ucx_properties_next(parser, name, value); 1.105 - 1.106 - // restore original buffer 1.107 - parser->tmp = parser->buffer; 1.108 - parser->buffer = orig_buf; 1.109 - parser->buflen = orig_len; 1.110 - parser->pos = newlen; 1.111 - 1.112 - /* 1.113 - * if ret == 0 the tmp buffer contained just space or a comment 1.114 - * we parse again with the original buffer to get a name/value 1.115 - * or a new tmp buffer 1.116 - */ 1.117 - return ret ? ret : ucx_properties_next(parser, name, value); 1.118 - } else { 1.119 - parser_tmp_append(parser, buf, len); 1.120 - return 0; 1.121 - } 1.122 - } else if(parser->tmp) { 1.123 - free(parser->tmp); 1.124 - parser->tmp = NULL; 1.125 - } 1.126 - 1.127 - char comment1 = parser->comment1; 1.128 - char comment2 = parser->comment2; 1.129 - char comment3 = parser->comment3; 1.130 - char delimiter = parser->delimiter; 1.131 - 1.132 - // get one line and parse it 1.133 - while(parser->pos < parser->buflen) { 1.134 - char *buf = parser->buffer + parser->pos; 1.135 - size_t len = parser->buflen - parser->pos; 1.136 - 1.137 - /* 1.138 - * First we check if we have at least one line. We also get indices of 1.139 - * delimiter and comment chars 1.140 - */ 1.141 - size_t delimiter_index = 0; 1.142 - size_t comment_index = 0; 1.143 - int has_comment = 0; 1.144 - 1.145 - size_t i = 0; 1.146 - char c = 0; 1.147 - for(;i<len;i++) { 1.148 - c = buf[i]; 1.149 - if(c == comment1 || c == comment2 || c == comment3) { 1.150 - if(comment_index == 0) { 1.151 - comment_index = i; 1.152 - has_comment = 1; 1.153 - } 1.154 - } else if(c == delimiter) { 1.155 - if(delimiter_index == 0 && !has_comment) { 1.156 - delimiter_index = i; 1.157 - } 1.158 - } else if(c == '\n') { 1.159 - break; 1.160 - } 1.161 - } 1.162 - 1.163 - if(c != '\n') { 1.164 - // we don't have enough data for a line 1.165 - // store remaining bytes in temporary buffer for next round 1.166 - parser->tmpcap = len + 128; 1.167 - parser->tmp = (char*)malloc(parser->tmpcap); 1.168 - parser->tmplen = len; 1.169 - memcpy(parser->tmp, buf, len); 1.170 - return 0; 1.171 - } 1.172 - 1.173 - sstr_t line = has_comment ? sstrn(buf, comment_index) : sstrn(buf, i); 1.174 - // check line 1.175 - if(delimiter_index == 0) { 1.176 - line = sstrtrim(line); 1.177 - if(line.length != 0) { 1.178 - parser->error = 1; 1.179 - } 1.180 - } else { 1.181 - sstr_t n = sstrn(buf, delimiter_index); 1.182 - sstr_t v = sstrn( 1.183 - buf + delimiter_index + 1, 1.184 - line.length - delimiter_index - 1); 1.185 - n = sstrtrim(n); 1.186 - v = sstrtrim(v); 1.187 - if(n.length != 0 || v.length != 0) { 1.188 - *name = n; 1.189 - *value = v; 1.190 - parser->pos += i + 1; 1.191 - return 1; 1.192 - } else { 1.193 - parser->error = 1; 1.194 - } 1.195 - } 1.196 - 1.197 - parser->pos += i + 1; 1.198 - } 1.199 - 1.200 - return 0; 1.201 -} 1.202 - 1.203 -int ucx_properties2map(UcxProperties *parser, UcxMap *map) { 1.204 - sstr_t name; 1.205 - sstr_t value; 1.206 - while(ucx_properties_next(parser, &name, &value)) { 1.207 - value = sstrdup_a(map->allocator, value); 1.208 - if(!value.ptr) { 1.209 - return 1; 1.210 - } 1.211 - if(ucx_map_sstr_put(map, name, value.ptr)) { 1.212 - alfree(map->allocator, value.ptr); 1.213 - return 1; 1.214 - } 1.215 - } 1.216 - if (parser->error) { 1.217 - return parser->error; 1.218 - } else { 1.219 - return 0; 1.220 - } 1.221 -} 1.222 - 1.223 -// buffer size is documented - change doc, when you change bufsize! 1.224 -#define UCX_PROPLOAD_BUFSIZE 1024 1.225 -int ucx_properties_load(UcxMap *map, FILE *file) { 1.226 - UcxProperties *parser = ucx_properties_new(); 1.227 - if(!(parser && map && file)) { 1.228 - return 1; 1.229 - } 1.230 - 1.231 - int error = 0; 1.232 - size_t r; 1.233 - char buf[UCX_PROPLOAD_BUFSIZE]; 1.234 - while((r = fread(buf, 1, UCX_PROPLOAD_BUFSIZE, file)) != 0) { 1.235 - ucx_properties_fill(parser, buf, r); 1.236 - error = ucx_properties2map(parser, map); 1.237 - if (error) { 1.238 - break; 1.239 - } 1.240 - } 1.241 - ucx_properties_free(parser); 1.242 - return error; 1.243 -} 1.244 - 1.245 -int ucx_properties_store(UcxMap *map, FILE *file) { 1.246 - UcxMapIterator iter = ucx_map_iterator(map); 1.247 - void *v; 1.248 - sstr_t value; 1.249 - size_t written; 1.250 - 1.251 - UCX_MAP_FOREACH(k, v, iter) { 1.252 - value = sstr((char*)v); 1.253 - 1.254 - written = 0; 1.255 - written += fwrite(k.data, 1, k.len, file); 1.256 - written += fwrite(" = ", 1, 3, file); 1.257 - written += fwrite(value.ptr, 1, value.length, file); 1.258 - written += fwrite("\n", 1, 1, file); 1.259 - 1.260 - if (written != k.len + value.length + 4) { 1.261 - return 1; 1.262 - } 1.263 - } 1.264 - 1.265 - return 0; 1.266 -} 1.267 -