231 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			231 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
//
 | 
						|
// ARCAA.CPP
 | 
						|
//
 | 
						|
//  Source file for ArchiveLib 2.0
 | 
						|
//
 | 
						|
//  Copyright (c) Greenleaf Software, Inc. 1994-1996
 | 
						|
//  All Rights Reserved
 | 
						|
//
 | 
						|
// CONTENTS
 | 
						|
//
 | 
						|
//  ALArchive::Append()
 | 
						|
//  ALArchiveAppendFromArchive()
 | 
						|
//
 | 
						|
// DESCRIPTION
 | 
						|
//
 | 
						|
//  This file contains the append from archive function.
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release
 | 
						|
 | 
						|
#include "arclib.h"
 | 
						|
#if !defined( AL_IBM )
 | 
						|
#pragma hdrstop
 | 
						|
#endif
 | 
						|
 | 
						|
#include "_openf.h"
 | 
						|
 | 
						|
//
 | 
						|
// NAME
 | 
						|
//
 | 
						|
//  ALArchive::Append()
 | 
						|
//
 | 
						|
// PLATFORMS/ENVIRONMENTS
 | 
						|
//
 | 
						|
//  Console  Windows  PM
 | 
						|
//  C++  C  VB  Delphi
 | 
						|
//
 | 
						|
// SHORT DESCRIPTION
 | 
						|
//
 | 
						|
//  Append a list of objects from an input archive to an existing archive.
 | 
						|
//
 | 
						|
// C++ SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  int ALArchive::Append( ALArchive &source_archive,
 | 
						|
//                         ALEntryList &source_list )
 | 
						|
//
 | 
						|
// C SYNOPSIS
 | 
						|
//
 | 
						|
//  #include "arclib.h"
 | 
						|
//
 | 
						|
//  int ALArchiveAppendFromArchive( hALArchive this_object,
 | 
						|
//                                  hALArchive input_archive,
 | 
						|
//                                  hALEntryList list );
 | 
						|
//
 | 
						|
// VB SYNOPSIS
 | 
						|
//
 | 
						|
//  Declare Function ALArchiveAppendFromArchive Lib "AL20LW"
 | 
						|
//    (ByVal this_object&,
 | 
						|
//     ByVal source_archive&,
 | 
						|
//     ByVal source_list&) As Integer
 | 
						|
//
 | 
						|
// DELPHI SYNOPSIS
 | 
						|
//
 | 
						|
//  function ALArchiveAppendFromArchive( this_object : hALArchive;
 | 
						|
//                                       source_archive : hALArchive;
 | 
						|
//                                       source_list : hALEntryList ) : Integer;
 | 
						|
//
 | 
						|
// ARGUMENTS
 | 
						|
//
 | 
						|
//  this_object  :   A reference or pointer to the ALArchive object that
 | 
						|
//                   is going to have the batch of files appended to it.
 | 
						|
//                   As always, the C++ version of this function doesn't
 | 
						|
//                   need 'this_object' as an argument, since C++
 | 
						|
//                   member functions get an explicit copy of this passed
 | 
						|
//                   when they are called.
 | 
						|
//
 | 
						|
//  source_archive : A reference to the archive that contains the objects
 | 
						|
//                   that are going to be added to this.  Since these
 | 
						|
//                   files are already compressed, this function can
 | 
						|
//                   really haul butt by just doing binary copies from the
 | 
						|
//                   source archive to this_object.
 | 
						|
//
 | 
						|
//  list         :  A reference to the ALEntryList that has copies of
 | 
						|
//                  all the storage objects to be inserted.  The list also
 | 
						|
//                  has the offset of all the objects in the source archive,
 | 
						|
//                  and their compressed sizes.
 | 
						|
//
 | 
						|
// DESCRIPTION
 | 
						|
//
 | 
						|
//  This function is called to insert a batch of objects into an archive.
 | 
						|
//  You might have noticed by looking at the header file ARC.H that this
 | 
						|
//  is not a virtual function, which means its behavior has to be
 | 
						|
//  generalized enough to support both Greenleaf and PKWare archives.
 | 
						|
//  All the specialization is done through the virtual functions that
 | 
						|
//  control directory information, object positioning, and so on.
 | 
						|
//
 | 
						|
//  All of the bookwork is done in this function.  Note that in order
 | 
						|
//  for this to work properly, we have to read in the entire directory
 | 
						|
//  into memory, because we are going to append to an existing file, and
 | 
						|
//  we assume the directory is at the end of the archive.  So the process
 | 
						|
//  basically consists of first reading the directory, then copying
 | 
						|
//  all the new jobs, then writing out the new combined directory.  The
 | 
						|
//  copying is done in another function, CopyJobs().
 | 
						|
//
 | 
						|
// RETURNS
 | 
						|
//
 | 
						|
//  An ArchiveLib status, ranging from AL_SUCCESS to any number of
 | 
						|
//  reasons for failure.
 | 
						|
//
 | 
						|
// EXAMPLE
 | 
						|
//
 | 
						|
// SEE ALSO
 | 
						|
//
 | 
						|
// REVISION HISTORY
 | 
						|
//
 | 
						|
//   February 14, 1996  2.0A : New release
 | 
						|
//
 | 
						|
 | 
						|
int AL_PROTO
 | 
						|
