123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- /* libanode: the Anode C reference implementation
- * Copyright (C) 2009-2010 Adam Ierymenko <[email protected]>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>. */
- #include <stdio.h>
- #include <stdlib.h>
- #include "dictionary.h"
- static const char *EMPTY_STR = "";
- void AnodeDictionary_clear(struct AnodeDictionary *d)
- {
- struct AnodeDictionaryEntry *e,*ne;
- int oldcs;
- unsigned int i;
- oldcs = d->case_sensitive;
- for(i=0;i<ANODE_DICTIONARY_FIXED_HASH_TABLE_SIZE;++i) {
- e = d->ht[i];
- while (e) {
- ne = e->next;
- if ((e->key)&&(e->key != EMPTY_STR)) free((void *)e->key);
- if ((e->value)&&(e->value != EMPTY_STR)) free((void *)e->value);
- free((void *)e);
- e = ne;
- }
- }
- Anode_zero((void *)d,sizeof(struct AnodeDictionary));
- d->case_sensitive = oldcs;
- }
- void AnodeDictionary_put(struct AnodeDictionary *d,const char *key,const char *value)
- {
- struct AnodeDictionaryEntry *e;
- char *p1;
- const char *p2;
- unsigned int bucket = (d->case_sensitive) ? AnodeDictionary__get_bucket(key) : AnodeDictionary__get_bucket_ci(key);
- unsigned int len,i;
- e = d->ht[bucket];
- while (e) {
- if (((d->case_sensitive) ? Anode_streq(key,e->key) : Anode_strcaseeq(key,e->key))) {
- if (!d->case_sensitive) {
- p1 = e->key;
- p2 = key;
- while (*p2) *(p1++) = *(p2++);
- }
- len = 0;
- while (value[len]) ++len;
- if (len) {
- if ((e->value)&&(e->value != EMPTY_STR))
- e->value = (char *)realloc((void *)e->value,len + 1);
- else e->value = (char *)malloc(len + 1);
- for(i=0;i<len;++i) e->value[i] = value[i];
- e->value[i] = (char)0;
- } else {
- if ((e->value)&&(e->value != EMPTY_STR)) free((void *)e->value);
- e->value = (char *)EMPTY_STR;
- }
- return;
- }
- e = e->next;
- }
- e = (struct AnodeDictionaryEntry *)malloc(sizeof(struct AnodeDictionaryEntry));
- len = 0;
- while (key[len]) ++len;
- if (len) {
- e->key = (char *)malloc(len + 1);
- for(i=0;i<len;++i) e->key[i] = key[i];
- e->key[i] = (char)0;
- } else e->key = (char *)EMPTY_STR;
- len = 0;
- while (value[len]) ++len;
- if (len) {
- e->value = (char *)malloc(len + 1);
- for(i=0;i<len;++i) e->value[i] = value[i];
- e->value[i] = (char)0;
- } else e->value = (char *)EMPTY_STR;
- e->next = d->ht[bucket];
- d->ht[bucket] = e;
- ++d->size;
- }
- void AnodeDictionary_read(
- struct AnodeDictionary *d,
- char *in,
- const char *line_breaks,
- const char *kv_breaks,
- const char *comment_chars,
- char escape_char,
- int trim_whitespace_from_keys,
- int trim_whitespace_from_values)
- {
- char *line = in;
- char *key;
- char *value;
- char *p1,*p2,*p3;
- char last = ~escape_char;
- int eof_state = 0;
- for(;;) {
- if ((!*in)||((Anode_strchr(line_breaks,*in))&&((last != escape_char)||(!escape_char)))) {
- if (!*in)
- eof_state = 1;
- else *in = (char)0;
- if ((*line)&&((comment_chars)&&(!Anode_strchr(comment_chars,*line)))) {
- key = line;
- while (*line) {
- if ((Anode_strchr(kv_breaks,*line))&&((last != escape_char)||(!escape_char))) {
- *(line++) = (char)0;
- break;
- } else last = *(line++);
- }
- while ((*line)&&(Anode_strchr(kv_breaks,*line))&&((last != escape_char)||(!escape_char)))
- last = *(line++);
- value = line;
- if (escape_char) {
- p1 = key;
- while (*p1) {
- if (*p1 == escape_char) {
- p2 = p1;
- p3 = p1 + 1;
- while (*p3)
- *(p2++) = *(p3++);
- *p2 = (char)0;
- }
- ++p1;
- }
- p1 = value;
- while (*p1) {
- if (*p1 == escape_char) {
- p2 = p1;
- p3 = p1 + 1;
- while (*p3)
- *(p2++) = *(p3++);
- *p2 = (char)0;
- }
- ++p1;
- }
- }
- if (trim_whitespace_from_keys)
- Anode_trim(key);
- if (trim_whitespace_from_values)
- Anode_trim(value);
- AnodeDictionary_put(d,key,value);
- }
- if (eof_state)
- break;
- else line = in + 1;
- }
- last = *(in++);
- }
- }
- long AnodeDictionary_write(
- struct AnodeDictionary *d,
- char *out,
- long out_size,
- const char *line_break,
- const char *kv_break)
- {
- struct AnodeDictionaryEntry *e;
- const char *tmp;
- long ptr = 0;
- unsigned int bucket;
- if (out_size <= 0)
- return -1;
- for(bucket=0;bucket<ANODE_DICTIONARY_FIXED_HASH_TABLE_SIZE;++bucket) {
- e = d->ht[bucket];
- while (e) {
- tmp = e->key;
- if (tmp) {
- while (*tmp) {
- out[ptr++] = *tmp++;
- if (ptr >= (out_size - 1)) return -1;
- }
- }
- tmp = kv_break;
- if (tmp) {
- while (*tmp) {
- out[ptr++] = *tmp++;
- if (ptr >= (out_size - 1)) return -1;
- }
- }
- tmp = e->value;
- if (tmp) {
- while (*tmp) {
- out[ptr++] = *tmp++;
- if (ptr >= (out_size - 1)) return -1;
- }
- }
- tmp = line_break;
- if (tmp) {
- while (*tmp) {
- out[ptr++] = *tmp++;
- if (ptr >= (out_size - 1)) return -1;
- }
- }
- e = e->next;
- }
- }
- out[ptr] = (char)0;
- return ptr;
- }
|