aboutsummaryrefslogtreecommitdiff
path: root/src/zebra.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/zebra.h')
-rw-r--r--src/zebra.h108
1 files changed, 100 insertions, 8 deletions
diff --git a/src/zebra.h b/src/zebra.h
index 2f24939..c05f62d 100644
--- a/src/zebra.h
+++ b/src/zebra.h
@@ -1,3 +1,37 @@
+/* Library for reading ZEBRA files.
+ *
+ * The ZEBRA file format is an old file format used by FORTRAN programs for
+ * memory management and storing data structures. In particular, it's the
+ * default file format used by SNOMAN.
+ *
+ * This library is fairly simple and almost certainly does *not* include all
+ * the details needed to read an arbitrary ZEBRA file. Instead I implemented as
+ * much as was necessary to read in SNOMAN files and fixed bugs along the way.
+ *
+ * Example usage:
+ *
+ * zebraBank b;
+ * zebraFile *z = zebra_open("Muons.zdab")
+ *
+ * while (1) {
+ * rv = read_next_logical_record(z);
+ *
+ * switch (rv) {
+ * case 1:
+ * // EOF
+ * goto end;
+ * case -1:
+ * fprintf(stderr, "error getting logical record: %s\n", zebra_err);
+ * goto err;
+ * }
+ *
+ * zebra_get_bank(z,&b,z->first_bank);
+ *
+ * // etc.
+ * }
+ *
+ */
+
#ifndef ZEBRA_H
#define ZEBRA_H
@@ -5,44 +39,102 @@
#include <stdlib.h> /* for size_t */
#include <stdint.h> /* for uint8_t, etc. */
+/* Maximum number of links in a bank.
+ *
+ * Technically we could malloc() this but that means we would have to free
+ * banks which would be annoying. */
+#define MAX_LINKS 100
+
+/* Global error string when any function returns -1. */
extern char zebra_err[256];
+/* Physical record markers. */
#define ZEBRA_SIG0 0x0123cdefUL
#define ZEBRA_SIG1 0x80708070UL
#define ZEBRA_SIG2 0x4321abcdUL
#define ZEBRA_SIG3 0x80618061UL
+/* Bitmasks for the physical record block size control word. */
#define ZEBRA_BLOCK_SIZE_MASK 0x00ffffffUL
#define ZEBRA_EMERGENCY_STOP 0x80000000UL
#define ZEBRA_END_OF_RUN 0x20000000UL
#define ZEBRA_START_OF_RUN 0x40000000UL
-typedef struct bank {
+typedef struct zebraBank {
+ /* Pointer to the next bank in the chain. */
uint32_t next;
+ /* Pointer to the supporting bank. */
uint32_t up;
+ /* Pointer to the previous bank in the chain (or to the referencing link in
+ * the supporting bank if it's the first). */
uint32_t orig;
+ /* Bank number. From the SNOMAN FAQ:
+ *
+ * "In general, ZEBRA attaches no special significance to the bank number,
+ * and it is perfectly O.K. to change it at any time." */
uint32_t number;
- uint32_t name;
+ /* Hollerith bank ID as an integer. */
+ uint32_t idh;
+ /* Total number of links in the bank.
+ *
+ * Note: In SNOMAN reference links aren't guaranteed to point to the start
+ * of a bank. According to the SNOMAN docs all reference links in SNOMAN
+ * should point to the bank's status word instead of the start of the bank,
+ * but I tried the following and it didn't seem to work:
+ *
+ * zebra_get_bank(z,&b,mctk.links[KMCTK_MCVX-1]-8);
+ *
+ * So, I'm not really sure how reference links work in SNOMAN. */
uint32_t num_links;
+ /* Number of structural links. The order of the links in the bank is:
+ *
+ * structural link 1
+ * structural link 2
+ * ...
+ * structural link num_structural_links
+ * reference link num_structural_links+1
+ * reference link num_structural_links+2
+ * ...
+ * reference link num_links
+ *
+ */
uint32_t num_structural_links;
+ /* Number of data words. */
uint32_t num_data_words;
+ /* Status word. */
uint32_t status;
+ /* Pointer to the bank data in zebraFile->buf. Note that after calling
+ * zebra_read_next_logical_record(), this pointer will no longer point to
+ * the bank data. */
uint32_t *data;
-} bank;
+ /* Reference and structural links. */
+ uint32_t links[MAX_LINKS];
+ /* The Hollerith bank name as a string instead of an integer. This can be
+ * useful when printing error messages or for debugging. */
+ char name[5];
+} zebraBank;
typedef struct zebraFile {
FILE *f;
- size_t offset;
+ /* Size of the current logical record in bytes. */
size_t lr_size;
+ /* Buffer used to read in the zebra file. */
uint8_t *buf;
+ /* Total size of the current buffer. */
size_t buf_size;
+ /* Relocation table. */
+ uint32_t *tab;
+ /* Number of words in the relocation table. */
+ size_t nwtab;
+ /* Link to first bank. */
+ uint32_t first_bank;
+ /* Number of words from the start of the buffer to the first bank word. */
+ uint32_t lr_offset;
} zebraFile;
zebraFile *zebra_open(const char *filename);
-int read_next_physical_record(zebraFile *z);
-int get_bytes(zebraFile *z, size_t size);
-int read_next_logical_record(zebraFile *z);
-int next_bank(zebraFile *z, bank *b);
+int zebra_read_next_logical_record(zebraFile *z);
+int zebra_get_bank(zebraFile *z, zebraBank *b, uint32_t link);
void zebra_close(zebraFile *z);
#endif