diff options
author | pixel <pixel> | 2004-11-27 21:44:15 +0000 |
---|---|---|
committer | pixel <pixel> | 2004-11-27 21:44:15 +0000 |
commit | 50f0dd331f8168fb5b2cd60c70178fad627b7fb6 (patch) | |
tree | 65fcec7bd507791f0db8a3af1b60ad9ac631f4a7 /lib/cdreader.cpp | |
parent | f1df76865d1751469deff19e62255d50a814f183 (diff) |
Large dos2unix commit...
Diffstat (limited to 'lib/cdreader.cpp')
-rw-r--r-- | lib/cdreader.cpp | 668 |
1 files changed, 334 insertions, 334 deletions
diff --git a/lib/cdreader.cpp b/lib/cdreader.cpp index 83bd1b3..7777c4d 100644 --- a/lib/cdreader.cpp +++ b/lib/cdreader.cpp @@ -1,334 +1,334 @@ -/* - * PSX-Tools Bundle Pack - * Copyright (C) 2002-2003 Nicolas "Pixel" Noble - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* $Id: cdreader.cpp,v 1.19 2003-12-26 19:05:31 pixel Exp $ */ - -#include <stdio.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 -#include "cdabstract.h" - -#define nsectorsarow 1 -#define cachesize 2048 - -bool cdreader::CanWrite() const { - return 0; -} - -bool cdreader::CanRead() const { - return 1; -} - -bool cdreader::CanSeek() const { - return 1; -} - -String cdreader::GetName() const { - return n + " raw reading"; -} - -ssize_t cdreader::GetSize() const { - 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[2352]; - size_t r = count; - - size_t remain = itell % 2352; - sectorseek(itell / 2352); - - while (count > 0) { - size_t n = MIN(2352 - remain, count); - fetchsector(sector); - bcopy(sector + remain, buf, n); - buf = ((char *) buf) + n; - itell += n; - count -= n; - remain = 0; - } - - return r; -} - -void cdreader::sectorseek(int sec) { - sector = sec; -} - -void cdreader::fetchsector(void * buf, int sec) { - if (sec >= 0) - sector = sec; - - if (sectors[sector]) { - actualize(sectors[sector]); - memcpy(buf, sectors[sector]->sector, 2352); - return; - } - - Byte buffers[2352 * nsectorsarow]; - - getsector(buffers, sec = sector, nsectorsarow); - - for (int i = nsectorsarow - 1; i >= 0; i--) { - introduce(buffers + i * 2352, sec + i); - } - - memcpy(buf, buffers, 2352); - - while (nsectors > cachesize) { - removetail(); - } -} - -cdreader::~cdreader() { - while (nsectors) { - removetail(); - } -} - -void cdreader::removetail() { - if (!tail) - return; - - sectors[tail->n] = 0; - - if (head == tail) { - free(tail); - head = tail = 0; - nsectors = 0; - } else { - cachedsector * p; - (p = tail->prev)->next = 0; - free(tail); - tail = p; - nsectors--; - } -} - -void cdreader::actualize(cachedsector * s) { - if (s == head) - return; - - if (s != tail) { - s->next->prev = s->prev; - } else { - tail = s->prev; - } - s->prev->next = s->next; - - head->prev = s; - s->prev = 0; - s->next = head; - head = s; -} - -void cdreader::introduce(Byte * datas, int n) { - cachedsector * s; - - s = (cachedsector *) malloc(sizeof(cachedsector)); - memcpy(s->sector, datas, 2352); - s->n = n; - - if (head) { - s->next = head; - head->prev = s; - head = s; - } else { - head = tail = s; - s->prev = s->next = 0; - } - sectors[n] = s; - - nsectors++; -} - -#ifdef __linux__ -#include <unistd.h> -#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) { - int i; - -#ifdef DEBUG - printm(M_INFO, "Opening cdrom device " + no + "\n"); -#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."); - } - - for (i = 0; i < 400000; i++) { - sectors[i] = 0; - } - head = tail = 0; - nsectors = 0; -} - -cdreader::cdreader(const cdreader & inp) : Handle(inp), n(inp.n) { - int i; - - for (i = 0; i < 400000; i++) { - sectors[i] = 0; - } - head = tail = 0; - nsectors = 0; -} - -void cdreader::getsector(void *buf, int sec, int nb) throw (GeneralException) { - struct cdrom_msf * msf = (struct cdrom_msf *) buf; - if (sec >= 0) - sector = sec; - - sector += 150; - - 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 + nb)/CD_SECS /CD_FRAMES; - msf->cdmsf_sec1 = ((sector + nb)/CD_FRAMES)%CD_SECS; - msf->cdmsf_frame1= (sector + nb)%CD_FRAMES; - - sector -= 150; - - if (ioctl(GetHandle(), CDROMREADRAW, buf) < 0) { - throw GeneralException(String("unable to read cd sector ") + sector + ": " + strerror(errno)); - } - - sector += nb; -} -#endif - -#if defined (_MSC_VER) || defined (__MINGW32__) -cdreader::cdreader(const String & no) throw (GeneralException) : - Handle(-1), n(no), sector(0) { - if (!(hFile = cdabstract::OpenIOCTLFile(no[0]))) - throw GeneralException("Error opening device " + no); - for (int i = 0; i < 400000; i++) { - sectors[i] = 0; - } - head = tail = 0; - nsectors = 0; -} - -cdreader::cdreader(const cdreader & i) : Handle(i), n(i.n) { - hFile = i.hFile; - for (int x = 0; x < 400000; x++) { - sectors[x] = 0; - } - head = tail = 0; - nsectors = 0; -} - -void cdreader::close() throw (GeneralException) { - CloseHandle(hFile); -} - -typedef enum _TRACK_MODE_TYPE { - YellowMode2, - XAForm2, - CDDA -} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE; - -typedef struct _RAW_READ_INFO { - LARGE_INTEGER DiskOffset; - ULONG SectorCount; - TRACK_MODE_TYPE TrackMode; -} RAW_READ_INFO, *PRAW_READ_INFO; - -void cdreader::getsector(void *buf, int sec, int nb) throw (GeneralException) { - RAW_READ_INFO rawIOCTL; - DWORD dwRet; - BOOL bStat; - bool done = false; - if (sec >= 0) - sector = sec; - - rawIOCTL.DiskOffset.QuadPart = sector * 2048; - rawIOCTL.SectorCount = nb; - rawIOCTL.TrackMode = YellowMode2; - - while (!done) { - SetLastError(0); - bStat = DeviceIoControl(hFile, IOCTL_CDROM_RAW_READ, - &rawIOCTL, sizeof(RAW_READ_INFO), - buf, 2352 * nb, &dwRet, NULL); - if (!bStat) { - DWORD dwErrCode = GetLastError(); - if (dwErrCode == ERROR_INVALID_FUNCTION) { - if (rawIOCTL.TrackMode == YellowMode2) { - rawIOCTL.TrackMode = XAForm2; - continue; - } - } - if (dwErrCode != ERROR_IO_PENDING) { - LPVOID lpMsgBuf; - if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, 0, NULL )) - throw GeneralException("Gave up on reading CD: unknown error"); - String errmsg = (LPCTSTR) lpMsgBuf; - LocalFree(lpMsgBuf); - throw GeneralException("Gave up on reading CD: " + errmsg); - } - } else { - done = true; - } - } - - sector += nb; -} - -#endif +/*
+ * PSX-Tools Bundle Pack
+ * Copyright (C) 2002-2003 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: cdreader.cpp,v 1.20 2004-11-27 21:44:48 pixel Exp $ */
+
+#include <stdio.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
+#include "cdabstract.h"
+
+#define nsectorsarow 1
+#define cachesize 2048
+
+bool cdreader::CanWrite() const {
+ return 0;
+}
+
+bool cdreader::CanRead() const {
+ return 1;
+}
+
+bool cdreader::CanSeek() const {
+ return 1;
+}
+
+String cdreader::GetName() const {
+ return n + " raw reading";
+}
+
+ssize_t cdreader::GetSize() const {
+ 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[2352];
+ size_t r = count;
+
+ size_t remain = itell % 2352;
+ sectorseek(itell / 2352);
+
+ while (count > 0) {
+ size_t n = MIN(2352 - remain, count);
+ fetchsector(sector);
+ bcopy(sector + remain, buf, n);
+ buf = ((char *) buf) + n;
+ itell += n;
+ count -= n;
+ remain = 0;
+ }
+
+ return r;
+}
+
+void cdreader::sectorseek(int sec) {
+ sector = sec;
+}
+
+void cdreader::fetchsector(void * buf, int sec) {
+ if (sec >= 0)
+ sector = sec;
+
+ if (sectors[sector]) {
+ actualize(sectors[sector]);
+ memcpy(buf, sectors[sector]->sector, 2352);
+ return;
+ }
+
+ Byte buffers[2352 * nsectorsarow];
+
+ getsector(buffers, sec = sector, nsectorsarow);
+
+ for (int i = nsectorsarow - 1; i >= 0; i--) {
+ introduce(buffers + i * 2352, sec + i);
+ }
+
+ memcpy(buf, buffers, 2352);
+
+ while (nsectors > cachesize) {
+ removetail();
+ }
+}
+
+cdreader::~cdreader() {
+ while (nsectors) {
+ removetail();
+ }
+}
+
+void cdreader::removetail() {
+ if (!tail)
+ return;
+
+ sectors[tail->n] = 0;
+
+ if (head == tail) {
+ free(tail);
+ head = tail = 0;
+ nsectors = 0;
+ } else {
+ cachedsector * p;
+ (p = tail->prev)->next = 0;
+ free(tail);
+ tail = p;
+ nsectors--;
+ }
+}
+
+void cdreader::actualize(cachedsector * s) {
+ if (s == head)
+ return;
+
+ if (s != tail) {
+ s->next->prev = s->prev;
+ } else {
+ tail = s->prev;
+ }
+ s->prev->next = s->next;
+
+ head->prev = s;
+ s->prev = 0;
+ s->next = head;
+ head = s;
+}
+
+void cdreader::introduce(Byte * datas, int n) {
+ cachedsector * s;
+
+ s = (cachedsector *) malloc(sizeof(cachedsector));
+ memcpy(s->sector, datas, 2352);
+ s->n = n;
+
+ if (head) {
+ s->next = head;
+ head->prev = s;
+ head = s;
+ } else {
+ head = tail = s;
+ s->prev = s->next = 0;
+ }
+ sectors[n] = s;
+
+ nsectors++;
+}
+
+#ifdef __linux__
+#include <unistd.h>
+#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) {
+ int i;
+
+#ifdef DEBUG
+ printm(M_INFO, "Opening cdrom device " + no + "\n");
+#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.");
+ }
+
+ for (i = 0; i < 400000; i++) {
+ sectors[i] = 0;
+ }
+ head = tail = 0;
+ nsectors = 0;
+}
+
+cdreader::cdreader(const cdreader & inp) : Handle(inp), n(inp.n) {
+ int i;
+
+ for (i = 0; i < 400000; i++) {
+ sectors[i] = 0;
+ }
+ head = tail = 0;
+ nsectors = 0;
+}
+
+void cdreader::getsector(void *buf, int sec, int nb) throw (GeneralException) {
+ struct cdrom_msf * msf = (struct cdrom_msf *) buf;
+ if (sec >= 0)
+ sector = sec;
+
+ sector += 150;
+
+ 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 + nb)/CD_SECS /CD_FRAMES;
+ msf->cdmsf_sec1 = ((sector + nb)/CD_FRAMES)%CD_SECS;
+ msf->cdmsf_frame1= (sector + nb)%CD_FRAMES;
+
+ sector -= 150;
+
+ if (ioctl(GetHandle(), CDROMREADRAW, buf) < 0) {
+ throw GeneralException(String("unable to read cd sector ") + sector + ": " + strerror(errno));
+ }
+
+ sector += nb;
+}
+#endif
+
+#if defined (_MSC_VER) || defined (__MINGW32__)
+cdreader::cdreader(const String & no) throw (GeneralException) :
+ Handle(-1), n(no), sector(0) {
+ if (!(hFile = cdabstract::OpenIOCTLFile(no[0])))
+ throw GeneralException("Error opening device " + no);
+ for (int i = 0; i < 400000; i++) {
+ sectors[i] = 0;
+ }
+ head = tail = 0;
+ nsectors = 0;
+}
+
+cdreader::cdreader(const cdreader & i) : Handle(i), n(i.n) {
+ hFile = i.hFile;
+ for (int x = 0; x < 400000; x++) {
+ sectors[x] = 0;
+ }
+ head = tail = 0;
+ nsectors = 0;
+}
+
+void cdreader::close() throw (GeneralException) {
+ CloseHandle(hFile);
+}
+
+typedef enum _TRACK_MODE_TYPE {
+ YellowMode2,
+ XAForm2,
+ CDDA
+} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE;
+
+typedef struct _RAW_READ_INFO {
+ LARGE_INTEGER DiskOffset;
+ ULONG SectorCount;
+ TRACK_MODE_TYPE TrackMode;
+} RAW_READ_INFO, *PRAW_READ_INFO;
+
+void cdreader::getsector(void *buf, int sec, int nb) throw (GeneralException) {
+ RAW_READ_INFO rawIOCTL;
+ DWORD dwRet;
+ BOOL bStat;
+ bool done = false;
+ if (sec >= 0)
+ sector = sec;
+
+ rawIOCTL.DiskOffset.QuadPart = sector * 2048;
+ rawIOCTL.SectorCount = nb;
+ rawIOCTL.TrackMode = YellowMode2;
+
+ while (!done) {
+ SetLastError(0);
+ bStat = DeviceIoControl(hFile, IOCTL_CDROM_RAW_READ,
+ &rawIOCTL, sizeof(RAW_READ_INFO),
+ buf, 2352 * nb, &dwRet, NULL);
+ if (!bStat) {
+ DWORD dwErrCode = GetLastError();
+ if (dwErrCode == ERROR_INVALID_FUNCTION) {
+ if (rawIOCTL.TrackMode == YellowMode2) {
+ rawIOCTL.TrackMode = XAForm2;
+ continue;
+ }
+ }
+ if (dwErrCode != ERROR_IO_PENDING) {
+ LPVOID lpMsgBuf;
+ if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf, 0, NULL ))
+ throw GeneralException("Gave up on reading CD: unknown error");
+ String errmsg = (LPCTSTR) lpMsgBuf;
+ LocalFree(lpMsgBuf);
+ throw GeneralException("Gave up on reading CD: " + errmsg);
+ }
+ } else {
+ done = true;
+ }
+ }
+
+ sector += nb;
+}
+
+#endif
|