ALArchive::Append( ALArchive AL_DLL_FAR &source_archive,  /* Tag public function */
 | 
						|
                   ALEntryList AL_DLL_FAR &source_list )
 | 
						|
{
 | 
						|
    ALEntryList old_list( source_list );
 | 
						|
//
 | 
						|
// Open the storage object for this.
 | 
						|
//
 | 
						|
    ALOpenInputFile archive( *mpArchiveStorageObject );
 | 
						|
//
 | 
						|
// I read in the current directory for this archive.  I am going to
 | 
						|
// write over the directory with new stuff, so I will have to write it
 | 
						|
// back out later.
 | 
						|
//
 | 
						|
    ReadDirectory( old_list );
 | 
						|
    if ( mStatus < 0 )
 | 
						|
        return mStatus;
 | 
						|
//
 | 
						|
// The list of new objects I am going to add needs to be scanned for
 | 
						|
// duplicates.  First I clear duplicate entries from the list itself.
 | 
						|
// Then I clear any duplicates between the current list and the
 | 
						|
// stuff already in the archive.
 | 
						|
//
 | 
						|
    source_list.UnmarkDuplicates( source_list, "Duplicate entry in list passed to Append()" );
 | 
						|
    source_list.UnmarkDuplicates( old_list, "Duplicate entry in list passed to Append()" );
 | 
						|
//
 | 
						|
// Here is where I have to add new code to reflect the difference
 | 
						|
// between the two versions of Append()
 | 
						|
//
 | 
						|
//
 | 
						|
// Set up the monitor.
 | 
						|
//
 | 
						|
    source_list.mrMonitor.mlJobSoFar = 0L;
 | 
						|
    if ( source_list.mrMonitor.miMonitorType == AL_MONITOR_JOB )
 | 
						|
        source_list.mrMonitor.mlJobSize = CalculateCompressedJobSize( source_list );
 | 
						|
    PreCreate();
 | 
						|
//
 | 
						|
// CopyJobs() takes care of actually adding the jobs to the archive.
 | 
						|
//
 | 
						|
    CopyJobs( source_archive, source_list );
 | 
						|
//
 | 
						|
// All the jobs are written, now I can figure out where the
 | 
						|
// directory is in the storage object.  I copy it, then write
 | 
						|
// it out to the storage object at position 0.
 | 
						|
//
 | 
						|
    mlDirectoryOffset = mpArchiveStorageObject->Tell();
 | 
						|
//
 | 
						|
// Once I know the directory offset, it's safe to do
 | 
						|
// a PostCreate().
 | 
						|
//
 | 
						|
    PostCreate();
 | 
						|
//
 | 
						|
// Return without writing the directory if there is an error in the
 | 
						|
// archive storage object.
 | 
						|
//
 | 
						|
    if ( mpArchiveStorageObject->mStatus < 0 ) {
 | 
						|
        source_list.mrMonitor.ArchiveOperation( AL_ARCHIVE_CLOSE, this, 0 );
 | 
						|
        return mStatus = mpArchiveStorageObject->mStatus;
 | 
						|
    }
 | 
						|
//
 | 
						|
// Now I write the old directory out, and then add in the new
 | 
						|
// directory entries.
 | 
						|
//
 | 
						|
    source_list.mrMonitor.ArchiveOperation( AL_START_DIRECTORY_WRITE, this, 0 );
 | 
						|
    miCount = 0;
 | 
						|
    PreWriteDir();
 | 
						|
    ALEntry *job = old_list.GetFirstEntry();
 | 
						|
    while ( job ) {
 | 
						|
        if ( job->miMark ) {
 | 
						|
            miCount++;
 | 
						|
            WriteDirEntry( *job );
 | 
						|
        }
 | 
						|
        job = job->GetNextEntry();
 | 
						|
    }
 | 
						|
    job = source_list.GetFirstEntry();
 | 
						|
    while ( job ) {
 | 
						|
        if ( job->miMark ) {
 | 
						|
            miCount++;
 | 
						|
            WriteDirEntry( *job );
 | 
						|
        }
 | 
						|
        job = job->GetNextEntry();
 | 
						|
    }
 | 
						|
    PostWriteDir();
 | 
						|
//
 | 
						|
// Update the monitor, check for errors, then leave.
 | 
						|
//
 | 
						|
    source_list.mrMonitor.ArchiveOperation( AL_END_DIRECTORY_WRITE, this, 0 );
 | 
						|
    source_list.mrMonitor.ArchiveOperation( AL_ARCHIVE_CLOSE, this, 0 );
 | 
						|
    ScanStatus( source_list );
 | 
						|
    return mStatus;
 | 
						|
}
 | 
						|
 | 
						|
#if !defined( AL_NO_C )
 | 
						|
 | 
						|
extern "C" AL_LINKAGE int AL_FUNCTION
 | 
						|
ALArchiveAppendFromArchive( hALArchive this_object,  /* Tag public function */
 | 
						|
                            hALArchive input_archive,
 | 
						|
                            hALEntryList list )
 | 
						|
{
 | 
						|
    AL_ASSERT( ((ALArchive *) this_object)->GoodTag(),
 | 
						|
               "archive argument is not a valid ALArchiveBase" );
 | 
						|
    AL_ASSERT( ((ALArchive *) input_archive)->GoodTag(),
 | 
						|
               "input archive argument is not a valid ALArchiveBase" );
 | 
						|
    AL_ASSERT( ((ALEntryList *) list)->GoodTag(),
 | 
						|
               "list argument is not a valid ALEntryList" );
 | 
						|
    return ((ALArchive *) this_object )->Append( *(ALArchive *) input_archive, *( (ALEntryList *) list ) );
 | 
						|
}
 | 
						|
#endif
 | 
						|
 |