--- /dev/null
+/* $Id: danbibr.c,v 1.1 2004-05-21 11:58:56 adam Exp $
+ Copyright (C) 2004
+ Index Data Aps
+
+This file is part of the Zebra server.
+
+Zebra 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.
+
+Zebra 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 Zebra; see the file LICENSE.zebra. If not, write to the
+Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <yaz/log.h>
+
+#include "grsread.h"
+
+#include <yaz/xmalloc.h>
+#include <yaz/log.h>
+#include <data1.h>
+
+#define READ_CHUNK 200
+
+struct danbibr_info {
+ WRBUF rec_buf;
+ char read_buf[READ_CHUNK+1]; /* space for \0 */
+};
+
+static void *grs_init_danbib(void)
+{
+ struct danbibr_info *p = (struct danbibr_info *) xmalloc (sizeof(*p));
+
+ p->rec_buf = wrbuf_alloc();
+ wrbuf_puts(p->rec_buf, "");
+ return p;
+}
+
+static int read_rec(struct grs_read_info *p)
+{
+ struct danbibr_info *info = p->clientData;
+
+ wrbuf_rewind(info->rec_buf);
+ while(1)
+ {
+ char *cp_split = 0;
+ int r = (*p->readf)(p->fh, info->read_buf, READ_CHUNK);
+ if (r <= 0)
+ {
+ if (wrbuf_len(info->rec_buf) > 0)
+ return 1;
+ else
+ return 0;
+ }
+ info->read_buf[r] = '\0';
+ wrbuf_puts(info->rec_buf, info->read_buf);
+
+ cp_split = strstr(wrbuf_buf(info->rec_buf), "\n$");
+ if (cp_split)
+ {
+ cp_split++; /* now at $ */
+ if (p->endf)
+ (*p->endf)(p->fh, p->offset +
+ (cp_split - wrbuf_buf(info->rec_buf)));
+
+ cp_split[0] = '\0';
+ return 1;
+ }
+ }
+}
+
+static data1_node *mk_tree(struct grs_read_info *p, const char *rec_buf)
+{
+ data1_node *root = data1_mk_root(p->dh, p->mem, "danbib");
+ const char *cp = rec_buf;
+
+ if (1) /* <text> all </text> */
+ {
+ data1_node *text_node = data1_mk_tag(p->dh, p->mem, "text", 0, root);
+ data1_mk_text_n(p->dh, p->mem, rec_buf, strlen(rec_buf), text_node);
+ }
+ while (*cp)
+ {
+ const char *start_tag = cp;
+ const char *start_text;
+ if (*cp == '\n')
+ {
+ cp++;
+ continue;
+ }
+ if (*cp == ' ') /* continuation */
+ {
+ while (*cp && *cp != '\n')
+ cp++;
+ }
+ else if (*cp == '$') /* header */
+ {
+ int no = 1;
+ cp++;
+ start_text = cp;
+ for(start_text = cp; *cp && *cp != '\n'; cp++)
+ if (*cp == ':')
+ {
+ if (start_text != cp)
+ {
+ char elemstr[20];
+ data1_node *hnode;
+ sprintf(elemstr, "head%d", no);
+
+ hnode = data1_mk_tag(p->dh, p->mem, elemstr, 0, root);
+ data1_mk_text_n(p->dh, p->mem, start_text,
+ cp - start_text, hnode);
+ start_text = cp+1;
+ }
+ no++;
+ }
+ }
+ else /* other */
+ {
+ while (*cp != ' ' && *cp && *cp != '\n')
+ cp++;
+ if (*cp == ' ')
+ {
+ data1_node *tag_node =
+ data1_mk_tag_n(p->dh, p->mem,
+ start_tag, cp - start_tag, 0, root);
+ cp++;
+ start_text = cp;
+ while (*cp != '\n' && *cp)
+ {
+ if (*cp == '*' && cp[1]) /* subfield */
+ {
+ data1_node *sub_tag_node;
+ if (start_text != cp)
+ data1_mk_text_n(p->dh, p->mem, start_text,
+ cp-start_text, tag_node);
+ cp++;
+ sub_tag_node =
+ data1_mk_tag_n(p->dh, p->mem, cp, 1, 0, tag_node);
+ cp++;
+ start_text = cp;
+ while (*cp && *cp != '\n'&& *cp != '*')
+ cp++;
+ if (start_text != cp)
+ data1_mk_text_n(p->dh, p->mem, start_text,
+ cp-start_text, sub_tag_node);
+ start_text = cp;
+ }
+ else
+ cp++;
+ }
+ if (start_text != cp)
+ data1_mk_text_n(p->dh, p->mem, start_text,
+ cp-start_text, tag_node);
+ }
+ }
+ }
+ return root;
+}
+
+static data1_node *grs_read_danbib (struct grs_read_info *p)
+{
+ struct danbibr_info *info = p->clientData;
+
+ if (read_rec(p))
+ return mk_tree(p, wrbuf_buf(info->rec_buf));
+ return 0;
+}
+
+static void grs_destroy_danbib(void *clientData)
+{
+ struct danbibr_info *p = (struct danbibr_info *) clientData;
+
+ wrbuf_free(p->rec_buf, 1);
+ xfree (p);
+}
+
+static struct recTypeGrs danbib_type = {
+ "danbib",
+ grs_init_danbib,
+ grs_destroy_danbib,
+ grs_read_danbib
+};
+
+RecTypeGrs recTypeGrs_danbib = &danbib_type;
+