/* * bread.c - 電子ブック/EPWINGユーティリティー 書籍読み込みモジュール * * Written by Junn Ohta (ohta@src.ricoh.co.jp). Public Domain. */ #include #include #include #ifdef MSDOS #include #endif #ifdef UNIX #include #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); }