diff options
Diffstat (limited to 'src/zebra.h')
-rw-r--r-- | src/zebra.h | 108 |
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 |