New function: iso2709_out. This function is the reverse of iso2709_cvt.
authorAdam Dickmeiss <adam@indexdata.dk>
Tue, 28 Mar 1995 16:07:06 +0000 (16:07 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Tue, 28 Mar 1995 16:07:06 +0000 (16:07 +0000)
util/Makefile
util/iso2709.c
util/iso2709dump.c
util/iso2709o.c [new file with mode: 0644]

index f0c53e0..9390fd1 100644 (file)
@@ -2,7 +2,10 @@
 # Europagate, 1995
 #
 # $Log: Makefile,v $
-# Revision 1.11  1995/03/28 11:42:41  adam
+# Revision 1.12  1995/03/28 16:07:06  adam
+# New function: iso2709_out. This function is the reverse of iso2709_cvt.
+#
+# Revision 1.11  1995/03/28  11:42:41  adam
 # First version of string-queue utility.
 #
 # Revision 1.10  1995/03/27  12:52:18  adam
@@ -41,7 +44,7 @@ INCLUDE=-I../include
 TPROG1=iso2709dump
 TPROG2=gwdbtest
 LIB=../lib/util.a
-PO=iso2709.o iso27dis.o gw-db.o gip.o gips.o gipc.o strqueue.o
+PO=iso2709.o iso27dis.o iso2709o.o gw-db.o gip.o gips.o gipc.o strqueue.o
 CPP=$(CC) -E
 DEFS=$(INCLUDE) -DSTUPID_ISO_DBC=1
 
index 812f8da..9e3f803 100644 (file)
@@ -4,7 +4,10 @@
  * Europagate, 1994-1995.
  *
  * $Log: iso2709.c,v $
- * Revision 1.10  1995/03/10 09:10:56  adam
+ * Revision 1.11  1995/03/28 16:07:07  adam
+ * New function: iso2709_out. This function is the reverse of iso2709_cvt.
+ *
+ * Revision 1.10  1995/03/10  09:10:56  adam
  * Removed dbc2709_cvt function. Makes heuristic guess for DBC2709 records.
  *
  * Revision 1.9  1995/03/08  12:36:39  adam
@@ -70,10 +73,6 @@ static void strncpyx (char *d, const char *s, int n)
             s++;
         }
     *d = '\0';
-#if 0
-    strncpy (d, s, n);
-    d[n] = '\0';
-#endif
 }
 
 char *iso2709_read (FILE *inf)
@@ -238,3 +237,4 @@ void iso2709_rm (Iso2709Rec rec)
         free (dir);
     }
 }
+
index e8d82da..663dd64 100644 (file)
@@ -4,7 +4,10 @@
  * Europagate, 1994-1995.
  *
  * $Log: iso2709dump.c,v $
- * Revision 1.6  1995/03/27 12:52:18  adam
+ * Revision 1.7  1995/03/28 16:07:07  adam
+ * New function: iso2709_out. This function is the reverse of iso2709_cvt.
+ *
+ * Revision 1.6  1995/03/27  12:52:18  adam
  * A little more verbose in marc dump.
  *
  * Revision 1.5  1995/02/22  21:32:36  adam
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <errno.h>
 
 #include <iso2709.h>
 
+static char *prog;
+
 int main (int argc, char **argv)
 {
     char *buf;
     Iso2709Rec rec;
     int no = 0;
+    int start_pos = 0;
+    int end_pos = 99999;
+    char *output_file = NULL;
+    char *input_file = NULL;
+    int verbose = 0;
+    int quiet = 0;
+    FILE *outf = NULL;
+    FILE *inf = stdin;
 
-    while ((buf = iso2709_read (stdin)))
+    prog = *argv;
+    while (--argc > 0)
     {
-        rec = iso2709_cvt (buf);
-        fprintf (stderr, "------- %d --------\n", ++no);
-        if (rec)
+        if (**++argv == '-')
         {
-            iso2709_display (rec, stderr);
-            iso2709_rm (rec);
+            switch (argv[0][1])
+            {
+            case 'h':
+            case 'H':
+                fprintf (stderr, "iso2709dump [options] [file]\n");
+                fprintf (stderr, "If no file is specified stdin is used\n");
+                fprintf (stderr, "Options:\n");
+                fprintf (stderr, " -p no        Starting position\n");
+                fprintf (stderr, " -l end       Ending position\n");
+                fprintf (stderr, " -o file      Raw MARC output file\n");
+                fprintf (stderr, " -v           Verbose\n");
+                fprintf (stderr, " -q           Quiet mode\n");
+                exit (1);
+            case 'p':
+                if (argv[0][2])
+                    start_pos = atoi (argv[0]+2);
+                else if (argc > 0)
+                {
+                    --argc;
+                    start_pos = atoi (*++argv);
+                }
+                else
+                {
+                    fprintf (stderr, "%s: missing start pos\n", prog);
+                    exit (1);
+                }
+                break;
+            case 'l':
+                if (argv[0][2])
+                    end_pos = atoi (argv[0]+2);
+                else if (argc > 0)
+                {
+                    --argc;
+                    end_pos = atoi (*++argv);
+                }
+                else
+                {
+                    fprintf (stderr, "%s: missing end pos\n", prog);
+                    exit (1);
+                }
+                break;
+            case 'o':
+                if (argv[0][2])
+                    output_file = argv[0]+2;
+                else if (argc > 0)
+                {
+                    --argc;
+                    output_file = *++argv;
+                }
+                else
+                {
+                    fprintf (stderr, "%s: missing output file\n", prog);
+                    exit (1);
+                }
+                break;
+            case 'v':
+                verbose = 1;
+                break;
+            case 'q':
+                quiet = 1;
+                break;
+            default:
+                fprintf (stderr, "%s: unknown option %s; use -h for help\n",
+                         prog, *argv);
+                exit (1);
+            }
         }
         else
+            input_file = *argv;
+    }
+    if (input_file)
+    {
+        inf = fopen (input_file, "r");
+        if (!inf)
+        {
+            fprintf (stderr, "%s: cannot open %s: %s\n",
+                     prog, input_file, strerror (errno));
+            exit (1);
+        }
+    }
+    if (output_file)
+    {
+        outf = fopen (output_file, "w");
+        if (!outf)
         {
-            fprintf (stderr, "Bad record\n");
-            break;
+            fprintf (stderr, "%s: cannot open %s: %s\n",
+                     prog, output_file, strerror (errno));
+            exit (1);
+        }
+    }
+    while ((buf = iso2709_read (inf)))
+    {
+        if (no >= start_pos && no <= end_pos)
+        {
+            char *obuf;
+            int olen;
+            
+            rec = iso2709_cvt (buf);
+            if (!quiet)
+                printf ("------- %d --------\n", no);
+            if (!rec)
+            {
+                if (!quiet)
+                    printf ("Bad record\n");
+                fprintf (stderr, "%s: bad record at position %d\n", prog, no);
+                break;
+            }
+            olen = iso2709_out (rec, &obuf, 0);
+            if (!quiet)
+                iso2709_display (rec, stdout);
+            if (outf && fwrite (obuf, 1, olen, outf) != olen)
+            {
+                fprintf (stderr, "%s: write fail of %s: %s\n",
+                         prog, output_file, strerror (errno));
+                exit (1);
+            }
+            free (obuf);
+            iso2709_rm (rec);
         }
         free (buf);
+        no++;
     }
+    if (outf)
+        fclose (outf);
     return 0;
 }
