1 /* 2 * libuci - Library for the Unified Configuration Interface 3 * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU Lesser General Public License version 2.1 7 * as published by the Free Software Foundation 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU Lesser General Public License for more details. 13 */ 14 15 #include <string.h> 16 #include <stdint.h> 17 18 #include "uci.h" 19 20 void uci_parse_section(struct uci_section *s, const struct uci_parse_option *opts, 21 int n_opts, struct uci_option **tb) 22 { 23 struct uci_element *e; 24 25 memset(tb, 0, n_opts * sizeof(*tb)); 26 27 uci_foreach_element(&s->options, e) { 28 struct uci_option *o = uci_to_option(e); 29 int i; 30 31 for (i = 0; i < n_opts; i++) { 32 if (tb[i]) 33 continue; 34 35 if (strcmp(opts[i].name, o->e.name) != 0) 36 continue; 37 38 if (opts[i].type != o->type) 39 continue; 40 41 /* match found */ 42 tb[i] = o; 43 break; 44 } 45 } 46 } 47 48 //----------------------------------------------------------------------------- 49 // MurmurHashNeutral2, by Austin Appleby 50 51 // Same as MurmurHash2, but endian- and alignment-neutral. 52 static uint32_t hash_murmur2(uint32_t h, const void * key, int len) 53 { 54 const unsigned char * data = key; 55 const uint32_t m = 0x5bd1e995; 56 const int r = 24; 57 58 while(len >= 4) 59 { 60 unsigned int k; 61 62 k = data[0]; 63 k |= data[1] << 8; 64 k |= data[2] << 16; 65 k |= data[3] << 24; 66 67 k *= m; 68 k ^= k >> r; 69 k *= m; 70 71 h *= m; 72 h ^= k; 73 74 data += 4; 75 len -= 4; 76 } 77 78 switch(len) 79 { 80 case 3: h ^= data[2] << 16; 81 /* fall through */ 82 case 2: h ^= data[1] << 8; 83 /* fall through */ 84 case 1: h ^= data[0]; 85 h *= m; 86 } 87 88 h ^= h >> 13; 89 h *= m; 90 h ^= h >> 15; 91 92 return h; 93 } 94 95 static uint32_t uci_hash_list(uint32_t h, const struct uci_list *list) 96 { 97 const struct uci_element *e; 98 99 uci_foreach_element(list, e) { 100 h = hash_murmur2(h, e->name, strlen(e->name) + 1); 101 } 102 return h; 103 } 104 105 uint32_t uci_hash_options(struct uci_option **tb, int n_opts) 106 { 107 uint32_t h = 0xdeadc0de; 108 int i; 109 110 for (i = 0; i < n_opts; i++) { 111 const struct uci_option *o = tb[i]; 112 113 if (!tb[i]) 114 continue; 115 116 h = hash_murmur2(h, o->e.name, strlen(o->e.name) + 1); 117 h = hash_murmur2(h, &o->type, sizeof(o->type)); 118 119 switch (tb[i]->type) { 120 case UCI_TYPE_STRING: 121 h = hash_murmur2(h, o->v.string, strlen(o->v.string) + 1); 122 break; 123 case UCI_TYPE_LIST: 124 h = uci_hash_list(h, &o->v.list); 125 break; 126 } 127 } 128 129 return h; 130 } 131 132 133
This page was automatically generated by LXR 0.3.1. • OpenWrt