Make --scan output a much smaller list of bad sectors
This commit is contained in:
parent
9a72df5d87
commit
6a2f279ea6
2 changed files with 85 additions and 38 deletions
|
|
@ -44,6 +44,33 @@
|
|||
int debug = 1;
|
||||
|
||||
|
||||
std::string BadSectors::toString() const
|
||||
{
|
||||
char buffer[1024];
|
||||
snprintf(buffer, sizeof(buffer),
|
||||
"%s: %d,%d,%d %d (%d)",
|
||||
file->fileName().c_str(),
|
||||
file->title,
|
||||
file->domain,
|
||||
file->number,
|
||||
start, number);
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
bool BadSectors::tryMerge(const BadSectors & follower)
|
||||
{
|
||||
if(follower.file != file)
|
||||
return false;
|
||||
if(start + number != follower.start)
|
||||
return false;
|
||||
number += follower.number;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
DVDCopy::DVDCopy() : badSectors(NULL)
|
||||
{
|
||||
reader = NULL;
|
||||
|
|
@ -219,8 +246,6 @@ void DVDCopy::scanForBadSectors(const char *device,
|
|||
{
|
||||
setup(device, NULL);
|
||||
|
||||
badSectors = fopen(badSectorsFile, "w");
|
||||
|
||||
for(std::vector<DVDFileData *>::iterator i = files.begin();
|
||||
i != files.end(); i++) {
|
||||
DVDFileData * dat = *i;
|
||||
|
|
@ -241,20 +266,35 @@ void DVDCopy::scanForBadSectors(const char *device,
|
|||
if(buffer[2] == 1 && buffer[first_pes_offset + 3] == 1)
|
||||
continue;
|
||||
else
|
||||
registerBadSectors(dat, blk + i, 1);
|
||||
registerBadSectors(dat, blk + i, 1, true);
|
||||
}
|
||||
};
|
||||
|
||||
auto failure = [this](int blk, int nb,
|
||||
const DVDFileData * dat) {
|
||||
registerBadSectors(dat, blk, nb);
|
||||
registerBadSectors(dat, blk, nb, true);
|
||||
};
|
||||
|
||||
file->walkFile(0, sz, 128,
|
||||
success, failure);
|
||||
/// @todo Compact the bad sectors file (this should be done at the
|
||||
/// very end, rewriting the whole file)
|
||||
}
|
||||
|
||||
// OK, now, we have a list of bad sectors. We simplify it
|
||||
std::vector<BadSectors> simplifiedBad;
|
||||
for(int i = 0; i < badSectorsList.size(); i++) {
|
||||
const BadSectors & bs = badSectorsList[i];
|
||||
if(!i)
|
||||
simplifiedBad.push_back(bs);
|
||||
else {
|
||||
if(! simplifiedBad.back().tryMerge(bs))
|
||||
simplifiedBad.push_back(bs);
|
||||
}
|
||||
}
|
||||
|
||||
FILE * bad = fopen(badSectorsFile, "w");
|
||||
for(int i = 0; i < simplifiedBad.size(); i++)
|
||||
fprintf(bad, "%s\n",
|
||||
simplifiedBad[i].toString().c_str());
|
||||
}
|
||||
|
||||
DVDCopy::~DVDCopy()
|
||||
|
|
@ -277,18 +317,15 @@ void DVDCopy::openBadSectorsFile(const char * mode)
|
|||
}
|
||||
|
||||
void DVDCopy::registerBadSectors(const DVDFileData * dat,
|
||||
int beg, int size)
|
||||
int beg, int size, bool dontWrite)
|
||||
{
|
||||
openBadSectorsFile("a");
|
||||
fprintf(badSectors, "%s: %d,%d,%d %d (%d)\n",
|
||||
dat->fileName().c_str(),
|
||||
dat->title,
|
||||
dat->domain,
|
||||
dat->number,
|
||||
beg, size);
|
||||
fflush(badSectors);
|
||||
|
||||
badSectorsList.push_back(BadSectors(dat, beg, size));
|
||||
if(! dontWrite) {
|
||||
openBadSectorsFile("a");
|
||||
fprintf(badSectors, "%s\n",
|
||||
badSectorsList.back().toString().c_str());
|
||||
fflush(badSectors);
|
||||
}
|
||||
}
|
||||
|
||||
int DVDCopy::findFile(int title, dvd_read_domain_t domain, int number)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,33 @@
|
|||
|
||||
#include "dvdreader.hh"
|
||||
|
||||
/// Class representing a series of consecutive bad sectors.
|
||||
///
|
||||
/// @todo Write to- and from- string methods.
|
||||
class BadSectors {
|
||||
public:
|
||||
|
||||
/// The underlying DVD file (ie something in the files list)
|
||||
const DVDFileData * file;
|
||||
|
||||
/// The starting sector
|
||||
int start;
|
||||
|
||||
/// The number of bad sectors;
|
||||
int number;
|
||||
|
||||
BadSectors(const DVDFileData * f, int s, int n) :
|
||||
file(f), start(s), number(n) {;}
|
||||
|
||||
/// Transform into a string
|
||||
std::string toString() const;
|
||||
|
||||
/// If the given bad sector is next to this one, appends it and
|
||||
/// return true, else return false
|
||||
bool tryMerge(const BadSectors & follower);
|
||||
};
|
||||
|
||||
|
||||
/// Handles the actual copying job, from a source to a target.
|
||||
class DVDCopy {
|
||||
/// Copies one file.
|
||||
|
|
@ -47,10 +74,12 @@ class DVDCopy {
|
|||
/// In the hope to be read again...
|
||||
FILE * badSectors;
|
||||
|
||||
/// Writes a bad sector list to the file, and add them to the
|
||||
/// badSectors list.
|
||||
/// Writes a bad sector list to the bad sectors file (unless
|
||||
/// dontWrite is true), and add them to the badSectors list (in any
|
||||
/// case).
|
||||
void registerBadSectors(const DVDFileData * dat,
|
||||
int beg, int size);
|
||||
int beg, int size,
|
||||
bool dontWrite = false);
|
||||
|
||||
|
||||
/// sets up the reader and gets the list of files, and sets up the
|
||||
|
|
@ -60,25 +89,6 @@ class DVDCopy {
|
|||
/// The underlying files of the source
|
||||
std::vector<DVDFileData *> files;
|
||||
|
||||
/// Subclass representing a single line in a bad sectors file.
|
||||
///
|
||||
/// @todo Write to- and from- string methods.
|
||||
class BadSectors {
|
||||
public:
|
||||
|
||||
/// The underlying DVD file (ie something in the files list)
|
||||
const DVDFileData * file;
|
||||
|
||||
/// The starting sector
|
||||
int start;
|
||||
|
||||
/// The number of bad sectors;
|
||||
int number;
|
||||
|
||||
BadSectors(const DVDFileData * f, int s, int n) :
|
||||
file(f), start(s), number(n) {;}
|
||||
};
|
||||
|
||||
/// The list of bad sectors, either read from the bad sectors file
|
||||
/// or directly populated registerBadSectors
|
||||
std::vector<BadSectors> badSectorsList;
|
||||
|
|
|
|||
Loading…
Reference in a new issue