Subversion Repositories spk

Rev

Blame | Last modification | View Log | RSS feed

#include "QtCatPck.h"
#include "../spk.h"

/*
========================================================================
 Cat and PCK FrontEnd Libraies using QT
========================================================================
*/


void UnpackFile ( const QString &filename, const QString &unpackedFile )
{
        size_t size;

        QString newFilename = filename;
        newFilename = newFilename.replace ( '/', '\\' );
        QString newUnpackedFile = unpackedFile;
        newUnpackedFile = newUnpackedFile.replace ( '/', '\\' );

        unsigned char *buffer = UnPCKFile ( newFilename, &size );

        if ( buffer )
        {
                FILE *id = fopen ( newUnpackedFile, "wb" );

                if ( id )
                {
                        fwrite ( buffer, size, 1, id );
                        fclose ( id );
                }

                delete buffer;
        }
}

void CopyCatFile ( const QString &from, const QString &to )
{
        if ( !to.contains ( "::" ) )
                return;

        QString tocatfile = to.section ( "::", 0, 0 );
        QString tofile = to.section ( "::", 1, 1 );

        if ( from.contains ( "::" ) )
        {
                CCatFile tocat;
                if ( tocat.Open ( tocatfile, CATREAD_CATDECRYPT, true ) )
                        return;

                tocat.AppendFile ( from, tofile );
        }
}


bool PackFile ( unsigned char *data, size_t size, const QString &filename, bool bPCK )
{
        if ( filename.find ( "::" ) == -1 )
        {
                // delete existing file first
                QString newfilename = filename;
                QFile delfile ( newfilename );
                if ( delfile.exists () )
                        delfile.remove ();

                // now open file for writing
                QFile f( filename );
                if ( f.open ( IO_WriteOnly ) )
                {
                        size_t newsize = 0;
                        unsigned char *d = PCKData ( data, size, &newsize );
                
                        bool ret = false;
                        if ( d )
                        {
                                f.writeBlock ( (const char *)d, newsize );
                                delete d;
                                ret = true;
                        }

                        f.close ();

                        return ret;
                }
        }
        else
        {
                QString catfile = filename.section ( "::", 0, 0 );
                QString file = filename.section ( "::", 1, 1 );

                CCatFile cat;
                int err = cat.Open ( catfile, CATREAD_CATDECRYPT, true );
                if ( (err != CATERR_NONE) && (err != CATERR_CREATED) )
                        return false;
        
                return cat.AppendData ( data, size, file );
        }

        return false;
}

bool PackFile ( QFile *readfile, const QString &filename, bool bPCK )
{
        if ( readfile->open ( IO_ReadOnly ) )
        {
                size_t size = QFileInfo ( *readfile ).size();
                unsigned char *data = new unsigned char [size];
                readfile->readBlock ( (char *)data, size );

                readfile->close();

                bool ret = PackFile ( data, size, filename, bPCK );

                delete [] data;

                return ret;
        }

        return false;
}

bool ExtractFromCat ( const QString &filename, const QString &savefile, bool convert, bool plain )
{
        if ( filename.find ( "::" ) == -1 )
                return false;


        QString catfile = filename.section ( "::", 0, 0 );
        QString file = filename.section ( "::", 1, 1 );

        // open the cat file
        CCatFile cat;
        if ( cat.Open ( catfile, CATREAD_CATDECRYPT ) )
                return false;

        // find the file to extract
        SInCatFile *f = cat.FindData ( file );
        if ( !f )
                return false;

        // read the data to memory
        if ( !cat.ReadFileToData ( f ) )
                return false;

        // check for extract
        QString sSaveFile = savefile;
        
        unsigned char *d = f->sData;
        size_t size = f->lSize;

        if ( (plain) && (IsDataPCK ( f->sData, f->lSize )) )
        {
                if ( convert )
                {
                        QString ext = QFileInfo(sSaveFile).extension(false).lower();
                        if ( ext == "pbb" )
                                sSaveFile = QFileInfo(sSaveFile).dirPath() + "/" + QFileInfo(sSaveFile).baseName(true) + ".bob";
                        else if ( ext == "pbd" )
                                sSaveFile = QFileInfo(sSaveFile).dirPath() + "/" + QFileInfo(sSaveFile).baseName(true) + ".bod";
                        else if ( ext == "pck" )
                        {
                                if ( file.left(5).lower() == "types" )
                                        sSaveFile = QFileInfo(sSaveFile).dirPath() + "/" + QFileInfo(sSaveFile).baseName(true) + ".txt";
                                else
                                        sSaveFile = QFileInfo(sSaveFile).dirPath() + "/" + QFileInfo(sSaveFile).baseName(true) + ".xml";
                        }
                }

                d = UnPCKData ( f->sData, f->lSize, &size );
        }

        if ( !d )
                return false;

        // now write to file
        QFile wfile ( sSaveFile );
        if ( wfile.open ( IO_WriteOnly ) )
        {
                wfile.writeBlock ( (const char *)d, size );
                wfile.close();
        }

        return true;
}

bool RemoveFromCat ( const QString &file )
{
        if ( !file.contains ( "::" ) )
                return false;

        QString catfile = file.section ( "::", 0, 0 );
        QString infile = file.section ( "::", 1, 1 );

        CCatFile cat;
        if ( cat.Open ( catfile, CATREAD_CATDECRYPT, false ) )
                return false;

        if ( !cat.RemoveFile ( infile ) )
                return false;

        return true;
}

QPtrList<SCatFile> GetCatList ( const QString &file )
{
        QPtrList<SCatFile> list;

        CCatFile cat;
        if ( !cat.Open ( file, CATREAD_CATDECRYPT, false ) )
        {
                for ( int i = 0; i < cat.GetNumFiles(); i++ )
                {
                        SInCatFile *cf = cat.GetFile (i);
                        SCatFile *f = new SCatFile;
                        f->iSize = cf->lSize;
                        f->sName = cf->sFile.c_str();
                        f->sName = f->sName.replace ( "\\", "/" );
                        list.append ( f );                      
                }
        }

        return list;
}


bool ExtractFile ( const QString &dir, const QString &file, const QString &to )
{
        bool done = false;

        // rmeove old file first
        if ( QFile ( to ).exists() )
                QFile ( to ).remove ();


        if ( file.contains ( "::" ) )
        {
                if ( ExtractFromCat ( file, to, true, true ) )
                        done = true;
        }
        else
        {
                // find first file to check
                QString sFile;
                int num;
                for ( num = 1; num <= 99; num++ )
                {
                        if ( num < 10 )
                                sFile.sprintf ( "0%d.cat", num );
                        else
                                sFile.sprintf ( "%d.cat", num );

                        if ( !QFile ( dir + "/" + sFile ).exists() )
                                break;
                }

                --num;
                for ( ; num; num-- )
                {
                        if ( num < 10 )
                                sFile.sprintf ( "0%d", num );
                        else
                                sFile.sprintf ( "%d", num );

                        if ( ExtractFromCat ( dir + "/" + sFile + ".cat::" + file, to, true, true ) )
                        {
                                done = true;
                                break;
                        }
                }
        }

        return done;
}


/*
  ================================================================
  =====            End of Cat/Pck Utils                      =====
  ================================================================
*/