diff options
| -rw-r--r-- | includes/cdreader.h | 43 | ||||
| -rwxr-xr-x | lib/Makefile | 4 | ||||
| -rw-r--r-- | lib/cdreader.cpp | 118 | 
3 files changed, 163 insertions, 2 deletions
| diff --git a/includes/cdreader.h b/includes/cdreader.h new file mode 100644 index 0000000..b409c33 --- /dev/null +++ b/includes/cdreader.h @@ -0,0 +1,43 @@ +#ifndef __CDREADER_H__ +#define __CDREADER_H__ +#ifdef __cplusplus + +#include <sys/types.h> +#include <time.h> +#include <String.h> +#include <Handle.h> + +class cdreader : public Handle { +  public: +      cdreader(const String & = "/dev/cdrom") throw (GeneralException); +      cdreader(const cdreader &); +      virtual ~cdreader() {} +    virtual bool CanWrite(); +    virtual bool CanRead(); +    virtual bool CanSeek(); +    virtual ssize_t read(void *buf, size_t count) throw (GeneralException);                                                      +    virtual off_t seek(off_t, int) throw (GeneralException); +    virtual String GetName(); +    virtual ssize_t GetSize(); +    virtual void getsector(void *, int = -1) throw (GeneralException); +    virtual void sectorseek(int); + +  protected: +    String n; +    int sector; +}; + +class Stdin_t : public cdreader { +  public: +      Stdin_t(); +      virtual ~Stdin_t() {} +    virtual bool CanSeek(); +    virtual String GetName(); +}; + +extern Stdin_t Stdin; + +#else +#error This only works with a C++ compiler +#endif +#endif diff --git a/lib/Makefile b/lib/Makefile index c351a36..ab722f9 100755 --- a/lib/Makefile +++ b/lib/Makefile @@ -1,9 +1,9 @@  #!/usr/bin/make -f -CPPFLAGS=-Wall -g -O3 -mcpu=i686 -pedantic -pedantic-errors -Werror -I../includes -DHAVE_ZLIB +CPPFLAGS=-Wall -g -O3 -mcpu=i686 -pedantic -Werror -I../includes -DHAVE_ZLIB  CXX=g++ -OBJECTS = cdutils.o lzss.o yazedc.o dteutils.o +OBJECTS = cdutils.o lzss.o yazedc.o dteutils.o cdreader.o  TARGET = lib.a  all: ${TARGET} diff --git a/lib/cdreader.cpp b/lib/cdreader.cpp new file mode 100644 index 0000000..a501b6d --- /dev/null +++ b/lib/cdreader.cpp @@ -0,0 +1,118 @@ +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include "cdreader.h" +#include "Exceptions.h" +#include "generic.h" +#ifdef HAVE_CONFIG_H +#include "config.h" +#else +#define _(x) x +#endif + +#ifdef __linux__ +#include <sys/ioctl.h> +#include <linux/cdrom.h> + +cdreader::cdreader(const String & no) throw (GeneralException) : +    Handle(open(no.to_charp(), O_RDONLY)), n(no), sector(0) { + +#ifdef DEBUG     +    fprintf(stderr, "Opening file %s, cdreader at %p\n", no.to_charp(), this); +#endif + +    if (GetHandle() < 0) { +	throw IOGeneral(String(_("Error opening file ")) + no + _(" for reading: ") + strerror(errno)); +    } +     +    struct stat s; +    fstat(GetHandle(), &s); + +    if (!S_ISBLK(s.st_mode)) { +	throw GeneralException(no + " is not a block device."); +    } +} + +cdreader::cdreader(const cdreader & i) : Handle(i), n(i.n) { +} + +bool cdreader::CanWrite() { +    return 0; +} + +bool cdreader::CanRead() { +    return 1; +} + +bool cdreader::CanSeek() { +    return 1; +} + +String cdreader::GetName() { +    return n + " raw reading"; +} + +ssize_t cdreader::GetSize() { +    return -1; +} + +off_t cdreader::seek(off_t offset, int whence) throw (GeneralException) { +    switch (whence) { +    case SEEK_SET: +	itell = offset; +	break; +    case SEEK_CUR: +	itell += offset; +	break; +    case SEEK_END: +	throw GeneralException("Can not yet seek from the end of a CD."); +    } +    return itell; +} + +ssize_t cdreader::read(void *buf, size_t count) throw (GeneralException) { +    char sector[CD_FRAMESIZE_RAW]; +    size_t r = count; +     +    size_t remain = itell % CD_FRAMESIZE_RAW; +    sectorseek(itell / CD_FRAMESIZE_RAW); +     +    while (count > 0) { +	size_t n = CD_FRAMESIZE_RAW - remain; +	getsector(sector); +	bcopy(sector, ((char *) buf) + remain, MIN(n, count)); +	count -= n; +	remain = 0; +    } +     +    return r; +} + +void cdreader::getsector(void *buf, int sec) throw (GeneralException) { +    struct cdrom_msf * msf = (struct cdrom_msf *) buf; +    if (sec >= 0) +	sector = sec; + +    msf->cdmsf_min0  =   sector   /CD_SECS   /CD_FRAMES; +    msf->cdmsf_sec0  =  (sector   /CD_FRAMES)%CD_SECS; +    msf->cdmsf_frame0=   sector   %CD_FRAMES; +    msf->cdmsf_min1  =  (sector+1)/CD_SECS   /CD_FRAMES; +    msf->cdmsf_sec1  = ((sector+1)/CD_FRAMES)%CD_SECS; +    msf->cdmsf_frame1=  (sector+1)%CD_FRAMES; + +    if (ioctl(GetHandle(), CDROMREADRAW, buf) < 0) { +	throw GeneralException(String("unable to read cd sector: ") + strerror(errno)); +    } +     +    sector++; +} + +void cdreader::sectorseek(int sec) { +    sector = sec; +} + +#endif | 
