// // EX12CON.CPP // // C++/DOS Example program for ArchiveLib 2.0 // // Copyright (c) Greenleaf Software, Inc. 1994 - 1996 // All Rights Reserved // // MEMBERS/FUNCTIONS DEMONSTRATED // // ALCompressed::ReadHeaderData() // ALCompressed::WriteHeaderData() // // DESCRIPTION // // This example shows how you can use the ReadHeaderData() and // WriteHeaderData() functions to store information in an ALCompressedObject. // This example derives a new class of ALCompressedObject that uses // the private data area of the compressed object to store the name of // the file that is compressed there. When the object is being extracted, // its name is updated in ReadHeaderData. // // You can also read the header data directly, without waiting for the // Extract() function to be called. This requires that you open the // compressed object,then seek to location 12. // // REVISION HISTORY // // February 1, 1996 : 2.0A : Second release // #include #include #include #include "al.h" // // This new derived class overrides the virtual function ReadHeaderData // and WriteHeaderData. // class AL_CLASS_TYPE MyCompressed : public ALCompressedObject { public : AL_INLINE_PROTO MyCompressed( ALStorage AL_DLL_FAR & storage, ALCompressor AL_DLL_FAR &compressor, ALDecompressor AL_DLL_FAR &decompressor ) : ALCompressedObject( storage, &compressor, &decompressor ){ ; }; virtual AL_INLINE_PROTO ~MyCompressed(){;} // // I use this member function to read the header data whenever I want to. // void AL_PROTO ReadHeader(); // // These special functions are declared, but not defined. I don't want the // compiler to generate default versions of these functions, so I specifically // declare them here. // protected : AL_PROTO MyCompressed( MyCompressed AL_DLL_FAR & ); MyCompressed AL_DLL_FAR & AL_PROTO operator=( const MyCompressed AL_DLL_FAR & ); // // The two virtual functions that I override in this class. // protected : int AL_PROTO WriteHeaderData( ALStorage AL_DLL_FAR * object ); int AL_PROTO ReadHeaderData( ALStorage AL_DLL_FAR * object ); }; // // In the base class, this virtual function does nothing at all. // In the derived class, I use this function to write the name of // the input file into the compressed object, using ArchiveLib string // format. // int AL_PROTO MyCompressed::WriteHeaderData(ALStorage AL_DLL_FAR * object ) { mpStorageObject->WriteString( (const char *) object->mName ); return AL_SUCCESS; } // // Before the output file gets extracted, this virtual function gets // called. I read the stored file name out of the compressed object, // and change the name of the output object. This code is a little // trickier than I would like because it has to read in data in the // ArchiveLibrary ReadString format. // int AL_PROTO MyCompressed::ReadHeaderData( ALStorage AL_DLL_FAR *output ) { short int len; if ( mpStorageObject->ReadGlShort( len ) < 0 ) return AL_READ_ERROR; char *new_string = new char[ len + 1 ]; if ( new_string ) { mpStorageObject->ReadBuffer( (unsigned char *) new_string, len ); new_string[ len ] = '\0'; } else return AL_READ_ERROR; cout << "Output object should be named: " << new_string << "\n"; if ( output ) output->mName = new_string; return AL_SUCCESS; } // // If you want to read the header data in outside of Extract() function, // this is what you have to do. // void AL_PROTO MyCompressed::ReadHeader() { cout << "Calling ReadHeaderData directly:\n"; mpStorageObject->Open(); mpStorageObject->Seek( 12 ); ReadHeaderData( 0 ); mpStorageObject->Close(); } main() { cout << "Archive Library 2.0\nEX12CON.CPP\n\n"; cout << "This example shows how you can use the ReadHeaderData() and\n"; cout << "WriteHeaderData() functions to store information in an ALCompressedObject.\n"; cout << "This example derives a new class of ALCompressedObject that uses\n"; cout << "the private data area of the compressed object to store the name of\n"; cout << "the file that is compressed there. When the object is being extracted,\n"; cout << "its name is updated in ReadHeaderData.\n\n"; getch(); ALMemory DataFile( "Memory objects can have long names" ); ALFile CompressedFile; ALMemory OutputFile( "Original output name" ); #if defined( ZIP ) ALPkCompressor Compressor( 3, 13 ); ALPkDecompressor Decompressor; #else ALGlCompressor Compressor( AL_GREENLEAF_LEVEL_4 ); ALGlDecompressor Decompressor; #endif MyCompressed *CompressedObject; // // Here is where I create the input data file and the compressed object. // This is all fairly realistic, you could write code that looks a lot // like this. // CompressedObject = new MyCompressed( CompressedFile, Compressor, Decompressor ); DataFile.Create(); // Temporary file for ( int i = 0 ; i < 64 ; i++ ) for ( int j = i; j < 64 ; j++ ) DataFile.WriteChar( j ); DataFile.Close(); cout << "Compressing\n"; // // When compressed using the derived class, the input object name will get // stored in the compressed file along with the compressed data. // CompressedObject->Insert( DataFile ); // // When I extract, the output file name should get set to the same as // that of the input file. // cout << "Extracting\n"; cout << "Output object is named: " << OutputFile.mName << "\n"; CompressedObject->Extract( OutputFile ); int status = DataFile.Compare( OutputFile ); cout << "Compare returned : " << status << "\n"; cout << "Output object is named: " << OutputFile.mName << "\n"; // // To read the data in the header of a compressed object, you can also // seek directly: // CompressedObject->ReadHeader(); delete CompressedObject; return status; }