714dd74636
git-svn-id: svn://10.65.10.50/trunk@5350 c028cbd2-c16b-5b4b-a496-9718f37d4682
167 lines
6.6 KiB
C
Executable File
167 lines
6.6 KiB
C
Executable File
/*
|
|
* EX18CON.C
|
|
*
|
|
* C/DOS Example program for ArchiveLib 2.0
|
|
*
|
|
* Copyright (c) Greenleaf Software, Inc. 1994 - 1996
|
|
* All Rights Reserved
|
|
*
|
|
* MEMBERS/FUNCTIONS DEMONSTRATED
|
|
*
|
|
* newALCompressedObject()
|
|
* deleteALCompressed()
|
|
* ALCompressedExtract()
|
|
* ALCompressedInsert()
|
|
* ALCompressedGetStatusCode()
|
|
* ALCompressedGetStatusDetail()
|
|
* ALCompressedGetStatusString()
|
|
* ALCompressedSetError()
|
|
* ALStoragePackedAttributes()
|
|
* ALStorageSetFromDosAttributes()
|
|
* ALStorageSetFromPackedAtts()
|
|
* ALStorageSetTimeDateFromUnix()
|
|
*
|
|
* DESCRIPTION
|
|
*
|
|
* This is another one of those example programs that ties together
|
|
* a bunch of marginally related functions. It starts off by creating
|
|
* a data file on disk, and writing some fixed patterns out to it. Next,
|
|
* the data file gets inserted into a compressed object, also on disk.
|
|
* Then the weird part: If a random number hits, I randomly change a
|
|
* byte in the compressed object. Finally, I extract the original data
|
|
* file from the compressed object, for better or worse.
|
|
*
|
|
* After this is all done, I have three TMP files on the disk. In an
|
|
* imitation of what you might do in a real debugging situation, I check
|
|
* to see if the input and output match. If they do match, I just go
|
|
* ahead and delete them, all is well. If they don't match, I want to
|
|
* hang on to the files. Not only do I hang on to the files, I give
|
|
* them a funny time date stamp, and set them to be read-only.
|
|
*
|
|
* REVISION HISTORY
|
|
*
|
|
* February 1, 1996 2.0A : Second release
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <conio.h>
|
|
|
|
#include "al.h"
|
|
|
|
int main()
|
|
{
|
|
hALStorage DataFile;
|
|
hALStorage CompressedFile;
|
|
hALStorage OutputFile;
|
|
hALCompressor Compressor;
|
|
hALDecompressor Decompressor;
|
|
hALCompressed CompressedObject;
|
|
int status;
|
|
short unsigned int atts;
|
|
int i;
|
|
int j;
|
|
|
|
printf( "Archive Library 2.0\nEX18CON.C\n\n" );
|
|
printf( "This is another one of those example programs that ties together\n" );
|
|
printf( "a bunch of marginally related functions. It starts off by creating\n" );
|
|
printf( "a data file on disk, and writing some fixed patterns out to it. Next,\n" );
|
|
printf( "the data file gets inserted into a compressed object, also on disk.\n" );
|
|
printf( "Then the weird part: If a random number hits, I randomly change a\n" );
|
|
printf( "byte in the compressed object. Finally, I extract the original data\n" );
|
|
printf( "file from the compressed object, for better or worse.\n\n" );
|
|
getch();
|
|
|
|
#if defined( ZIP )
|
|
Compressor = newALPkCompressor( AL_DEFAULT, AL_DEFAULT, AL_DEFAULT );
|
|
Decompressor = newALPkDecompressor();
|
|
#else
|
|
Compressor = newALGlCompressor( AL_DEFAULT, 0 );
|
|
Decompressor = newALGlDecompressor( AL_DEFAULT );
|
|
#endif
|
|
/*
|
|
* 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.
|
|
*/
|
|
DataFile = newALFile( "" );
|
|
CompressedFile = newALFile( "" );
|
|
OutputFile = newALFile( "" );
|
|
CompressedObject = newALCompressed( CompressedFile, Compressor, Decompressor );
|
|
ALStorageCreate( DataFile, -1 ); /* Temporary file */
|
|
for ( i = 0 ; i < 64 ; i++ )
|
|
for ( j = i; j < 64 ; j++ )
|
|
ALStorageWriteChar( DataFile, j );
|
|
ALStorageClose( DataFile );
|
|
ALCompressedInsert( CompressedObject, DataFile );
|
|
/*
|
|
* If the one in four chance hits, I change a single byte in the compressed
|
|
* file. This will almost always cause an expansion error, although it
|
|
* is possible to create a benign change (like the 1/256 chance that you
|
|
* write over the old byte with a new byte that is the same!)
|
|
*/
|
|
srand( (unsigned) time( NULL ) );
|
|
if ( ( rand() & 3 ) == 0 ) {
|
|
printf( "Mangling the compressed file!\n" );
|
|
ALStorageOpen( CompressedFile );
|
|
ALStorageSeek( CompressedFile, 32 + ( rand() & 31 ));
|
|
ALStorageWriteChar( CompressedFile, ( rand() & 0xff ) );
|
|
ALStorageClose( CompressedFile );
|
|
}
|
|
/*
|
|
* Now I try to extract the output file. Once I have done that, I perform
|
|
* a compare to the original to see how things went. Note that there is
|
|
* a tricky bit here. The only time ALFile objects will get new time/date
|
|
* and attribute stamps is if they are closed immediately after having been
|
|
* created. The CompressedObject->Extract() call will create the file,
|
|
* then close it. Once it is closed, the flag indicating that it was just
|
|
* created will be cleared, so I won't be able to set the time stamp. But,
|
|
* if *I* create it here, the Extract() function will leave it open after
|
|
* performing its magic. After it returns, I have to close the file,
|
|
* but I can mung the time/date stamp first.
|
|
*/
|
|
ALStorageCreate( OutputFile, AL_DEFAULT );
|
|
ALCompressedExtract( CompressedObject, OutputFile );
|
|
ALStorageSeek( OutputFile, 0L );
|
|
status = ALStorageCompare( DataFile, OutputFile );
|
|
printf( "Compare returned : %d\n", status );
|
|
/*
|
|
* If the comparison passed, I just delete all of the TMP files created
|
|
* here. (Note that they all have TMP names because I didn't give them
|
|
* any names in their constructors.)
|
|
*/
|
|
if ( status >= 0 ) {
|
|
ALStorageDelete( DataFile );
|
|
ALStorageDelete( CompressedFile );
|
|
ALStorageClose( OutputFile );
|
|
ALStorageDelete( OutputFile );
|
|
} else {
|
|
ALStorageSetTimeDateFromUnix(
|
|
OutputFile,
|
|
20L*365L*24L*60L*60L + 5L*24L*60L*60L + 12L*60L*60L );
|
|
atts = ALStoragePackedAttributes( OutputFile );
|
|
atts = (short unsigned int) ( atts | ATTR_READ_ONLY );
|
|
ALStorageSetFromPackedAtts( OutputFile, atts );
|
|
ALStorageClose( OutputFile );
|
|
ALCompressedSetError( CompressedObject,
|
|
status,
|
|
ALStorageGetStatusDetail( DataFile ) );
|
|
}
|
|
printf( "Compressed object status code: %d\n",
|
|
ALCompressedGetStatusCode( CompressedObject ) );
|
|
printf( "Compressed object status string: %s\n",
|
|
ALCompressedGetStatusString( CompressedObject ) );
|
|
printf( "Compressed object status detail: %s\n",
|
|
ALCompressedGetStatusDetail( CompressedObject ) );
|
|
|
|
deleteALCompressed( CompressedObject );
|
|
deleteALCompressor( Compressor );
|
|
deleteALDecompressor( Decompressor );
|
|
deleteALStorage( CompressedFile );
|
|
deleteALStorage( DataFile );
|
|
deleteALStorage( OutputFile );
|
|
return status;
|
|
}
|