ZVFS is a Tcl extension that causes TCL to view the contents of a ZIP archive as real, uncompressed, individually-accessible files. Using ZVFS, you "mount" a ZIP archive on a directory of your filesystem. Thereafter, all of the contents of the ZIP archive appear to be files contained within the directory on which the ZIP file is mounted.
For example, suppose you have a ZIP archive named example1.zip and suppose this archive contains three files named abc.tcl, pqrs.gif, and xyz.tcl. You can mount this ZIP archive as follows:
zvfs::mount example1.zip /zip1
After executing the above command, the contents of the ZIP archive appear to be files in the /zip1 directory. So, for instance, you can now execute commands like these:
source /zip1/abc.tcl image create photo img1 -data /zip1/pqrs.gif puts "The size of file xyz.tcl is [file size /zip1/xyz.tcl]"
The files /zip1/abc.tcl, /zip1/pqrs.gif, and /zip1.xyz.tcl never really exist as separate files on your disk drive. They are always contained within the ZIP archive and are not unpacked. The ZVFS extension intercepts Tcl's attempt to open and read these files and substitutes data from the ZIP archive that is extracted and decompressed on the fly.
The ZVFS has been compiled into freeWrap. This extension provides the following new TCL commands:
As discussed above, the zvfs::mount command mounts a new ZIP archive file so that the contents of the archive appear to TCLl to be regular files. The first argument is the name of the ZIP archive file. The second argument is the name of the directory that will appear to hold the contents of the ZIP archive. The ZIP archive may be unmounted using the zvfs::unmount command.
The zvfs::exists checks to see if the file named as its first argument exists in a mounted ZIP archive. You can do almost the same thing with the built-in file exists command of TCL. The file exists command will return true if the named file is contained in a mounted ZIP archive. But file exists will also return true if its argument is a real file on the disk, whereas zvfs::exists will only return true if the argument is contain in a mounted ZIP archive.
The zvfs::info command takes a single argument which is the name of a file contained in a mounted ZIP archive. If the argument is something other than such a file, this routine returns an empty string. IF the argument is a file in a ZIP archive, then this routine returns the following information about that file:
The zvfs::list command returns a list of all files contained within all mounted ZIP archives. If a single argument is given, that argument is interpreted as a glob pattern and only files that match that glob pattern will match. If the -regexp switch appears then the argument is interpreted as a regular expression and only files that match the regular expression are listed.
The zvfs::filelcopy command may be used to copy a file from one location to another. ZVFS works by putting hooks into the TCL I/O subsystem. It turns out that the built-in file copy command of TCL bypasses the TCL I/O subsystem for efficiency reasons. Hence, file copy will not work on ZVFS files. The zvfs::filecopy command is provided as an alternative.
The files in a ZIP archive are read-only. You cannot open a ZVFS mounted file for writing.
ZVFS is implemented using the (undocumented) TclInsertProc() API of the TCL core. This API allows TCL extensions to intercept calls to check the status of files or to open files. But there is no provision for handling directory listings, so the glob command will not see ZVFS mounted files. Nor is there any way to intercept attempts to rename or delete files, so those operations are also not supported by ZVFS. Built-in commands or extensions that bypass the TCL I/O mechanism (ex: the file copy command and the "winico" extension) will not see ZVFS files.
You can source scripts that are ZVFS mounted files. But you cannot load new TCL extensions out of ZVFS. If you store a shared library or DLL in a ZIP archive, you'll have to first copy the DLL out of the archive into a real disk file before attempting to load it. You can use the built-in zvfs::filecopy command of TCL to copy the DLL out of ZVFS into a real disk file and then load the copy, if you like. You just can not load the DLL directly out of ZVFS. This is an operating system limitation.
ZVFS allows you to mount a ZIP archive on top of an existing filesystem. TCL first looks for the file in the ZIP archive and if it is not found there it then looks in the underlying filesystem. You can also mount multiple ZIP archives on top of one another. The ZIP archives are searched from the most recently mounted back to the least recently mounted.
This overlay behavior is useful for distributing patches or updates to a large program. Suppose you have a large application that contains many TCL scripts which you distribute as a single ZIP archive file. You can start up your application using code like the following:
foreach file [lsort -dictionary [glob appcode*.zip]] { zvfs::mount $file /appcode }
This loop finds all ZIP archive (in a certain directory) that begin with the prefix appcode. It then mounts each ZIP archive on the same /appcode directory.
You can use this scheme to ship the TCL scripts of your application in a file named appcode000.zip. If there is later a change or update to your program that effects a small subset of the TCL scripts, you can create a patch file named appcode001.zip that contains only the scripts that changed. By placing appcode001.zip in the same directory as appcode000.zip and restarting the application, all the files in appcode001.zip will override files with the same name in appcode000.zip. Subsequent updates can be named appcode002.zip, appcode003, and so forth.
This kind of update scheme makes it very easy to back out a change. Suppose after trying out a particular update, the user decides they do not like it and want to go back to the prior version. All they have to do is remove (or rename) the appropriate appcode*.zip file and restart the application and the code automatically reverts to its previous configuration. Updates are completely and trivially reversible!
The directory information for most executable formats is at the beginning of the file and the directory information for the ZIP archive format is at the end of the file. This means that you can append extra data to an executable and the operating system will not care and you can prepend information to a ZIP archive and the ZVFS extension will not care. So then, there is nothing to prevent you from appending the ZIP archive to the executable that contains a TCL interpreter and thereby put your entire application into a single standalone file.
FreeWrap is a compiled C program that creates a TCL interpreter, adds the ZVFS extention, reads the TCL initialization scripts from the attached ZIP archive then executes a TCL script from the same archive. A ZIP archiver program (InfoZIP) has been included into freeWrap's attached archive. It is used by freeWrap to perform all file additions and deletions to the archive portion of freeWrapped applications.
When you execute freeWrap or freeWrapped applications, the operating system loads and runs the first part of the file as the executable. Then the freeWrap code calls the ZVFS extension to read the TCL scripts from the end of the file.
The source to the ZVFS extension iscontained in a single C file named zvfs.c.