All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines
Public Member Functions
QGpCoreTools::Tar Class Reference

Brief description of class still missing. More...

#include <Tar.h>

List of all members.

Public Member Functions

bool addFile (QString fileName, const QByteArray &data)
void close ()
bool file (const QString fileName, QByteArray &data)
QString fileName () const
bool nextFile (QString &fileName, QByteArray &data, bool cache=false)
bool open (QString file, QIODevice::OpenMode m)
bool rewind ()
 Tar ()
 ~Tar ()

Detailed Description

Brief description of class still missing.

Full description of class still missing


Constructor & Destructor Documentation

Description of constructor still missing

References TRACE.

{
  TRACE;
  _f=0;
  _cachedFiles.setMaxCost(256*1024*1024); // a 256 Mb cache
}

Description of destructor still missing

References close(), and TRACE.

{
  TRACE;
  close();
}

Member Function Documentation

bool QGpCoreTools::Tar::addFile ( QString  fileName,
const QByteArray &  data 
)

Add data with fileName in tar archive

References QGpCoreTools::endl(), QGpCoreTools::App::stream(), QGpCoreTools::tr(), and TRACE.

Referenced by QGpCoreTools::XMLTarStream::addFile(), and QGpCoreTools::XMLTarStream::addXmlFile().

{
  TRACE;
  int nameLen=fileName.count();
  if(nameLen>100) {
    App::stream() << tr("File names greater than 99 charaters are currently not supported") << endl;
    return false;
  }
  if(nameLen<100) nameLen++;
  TarHeader fh;
  memset((char *) &fh, 0, 512);  // initialize a blank header block

  memcpy(fh.name, fileName.toAscii().data(), nameLen);
  memcpy(fh.mode,"0000644", 8);// default permissions -rw-r--r--
  memcpy(fh.uid,"0001750", 8);  // default user uid 1000
  memcpy(fh.gid,"0000144", 8);  // default group gid 100
  // Maximum size of a QByteArray is less than maximum size of file in tar file 777 7777 7777 in octal > 0x7FFFFFFF
  memcpy(fh.size, int2octal(data.size()), 12);
  // Modification time
  memcpy(fh.mtime, int2octal(QDateTime::currentDateTime().toTime_t()), 12);
  memcpy(fh.chksum,"        ", 8); // blank checksum
  fh.typeflag='0'; // regular file
  // ignore link name
  memcpy(fh.magic,"ustar  ",8); // magic tag
  memcpy(fh.uname,"username",9);
  memcpy(fh.gname,"users",6);
  // Computing checksum
  checksum(fh);
  // max checksum is 0x1FFFF, hence 377777 in octal
  memcpy(fh.chksum, int2octal(checksum(fh))+5, 7);

  // header block is ready to send to stream
  if(!writeBlock((char *) &fh)) return false;

  const char * dataPtr=data.data();
  const char * endDataPtr=dataPtr+data.size()-512;
  while(dataPtr<endDataPtr) {
    if(!writeBlock(dataPtr)) return false;
    dataPtr+=512;
  }
  endDataPtr+=512;
  static char buffer[512];
  memset(buffer, 0, 512);  // initialize a blank block
  memcpy(buffer, dataPtr, endDataPtr-dataPtr);
  if(!writeBlock(buffer)) return false;
  return true;
}

Description of destructor still missing

References TRACE.

Referenced by ~Tar().

{
  TRACE;
  if(_f) {
    // Terminate the tar file with two blank blocks
    if(_mode==QIODevice::WriteOnly) {
      char buffer[512];
      memset(buffer, 0, 512);  // initialize a blank block
      writeBlock(buffer);
      writeBlock(buffer);
    }
    gzclose(_f);
    _f=0;
  }
}
bool QGpCoreTools::Tar::file ( const QString  fileName,
QByteArray &  data 
)

Random access to file in an efficient way with cache to avoid useless and expensive unzip operations

References nextFile(), and TRACE.

Referenced by QGpCoreTools::XMLTarStream::file(), and open().

{
  TRACE;
  // Check if file available in cache
  if(_cachedFiles.contains(fileName)) {
    data= *_cachedFiles.object(fileName);
    return true;
  }
  QString readFileName;
  if(_fileOffsets.contains(fileName)) { /* file already read but removed from cache
                                              go directly to right position
                                              this might happen only for very big archives
                                            */
    gzseek(_f, _fileOffsets.value(fileName), SEEK_SET);
    if(nextFile(readFileName, data, true)) {
      return (readFileName==fileName);
    } else {
      return false;
    }
  }
  // search for correct header block, matching fileName
  while(fileName!= readFileName) {
    if(!nextFile(readFileName, data, true)) return false;
  }
  return true;
}
QString QGpCoreTools::Tar::fileName ( ) const [inline]
{return _fileName;}
bool QGpCoreTools::Tar::nextFile ( QString &  fileName,
QByteArray &  data,
bool  cache = false 
)

Extract data with fileName in tar archive. Files are read sequentially without using cache if cache is false

References QGpCoreTools::TarHeader::name, and TRACE.

Referenced by file().

{
  TRACE;
  z_off_t offset=gztell (_f);
  // read header block
  TarHeader fh;
  if( !readBlock((char *) &fh)) return false;
  fileName=fh.name;
  if(fileName.isEmpty()) { // probably end of tar archive
    return false;
  }
  // Read blocks of data
  if(readFile (fh, data)) {
    if(cache) {
      _cachedFiles.insert(fileName, new QByteArray(data), data.size());
      _fileOffsets.insert(fileName, offset);
    }
    return true;
  } else return false;
}
bool QGpCoreTools::Tar::open ( QString  file,
QIODevice::OpenMode  m 
)

Open a compressed gz file or uncompressed (automatically detected by zlib)

Accepted modes are QIODevice::ReadOnly and QIODevice::WriteOnly. When creating the file, it is always compressed, but on reading, it may be compressed or not.

References QGpCoreTools::endl(), file(), QGpCoreTools::App::stream(), QGpCoreTools::tr(), and TRACE.

Referenced by QGpCoreTools::XMLTarStream::open().

{
  TRACE;
  _fileName=file;
  _mode=m;
  switch (_mode) {
  case QIODevice::ReadOnly:
    _f=gzopen(file.toAscii().data(),"rb");
    return _f;
  case QIODevice::WriteOnly:
    _f=gzopen(file.toAscii().data(),"wb");
    return _f;
  default:
    App::stream() << tr("Tar: Unsupported file mode access") << endl;
    return false;
  }
}

Reset file pointer to the first file

References TRACE.

{
  TRACE;
  return (gzrewind(_f)==0);
}

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines