177 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| //
 | |
| // 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 <time.h>
 | |
| #include <stdlib.h>
 | |
| #include <conio.h>
 | |
| 
 | |
| #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;
 | |
| }
 |