Packages Come In All Sizes (by Eric Pankoke)

There will be very few instances where you will need to distribute an application without some sort of supporting file set. Whether you’re building a database system or a multimedia application, you might have one or more directories filled with extra material that you don’t necessarily want the user to see outside of the application itself. PPL provides a nice mechanism for this through the use of a Package file. A package file is a file that can contain one or more files of any type all bundled up together into one file with a .pkg extension. You can create a package file pro grammatically or you can use the Package Manager supplied with PPL to do so. Run the PPL console (it’s called PPL.EXE, and resides under the RUNTIME directory of your PPL install). From the File menu, select Package Manger. You can use this tool to view, create and manage package files. It’s pretty self explanatory, so I won’t really go into details here. Once you’ve created a package file, you’ll of course want to use it in your program. To open a package
file, you simply call:

handle$ = OpenPackage(AppPath$ + “mydata.pkg”, key$);

The first parameter is a full path and name to the file you wish to open, and the second parameter is the key used to unlock the package file. If a file with the name you’ve specified does not exist, OpenPackage will create it and use the value specified in key$ as the password. When creating a package file in the Package Manager you do not get the opportunity to supply a key, so key$ would be an empty string (“”). If you want a key, you will need to create the package pragmatically. You must be sure to keep track of the return value, as this is the handle that will be passed to all other package functions.

To retrieve the contents of a package file, call:

PackageFiles(&lst$, handle$);

This will provide you with a list containing the names of all of the files contained in the package. Of course, you will probably know all of these names already, so let’s get to the heart of the matter: extracting and using the files. There are currently two ways of retrieving a file. The quickest way is to call the following:

data$ = LoadPackageFile(handle$, “filename”);

This returns the contents of the file as a string in memory, which you can then display or manipulate however you choose. Currently, if the file is some sort of multimedia file or a database, this won’t be of much use to you. Starting in PPL v1.1, however, there are two new functions that will work in conjunction with LoadPackageFile called LoadSpriteFromMem and LoadSoundFromMem. These will be discussed more after 1.1 is released. For cases where you need to interact with the file in some way, you’ll want to call:

tmpfile$ = ExtractFileFromPackage(handle$, “filename”);

This function will retrieve the contents of the requested file and store it in a temporary file. The return value is the name of the temporary file where the data is stored. So let’s say you wanted to retrieve a database, do some work on it, then store the database back to the package. The code would look something like this:

dbfile$ = ExtractFileFromPackage(handle$, “MyData.db”);
dbhandle$ = sql_open(dbfile$);
if(dbhandle$ > 0)
//Check out the October newsletter for an SQLite primer
end;
dbnew$ = ExtractFilePath(dbfile$) % "aviator.db";
MoveFile(dbfile$, dbnew$);
AddFileToPackage(package$, dbnew$);
DeleteFile(dbnew$);

If you will need to place the file back into the package after you’ve done your work with it, the 3 lines following end; are necessary. ExtractFileFromPackage creates a random name for the file, and AddFileToPackage takes the name of the file you’re adding and uses that as the name inside of the package. So, if you want to replace the file that exists in the package with the version your application has just modified, you need to rename it to match the name that exists in the package. ExtractFilePath returns the path portion of a path / file name string, so if you use that on the file path returned from ExtractFileFromPackage, then use the file name that was used to add the file to the package initially, you can rename the temp file so that it will be stored correctly in the package again. The final step to updating the package is:

AddFileToPackage(handle$, “filename”);

The first parameter is that wonderful handle that was retrieved on your call to OpenPackage. filename is a string containing the full path and name of the file you wish to add. As mentioned before, the actual name of the file (no path) will be used to reference the file within the package. If you call AddFileToPackage with a file that already exists in the package, the file in the package will be replaced with the one you are adding. Finally, when all of your work is done and you don’t need the package any more, simply call:

ClosePackage(handle$);

This will make sure that the contents of the package have been updated and the handle will be released from memory.