104 parser->buffer = orig_buf; |
105 parser->buffer = orig_buf; |
105 parser->buflen = orig_len; |
106 parser->buflen = orig_len; |
106 parser->pos = newlen; |
107 parser->pos = newlen; |
107 |
108 |
108 /* |
109 /* |
109 * if ret == 0 the tmp buffer contained just space or comment |
110 * if ret == 0 the tmp buffer contained just space or a comment |
110 * 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 |
111 * or a new tmp buffer |
112 * or a new tmp buffer |
112 */ |
113 */ |
113 return ret ? ret : ucx_prop_parse(parser, name, value); |
114 return ret ? ret : ucx_prop_parse(parser, name, value); |
114 } else { |
115 } else { |
124 char comment2 = parser->comment2; |
125 char comment2 = parser->comment2; |
125 char comment3 = parser->comment3; |
126 char comment3 = parser->comment3; |
126 char delimiter = parser->delimiter; |
127 char delimiter = parser->delimiter; |
127 |
128 |
128 // get one line and parse it |
129 // get one line and parse it |
129 while(1) { |
130 while(parser->pos < parser->buflen) { |
130 if(parser->pos >= parser->buflen) { |
|
131 return 0; |
|
132 } |
|
133 char *buf = parser->buffer + parser->pos; |
131 char *buf = parser->buffer + parser->pos; |
134 size_t len = parser->buflen - parser->pos; |
132 size_t len = parser->buflen - parser->pos; |
135 |
133 |
136 /* |
134 /* |
137 * First we check if we have at least one line. We also get indices of |
135 * First we check if we have at least one line. We also get indices of |
158 break; |
156 break; |
159 } |
157 } |
160 } |
158 } |
161 |
159 |
162 if(c != '\n') { |
160 if(c != '\n') { |
163 // we have not enough data for a line |
161 // we don't have enough data for a line |
164 // store remaining bytes in temporary buffer for next round |
162 // store remaining bytes in temporary buffer for next round |
165 parser->tmpcap = len + 128; |
163 parser->tmpcap = len + 128; |
166 parser->tmp = (char*)malloc(parser->tmpcap); |
164 parser->tmp = (char*)malloc(parser->tmpcap); |
167 parser->tmplen = len; |
165 parser->tmplen = len; |
168 memcpy(parser->tmp, buf, len); |
166 memcpy(parser->tmp, buf, len); |
172 sstr_t line = has_comment ? sstrn(buf, comment_index) : sstrn(buf, i); |
170 sstr_t line = has_comment ? sstrn(buf, comment_index) : sstrn(buf, i); |
173 // check line |
171 // check line |
174 if(delimiter_index == 0) { |
172 if(delimiter_index == 0) { |
175 line = sstrtrim(line); |
173 line = sstrtrim(line); |
176 if(line.length != 0) { |
174 if(line.length != 0) { |
177 // syntax error |
175 parser->error = 1; |
178 // TODO |
|
179 } |
176 } |
180 parser->pos += i + 1; |
177 } else { |
181 continue; |
178 sstr_t n = sstrn(buf, delimiter_index); |
182 } |
179 sstr_t v = sstrn(buf+delimiter_index+1, i-delimiter_index-1); |
183 |
180 n = sstrtrim(n); |
184 sstr_t n = sstrn(buf, delimiter_index); |
181 v = sstrtrim(v); |
185 sstr_t v = sstrn(buf + delimiter_index + 1, i - delimiter_index - 1); |
182 if(n.length != 0 || v.length != 0) { |
186 n = sstrtrim(n); |
183 *name = n; |
187 v = sstrtrim(v); |
184 *value = v; |
188 if(n.length == 0 || v.length == 0) { |
185 parser->pos += i + 1; |
189 // syntax error |
186 return 1; |
190 // TODO |
187 } else { |
191 parser->pos += i + 1; |
188 parser->error = 1; |
192 continue; |
189 } |
193 } |
190 } |
194 |
|
195 *name = n; |
|
196 *value = v; |
|
197 |
191 |
198 parser->pos += i + 1; |
192 parser->pos += i + 1; |
199 break; |
193 } |
200 } |
194 |
201 |
195 return 0; |
202 return 1; |
196 } |
203 } |
197 |
204 |
198 int ucx_prop_parse2map(UcxPropParser *parser, UcxMap *map) { |
|
199 sstr_t name; |
|
200 sstr_t value; |
|
201 while(ucx_prop_parse(parser, &name, &value)) { |
|
202 name = sstrdup_alloc(map->allocator, name); |
|
203 if(!name.ptr) { |
|
204 return 1; |
|
205 } |
|
206 value = sstrdup_alloc(map->allocator, value); |
|
207 if(!value.ptr) { |
|
208 map->allocator->free(map->allocator->pool, value.ptr); |
|
209 return 1; |
|
210 } |
|
211 if(ucx_map_sstr_put(map, name, value.ptr)) { |
|
212 map->allocator->free(map->allocator->pool, name.ptr); |
|
213 map->allocator->free(map->allocator->pool, value.ptr); |
|
214 return 1; |
|
215 } |
|
216 } |
|
217 if(parser->error) { |
|
218 return 1; |
|
219 } else { |
|
220 return 0; |
|
221 } |
|
222 } |
|
223 |
|
224 int ucx_properties_load(UcxMap *map, FILE *file) { |
|
225 UcxPropParser *parser = ucx_prop_new(); |
|
226 if(!parser || !map || !file) { |
|
227 return 1; |
|
228 } |
|
229 |
|
230 int error = 0; |
|
231 size_t r; |
|
232 char buf[1024]; |
|
233 while((r = fread(buf, 1, 1024, file)) != 0) { |
|
234 ucx_prop_fill(parser, buf, r); |
|
235 if(ucx_prop_parse2map(parser, map)) { |
|
236 error = 1; |
|
237 break; |
|
238 } |
|
239 } |
|
240 |
|
241 ucx_prop_free(parser); |
|
242 return error; |
|
243 } |
|
244 |
|
245 int ucx_properties_store(UcxMap *map, FILE *file) { |
|
246 UcxMapIterator iter = ucx_map_iterator(map); |
|
247 char *k, *v; |
|
248 sstr_t key, value; |
|
249 size_t written; |
|
250 |
|
251 UCX_MAP_FOREACH(v, iter) { |
|
252 k = (char*) iter.cur->key.data; |
|
253 key = sstrn(k, iter.cur->key.len); |
|
254 value = sstr(v); |
|
255 |
|
256 written = 0; |
|
257 written += fwrite(key.ptr, 1, key.length, file); |
|
258 written += fwrite(" = ", 1, 3, file); |
|
259 written += fwrite(value.ptr, 1, value.length, file); |
|
260 written += fwrite("\n", 1, 1, file); |
|
261 |
|
262 if (written != key.length + value.length + 4) return 1; |
|
263 } |
|
264 |
|
265 return 0; |
|
266 } |
|
267 |