// KDat - a tar-based DAT archiver // Copyright (C) 1998-2000 Sean Vyain, svyain@mail.tds.net // Copyright (C) 2001-2002 Lawrence Widman, kdat@cardiothink.com // // 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #ifndef _TapeDrive_h_ #define _TapeDrive_h_ #include class Tape; /** * @short An OO interface to the tape drive. */ class TapeDrive : public TQObject { Q_OBJECT int _fd; bool _readOnly; Tape* _tape; char* _writeBuf; char* _readBuf; int _writeBufIdx; int _readBufIdx; static TapeDrive* _instance; TapeDrive(); public: /** * Destroy the tape drive (figuratively speaking, of course). */ ~TapeDrive(); /** * Get a reference to the single instance of the tape drive object. * * @return A pointer to the tape drive object. */ static TapeDrive* instance(); /** * Close the tape device. If data was written to the tape drive, then this * will also cause a single end-of-file marker to be written out. This is * the preferred way to write an end-of-file marker to the tape. */ void close(); /** * Physically eject the tape from the drive. Some tape drives do not * support this operation well. */ void eject(); /** * If there is unwritten data in the buffer, it will be flushed out. This * method is called when necessary by the other tape drive methods. */ void flush(); /** * Get the current tape file number. The first tape file is number 0. * * @return >= 0 on success, -1 on failure. */ int getFile(); /** * Get the current tape block number within the current file. The first * tape block number within a file is 0. * * @return >= 0 on success, -1 on failure. */ int getBlock(); /** * Determine whether the tape can be written to. * * @return TRUE if the tape cannot be written to, otherwise FALSE. */ bool isReadOnly(); /** * Determine whether there is a tape in the drive. * * @return TRUE if there is a tape, otherwise FALSE. */ bool isTapePresent(); /** * Load the tape into the drive. * * @return TRUE on success, otherwise FALSE. */ bool load(); /** * Lock the tape in the drive, so that it cannot be ejected manually by the * user. Not all tape drives support this operation. * * @return TRUE on success, otherwise FALSE. */ bool lock(); /** * Skip over one or more end-of-file markers on the tape. The tape is * positioned just after the last skipped end-of-file marker. * * @param count The number of end-of-file markers to skip over. * * @return TRUE on success, otherwise FALSE. */ bool nextFile( int count ); /** * Skip over one or more tape blocks within the current tape file. * * @param count The number of tape blocks to skip over. * * @return TRUE on success, otherwise FALSE. */ bool nextRecord( int count ); /** * Open the tape device for reading and writing. If this fails, try * opening the tape device for reading only. Check isReadOnly() to see * if the tape device was opened for reading and writing. * * @return TRUE if the tape device was opened for reading and/or writing, * otherwise FALSE. */ void open(); /** * Determine wether the tape is positioned just after an end-of-file * marker. * * @return TRUE if the tape is positioned after an end-of-file marker, * otherwise FALSE. */ bool pastEOF(); /** * Backspace over one or more end-of-file markers. The tape is positioned * just before the last end-of-file marker. * * @param count The number of end-of-file markers to backspace over. * * @return TRUE on success, otherwise FALSE. */ bool prevFile( int count ); /** * Backspace over one or more tape blocks. * * @param count The number of tape block to backspace over. * * @return TRUE on success, otherwise FALSE. */ bool prevRecord( int count ); /** * Read data from the tape. * * @param buf The buffer to read into. * @param len The number of bytes to read. * * @return The actual number of bytes read, or -1 on failure. */ int read( char* buf, int len ); /** * Read the KDat tape header (if there is one), and get the index * associated with the tape. * * @return A pointer to the tape index, or NULL if the tape does not have * a KDat header. */ Tape* readHeader(); /** * Rewind the tape. * * @return TRUE on success, otherwise FALSE. */ bool rewind(); /** * Move the tape to the given tar block within the given tape file. This * method will intelligently move the tape to the desired position. * * @param file The tape file number. * @param tarBlock The desired tar block (NOT tape block). * * @return TRUE on success, otherwise FALSE. */ bool seek( int file, int tarBlock ); /** * Set the hardware tape block size. * * @param blockSize The new tape block size in bytes. * * @return TRUE on success, otherwise FALSE. */ bool setBlockSize( int blockSize ); /** * Unlock the tape in the drive, so that it can be ejected manually by the * user. Not all tape drives support this operation. * * @return TRUE on success, otherwise FALSE. */ bool unlock(); /** * Write data to the tape. * * @param buf The buffer to write from. * @param len The number of bytes to write. * * @return The actual number of bytes written, or -1 on failure. */ int write( const char* buf, int len ); signals: /** * This signal is emitted for one-line, informational messages. * * @param msg The informational message. */ void sigStatus( const TQString & msg ); }; #endif