Run latex
[egate.git] / util / iso2709o.c
1 /*
2  * Copyright (c) 1995, the EUROPAGATE consortium (see below).
3  *
4  * The EUROPAGATE consortium members are:
5  *
6  *    University College Dublin
7  *    Danmarks Teknologiske Videnscenter
8  *    An Chomhairle Leabharlanna
9  *    Consejo Superior de Investigaciones Cientificas
10  *
11  * Permission to use, copy, modify, distribute, and sell this software and
12  * its documentation, in whole or in part, for any purpose, is hereby granted,
13  * provided that:
14  *
15  * 1. This copyright and permission notice appear in all copies of the
16  * software and its documentation. Notices of copyright or attribution
17  * which appear at the beginning of any file must remain unchanged.
18  *
19  * 2. The names of EUROPAGATE or the project partners may not be used to
20  * endorse or promote products derived from this software without specific
21  * prior written permission.
22  *
23  * 3. Users of this software (implementors and gateway operators) agree to
24  * inform the EUROPAGATE consortium of their use of the software. This
25  * information will be used to evaluate the EUROPAGATE project and the
26  * software, and to plan further developments. The consortium may use
27  * the information in later publications.
28  * 
29  * 4. Users of this software agree to make their best efforts, when
30  * documenting their use of the software, to acknowledge the EUROPAGATE
31  * consortium, and the role played by the software in their work.
32  *
33  * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
34  * EXPRESS, IMPLIED, OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
35  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
36  * IN NO EVENT SHALL THE EUROPAGATE CONSORTIUM OR ITS MEMBERS BE LIABLE
37  * FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF
38  * ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
39  * OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND
40  * ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
41  * USE OR PERFORMANCE OF THIS SOFTWARE.
42  *
43  */
44 /*
45  * Iso2709 record management
46  *
47  * Europagate, 1995.
48  *
49  * $Log: iso2709o.c,v $
50  * Revision 1.3  1995/05/16 09:40:54  adam
51  * LICENSE.
52  *
53  * Revision 1.2  1995/03/30  14:22:19  adam
54  * More work on new MARC anchor functions.
55  *
56  * Revision 1.1  1995/03/28  16:07:07  adam
57  * New function: iso2709_out. This function is the reverse of iso2709_cvt.
58  *
59  */
60
61 #include <stdlib.h>
62 #include <string.h>
63 #include <stdio.h>
64 #include <assert.h>
65 #include <ctype.h>
66
67 #include <iso2709p.h>
68
69 static void memint (char *p, int val, int len)
70 {
71     static char buf[9];
72
73     if (len == 1)
74         *p = val + '0';
75     else
76     {
77         sprintf (buf, "%08d", val);
78         memcpy (p, buf+8-len, len);
79     }
80 }
81
82 int iso2709_out (Iso2709Rec p, char **buf, int bsize)
83 {
84     struct iso2709_field *field;
85     struct iso2709_dir *dir;
86     int len = 26;
87     int base_address = 25;
88     int entry_p, data_p;
89     char *op;
90
91     for (dir = p->directory; dir; dir = dir->next)
92     {
93         len += 4 + p->length_data_entry + p->length_starting
94             + p->length_implementation;
95         base_address += 3 + p->length_data_entry + p->length_starting
96             + p->length_implementation;
97         if (dir->indicator)
98             len += p->indicator_length;
99         for (field = dir->fields; field; field = field->next)
100         {
101             if (*field->identifier)
102                 len += p->identifier_length;
103             len += strlen (field->data);
104         }
105     }
106     if (!buf)
107         return len;
108     if (bsize)
109     {
110         if (bsize <= len)
111             return -2;
112     }
113     else
114     {
115         *buf = malloc (len);
116         if (!*buf)
117             return -1;
118     }
119     op = *buf;
120     memint (op, len, 5);
121     memcpy (op+5, p->record_status, 1);
122     memcpy (op+6, p->implementation_codes, 4);
123     memint (op+10, p->indicator_length, 1);
124     memint (op+11, p->identifier_length, 1);
125     memint (op+12, base_address, 5);
126     memcpy (op+17, p->user_systems, 3);
127     memint (op+20, p->length_data_entry, 1);
128     memint (op+21, p->length_starting, 1);
129     memint (op+22, p->length_implementation, 1);
130     memcpy (op+23, p->future_use, 1);
131     
132     entry_p = 24;
133     data_p = base_address;
134
135     for (dir = p->directory; dir; dir = dir->next)
136     {
137         int data_0 = data_p;
138         if (dir->indicator)
139         {
140             memcpy (op + data_p, dir->indicator, p->indicator_length);
141             data_p += p->indicator_length;
142         }
143         for (field = dir->fields; field; field = field->next)
144         {
145             if (*field->identifier)
146             {
147                 op[data_p] = ISO2709_IDFS;
148                 memcpy (op + data_p+1, field->identifier,
149                         p->identifier_length-1);
150                 data_p += p->identifier_length;
151             }
152             memcpy (op + data_p, field->data, strlen(field->data));
153             data_p += strlen(field->data);
154         }
155         op[data_p++] = ISO2709_FS;
156
157         memcpy (op + entry_p, dir->tag, 3);
158         entry_p += 3;
159         memint (op + entry_p, data_p - data_0, p->length_data_entry);
160         entry_p += p->length_data_entry;
161         memint (op + entry_p, data_0 - base_address, p->length_starting);
162         entry_p += p->length_starting;
163         entry_p += p->length_implementation;
164     }
165     op[entry_p++] = ISO2709_FS;
166     assert (entry_p == base_address);
167     op[data_p++] = ISO2709_RS;
168     assert (data_p == len);
169     return len;
170 }