diff --git a/util/iso2709o.c b/util/iso2709o.c
new file mode 100644 (file)
index 0000000..1af8693
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Iso2709 record management
+ *
+ * Europagate, 1995.
+ *
+ * $Log: iso2709o.c,v $
+ * Revision 1.1  1995/03/28 16:07:07  adam
+ * New function: iso2709_out. This function is the reverse of iso2709_cvt.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include <iso2709p.h>
+
+static void memint (char *p, int val, int len)
+{
+    static char buf[9];
+
+    if (len == 1)
+        *p = val + '0';
+    else
+    {
+        sprintf (buf, "%08d", val);
+        memcpy (p, buf+8-len, len);
+    }
+}
+
+int iso2709_out (Iso2709Rec p, char **buf, int bsize)
+{
+    struct iso2709_field *field;
+    struct iso2709_dir *dir;
+    int len = 26;
+    int base_address = 25;
+    int entry_p, data_p;
+    char *op;
+
+    for (dir = p->directory; dir; dir = dir->next)
+    {
+        len += 4 + p->length_data_entry + p->length_starting
+            + p->length_implementation;
+        base_address += 3 + p->length_data_entry + p->length_starting
+            + p->length_implementation;
+        if (dir->indicator)
+            len += p->indicator_length;
+        for (field = dir->fields; field; field = field->next)
+        {
+            if (field->identifier)
+                len += p->identifier_length;
+            len += strlen (field->data);
+        }
+    }
+    if (!buf)
+        return len;
+    if (bsize)
+    {
+        if (bsize <= len)
+            return -2;
+    }
+    else
+    {
+        *buf = malloc (len);
+        if (!*buf)
+            return -1;
+    }
+    op = *buf;
+    memint (op, len, 5);
+    memcpy (op+5, p->record_status, 1);
+    memcpy (op+6, p->implementation_codes, 4);
+    memint (op+10, p->indicator_length, 1);
+    memint (op+11, p->identifier_length, 1);
+    memint (op+12, base_address, 5);
+    memcpy (op+17, p->user_systems, 3);
+    memint (op+20, p->length_data_entry, 1);
+    memint (op+21, p->length_starting, 1);
+    memint (op+22, p->length_implementation, 1);
+    memcpy (op+23, p->future_use, 1);
+    
+    entry_p = 24;
+    data_p = base_address;
+
+    for (dir = p->directory; dir; dir = dir->next)
+    {
+        int data_0 = data_p;
+        if (dir->indicator)
+        {
+            memcpy (op + data_p, dir->indicator, p->indicator_length);
+            data_p += p->indicator_length;
+        }
+        for (field = dir->fields; field; field = field->next)
+        {
+            if (field->identifier)
+            {
+                op[data_p] = ISO2709_IDFS;
+                memcpy (op + data_p+1, field->identifier,
+                        p->identifier_length-1);
+                data_p += p->identifier_length;
+            }
+            memcpy (op + data_p, field->data, strlen(field->data));
+            data_p += strlen(field->data);
+        }
+        op[data_p++] = ISO2709_FS;
+
+        memcpy (op + entry_p, dir->tag, 3);
+        entry_p += 3;
+        memint (op + entry_p, data_p - data_0, p->length_data_entry);
+        entry_p += p->length_data_entry;
+        memint (op + entry_p, data_0 - base_address, p->length_starting);
+        entry_p += p->length_starting;
+        entry_p += p->length_implementation;
+    }
+    op[entry_p++] = ISO2709_FS;
+    assert (entry_p == base_address);
+    op[data_p++] = ISO2709_RS;
+    assert (data_p == len);
+    return len;
+}