1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
#ifndef __MEMITEM_H__ /* file wrapper */
#define __MEMITEM_H__
/*
* Jeffrey Friedl
* Omron Corporation ʳ
* Nagaokakyoshi, Japan 617Ĺ
*
* jfriedl@nff.ncl.omron.co.jp
*
* This work is placed under the terms of the GNU General Purpose License
* (the "GNU Copyleft").
*
* Routines for accessing sequential bytes in a file via with a short
* read-ahead cache.
*/
#include <stdio.h>
#include "xmalloc.h"
#include "output.h"
#define DEFAULT_DATALEN 512
typedef long MemLoc;
typedef struct {
FILE *fp; /* file this item is found in */
unsigned char *data; /* a pre-loaded block of bytes */
MemLoc start; /* index into the file representing where DATA starts */
MemLoc end; /* index for where DATA ends */
MemLoc loc; /* index (into file!) of ``current file pointer'' */
unsigned datalen; /* size of memory allocated for DATA -- will usually
be (end-start) excapt near the end of the file */
} MemItem;
/*
* Given a memitem and a starting location, pre-read a block.
*/
static __inline__ void
FillMemPage(MemItem *m, MemLoc start)
{
if (!m->data) {
if (!m->datalen)
m->datalen = DEFAULT_DATALEN;
m->data = xmalloc(m->datalen);
}
if (fseek(m->fp, m->start = start, SEEK_SET) != 0)
die("Bad fseek to %ld (fp=%x) at %s line %d: %n\n",
(unsigned)m->start, m->fp, __FILE__, __LINE__);
m->end = start + fread(m->data, 1, m->datalen, m->fp);
}
/*
* Get the next byte from the memory-item, reading from disk if need be.
*/
static __inline__ unsigned char
GetMemByte(MemItem *m)
{
if (!m->data || m->loc < m->start || m->loc >= m->end)
FillMemPage(m, m->loc);
return m->data[m->loc++ - m->start];
}
/*
* (re)set the memory item to point to the given file and location.
*/
static __inline__ void
SetMem(MemItem *m, FILE *fp, MemLoc loc)
{
m->fp = fp;
FillMemPage(m, m->loc = loc);
}
#endif /*__MEMITEM_H__ */
|