/*
* bread.c - 電子ブック/EPWINGユーティリティー 書籍読み込みモジュール
*
* Written by Junn Ohta (ohta@src.ricoh.co.jp). Public Domain.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#ifdef MSDOS
#include <io.h>
#endif
#ifdef UNIX
#include <unistd.h>
#endif
#include "epw.h"
#ifndef O_BINARY
#define O_BINARY 0
#endif
static int rfd = -1;
static long rblkno;
static byte rblkbuf[BLKSIZ];
static byte *rp, *rendp = &rblkbuf[BLKSIZ];
int
open_book(file)
uchr *file;
{
if (rfd != -1)
close_book();
if ((rfd = open(file, O_RDONLY|O_BINARY)) < 0)
return ERR;
rblkno = 0L;
if (read_block() == ERR)
return ERR;
return OK;
}
int
close_book()
{
if (rfd == -1)
return ERR;
if (close(rfd) < 0)
return ERR;
return OK;
}
int
locate_block(blk)
long blk;
{
if (rfd == -1)
return ERR;
if (blk <= 0L)
return ERR;
if (rblkno == blk) {
rp = rblkbuf;
return OK;
}
if (lseek(rfd, (blk - 1L) * BLKSIZ, 0) < 0)
return ERR;
if (read_block() == ERR)
return ERR;
rblkno = blk;
return OK;
}
int
read_block()
{
if (rfd == -1)
return ERR;
if (read(rfd, (char *)rblkbuf, BLKSIZ) < BLKSIZ)
return ERR;
rp = rblkbuf;
rblkno++;
return OK;
}
long
cur_block()
{
return rblkno;
}
int
cur_off()
{
return rp - rblkbuf;
}
byte
getbyte()
{
if (rp >= rendp)
read_block();
return *rp++;
}
word
getword()
{
word w;
w = getbyte() << 8;
w += getbyte();
return w;
}
dword
getdword()
{
dword d;
d = (dword)getbyte() << 24;
d += (dword)getbyte() << 16;
d += (dword)getbyte() << 8;
d += (dword)getbyte();
return d;
}
long
getbcd(len)
int len;
{
int err;
byte b1, b2;
long d;
err = FALSE;
d = 0L;
while (len--) {
b2 = getbyte();
b1 = b2 >> 4;
b2 &= 0x0f;
if (b1 > 9 || b2 > 9)
err = TRUE;
d = d * 100 + b1 * 10 + b2;
}
if (err)
return -1L;
return d;
}
byte *
getbytes(buf, len)
byte *buf;
int len;
{
byte *p;
p = buf;
while (len--)
*p++ = getbyte();
return buf;
}
INFO_T *
getinfo(blk)
long blk;
{
int i, j, k;
INFO_T *infop;
ITEM_T *itemp;
CINFO_T *cinfop;
CENT_T *centp;
CITEM_T *citemp;
if (locate_block(blk) == ERR)
return NULL;
infop = (INFO_T *)malloc(sizeof(INFO_T));
if (infop == NULL)
return NULL;
infop->items = getword();
getbytes(infop->resv1, RESV1_LEN);
infop->idxhndl = getbyte();
getbytes(infop->resv2, RESV2_LEN);
infop->item = (ITEM_T *)malloc(sizeof(ITEM_T) * infop->items);
if (infop->item == NULL)
return NULL;
itemp = infop->item;
for (i = 0; i < infop->items; i++) {
itemp->itemid = getbyte();
getbytes(itemp->resv3, RESV3_LEN);
itemp->topblk = getdword();
itemp->blks = getdword();
itemp->idxvalid = getbyte();
itemp->idxinfo = getbyte() << 16;
itemp->idxinfo += getbyte() << 8;
itemp->idxinfo += getbyte();
getbytes(itemp->resv4, RESV4_LEN);
itemp->cinfo = NULL;
itemp++;
}
infop->dspvalid = getbyte();
getbytes(infop->resv5, RESV5_LEN);
infop->dsplist = getbyte();
infop->dspstyle = getbyte();
getbytes(infop->resv6, RESV6_LEN);
itemp = infop->item;
for (i = 0; i < infop->items; i++) {
if (itemp->itemid != ID_CINFO) {
itemp++;
continue;
}
if (locate_block(itemp->topblk) == ERR)
return NULL;
itemp->cinfo = (CINFO_T *)malloc(sizeof(CINFO_T));
if (itemp->cinfo == NULL)
return NULL;
cinfop = itemp->cinfo;
cinfop->cents = getword();
getbytes(cinfop->cresv1, CRESV1_LEN);
cinfop->cent = (CENT_T *)malloc(sizeof(CENT_T) * cinfop->cents);
if (cinfop->cent == NULL)
return NULL;
centp = cinfop->cent;
for (j = 0; j < cinfop->cents; j++) {
centp->citems = getbyte();
getbytes(centp->cresv2, CRESV2_LEN);
getbytes(centp->cname, CNAME_LEN);
centp->citem = (CITEM_T *)malloc(sizeof(CITEM_T) * centp->citems);
if (centp->citem == NULL)
return NULL;
citemp = centp->citem;
for (k = 0; k < centp->citems; k++) {
citemp->citemid = getbyte();
getbytes(citemp->cresv3, CRESV3_LEN);
citemp->ctopblk = getdword();
citemp->cblks = getdword();
getbytes(citemp->cresv4, CRESV4_LEN);
citemp++;
}
centp++;
}
itemp++;
}
return infop;
}
void
freeinfo(infop)
INFO_T *infop;
{
int i, j;
ITEM_T *itemp;
CINFO_T *cinfop;
CENT_T *centp;
itemp = infop->item;
for (i = 0; i < infop->items; i++) {
if (itemp->cinfo != NULL) {
cinfop = itemp->cinfo;
centp = cinfop->cent;
for (j = 0; j < cinfop->cents; j++) {
free((char *)centp->citem);
centp++;
}
free((char *)cinfop->cent);
free((char *)itemp->cinfo);
}
itemp++;
}
free((char *)infop->item);
free((char *)infop);
}
syntax highlighted by Code2HTML, v. 0.9.1