Source Code (Use browser search to find items of interest.)
Class Index
kdat'File (./kdeadmin/kdat/File.h:32)
class File {
bool _stubbed;
union {
struct {
int _size;
int _mtime;
int _startRecord;
int _endRecord;
} _data;
struct {
FILE* _fptr;
int _offset;
} _stub;
} _union;
QString _name;
File* _parent;
QList<File> _children;
RangeList _ranges;
public:
/**
* Create a new file entry.
*
* @param parent The directory file entry that contains this file.
* @param size The size of the file in bytes.
* @param mtime The last modification time of the file in seconds since
* the Epoch.
* @param startRecord The first tar record number in the file.
* @param endRecord The last tar record number in the file.
* @param name The file name. If the file name ends with a '/' then it
* is assumed to be a directory name. Only the last part of
* the file's path name should be passed in. The rest of the
* path is determined by this file entry's ancestors.
*/
File( File* parent, int size, int mtime, int startRecord, int endRecord, const char* name );
/**
* Create a new stubbed instance of a file entry. The file pointer and
* offset specify where the actual instance data can be found. The real
* data is read on demand when one of the accessor functions is called.
*
* @param parent The directory file entry that contains this file.
* @param fptr The open index file containing this file entry. The file
* must be left open so that the file entry information can
* be read at a later time.
* @param offset The offset that will be seeked to when reading the file
* entry information.
*/
File( File* parent, FILE* fptr, int offset );
/**
* Destroy the file entry and all of its children.
*/
~File();
/**
* Insure that all of the data fields for this file entry have been read
* in. If the file entry is a stub then the actual data is read from the
* index file. If the file entry is not a stub then no action is taken.
*
* @param version The version of the old tape index.
*/
void read( int version = KDAT_INDEX_FILE_VERSION );
/**
* Recursively read the instance for this file entry and all of it's
* children. This method is used when converting from an older index format.
*
* @param version The version of the old tape index.
*/
void readAll( int version );
/**
* Write out the file entry to the open file. Entries for each of its
* children will also be written.
*/
void write( FILE* fptr );
/**
* Determine whether this file entry represents a directory. If the file
* name ends in a '/' then it is assumed that it is a directory.
*
* @return TRUE if the file represents a directory, or FALSE if it is an
* ordinary file.
*/
bool isDirectory();
/**
* Get the size of the file.
*
* @return The size, in bytes, of the file.
*/
int getSize();
/**
* Get the last modification time for the file.
*
* @ return The last time the file was modified, in seconds since the Epoch.
*/
int getMTime();
/**
* Get the tar record number for the file. This is the number of 512-byte
* tar blocks that must be read before getting to this file.
*
* @return The tar record number for the file.
*/
int getStartRecord();
/**
* Get the tar record number that is just past the end of the file. This
* number minus the start record gives the number of 512-byte tar blocks
* that this file occupies in the archive.
*
* @return The last tar record number for the file.
*/
int getEndRecord();
/**
* Get the name of this file. Only the last component of the full path
* name is returned.
*
* @return The file's name.
*/
QString getName();
/**
* Get the full path name of the file.
*
* @return The full path to the file.
*/
QString getFullPathName();
/**
* Get the file entry's parent. A NULL parent indicates that this is one
* of (possibly) many top level directories within the tar archive.
*
* @return A pointer to the file entry that contains this file entry.
*/
File* getParent();
/**
* Get the children of this file entry. A normal file will never have any
* children. A directory may or may not have children.
*
* @return A list of the immediate children of this file entry.
*/
const QList<File>& getChildren();
/**
* Get the list of ranges of this file and all of its children.
*
* @return A list of ranges.
*/
const QList<Range>& getRanges();
/**
* Add a new file entry as a child of this file entry.
*
* @param file The file to add.
*/
void addChild( File* file );
/**
* Recursively calculate the list of ranges for all of the file's children.
*/
void calcRanges();
};
kdat'File::File() (./kdeadmin/kdat/File.cpp:23)
File::File( File* parent, int size, int mtime, int startRecord, int endRecord, const char* name )
: _stubbed( FALSE ),
_name( name ),
_parent( parent )
{
assert( endRecord >= startRecord );
_union._data._size = size;
_union._data._mtime = mtime;
_union._data._startRecord = startRecord;
_union._data._endRecord = endRecord;
}
kdat'File::File() (./kdeadmin/kdat/File.cpp:36)
File::File( File* parent, FILE* fptr, int offset )
: _stubbed( TRUE ),
_parent( parent )
{
_union._stub._fptr = fptr;
_union._stub._offset = offset;
}
kdat'File::~File() (./kdeadmin/kdat/File.cpp:44)
File::~File()
{
while ( _children.first() ) {
delete _children.first();
_children.removeFirst();
}
}
kdat'File::read() (./kdeadmin/kdat/File.cpp:52)
void File::read( int version )
{
if ( !_stubbed ) {
return;
}
_stubbed = FALSE;
FILE* fptr = _union._stub._fptr;
fseek( fptr, _union._stub._offset, SEEK_SET );
// File name (4 bytes + n chars).
int ival;
fread( &ival, sizeof( ival ), 1, fptr );
char * buf = new char[ival+1];
buf[ival] = '\0';
fread( buf, sizeof( char ), ival, fptr );
_name = buf;
delete [] buf;
// File size (4 bytes).
fread( &ival, sizeof( ival ), 1, fptr );
_union._data._size = ival;
// File modification time (4 bytes).
fread( &ival, sizeof( ival ), 1, fptr );
_union._data._mtime = ival;
// Start record number.
fread( &ival, sizeof( ival ), 1, fptr );
_union._data._startRecord = ival;
// End record number.
fread( &ival, sizeof( ival ), 1, fptr );
_union._data._endRecord = ival;
//%%% This is a kludge to cope with some screwed up tape indexes.
//%%% Hopefully the file with the zero end record is *always* at
//%%% the end of the archive.
if ( ( _union._data._endRecord <= 0 ) && ( _union._data._startRecord != _union._data._endRecord ) ) {
_union._data._endRecord = MAXINT;
}
if ( version > 3 ) {
fread( &ival, sizeof( ival ), 1, fptr );
int rc = ival;
int start = 0;
int end = 0;
for ( int ii = 0; ii < rc; ii++ ) {
fread( &ival, sizeof( ival ), 1, fptr );
start = ival;
fread( &ival, sizeof( ival ), 1, fptr );
end = ival;
_ranges.addRange( start, end );
}
}
//===== Read files =====
fread( &ival, sizeof( ival ), 1, fptr );
for ( int count = ival; count > 0; count-- ) {
fread( &ival, sizeof( ival ), 1, fptr );
addChild( new File( this, fptr, ival ) );
}
}
kdat'File::readAll() (./kdeadmin/kdat/File.cpp:120)
void File::readAll( int version )
{
read( version );
QListIterator<File> i( getChildren() );
for ( ; i.current(); ++i ) {
i.current()->readAll( version );
}
}
kdat'File::write() (./kdeadmin/kdat/File.cpp:130)
void File::write( FILE* fptr )
{
int zero = 0;
// File name (4 bytes + n chars).
int ival = getName().length();
fwrite( &ival, sizeof( ival ), 1, fptr );
fwrite( getName().data(), sizeof( char ), ival, fptr );
// File size (4 bytes).
ival = getSize();
fwrite( &ival, sizeof( ival ), 1, fptr );
// File modification time (4 bytes).
ival = getMTime();
fwrite( &ival, sizeof( ival ), 1, fptr );
// Start record number.
ival = getStartRecord();
fwrite( &ival, sizeof( ival ), 1, fptr );
// End record number.
ival = getEndRecord();
fwrite( &ival, sizeof( ival ), 1, fptr );
// Child range list.
ival = _ranges.getRanges().count();
fwrite( &ival, sizeof( ival ), 1, fptr );
QListIterator<Range> it( _ranges.getRanges() );
for ( ; it.current(); ++it ) {
ival = it.current()->getStart();
fwrite( &ival, sizeof( ival ), 1, fptr );
ival = it.current()->getEnd();
fwrite( &ival, sizeof( ival ), 1, fptr );
}
// Number of immediate children (4 bytes).
ival = getChildren().count();
fwrite( &ival, sizeof( ival ), 1, fptr );
// Fill in file offsets later...
int fileTable = ftell( fptr );
for ( ; ival > 0; ival-- ) {
fwrite( &zero, sizeof( zero ), 1, fptr );
}
//===== Write files =====
ival = _children.count();
fwrite( &ival, sizeof( ival ), 1, fptr );
QListIterator<File> i( _children );
int count = 0;
for ( ; i.current(); ++i, count++ ) {
// Fill in the file offset.
int here = ftell( fptr );
fseek( fptr, fileTable + 4*count, SEEK_SET );
fwrite( &here, sizeof( here ), 1, fptr );
fseek( fptr, here, SEEK_SET );
i.current()->write( fptr );
}
}
kdat'File::isDirectory() (./kdeadmin/kdat/File.cpp:193)
bool File::isDirectory()
{
read();
return _name[ _name.length() - 1 ] == '/';
}
kdat'File::getSize() (./kdeadmin/kdat/File.cpp:200)
int File::getSize()
{
read();
return _union._data._size;
}
kdat'File::getMTime() (./kdeadmin/kdat/File.cpp:207)
int File::getMTime()
{
read();
return _union._data._mtime;
}
kdat'File::getStartRecord() (./kdeadmin/kdat/File.cpp:214)
int File::getStartRecord()
{
read();
return _union._data._startRecord;
}
kdat'File::getEndRecord() (./kdeadmin/kdat/File.cpp:221)
int File::getEndRecord()
{
read();
return _union._data._endRecord;
}
kdat'File::getName() (./kdeadmin/kdat/File.cpp:228)
QString File::getName()
{
read();
return _name;
}
kdat'File::getFullPathName() (./kdeadmin/kdat/File.cpp:235)
QString File::getFullPathName()
{
QString tmp = _name.copy();
for ( File* parent = getParent(); parent; parent = parent->getParent() ) {
tmp.prepend( parent->getName() );
}
return tmp;
}
kdat'File::getParent() (./kdeadmin/kdat/File.cpp:245)
File* File::getParent()
{
return _parent;
}
kdat'File::getChildren() (./kdeadmin/kdat/File.cpp:250)
const QList<File>& File::getChildren()
{
read();
return _children;
}
kdat'File::getRanges() (./kdeadmin/kdat/File.cpp:257)
const QList<Range>& File::getRanges()
{
read();
return _ranges.getRanges();
}
kdat'File::addChild() (./kdeadmin/kdat/File.cpp:264)
void File::addChild( File* file )
{
read();
_children.append( file );
}
kdat'File::calcRanges() (./kdeadmin/kdat/File.cpp:271)
void File::calcRanges()
{
assert( !_stubbed );
_ranges.clear();
_ranges.addRange( getStartRecord(), getEndRecord() );
QListIterator<File> it( getChildren() );
for ( ; it.current(); ++it ) {
it.current()->calcRanges();
QListIterator<Range> it2( it.current()->getRanges() );
for ( ; it2.current(); ++it2 ) {
_ranges.addRange( it2.current()->getStart(), it2.current()->getEnd() );
}
}
}