--- /dev/null
+/*
+ * 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;
+}