-
Notifications
You must be signed in to change notification settings - Fork 3
Architecture
The project depends on 7-zip DLL and we should not rely on traditional approach to locate & load the DLL. We need to be able to ensure that before using the objects within the project, the 7-zip DLL is loaded using the LoadLibrary
win32 API. This also implies the need to control the object creation to ensure that they are not created at wrong time or lead to a situation where a consuming codebase may cause either a memory leak or an access violation.
An ActiveX DLL does not allow use of a module. twinBasic does not currently support singleton objects (yet), so we cannot create a class that prevents users from trying to New
it up. Thus, a compromise was made to create a predeclared class ArchiveFactory
which forwards the calls to a private Objects
module. This way, a New'd
ArchiveFactory` would still appear to have the same "state" and we avoid redundant initialization, while offering the users the option to force a release. Technically a release is not required since it should be done automatically when the DLL is unloaded.
It is then through the ArchiveFactory
object that we can then create objects such as ArchiveExtractor
which is not creatable because it uses parameterized constructor. This help us avoid the common pattern in VBx world where we are forced to do something like this:
Set x = New Foo
x.Init(a, b, c)
Because this relies on a temporal coupling, requiring the users to make the invocation in correct sequence for the object to work correctly. We want to eliminate that, and using a factory is a good way to encapsulate the parameterized constructor and still make it available to the COM consumers that could otherwise not New
it directly themselves.
All interfaces are defined in the Abstract
subfolder and come from 7-zip's source code. At a high level, the 7-zip provides 2 groups of interfaces; one for extracting from an archive file, other for compressing into an archive file. However, both use streams to transfer data. In theory, we don't have to transfer to a file; we could directly copy to a database field, to some HTTP request, or whatever. For that reason, ADODB.Stream
object is used to help implement the Filestream
class in both directions.
However, because extracting an archive file may potentially generate files and folders, there will be multiple "out" streams created for each file and a separate process to handle creating folders, we need to orchestrate the extraction and compression process. For that purpose, the ArchiveExtractor
handles all the callbacks from 7-zip and provides the necessary out streams to allow 7-zip to write out the uncompressed data into the stream.