30 #include <stdlib.h> |
30 #include <stdlib.h> |
31 #include <string.h> |
31 #include <string.h> |
32 |
32 |
33 #include "properties.h" |
33 #include "properties.h" |
34 |
34 |
35 UcxPropParser *ucx_prop_new() { |
35 UcxProperties *ucx_properties_new() { |
36 UcxPropParser *parser = (UcxPropParser*)malloc( |
36 UcxProperties *parser = (UcxProperties*)malloc( |
37 sizeof(UcxPropParser)); |
37 sizeof(UcxProperties)); |
38 if(!parser) { |
38 if(!parser) { |
39 return NULL; |
39 return NULL; |
40 } |
40 } |
41 |
41 |
42 parser->buffer = NULL; |
42 parser->buffer = NULL; |
52 parser->comment3 = 0; |
52 parser->comment3 = 0; |
53 |
53 |
54 return parser; |
54 return parser; |
55 } |
55 } |
56 |
56 |
57 void ucx_prop_free(UcxPropParser *parser) { |
57 void ucx_properties_free(UcxProperties *parser) { |
58 if(parser->tmp) { |
58 if(parser->tmp) { |
59 free(parser->tmp); |
59 free(parser->tmp); |
60 } |
60 } |
61 free(parser); |
61 free(parser); |
62 } |
62 } |
63 |
63 |
64 void ucx_prop_fill(UcxPropParser *parser, char *buf, size_t len) { |
64 void ucx_properties_fill(UcxProperties *parser, char *buf, size_t len) { |
65 parser->buffer = buf; |
65 parser->buffer = buf; |
66 parser->buflen = len; |
66 parser->buflen = len; |
67 parser->pos = 0; |
67 parser->pos = 0; |
68 } |
68 } |
69 |
69 |
70 static void parser_tmp_append(UcxPropParser *parser, char *buf, size_t len) { |
70 static void parser_tmp_append(UcxProperties *parser, char *buf, size_t len) { |
71 if(parser->tmpcap - parser->tmplen < len) { |
71 if(parser->tmpcap - parser->tmplen < len) { |
72 size_t newcap = parser->tmpcap + len + 64; |
72 size_t newcap = parser->tmpcap + len + 64; |
73 parser->tmp = (char*)realloc(parser->tmp, newcap); |
73 parser->tmp = (char*)realloc(parser->tmp, newcap); |
74 parser->tmpcap = newcap; |
74 parser->tmpcap = newcap; |
75 } |
75 } |
76 memcpy(parser->tmp + parser->tmplen, buf, len); |
76 memcpy(parser->tmp + parser->tmplen, buf, len); |
77 parser->tmplen += len; |
77 parser->tmplen += len; |
78 } |
78 } |
79 |
79 |
80 int ucx_prop_parse(UcxPropParser *parser, sstr_t *name, sstr_t *value) { |
80 int ucx_properties_next(UcxProperties *parser, sstr_t *name, sstr_t *value) { |
81 if(parser->tmplen > 0) { |
81 if(parser->tmplen > 0) { |
82 char *buf = parser->buffer + parser->pos; |
82 char *buf = parser->buffer + parser->pos; |
83 size_t len = parser->buflen - parser->pos; |
83 size_t len = parser->buflen - parser->pos; |
84 sstr_t str = sstrn(buf, len); |
84 sstr_t str = sstrn(buf, len); |
85 sstr_t nl = sstrchr(str, '\n'); |
85 sstr_t nl = sstrchr(str, '\n'); |
96 parser->pos = 0; |
96 parser->pos = 0; |
97 parser->tmp = NULL; |
97 parser->tmp = NULL; |
98 parser->tmpcap = 0; |
98 parser->tmpcap = 0; |
99 parser->tmplen = 0; |
99 parser->tmplen = 0; |
100 // run parse with the tmp buffer as main buffer |
100 // run parse with the tmp buffer as main buffer |
101 int ret = ucx_prop_parse(parser, name, value); |
101 int ret = ucx_properties_next(parser, name, value); |
102 |
102 |
103 // restore original buffer |
103 // restore original buffer |
104 parser->tmp = parser->buffer; |
104 parser->tmp = parser->buffer; |
105 parser->buffer = orig_buf; |
105 parser->buffer = orig_buf; |
106 parser->buflen = orig_len; |
106 parser->buflen = orig_len; |
109 /* |
109 /* |
110 * if ret == 0 the tmp buffer contained just space or a comment |
110 * if ret == 0 the tmp buffer contained just space or a comment |
111 * we parse again with the original buffer to get a name/value |
111 * we parse again with the original buffer to get a name/value |
112 * or a new tmp buffer |
112 * or a new tmp buffer |
113 */ |
113 */ |
114 return ret ? ret : ucx_prop_parse(parser, name, value); |
114 return ret ? ret : ucx_properties_next(parser, name, value); |
115 } else { |
115 } else { |
116 parser_tmp_append(parser, buf, len); |
116 parser_tmp_append(parser, buf, len); |
117 return 0; |
117 return 0; |
118 } |
118 } |
119 } else if(parser->tmp) { |
119 } else if(parser->tmp) { |
193 } |
193 } |
194 |
194 |
195 return 0; |
195 return 0; |
196 } |
196 } |
197 |
197 |
198 int ucx_prop_parse2map(UcxPropParser *parser, UcxMap *map) { |
198 int ucx_properties2map(UcxProperties *parser, UcxMap *map) { |
199 sstr_t name; |
199 sstr_t name; |
200 sstr_t value; |
200 sstr_t value; |
201 while(ucx_prop_parse(parser, &name, &value)) { |
201 while(ucx_properties_next(parser, &name, &value)) { |
202 name = sstrdup_alloc(map->allocator, name); |
202 name = sstrdup_alloc(map->allocator, name); |
203 if(!name.ptr) { |
203 if(!name.ptr) { |
204 return 1; |
204 return 1; |
205 } |
205 } |
206 value = sstrdup_alloc(map->allocator, value); |
206 value = sstrdup_alloc(map->allocator, value); |
220 return 0; |
220 return 0; |
221 } |
221 } |
222 } |
222 } |
223 |
223 |
224 int ucx_properties_load(UcxMap *map, FILE *file) { |
224 int ucx_properties_load(UcxMap *map, FILE *file) { |
225 UcxPropParser *parser = ucx_prop_new(); |
225 UcxProperties *parser = ucx_properties_new(); |
226 if(!parser || !map || !file) { |
226 if(!parser || !map || !file) { |
227 return 1; |
227 return 1; |
228 } |
228 } |
229 |
229 |
230 int error = 0; |
230 int error = 0; |
231 size_t r; |
231 size_t r; |
232 char buf[1024]; |
232 char buf[1024]; |
233 while((r = fread(buf, 1, 1024, file)) != 0) { |
233 while((r = fread(buf, 1, 1024, file)) != 0) { |
234 ucx_prop_fill(parser, buf, r); |
234 ucx_properties_fill(parser, buf, r); |
235 if(ucx_prop_parse2map(parser, map)) { |
235 if(ucx_properties2map(parser, map)) { |
236 error = 1; |
236 error = 1; |
237 break; |
237 break; |
238 } |
238 } |
239 } |
239 } |
240 |
240 |
241 ucx_prop_free(parser); |
241 ucx_properties_free(parser); |
242 return error; |
242 return error; |
243 } |
243 } |
244 |
244 |
245 int ucx_properties_store(UcxMap *map, FILE *file) { |
245 int ucx_properties_store(UcxMap *map, FILE *file) { |
246 UcxMapIterator iter = ucx_map_iterator(map); |
246 UcxMapIterator iter = ucx_map_iterator(map); |