X-Git-Url: http://git.indexdata.com/?p=pazpar2-moved-to-github.git;a=blobdiff_plain;f=src%2Fmarchash.c;h=f304fa38b90026c23b469d4f9d817fa93ae74155;hp=5def5202afef1246b07819ce7c3bdc9f2a533311;hb=HEAD;hpb=2c07c3edbd2fb4c6f72b6527632fab264b6ab66b diff --git a/src/marchash.c b/src/marchash.c index 5def520..f304fa3 100644 --- a/src/marchash.c +++ b/src/marchash.c @@ -1,33 +1,48 @@ +/* This file is part of Pazpar2. + Copyright (C) Index Data + +Pazpar2 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 2, or (at your option) any later +version. + +Pazpar2 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, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +/** \file + \brief MARC MAP utilities (hash lookup etc) +*/ + +#if HAVE_CONFIG_H +#include +#else +/* disable inline if AC_C_INLINE is not in use (Windows) */ +#define inline +#endif + #include #include #include +#include #include #include #include -#include - -// Jenkins one-at-a-time hash (from pp2 reclists.c, wikipedia) -static unsigned int hash(const unsigned char *key) -{ - unsigned int hash = 0; - - while (*key) - { - hash += *(key++); - hash += (hash << 10); - hash ^= (hash >> 6); - } - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - return hash; -} +#include "jenkins_hash.h" +#include "marchash.h" -inline char *strtrimcat (char *dest, char *src) +static inline void strtrimcat(char *dest, const char *src) { - char *in; + const char *in; char *out; char *last_nonspace; in = src; @@ -51,13 +66,13 @@ inline char *strtrimcat (char *dest, char *src) *(++last_nonspace) = '\0'; } -inline char *strtrimcpy (char *dest, char *src) +static inline void strtrimcpy(char *dest, const char *src) { *dest = '\0'; strtrimcat(dest, src); } -struct marchash *marchash_create (NMEM nmem) +struct marchash *marchash_create(NMEM nmem) { struct marchash *new; new = nmem_malloc(nmem, sizeof (struct marchash)); @@ -66,57 +81,78 @@ struct marchash *marchash_create (NMEM nmem) return new; } -int marchash_ingest_marcxml (struct marchash *marchash, xmlNodePtr rec_node) +void marchash_ingest_marcxml(struct marchash *marchash, xmlNodePtr rec_node) { xmlNodePtr field_node; xmlNodePtr sub_node; - field_node = rec_node->children; struct marcfield *field; + field_node = rec_node->children; while (field_node) { if (field_node->type == XML_ELEMENT_NODE) { field = NULL; - if (!strcmp(field_node->name, "controlfield")) + if (!strcmp((const char *) field_node->name, "controlfield")) { - field = marchash_add_field(marchash, xmlGetProp(field_node, "tag"), xmlNodeGetContent(field_node)); + xmlChar *content = xmlNodeGetContent(field_node); + xmlChar *tag = xmlGetProp(field_node, BAD_CAST "tag"); + if (tag && content) + field = marchash_add_field( + marchash, (const char *) tag, (const char *) content); + xmlFree(content); + xmlFree(tag); } - else if (!strcmp(field_node->name, "datafield")) + else if (!strcmp((const char *) field_node->name, "datafield")) { - field = marchash_add_field(marchash, xmlGetProp(field_node, "tag"), xmlNodeGetContent(field_node)); + xmlChar *content = xmlNodeGetContent(field_node); + xmlChar *tag = xmlGetProp(field_node, BAD_CAST "tag"); + if (tag && content) + field = marchash_add_field( + marchash, (const char *) tag, (const char *) content); + xmlFree(content); + xmlFree(tag); } if (field) { sub_node = field_node->children; - while (sub_node) + while (sub_node) { - if ((sub_node->type == XML_ELEMENT_NODE) && (!strcmp(sub_node->name, "subfield"))) + if ((sub_node->type == XML_ELEMENT_NODE) && + !strcmp((const char *) sub_node->name, "subfield")) { - marchash_add_subfield(marchash, field, xmlGetProp(sub_node, "code")[0], xmlNodeGetContent(sub_node)); + xmlChar *content = xmlNodeGetContent(sub_node); + xmlChar *code = xmlGetProp(sub_node, BAD_CAST "code"); + if (code && content) + marchash_add_subfield( + marchash, field, + code[0], (const char *) content); + xmlFree(content); + xmlFree(code); } sub_node = sub_node->next; - } + } } } field_node = field_node->next; } } -struct marcfield *marchash_add_field (struct marchash *marchash, char *key, char *val) +struct marcfield *marchash_add_field(struct marchash *marchash, + const char *key, const char *val) { int slot; struct marcfield *new; struct marcfield *last; - - slot = hash(key) & MARCHASH_MASK; + + slot = jenkins_hash((const unsigned char *) key) & MARCHASH_MASK; new = marchash->table[slot]; last = NULL; - - while (new) + + while (new) { - last = new; - new = new->next; + last = new; + new = new->next; } new = nmem_malloc(marchash->nmem, sizeof (struct marcfield)); @@ -129,8 +165,8 @@ struct marcfield *marchash_add_field (struct marchash *marchash, char *key, char new->next = NULL; new->subfields = NULL; strncpy(new->key, key, 4); - - // only 3 char in a marc field name + + // only 3 char in a marc field name if (new->key[3] != '\0') return 0; @@ -140,7 +176,9 @@ struct marcfield *marchash_add_field (struct marchash *marchash, char *key, char return new; } -struct marcsubfield *marchash_add_subfield (struct marchash *marchash, struct marcfield *field, char key, char *val) +struct marcsubfield *marchash_add_subfield(struct marchash *marchash, + struct marcfield *field, + const char key, const char *val) { struct marcsubfield *new; struct marcsubfield *last; @@ -167,13 +205,14 @@ struct marcsubfield *marchash_add_subfield (struct marchash *marchash, struct ma return new; } -struct marcfield *marchash_get_field (struct marchash *marchash, char *key, struct marcfield *last) +struct marcfield *marchash_get_field (struct marchash *marchash, + const char *key, struct marcfield *last) { struct marcfield *cur; if (last) cur = last->next; - else - cur = marchash->table[hash(key) & MARCHASH_MASK]; + else + cur = marchash->table[jenkins_hash((const unsigned char *)key) & MARCHASH_MASK]; while (cur) { if (!strcmp(cur->key, key)) @@ -183,7 +222,9 @@ struct marcfield *marchash_get_field (struct marchash *marchash, char *key, stru return NULL; } -struct marcsubfield *marchash_get_subfield (char key, struct marcfield *field, struct marcsubfield *last) +struct marcsubfield *marchash_get_subfield(char key, + struct marcfield *field, + struct marcsubfield *last) { struct marcsubfield *cur; if (last) @@ -199,7 +240,8 @@ struct marcsubfield *marchash_get_subfield (char key, struct marcfield *field, s return NULL; } -char *marchash_catenate_subfields (struct marcfield *field, char *delim, NMEM nmem) +char *marchash_catenate_subfields(struct marcfield *field, + const char *delim, NMEM nmem) { char *output; struct marcsubfield *cur; @@ -211,9 +253,9 @@ char *marchash_catenate_subfields (struct marcfield *field, char *delim, NMEM nm { outsize += strlen(cur->val) + delimsize; cur = cur->next; - } + } if (outsize > 0) - output = nmem_malloc(nmem, outsize); + output = nmem_malloc(nmem, outsize); else return NULL; *output = '\0'; @@ -222,8 +264,16 @@ char *marchash_catenate_subfields (struct marcfield *field, char *delim, NMEM nm { strtrimcat(output, cur->val); if (cur->next) - strcat(output, delim); + strcat(output, delim); cur = cur->next; - } + } return output; } +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */