| VLIST XTRA HELP: METHODS DOCUMENTATION |
vList_register |  | READING AND STORING BINARY DATA |  | CREATING POPULATED LISTS
|  | writeBinary |  | newList
SAVING AND LOADING LISTS |  | readBinary |  | newPropList
newxtra |  | lengthBinary |  |
fileDialogOpen |  | binaryMode |  | LIST/DATATYPE INFORMATION
fileDialogSave |  |  |  | sortP
new xtra(urlString) |  | FILE UTILITY OPERATIONS |  | isSame
write |  | fileExist |  | numRef
read |  | deleteFile |  | float32P
new |  | fileSpace |  | float32
content |  |  |  | vList_size
|  | VLIST MEMBER OPERATIONS |  | vList_sizeOnDisk
ENCRYPTION |  | into |  |
write |  | after |  | EXPORTING DATA TO SHOCKFILER XTRA
read |  | before |  | vList_to_sf
encrypt |  | importFile |  |
decrypt |  | vList_readFromMedia |  | MISCELLANEOUS
encryptionStrength |  | vList_checkMedia |  | fpReset
|  |  |  | setFileName
COMPRESSION |  | LINGO LIST OPERATIONS |  | vList_version
instance.compression |  | concatenate |  |
member.compression |  | insertAt |  | ERROR REPORTING
|  | insertPropAt |  | vList_error
MIME BASE64 ENCODING |  | setPropAt |  | vList_errorString
b64_encode_compress |  | changeProp |  |
b64_encode |  | appendProp |  |
b64_decode |  | unsort |  |
|  | duplicateSort |  |
vList_register([111,222,333]) - global function, used to register Xtra. It can be called at any time, usually when the Director movie starts. Unregistered versions of the Xtra are functional for evaluation purposes, but will display a warning the first time you use a method other than vList_Register. vList serial number are strings, and have the generic format VLSXX-1111-2222-3333, where XX is the major Xtra version. In order to protect your serial number from being included as a string in your Director projectors or dcr movies, the vList_Register function requires only the three groups of numbers 1111, 2222 and 3333 inside a Director list. Leading zeroes do not need to be entered. An example: if your serial number is VLS20-0123-4567-0089 then you should register using the following command, usually on a startmovie handler: Lingo: vList_register([123, 4567,89]) JavaScript syntax : vList_register(list(123, 4567,89)) SAVING AND LOADING LISTS new xtra("vList",filepathString,|relativePathString|) new xtra("vList",filepathString,|optionsPropertylist|) new xtra("vList",filepathString,|singleoptionNumber|) - where filepathString is a string containing either the full path to the file, or just the file name; relativePathString is a string containing either a filename or the full path to the vlist file (Optional argument); optionsPropertylist is a property list containing path information (Optional argument); singleoptionNumber is an integer specifying one numeric option (Optional argument). Returns an instance of vList Xtra linked to the specified file. Creates a new instance of vList Xtra linked to a file. You must save the vList instance returned by this command into a variable and pass it as the first argument of read, write, readBinary or writeBinary. This command simply establishes the path to the target file. If the target file does not yet exist, it will not be created until a write executes. Simple Case Without Optional Parameters The simplest use of new is to pass a full file path in filepathString like this: inst = new xtra ("vlist", "C:\temp\myfile.lst") A subsequent use of read, readBinary, write or writeBinary will use the specified path to read or create the file. You can also pass just a filename in filepathString. inst = new xtra ("vlist", "myfile.lst") In that case, vlist determines the directory to use. vList automatically adds a file suffix of .LST to the filename passed in, if the filename does not already have a suffix, for compatibility with Windows file naming conventions. filepathString You can pass either the full path to the file or just the file name in filepathString. If you pass just a file name, vList constructs the path to the file when it is time to read or write as follows:
vList File Command | Authoring, Projector | Shockwave
write, read | same directory as movie (Lingo's the moviepath) | folder named "vLists" inside the Shockwave support folder
writeBinary, readBinary | same directory as movie (Lingo's the moviepath) | folder named "dswMedia" inside the Shockwave support folder
If the movie has not been saved yet so there is no moviePath, Director's authoring directory is used as the base. In Shockwave, a subfolder called "vLists" or "dswMedia" inside the Shockwave support folder on the user's boot drive is used as the base. The vLists folder is created by vList Xtra. The dswMedia folder is Macromedia's standard folder for restricted reading and writing of media files in Shockwave. Macromedia has changed the location and name of the DSWMEDIA folder several times. Since there is no function in the Xtras API to retrieve the path, it is up to Xtra developers to hardcode the changes into their xtras. You may notice on OSX that vList uses this path for Shockwave 10.0 HD:Library:Application Support:Macromedia:Shockwave 10:DswMedia and this one for Shockwave 10.1 HD:Users:User1:Library:Application Support:Macromedia:Shockwave 10:DswMedia and this one for Shockwave 11 HD:Users:User1:Library:Application Support:Adobe:Shockwave 11:DswMedia That is because Macromedia and Adobe changed the DSWMEDIA path between those 3 releases. Protected Web Media One way to make use of read/writeBinary in Shockwave is to retrieve needed media at runtime. Doing the following in Lingo links the cast member to a file named "image.jpg" in the user's local dswmedia folder: member("image").filename = "image.jpg" -- this Lingo command is currently broken on Mac in Shockwave but there is a workaround The following code extracts an image file from a remote vList container and links to it temporaily. When it is no longer needed, it can be deleted. preloadNetThing("http://www.mydomain.com/vListFile.lst") ... inst = xtra ("vList").new ("http://www.mydomain.com/vListFile.lst") -- Decrypt content, which is a property list that looks like -- [#FlashFile1: "dj+(&^jd883638..", #FlashFile2: "3bx638..." ...] propertyList = inst.read ([33, 44, 55, 22, 44, 66, 77]) binDataForOneFile = propertyList.FlashFile1 -- establish a path in dswMedia inst = xtra ("vList").new ("flashfile1.swf") inst.writeBinary (binDataForOneFile) -- link the file in dswMedia to a cast member member ("FlashFile1").filename = "flashfile1.swf" .... -- All done. Get rid of file. member ("FlashFile1").filename = empty inst.deleteFile() |relativePathString| If you pass just a file name, you can use the optional parameter relativePathString to specify a path in subfolders below the current movie's path. If you pass a full filepath in filepathString, relativePathString is ignored. If you pass a single or nested folder path in relativePathString and the folder does not exist, vList will create the folder or folder hierarchy when it creates the file. You can use the @ sign instead of the platform-specific path separators, in a relative path. The following relative path when issued from a projector: new (xtra "vlist", "datafile.lst", "Students@Morning") will translate into one of these depending whether it was running on Mac or PC [the moviePath]\Students\Morning\datafile.lst [the moviePath]:Students:Morning:datafile.lst When issued in Shockwave and used with the read command it will translate to: [Shockwave support folder]\vLists\Students\Morning\datafile.lst When issued in Shockwave and used with the readBinary command it will translate to: [Shockwave support folder]dswmedia\Students\Morning\datafile.lst Note: vList unfortunately has its own use for the @ sign that has nothing to do with Lingo's use of it to specify relative paths. In this vList context @ is only a substitute for \ or :. If vList sees @ at the beginning of a relative path string, it will try to resolve it as a system path, as described in the next section. vList does not impose any limit beyond what Director and the OS do on the length of the file name or entire file path. Limits cross-platform are 31 characters for file name including extension and 255 characters for the full file path including the file name. System Folder Key Words You can specify a system folder as the starting place for the relative path string by using a vList keyword at the beginning of the path. To write to one of the pre-defined system folders you start the relative path with the @ sign and the vList keyword for the folder you want to access. For instance, the following opens an instance of vList that will access the file at path C:\WINDOWS\SYSTEM\TEMP\SUBDATA.LST inst = new xtra ("vlist","data.lst","@TMPDIR\SUBFOLDER\DATA.LST" )
Keyword | Win 95 | Win 98 | class="colorvlist"Win NT | Win ME | Win 2000,XP | Mac Classic | Mac OSX
@SYSPRF | C:\ WINDOWS\ xtrasdir\ | C:\ WINDOWS\ xtrasdir\ | C:\ WINDOWS\ xtrasdir\ | C:\ WINDOWS\ All Users\ Documents \ | C: \ Documents and Settings \ All Users \ Documents \ | BootDrive : System Folder : Preferences: | BootDrive : Library : Preferences:
@USRPRF | C:\ WINDOWS\ xtrasdir\ | C:\ WINDOWS\ Application Data \ | C:\ WINDOWS\ Profiles \ [username] \ Application Data \ | C:\ WINDOWS\ Application Data \ | C: \ Documents and Settings \ [username] \ Application Data\ | BootDrive : System Folder : Preferences: | BootDrive : Users : [username] : Library : Preferences:
@TMPDIR | C:\ WINDOWS \ TEMP\ | C:\ WINDOWS \ TEMP\ | C: \ TEMP \ | C:\ WINDOWS \ TEMP\ | C: \ Documents and Settings \ [username] \ Local Settings\ Temp \ | BootDrive : Temporary Items: | BootDrive : private : tmp 501 : Temporary Items:
This method of accessing system folders is limited, but the key words and usage are easy to remember. Version 1.6.5 introduced a more comprehensive alternate method that uses system folder type numbers to access many more folders. You can use the @ sign in a system-defined folder path to make it work cross-platform: @TMPDIR@SUBFOLDER@DATA.LST You must start a system-defined folder relative path with an @ sign and the keyword in upper case, otherwise the key word will not be recognized. Note: On systems like XP and OSX the user may not have permission to write to some system directories. In that case vList returns an error and cannot complete the write. Shockwave When running under Shockwave, you cannot use a full path for the filepathString argument. You can, however, use the relative path arguments to create subdirectories in the Shockwave support folder or you can use the system-defined folders to save to those locations from Shockwave. Examples: fileLink = new xtra ("vList","C:\TEMP\STORE.LST") -- Creates a link to a file at the absolute path "C:\TEMP\STORE.LST" fileLink = new xtra ("vList","INFOFILE") -- Creates a link to file "INFOFILE.LST" in the same directory as the movie if running from projector -- Creates a link to file "INFOFILE.LST" in folder "vLists" at the root of the Shockwave support -- folder if running in Shockwave fileLink = new xtra ("vList","FOO.LST","DATA") -- Creates a link to file "FOO.LST" in the directory "DATA", which is a -- subdirectory of the movie's directory. fileLink = new xtra ("vList","Phonics","Lessons@English") -- Creates a link to file "Phonics.LST" in the directory "English", which is a -- subdirectory of "Lessons", which is a subdirectory of the movie's directory. -- The path "Lessons:English" will only work on both platforms because it uses -- the cross-platform path delimiter character. |optionsPropertylist| The options property list is a list of option names and their values. Since the options are named it doesn't matter what order they are passed in. The value of the #type option determines what other options can be specified and how they are interpreted. Folder Type Options [#type: foldertypeNumber, #domain: osxDomain, #location: pathRelativeToFolder] foldertypeNumber - Both the Windows and Mac System programming APIs have many predetermined directory paths that can be referenced from C code using a 4-byte value for the directory. For instance the Desktop folder and the current user's Documents folder have codes. vList can accept this value as an integer and pass it on to the system to allow access to any foldertype recognized by the API. There are hundreds of folder types on both platforms. Rather than duplicate them in vList doc, the Director movie prefs.dir contains the lists for both platforms and a script for easily accessing them by symbol or by number. You can find Microsoft documentation for folder types here. Apple doc for folder types is not so consolidated. These URL's are the place to start: constant_6.html APIIndex.html Note that Win doc represents the type code in hex and Mac doc represents it as 4 characters. The movie prefs.dir has handlers that you can use to convert either format into the integer representation that vList needs for the foldertype value. domain - Optional parameter. A domain is an OSX-only classification above folder type that determines that path to the folder type. Currently there are System, Local, User, Network and Classic domains. Domains codes are also referenced with a large integer in vList. The movie prefs.dir provides a list of domain types and code for finding the right number to use to reference a domain. Here is an example of how the same folder type points to two different paths depending on which domain is specified: Foldertype: kFontsFolderType (1718578804) Domain: kUserDomain (-32763) BootDrive: Users:username: Library: Fonts: Domain: kSystemDomain (-32766) BootDrive: System: Libarary: Fonts: You can learn more about domains here: constant_11.html location - Optional parameter. String containing a folder path relative to the folder specified by folder type and possibly domain. Example: -- kApplicationsFoldertype = 1634758771] --kSystemDomain = -32766 inst = new xtra("vlist","file.lst",[#type:1634758771 ,#domain: -32766, #location:"MyApp:Data" ]) The type and domain params together specify the path : BootDrive: Applications: The location param specifies a subdirectory, which will be created if it doesn't exist, relative to the initial directory: BootDrive: Applications: MyApp: Data: file.lst Open/Save Dialog Options [#type: -1, #prompt: dialogText, #location: initialDirectory] type - Passing a type of -1 causes an open file dialog to display when read or readBinary are used with the instance, and causes a save file dialog to display when write or writeBinary are used with the instance. The path to the file is obtained at this time from the user. If the user Cancels the dialog then the read or write op will return a "User access denied" error. prompt - Optional param. String with text to display on the dialog like "Choose your scores file" location - Optional param. In this context the location param does not contain a relative path. It contains the full path to the initial directory the dialog should show the user, or a folder type number for the initial directory. On Mac Classic, using #location to specify the start directory for the dialog is supported in System 8.5 and above. Examples: inst = xtra ("vList").new ("aFileName", [#type:-1]) inst = xtra ("vList").new ("aFileName", [#type:-1, #prompt: "a useful description"]) inst = xtra ("vList").new ("aFileName", [#type:-1, #prompt: "Choose your Music Prefs file", #location: 837474747]) inst = xtra ("vList").new ("aFileName", [#type:-1, #prompt: "Choose a folder to save your sounds", #location: "C:\dir1\dir2"]) Local Shockwave Playback Options [#type: -2, #location: relativePath] type - Passing a type of -2 causes vList to use "the moviepath" as a starting point when a Shockwave movie is located on the user's hard drive and playing back through Shockwave. Since you cannot build a path using "the moviepath" under Shockwave with Lingo, this feature allows you to save and read vList files and binary files relative to a Shockwave movie located on the user's hard drive. It does not allow you to save or read files relative to a Shockwave movie that resides on a web server. location - Optional param. String containing a folder path relative to the local Shockwave movie's path. Example -- Shockwave movie is at path "Macintosh HD:testing: movie.dcr" inst = new xtra("vlist","local.jpg",[#type: -, #location:"graphics"] -- The path to this file is "Macintosh HD:testing: graphics: local.jpg" data = inst.readBinary() |singleOptionNumber| If you only need to specify the type param without any additional options, you can pass the type number as the third parameter to new without creating an options property list. The value for type can be a folder type number, -2 or -1. Examples inst = new xtra("vlist","prefs.lst",1886545254) -- kPreferencesFoldertype -- Creates a path to file prefs.lst in the System Preferences folder inst = new xtra("vlist","local.lst",-2) -- Creates a path to file local.lst in the same folder as the local Shockwave movie inst = new xtra("vlist","test.lst",-1) -- Prompts the user for the path to "test.lst" when read, readBinary, write or writeBinary are used with this instance. vlistInstance.fileDialogOpen(|optionsPropertylist|) - where optionsPropertylist is a property list for customizing the dialog. Optional argument. Returns the filepath chosen in the dialog, or "" if no path was chosen. Always returns "" in Shockwave. This command returns the filepath chosen and also resets the filepath of the file instance to the chosen path. The string you pass in for filename when you create the instance will be overwritten with the path chosen or "" if the user cancelled the dialog. Do not pass a full file path in the instance if you are going to use file dialogs. They will not open if the existing path contains file separators ( : or \ ). In Shockwave this command allows you to work with a file the user has chosen, but you will not have access to the actual file path. The optionsPropertyList is the same format used for the new command, except you do not have to pass the #type property, which is ignored. Note: You should check the return value of this method or check vList_Error in case the user pressed Cancel, so you can discontinue further operations. If you call a read method for the instance after displaying a dialog where the user pressed Cancel, there is still no valid filepath, so the read method will display the Open dialog again. vlistInstance.fileDialogSave(|optionsPropertylist|) - where optionsPropertylist is a property list for customizing the dialog. Optional argument. Returns the filepath chosen in the dialog, or "" if no path was chosen. Always returns "" in Shockwave. This command returns the filepath chosen and also resets the filepath of the file instance to the chosen path. The string you pass in for filename when you create the instance is used for the default save file name in the dialog. Do not pass a full file path in the instance if you are going to use file dialogs. They will not open if the existing path contains file separators ( : or \ ). In Shockwave this command allows you to work with a file the user has chosen, but you will not have access to the actual file path. The optionsPropertyList is the same format used for the new command, except you do not have to pass the #type property, which is ignored. Note: You should check the return value of this method or check vList_Error in case the user pressed Cancel, so you can discontinue further operations. If you call a write method for the instance after displaying a dialog where the user pressed Cancel, there is still no valid filepath, so the write method will display the Save dialog again. newxtra("vList",urlString,) - where urlString is a string containing the URL for a file previously retrieved using the Lingo command preloadnetthing. Returns an instance of vList Xtra linked to the specified file in the internet cache. Creates a new instance of vList Xtra linked to a file fully downloaded into the internet cache. You must first download the URL using preloadnetthing and wait for netDone to return true before trying to read from the cached URL file. Save the vList instance returned by this command into a variable and pass it as an argument to read. This command simply establishes the path to the target file. If the target file does not yet exist, or is not yet fully downloaded, no error will occur until a read is issued. You can read from a cached URL but you cannot write to it or delete it. Example: property inProgress,netID,url on beginSprite me inProgress = false end on mouseUp me url = "http://www.macromedia.com/STORAGE.LST" netID = preloadNetThing(url) inProgress = true end on exitFrame me if inProgress = false then exit if netDone(netID) = true then inProgress = false if netError(netID) = 0 or (netError(netID) = "OK") then netFile = new xtra("vlist",url) alist = netFile.read() end if end if end vlistInstance.write(dataToStore,[encryption key]) - where vlistInstance is the instance previously created by the new method, dataToStore is a Lingo list or any other supported data type and encryption key is a linear list containing between 6 and 16 integers (Optional parameter). Returns 0 if successful, or a negative number in case of error. This error code can be misleading, and it is better in case of an error to look at the value returned by vList_error or vList_errorString. Do check the error status after a write. An unsuccessful read is usually due to a previous unsuccessful write. Writes out a list, or any other supported data type, to the filepath the instance is linked to. Creates the file if it does not exist. If the file name supplied does not have a .LST extension, vList adds the extension when it creates the file. If the file already exists, this method overwrites the existing file. Use fileExist to prevent accidental overwrite. Note: This command only works with local files. It returns an error if used with a cached URL file. Shockwave Under Shockwave, if the size of the new data you are writing exceeds 128K, the Xtra shows a dialog that allows the user to cancel the operation. In this case this command returns a negative value you can check with vList_error and vList_errorString. If the user allows the operation no further disk space limit is imposed on data written during the session. Examples: fileLink = new xtra("vlist","C:\TEMP\STORE.LST") alist = [1,2,3] if fileLink.write (aList) <> 0 then put vList_errorString() into field "status" end if -- with optional encryption fileLink.write(alist,[54,22,240,98,5,6]) vlistInstance.read([encryption key]) - where vlistInstance is the instance previously created by the new method and encryption key is a linear list containing between 6 and 16 integers (Optional parameter). Returns the contents of the file. Reads in a list, or any other data type that has been stored, from the file the instance is linked to. If the list contents have been encryptedthe contents are decrypted with the provided key. If the list contents have been compressed, vList detects the compression automatically and decompresses the contents. There is no explicit decompress command. If the vList instance is linked to a cached URL the file must be fully downloaded first using the Lingo command preloadNetThing call in order for the read to work. Note: If you use this command to read from a file not created by vList it will return an error. Examples: fileLink = new xtra("vlist","C:\TEMP\STORE.LST") thelist = fileLink.read() -- to decrypt a list encrypted with key [54,22,240,98,5,6] thelist = fileLink.read([54,22,240,98,5,6]) new(#vList) - Returns the newly-created vList member. The new member command is part of Lingo, and not technically a vList command. You can use Lingo's new command to create a new cast member of any type. vList Xtra adds a new cast member type of #vList which stores Lingo lists. Use the new command to create vList members on the fly in Lingo, or select Insert -> Database -> vList from Director's authoring menu. Example: newListMem = new(#vList) put newListMem -- (member 1 of castLib 1) Content Property of vList Member vList members have many useful properties but the most important one is "content". A vList member's content property contains the data it stores. You set and read the content property of a vList member to access its stored data, which most likely will be a list but can be any type of supported data. Either dot syntax or "the propertyname of" syntax will access the content property of a vList member. The syntax "put list into member vListMember" will also write a list to a vList member. Remember to check the error status after writing content to a vList member. An unsuccessful read is usually due to a previous unsuccessful write. When you set a variable to the content property of a vList member that contains compressed data, vList detects the compression, decompresses the data on the fly, and returns the decompressed data. There is no explicit decompress command. Examples: listStorageMember = new(#vList) put member(listStorageMember).content -- < Void > member(listStorageMember).content = ["a","b","c"] put the content of member(listStorageMember) -- ["a","b","c"] put [1,2,3] into member(listStorageMember) put member(listStorageMember).content -- [1,2,3] -- put member("vList member").content into aVariable localList = member("vList member").content ENCRYPTION vList Xtra employs AES (Advanced Encryption Standard) encryption , the standard for secret-key encrypted transfer of unclassified information recently adopted by NIST, the US National Institute of Standards, as a replacement for DES. vList Xtra encrypts list data with a block cipher, and a key length of 128 bits. (Psssst ... if your eyes are starting to glaze over, there is a good intro to cryptography that explains these concepts here.) This is the same key size used by the strongest level of Netscape's SSL (Secure Socket Layer) encryption, the standard that protects credit card numbers and other private information in a browser. In fact, 128-bit encryption is so strong that many countries, including the United States, place restrictions on the export of applications that use it. The list of integers required as an argument in vList Xtra's encrypt methods is used for the key. The maximum integers allowed in the list is 16 (16 * 8 bits per integer = 128 bits). The minimum is 6. Since 16 are needed for a 128 bit key, vList fills in any that are not passed, by itself. If more than 16 are passed, no error is returned but vList will only use the first 16. Since only 8 bits are allowed for each value, the maximum allowed value of any integer on the list is 255. If a larger value is passed the Xtra does a modulo 256 on the value to get a value it can use. For example 300 would be converted to 44. Starting with version 1.8.6, vList includes a function (vList_encryptionStrength) that lets developers reduce the encryption level used by the Xtra to 64-bit keys, if necessary due to export restrictions. Again, please consult the encryption section for more information on this. vList Xtra does not store the encryption key within an encrypted list file or list member, so it is very important to make a backup of the content of your encrypted members or list files. If you forget the encryption key, there is NO way to retrieve the content. AES encryption is very secure, but your list content can be recovered if someone guesses or uncovers your secret encryption key. It is essential that you take precautions to protect your key. Most people will opt to store the key in the Lingo code of the movie file that needs to access the encrypted files or members. This is the easiest thing to do, and there are some tips following to help you keep the key safe. vList Xtra does not restrict you to any particular form of key handling. If you do not want to store the key inside your Director movie, here are some examples of alternate schemes for encryption key-handling. - The key is in a separate file, either local or remote, with the path to the key or an assumption about the relative path in the code. - The user enters the key each time. It is not stored. - The key is on removeable media or a dongle that is inserted for use but stored elsewhere. Steps to follow in order to protect your encryption key in Director movie files When you protect your movies, Director strips the text of the Lingo code, and in the process also the code used to pass your encryption keys to vList Xtra methods. So the first precaution is to deliver your movies in protected form (*.DXR or *.CXR files) or, even better, in Shockwave compacted form (*.DCR or *.CCR files). Protected Lingo scripts are the only kind of information that lurkers and hackers have, for the most part, been unable to retrieve and study. All of the other Director member types are left unprotected and are fairly easy to access. This includes the content of pictures or 3D objects inside protected or even Shockwave compacted movies. This situation is the very reason why vList Xtra offers an encryption function, in order to fully protect the content of the information you deliver inside a Director file. vList Xtra uses a Lingo list of integer numbers to pass the key instead of strings. For example an encryption key like "password" should be passed to vList as: member (listMem).encrypt ("this is the text to store", [112, 97, 115, 115, 119, 111, 114, 100]) A list is used for the key instead of a string because string variables are visible even in a protected movie file. If a string variable was used for the key instead, someone could use a binary editor on your movie file, even protected by Director, and retrieve your keys, because strings are easily identifiable in a stream of binary data that otherwise is similar to a random succession of numbers. But you should go a step further and use lists of numbers that have no special meaning when translated to characters. This will make the life of eavesdroppers much more difficult. For example the previous key, even passed as a list of numbers is stored in a movie file by Director as: Å pÅ aÅ sÅ sÅ wÅ oÅ rÅ d As you can see we can still clearly recognize the word "password", so it is better to use a sequence of numbers that has no meaning as a word: -- this is better than using numbers that form in sequence a meaningful word or expression encryptKey = [187, 200, 55, 99, 44, 21] member (listMem).encrypt ("this is a text", encryptKey) But even if you do so, Director still stores initialization code that create a recognizable pattern, with numbers separated by the character "Å", as we can see from the preceding binary translation. So we also advise you to generate your keys at runtime, with Lingo code, instead of hardcoding the numbers, even if those numbers have no special meaning as character code: -- this one is better encryptKey = [] append encryptKey, 187 append encryptKey, encryptKey[1]+13 append encryptKey, encryptKey[2]-encryptKey[1]+42 ... member (listMem).encrypt ("this is a text", encryptKey) Another measure of protection is to deactivate the Lingo tracing mode when creating your key: encryptKey = generateMyKey(aNumber) member (listMem).encrypt (aList, encryptKey) The generateMyKey handler could be written as: on generateMyKey aNumber oldTrace = the trace the trace = false encryptKey = [] append encryptKey, aNumber append encryptKey, encryptKey[1]+15 append encryptKey, encryptKey[2]-encryptKey[1]+100 ... the trace = oldTrace return encryptKey end This way you can use the same code for the creation of the encryption and the decrytion key, and as long as you pass the same seed number, a Lingo handler will always returns the same result. You can create integer numbers greater than 255 and still use them because vList Xtra will apply a modulo operation that also will give always the same result: 1040 modulo 256 is equal to 528 modulo 256 which is equal to 16 But if you use a division operation in your key generating code, you must remember to cast the result to an integer, because Director will create a float number as a result of some code like: append encryptKey, 100 / 3 -- a float number is stored in the encryptKey list. This is not allowed -- so vList Xtra will return an error append encryptKey, integer (100 / 3) -- better, the result is truncated to the integer part and stored as 33 Also don't use global variables to store your key. If you do store a key list in a variable, be sure to use only a local variable. Finally, although vList allows you to enter a minimum of six 8-bit values, this is for convenience only during development. For complete protection, we encourage you to make full use of all 128 bits of encryption, and pass all sixteen 8-bit values to the vList encryption commands. In summary, for the best security: - Convert your movie files containing encryption keys to protected or Shockwave format - Do not use integers that form a word - Do not store your key in a global - Turn trace off before setting your key - Generate your encryption key at runtime with Lingo code - Pass all 16 encryption values vlistInstance.write(dataToStore,encryption key) - Encrypts data and writes it to a vList file. There is no separate command to encrypt a file. You encrypt a file by adding an encryption key parameter to the write command. read(vlistInstance.encryption key) - Decrypts data contained by the file and returns the decrypted data. There is no separate command to decrypt a file. You decrypt a file by adding an encryption key parameter to the read command. member(vList member).encrypt(dataToStore,encryptionCodeList) - where dataToStore is a Lingo list or any other supported data type and encryptionCodeList is a linear list containing between 6 and 16 integers. Encrypts and then stores the specified data in the vList member. Example: alist = [#dog,#cat,#bird] listMem = new(#vList) member(listMem).encrypt(alist,[45,90,232,159,45,12,65]) member(vList member).decrypt(encryptionCodeList) - where encryptionCodeList is a linear list containing between 6 and 16 integers. Retrieves and decrypts the list contained in the vList member. Example: decryptedList = member(listMem).decrypt( [45,90,232,159,45,12,65]) vList_encryptionStrength(encryptionBits) - where encryptionBits is 64 or 128. vList operates by default with 128-bit keys for encryption, but this can be reduced globally to 64, if necessary to comply with local export restrictions in some countries. This method was introduced in version 1.8.6, previous releases of vList shipped with 64-bit and 128-bit versions available as separate Xtras. Example: vList_encryptionStrength(64) COMPRESSION vList Xtra offers optional compression/decompression of data contained in vList members or files, using the ZIP algorithm. vList Xtra does not create standalone ZIP files. It creates files in vList format that contain compressed data. vList files containing compressed data can only be read by vList Xtra. vList Xtra cannot read standalone ZIP files. You compress data by first turning compression on for an empty file or member vList container, then putting the data you want to compress into the container. Activating compression for an empty file or member causes subsequent data written to the container to be compressed before it is stored.Setting the compression property to true or false via Lingo does not affect data already stored in the container. You don't have to do anything special to decompress data in a vList container. When vList Xtra performs any read operation on a file or member, it detects whether or not the data is compressed and automatically decompresses the data before returning the result of the read. Combining compression with encryption and Base64 encoding You can combine compression with encryption and Base64 encoding. The three are always applied in the same order, represented by the diagram below: Compression looks for redundancy in the data while encryption eliminates it, attempting to produce a random data stream. Compressing encrypted data would result in a very low compression ratio, therefore compression is always applied to the unchanged data. Base64 encoding must always be the last conversion applied, since it serves as the "envelope" that allows the data to be transmitted unchanged over the internet. When writing data, apply the three methods in this order: 1. Compress 2. Encrypt 3. Base64 Encode When reading data,vList commands perform the reverse process automatically: 1. Base64 Decode 2. Decrypt 3. Decompress The b64_decode function decodes a Base64 string, then decrypts the resulting data, if you pass a decryption key as one of the arguments. It then scans the decrypted data for a flag that indicates that it is compressed, and decompresses it if necessary. The read (file, key) and decrypt (member, key ) functions also automatically detect compression in decrypted data and perform decompression before returning the data. Activating compression for a member containing encrypted data returns an error message because the sequence for applying the two methods is out of order. The correct sequence is: mem = new (#vList) mem.compression = 1 mem.encrypt (someData, encryptionKeyList) To compress member data that is already encrypted, do the following: 1. Decrypt and read the content into a variable using decrypt (member, key ) 2. Put "" into the member to erase the current data 3. Activate compression for the member 4. Put the decrypted content back in to the member The following handler illustrates these steps: on compressEncryptedMember memName, encryptKey data = member (memName).decrypt (encryptKey) put empty into member(memName) member(memName).compression = true member(memName).encrypt (data, encryptKey) end Compressing bitmaps For #bitmap members, applying compression to the stored properties member().media or member().picture results in about the same space savings for either one. If you store and compress the member's image property instead, you will get better space savings. put member ("bitmap").image.duplicate() into member "vList" vListInstance.compression(compressionFlag) - where vlistInstance is the instance previously created by the new method and compressionFlag is true to activate compression, false to deactivate compression. No return. Use the compressed function to determine the current status. Activates or deactivates compression for the file. Function affects subsequent writes to the file but does not change any data currently contained in the file. Example: xTraInstance = new xtra("vlist", "myfile") -- activate compression xTraInstance.compression (1) xTraInstance.write (someData) if xTraInstance.compressed () then put "everything OK" else alert "data not compressed. problem" end if -- how much we gain on disk with compression put xTraInstance.compressionRatio() -- 60.5% member(vList member).compression = compressionFlag - where compressionFlag is true to activate compression, false to deactivate compression. Activates or deactivates compression for the member. Function affects subsequent writes to the member but does not change any data currently contained in the member. MIME BASE64 ENCODING Base64 encoding is a method of encoding data using only 6-bit characters for e-mail or internet transmission. MIME (Multipurpose Internet Mail Extensions) defines standards for transmitting internet messages and the various kinds of text and binary data they can include. You can use Base64 encoding to transform a binary vList file into a string that Director's postNetText command can send to a CGI script on a remote web server. The receiving CGI script can then store the data by one of the following methods: - Base64 decode the data and saves the resulting bytes into a binary file on the server. Since the data is a complete vList file before Base64 encoding, the receiving CGI script does not need any special logic to reconstruct the vList file.It must only decode the Base64 string and save the raw data to a binary file, which will then be a valid vList file. - Save the Base64 string to a file without decoding it. Later on when the file is retrieved from the server, use vList's b64_decode function to decode it. This is less efficient because the stored Base64 files will be larger than the vList files they contain, so they will take longer to download when retrieved. Sending Base64 strings via postNetText Every character in the string returned from b64_encode must be transmitted unchanged by postNetText, or it will not decode into a valid vList file later on. The following options in postNetText must be set correctly to insure accurate transmission by postNetText: Date sent as string, not property list: When you pass the data to be sent as a property list, postNetText URL-encodes some of the characters as though the data were coming from a form. Do not use the propertyList option to transmit a Base64 encoded string because it may change some of the characters in the string. ServerOS parameter must be set to "Win": The server OS parameter changes line ending characters in the data to the line endings used on the specified server platform. If you do not set this parameter it defaults to UNIX which will change all the line endings to just LF. You MUST set this parameter to "Win" regardless of what platform the receiving web server is on, otherwise the CR/LF (Win style) line endings in the Base64 string will be changed by postNetText and it will not decode correctly. Trouble-shooting failed transmission Using postNetText to transmit data to a CGI script successfully requires a good working understanding of network Lingo programming, the HTTP protocol, and CGI programming. You can further insure success by keeping the limitations of Director's postNetText in mind: do not try to use it in versions of Director or Shockwave prior to 8.5, or on the Mac in any environment other than Shockwave. If the data does not transmit and decode successfully on the server, here are some things to check: Verify the data sent: Save the text string created by b64_encode using FileIO Xtra before transmitting it. Use any utility that can decode MIME Base64, such as Stuffit Expander, to verify that the resulting file is a valid vList file. If the CGI is decoding the Base64 string, determine whether or not the CGI's Base64 decode function requires a MIME header: Some library functions for Base64 decoding accept only the Base64 data itself and will error out or produce no output data if they are passed a MIME header. Pass "" in b64_encode's filename parameter to get a Base64 string with no MIME header. Allow the server time to decode and save the file before trying to retrieve it. A very large file may take some time to decode and save. If you try to retrieve it before the process has finished you may get only a partial file or a network error. Verify the data received: Build debugging code into your CGI to help you verify that you are receiving the data intact: 1. Compare the environment variable "Content-length" to the length of the string you receive from the POST. They should be identical. 2. Compare the character values of each character received by the CGI to those sent (charToNum function in Lingo). This step will reveal any character substitution being done by postNetText. If this is happening, your postNetText options are not set correctly. 3. Use netTextResult: If you send debug output from your CGI, you can examine if from Lingo after netDone() returns true by using the netTextResult() function. 4. Save the Base64 string to a file before decoding: If your CGI is doing the Base64 decoding, add code to your CGI that saves the raw Base64 string to a file before decoding. Download the file to your local hard drive and use any utility that can decode MIME Base64, such as Stuffit Expander, to verify that the resulting file is a valid vList file. This step will help you narrow down whether the problem is with getting the data intact, or with decoding it. b64_encode_compress(data,fileName,compressionFlag,|encryptionKey or optionsList|) - where: data is a Lingo list or any other supported data type; fileName is the string filename to use in MIME header, or empty string. The filename is used by MIME decoders which will save the decoded file using the specified filename.Limited to 24 characters including the file extension. If an empty string is passed, no MIME header will be added to the returned data. If the filename is passed with no file extension, vList will add a .LST extension; compressionFlag is a boolean ( 1 or 0 ) value indicates whether or not to compress the data before encoding; encryption key or optionsList is a linear list containing between 6 and 16 integers or options property list. Optional parameter. Returns a string containing a vList file encoded using MIME base64 encoding Creates a vList file in memory ( optionally compressed and / or encrypted ) from the passed-in data, then MIME Base64 encodes the vList file and returns it as a string. This command accepts 4 params at most. If you want to use encryption and set the binaryMode flag, use a property list to hold both values: b64_encode_compress ("data to store", "myfile.lst", 1, [#encryptKey: [1,2,3,4,5,6,7,8], #binaryMode: 1] ) All of the following are valid syntax: encryptionKey = [1,2,3,4,5,6,7,8,9,10,11,12] b64_encode_compress (aLingoValue, filename, compressionFlag ) b64_encode_compress (aLingoValue, filename, compressionFlag, encryptionKey] ) b64_encode_compress (aLingoValue, filename, compressionFlag, [#binaryMode: 1] ) b64_encode_compress (aLingoValue, filename, compressionFlag, [#encryptKey: encryptionKey, #binaryMode: 1] ) b64_encode_compress (aLingoValue, filename, compressionFlag, [#encryptKey: encryptionKey] ) vList's b64_encode function returns a string with a MIME header and Base64 Content-Transfer encoding if you pass a file name in parameter two. Here is what the encoded data looks like: put b64_encode_compress([1,2,3],"myfile.lst",0 ) -- "MIME-Version: 1.0 Content-Type: application/octet-stream; name="myfile.lst" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="myfile.lst" AAAAAQAAAr463mixAAAAAwAAADgAAACMAAAABwABAAAAAAAAAQAAAAAAAAAAAAAAAAAAXAAA AGgAAAAAAAAATBMHB9EAAAAAAAAAAII7npKl1hHUv4gAUOSQMhoAAAAHAAAAAAAAAAEAAAAH AAAAAwAAAAEAAAABAAAAAQAAAAEAAAACAAAAAQAAAAM= " If you pass an empty string for the filename parameter, the b64_encode function will return only the Base64 encoded data with no MIME header: put b64_encode_compress([1,2,3],"", 0) -- "AAAAAQAAAFU63mixAAAAAwAAAEgAAACMAAAABwABAAAAAAAAAQAAAAAAAAAAAAAAAAAAXAAA AGgAAAAAAAAATBAHB9EAAAAAAAAAAII7npKl1hHUv4gAUOSQMhoAAAAHAAAAAAAAAAEAAAAH AAAAAwAAAAEAAAABAAAAAQAAAAEAAAACAAAAAQAAAAM=" Examples: -- Compresses list "animals" because the compression flag parameter is 1, then -- creates a vList file in memory out of the compressed list, then converts the file -- into a MIME Base64 encoded string, which will be returned into variable aString. -- When aString is later decoded, the decoder will name the resulting file -- "animallist.lst". vList added the .lst extension to the file name. -- animals = [#dog,#cat,#bird] aString = b64_encode_compress (animals,"animallist", 1) -- Converts variable data into a one-item list, encrypts the list, then converts the -- list into a vList file in memory, then converts the file -- into a MIME Base64 encoded string, which will be returned into variable aString. -- When aString is later decoded, the decoder will name the resulting file -- "imagedata.lst". The resulting will be an encrypted vList file. -- data = member(15).media aString = b64_encode_compress (data,"imagedata.lst", 0 ,[10, 20, 30, 40, 50, 60, 70]) -- Base64 encoding combined with postNetText -- on mouseUp me url = "http://www.domain.com/cgibin/filercgi" listtosend = [1,2,3,4,5] sendString = b64_encode_compress(listtosend,"", 0) postNetText(url,sendString,"Win") end b64_encode(data,fileName,|encryptionKey or optionsList|) - where: data is a Lingo list or any other supported data type; fileName is the string filename to use in MIME header, or empty string. The filename is used by MIME decoders which will save the decoded file using the specified filename.Limited to 24 characters including the file extension. If an empty string is passed, no MIME header will be added to the returned data. If the filename is passed with no file extension, vList will add a .LST extension; encryption key or optionsList is a linear list containing between 6 and 16 integers or options property list. Optional parameter. Returns a string containing a vList file encoded using MIME base64 encoding. Creates a vList file in memory ( optionally encrypted ) from the passed-in data, then MIME Base64 encodes the vList file and returns it as a string. See b64_encode_compress for more information. This command accepts 3 params at most. If you want to use encryption and set the binaryMode flag, use a property list to hold both values: b64_encode ("data to store", "myfile.lst", [#encryptKey: [1,2,3,4,5,6,7,8], #binaryMode: 1] ) All of the following are valid syntax: encryptionKey = [1,2,3,4,5,6,7,8,9,10,11,12] b64_encode (aLingoValue, filename ) b64_encode (aLingoValue, filename, encryptionKey] ) b64_encode (aLingoValue, filename, [#binaryMode: 1] ) b64_encode (aLingoValue, filename, [#encryptKey: encryptionKey, #binaryMode: 1] ) b64_encode (aLingoValue, filename, [#encryptKey: encryptionKey] ) Example: put b64_encode([1,2,3],"myfile.lst") -- "MIME-Version: 1.0 Content-Type: application/octet-stream; name="myfile.lst" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="myfile.lst" AAAAAQAAAr463mixAAAAAwAAADgAAACMAAAABwABAAAAAAAAAQAAAAAAAAAAAAAAAAAAXAAA AGgAAAAAAAAATBMHB9EAAAAAAAAAAII7npKl1hHUv4gAUOSQMhoAAAAHAAAAAAAAAAEAAAAH AAAAAwAAAAEAAAABAAAAAQAAAAEAAAACAAAAAQAAAAM= " listData = b64_decode(MIMEencodedString,|encryptionKey or optionsList|) - where MIMEencodedString is a MIME Base64 string previously created by vList and encryption key is a linear list containing between 6 and 16 integers, or property list for multiple params (Optional parameter). Decodes a MIME Base64 string created by vList, into a vList file in memory. Then decrypts the file if it is encrypted, extracts the content property (the list or other data stored in the file) , decompresses the content if it is compressed,and returns it into the variable. This command accepts 2 params at most. If you want to decrypt and set the binaryMode flag, use a property list to hold both values: b64_decode ( encodedString, [#encryptKey: [1,2,3,4,5,6,7,8], #binaryMode: 1] ) All of the following are valid syntax: encryptionKey = [1,2,3,4,5,6,7,8,9,10,11,12] b64_decode (encodedString ) b64_decode (encodedString, encryptionKey ) b64_decode (encodedString, [#binaryMode: 1] ) b64_decode (encodedString, [#encryptKey: encryptionKey, #binaryMode: 1] ) b64_decode (encodedString, [#encryptKey: encryptionKey] ) Note: this function was designed to decode Base64 strings created by vList Xtra. Possibly a future version will add the ability to decode MIME Base64 strings created by other sources. Example: thelist = [1,2,3] encrypted_then_encoded_string = b64_encode(thelist,"",[10, 20, 30, 40, 50, 60, 70]) put encrypted_then_encoded_string -- "AAAAAQAAAr463mixAAAAAwAAADgAAACMAAAABwABAAAAAAAAAQEAAAAAAAAAAAAAAAAAXAAA AGgAAAAAAAAATB8HB9EAAAAAAAAAAIzGlRp1Seh1UEaQNVrsaydgmBX/TmuhLaXB2/xQ/M4z 5ngUgYAvp58qr0JBz0G4ArB51LitXv2MPaBsZOOxXAK= " get_it_back = b64_decode(encrypted_then_encoded_string,[10, 20, 30, 40, 50, 60, 70]) put get_it_back -- [1,2,3] READING AND STORING BINARY DATA The following commands allow vList to read and create files of binary data. Previously vList was only able to read from files in vList format. You can use these commands to do things like: - Read in a media file, store it internally in a vlist member, then recreate the media file at a later date - Copy files - Read a local file in and transmit it using postnettext or ShockFiler Xtra Null byte Lingo requires a string to end with a null (0) byte character in order for operations like length(string) and char x of string to work correctly. To accommodate Lingo, vList's readBinary function automatically adds a null character to the the end of the binary data it is reading in. It does not add a null to a binary string it writes out with writeBinary. This behavior should work transparently both for binary files you plan to read and write using only vList and for binary Files you write for other applications to read. If you need behavior other than the default (writeBinary - no null, readBinary - add null), use the nullFlag optional parameter with readBinary and writeBinary to control whether or not the null bytes is appended to the binary string. Null bytes are not an issue for the normal read or write commands.There is no nullFlag param for those commands. IMPORTANT: In beta versions 1.6.5 and 1.6.7 the behavior for readBinary and writeBinary was reversed. WriteBinary wrote a 0 byte to the end of every file and readBinary did not add any byte to the string it read in. This behavior caused problems because some programs reading the binary files with the extra 0 character would not read the files. Also Director wants any string it reads in to be terminated with the 0 character. So it made sense to change the default behavior from: 1.6.5,1.6.7 writeBinary - added 0 char readBinary - did not add any 0 char to 1.6.9 writeBinary - does not add 0 char readBinary - adds a 0 char to the string it reads in If you are having crash problems reading in data you stored with 165 or 167 writeBinary or readBinary into vlist container, the easiest thing to do is to store the data again using 169 and the default null setting. Or you can use the null setting to turn the null character on or off depending on how the data was previously stored. vlistInstance.writeBinary(binaryDatastring,[nullFlag]) - where: vlistInstance is the instance previously created by the new method; binaryDatastring is the string containing binary data; nullFlag is Optional. 1 to append a null character to the binary string written out to the file, 0 not to append null. Default is 0 if this param is not passed; Returns 0 if successful, or a negative number in case of error. This error code can be misleading, and it is better in case of an error to look at the value returned by vList_error or vList_errorString. Do check the error status after a write. An unsuccessful read is usually due to a previous unsuccessful write. Creates or overwrites a binary file at the path specified for the instance. Unlike the write method, this method does not create a vList file containing the data. It creates a binary file made out of the data in binaryDatastring. So the data in binaryDatastring must be sufficient to create a self-standing file of the type desired. Note: an Xtra has to be intentionally written to manage binary data stored in a Lingo string so that Director doesn't truncate the data on a 0 byte. If you are reading data from any source other than readBinary or BinaryIO Xtra into a Lingo variable, and later writing it out using writeBinary, please use lengthBinary(binaryString) first, to make sure that the length of the data is correct. -- read in a JPEG file vListInstance = new xtra("vlist", "image.jpg") aString = vListInstance.readBinary () if not stringP(aString) then put "the file was not read" abort end if -- now write under another name vListInstance = new xtra("vlist", "image2.jpg") res = vListInstance.writeBinary (aString) if res < 0 then put "the file was not written" abort end if readBinary(vlistInstance.[nullFlag]) - where: vlistInstance is the instance previously created by the new method; nullFlag is Optional. 1 to append a null character to the binary string read from the file, 0 not to append null. Default is 1 if this param is not passed; Returns the contents of the file. Reads data from a binary file into a Lingo string variable. If the vList instance is linked to a cached URL the file must be fully downloaded first using the Lingo command preloadNetThing call in order for the read to work. Example 1 -- Display a dialog and read in file vListInstance = new xtra("vlist", "image.jpg",-1) binaryData = vListInstance.readBinary () storageMem = new(#vlist) -- store data in vlist member storageMem.content = binaryData Example 2: property inProgress,netID,url on beginSprite me inProgress = false end on mouseUp me url = "http://www.macromedia.com/picture.gif" netID = preloadNetThing(url) inProgress = true end on exitFrame me if inProgress = false then exit if netDone(netID) = true then inProgress = false if netError(netID) = 0 or (netError(netID) = "OK") then netFile = new xtra("vlist",url) binData = netFile.readBinary() localFile = new xtra("vlist","localpict.gif") localFile.writeBinary(binData) end if end if end lengthBinary(binaryDatastring) - where binaryDatastring is a Lingo string variable containing binary data. Returns an integer length of the binary data in the variable. Use this instead of the Lingo length() function to return the length of a binary string variable. Most of the time this value will be one more than the Lingo length function for the same variable, but sometimes it will not match it at all. y = new xtra("vlist","file.pdf") bin = y.readBinary() put lengthBinary(bin) -- 8810 vListInstance.binaryMode(boolean) member("vlist").binaryMode = boolean - where vlistInstance is the instance previously created by the new method and boolean is true to turn on binary storage for future writes. No return. vList, by default, performs cross-mapping on characters above numToChar(127) in strings stored inside its vList files and members. This enables strings containing only text to display the correct accented characters on Mac and PC. The default cross-mapping behavior is not desireable for strings containing binary data because it will corrupt the data. Turn off the default cross-mapping behavior by turning the binaryMode option on for a vList file or member before putting binary data into it. Note: You do not need to use binaryMode on an instance that you use to access a non-vList file. Data read using readBinary or written using writeBinary is always handled as binary. This option is only relevant for vList containers. -- an external vList file vListInstance = new xtra("vlist", "image.gif") aBinaryString = vListInstance.readBinary() vListInstance = new xtra("vlist", "storage.lst") -- we are going to store binary data in a vlist file vListInstance.binaryMode (true) vListInstance.write (aBinaryString) -- a vList member mb = new (#vList) mb.name = "aBinaryMember" mb.binaryMode = true mb.content = aBinaryString The binaryMode option works for read as well. You can turn cross-mapping on and off to read the same data string with high-ASCII characters cross-mapped for the platform and without. on writeMac astring = numToChar(128) vListInstance = new xtra("vlist", "storage.lst") vListInstance.write (astring) end on readonPC_WithMapping vListInstance = new xtra("vlist", "storage.lst") data = vListInstance.read() alert(string(charToNum(data))) -- 196 end on readonPC_WithoutMapping vListInstance = new xtra("vlist", "storage.lst") vListInstance.binaryMode(true) data = vListInstance.read() alert(string(charToNum(data))) -- 128 end If the original data was written with binaryMode on, you can still turn binaryMode off to read it in. This may be useful in the case where the binary file contains fields of text data at known offsets. In that case you can do two reads, one as binary to preserve the file, and one with binary turned off into a second variable. You can then extract the cross-mapped text from the second variable. Check the vList container's binaryContent property to determine whether or not it was written with binaryMode turned on. FILE UTILITY OPERATIONS The following commands require an instance of vList linked to a file, which is created with the new command. vlistInstance = new xtra("vlist","datafile.lst") vlistInstance.fileExist([encryption key]) - where vlistInstance is the instance previously created by the new method and encryption key is a linear list containing between 6 and 16 integers (Optional parameter). Returns 1 if a file at the path specified previously in the new command, exists and it is a vList file, 2 if it exists but it is not a vList file, or 0 if it doesn't exist. If the optional encryption key parameter is passed, the function will only return 1 if a vList file exists at the path and the file is encrypted with the specified key. Examples: -- File "C:\TEMP\FOLDER\DATA.LST" does not exist at all myFile = new xtra("vlist", "C:\TEMP\FOLDER\DATA.LST") put myFile.fileExist() -- 0 -- A vList file exists at "Work:Project:foo.lst" with an encryption key -- of [213,222,89,23,43,12,45] myFile = new xtra("vlist", "Work:Project:foo.lst",[213,222,89,23,43,12,45] ) put myFile.fileExist([213,222,89,23,43,12,45]) -- 1 -- Sequence of commands to check for readable encrypted files -- fil = new xtra("vlist", "vlistFile.lst") if fil.fileExist() = 1 then -- we have a valid vList file here if fil.encrypted() then if fil.fileExist(myEncryptKey) then -- file is encrypted and we have a valid key else -- encrypted, but we have forgotten the key end if else -- the file exists and is not encrypted end if else -- no vList file, we can safely create one by that name end if vlistInstance.deleteFile() - where vlistInstance is the instance previously created by the new method. Returns 0 if successful, or a negative number in case of error (this error code can be misleading, and it is better in case of error to look at the value returned by vList_error or vList_errorString). Deletes the file at the path specified previously in the new command. This command will delete any file by the specified name, not just vList files. Note: This command only works on local files. You cannot use this command successfully if the vList instance is linked to a URL file in the internet cache. Example: -- Delete the vList file at "C:\TEMP\FOLDER\DATA.LST" -- myFile = new xtra("vlist", "C:\TEMP\FOLDER\DATA.LST") myFile.deleteFile() bytesWritten = vlistInstance.fileSpace( ) - where vlistInstance is the instance previously created by the new method. Returns an Integer amount of data written to new files during this session, in bytes. This function is useful in Shockwave to monitor the amount of data you are writing so that you will know when you are getting near the limit (128K) that will trigger a security dialog that asks the user for permission for further writes. The function reports data written to vList files during one session, a session being the period of time the user keeps the browser page open that contains the Shockwave movie that loaded vList Xtra. Going to amother movie that loads into the same page, continues the session. Going to another HTML page containing another movie, from the original movie, ends the session. The filespace function, tells you how many bytes that count toward the limit of 128K (131072 bytes), you have already written to other files during the session. The filespace function is tied to the current file instance. It is telling you, "This is the number of bytes counting toward the limit that are already used, if you write to the current file.". The value can be positive or negative. A negative value is a credit. To calculate the maximum number of bytes you can write to the current file without triggering the Shockwave dialog: inst = new xtra("vlist","foo.lst") val = inst.filespace() limit = 131072 safeWriteBytes = limit - val So if val is -30000, which is a 30000 credit, 131072 - (-30000) results in a total allowed write of 161072. (131072 + 30000 credit) The filespace value returned for an open file instance does not change for the instance while you have it open, unless you delete the file. Checking it before and after a write will return the same value. If you open another file, check filespace again before writing, to get an updated value for the current file that takes into account what you wrote to the previous file. The filespace value is cumulative. If you create file1 and write 100K to it, then create file2 in the same Shockwave session and attempt to write 29K or more to it, you will trigger a user permission dialog. If you open and write to an existing file you have a credit for the entire size of the file, even if the file is larger than the 128K limit. The reason for this exception is that if the file is already on disk, then writing data less than or the same size as the data already there cannot cause disk space problems for the user. Any new bytes you write to an existing file during the current session are subtracted from the credit when you close the file and open another file. If FileA exists and is 100 bytes long, you have 100 bytes of credit as long as you keep writing to FileA. If you write 50 bytes to FileA, then open FileB, the 50 new bytes are subtracted from the credit and you now have 50 bytes of credit to apply to future writes. Note that vList does not check to see whether or not a file is a vList file when a "new" command is issued. If you use new to create an instance of vList linked to a non-vList file, then do inst.fileSpace(), it will show a credit for the non-vList file.
Action | Filespace value
Create FileA | 0
Write 50 bytes to FileA |
Create FileB | 50
You have written 50 bytes to A toward the limit
Open existing FileA size 100 bytes | -100
Write 50 bytes to A |
Create FileB | -50
Opening existing FileA gave a 100 byte credit. The 50 bytes of new data written to A was subtracted from the credit, leaving a 50 byte credit.
Open existing FileA size 100 bytes | -100
Write 150 bytes to A |
Create FileB | 50
The 150 new bytes written to A was offset by the 100 bytes credit, leaving a net of 50 new bytes written this session.
Open existing FileA size 100 bytes | -100
Delete FileA | 0
Deleting a file erases its credit.
Open existing FileA size 100 bytes | -100
Write 50 bytes to A |
Delete FileA | 50
If FileA had not been deleted, its credit would have been applied and offset the 50 new bytes written for a net of -50, but deleting the file erased the credit and the entire 50 bytes count toward the limit.
Example: inst = new xtra("vlist", "aFile") alist = [1,2,3] temp = new(#vlist) temp.content = alist totalSize = inst.fileSpace() + member(temp).sizeOnDisk if (totalSize < 128*1024) then -- no shockwave warning dialog inst.write (aList) else -- shockwave warning dialog will be shown -- if we write to the file, so do something else end if VLIST MEMBER OPERATIONS The following operations borrow familiar syntax usually associated with fields and strings to alter the contents of vList members. Adding data with these methods to a sorted list stored inside a vList member returns the list to an unsorted state. Note: It is important to use full member syntax with these commands. Correct memberRef = new(#vList) put list after member(memberRef) Incorrect memberRef = new(#vList) put list after memberRef put data into member(vList member) - Puts a list or any data value into the specified vList member. (Lingo only) Example: put [1,2,3] into member("listStorage") put member("listStorage").content -- [1,2,3] put 2551 into member("listStorage") put member("listStorage").content -- 2551 put aList after member(vList member) - Appends the data to the vList member's current content. (Lingo only). If the current content of the vList member is a list, the data to append must also be a list of the same type otherwise vList will return "handler not defined". If the two lists are the same type, the items contained by the passed-in list are appended to the existing list. If the current content of the vList member is some other data type, vList will convert its content to a linear list consisting of the original data item followed by the one to append. Examples: put member("listStorage").content -- [1,2,3] put [4,5,6] after member("listStorage") put member("listStorage").content -- [1,2,3,4,5,6] put member("listStorage").content -- [#dog:1,#horse:2] put [#camel:8] after member("listStorage") put member("listStorage").content -- [#dog:1,#horse:2,#camel:8] put member("listStorage").content -- 85 put 47 after member("listStorage") put member("listStorage").content -- [ 85,47 ] put member("bitmap").media into member("listStorage") put member("listStorage").content -- (media fad8890) put 2 after member("listStorage") put member("listStorage").content -- [(media fad8890), 2] put aList before member(vList member) - Prepends the data to the vList member's current content. (Lingo only) If the current content of the vList member is a list, the data to prepend must also be a list of the same type otherwise vList will return "handler not defined". If the two lists are the same type, the items contained by the passed-in list are put before the items in the existing list. If the current content of the vList member is some other data type, vList will convert its content to a linear list consisting of the passed-in data followed by the original data item. Examples: put member("listStorage").content -- [1,2,3] put [4,5,6] before member("listStorage") put member("listStorage").content -- [4,5,6,1,2,3] put member("listStorage").content -- [#dog:1,#horse:2] put [#camel:8] before member("listStorage") put member("listStorage").content -- [#camel:8,#dog:1,#horse:2] put member("listStorage").content -- 85 put 47 before member("listStorage") put member("listStorage").content -- [ 47,85 ] member(vList member).importFile(| filePathString |) - where filePathString is either a full path to the vList file to import or just a file name. If just a file name is passed, vList looks for the file in the current movie's directory (Optional argument). Returns 0 if successful, or a negative number in case of error (this error code can be misleading, and it is better in case of error to look at the value returned by vList_error or vList_errorString). Imports the list contained in a vList file into a vList member. If filePathString is not passed, puts up a file picker dialog. This command is not available in Shockwave. Example: -- puts up a file picker and imports the chosen vList file importFile(member("listStorage")) -- imports vList file "scores.lst" in the movie's directory importFile(member("listStorage"),"scores.lst") -- imports the vList file at the specified path importFile(member("listStorage"),"Macintosh HD:games:scores.lst") mediaContents = vList_readFromMedia(vListMediaProperty[encryptionKey]) - where vListMediaProperty is the the media property of a vList member either stored in a variable or obtained from member(vlist).media and encryption key is a linear list containing between 6 and 16 integers (Optional parameter). Returns the data contained in the vList media. Provides a shortcut for retrieving data from vList members that have been stored inside other vList members or files by storing (vList member).media. Also provides a workaround for a problem with setting the media property of a vList member in a repeat loop. Example: -- one vList member stores the media of several others testList = list (member("vList1").media, member("vlist2").media) member("storage").content = testlist -- later, we want to retrieve the data -- Long way to extract data scratch = new(#vlist) scratch.media = member("storage").content[1] dataWeWant = scratch.content erase scratch -- Short way dataWeWant = vList_readFromMedia(member("storage").content[1]) OKflag = vList_checkMedia(vListMediaProperty,[encryptionKey]) - where vListMediaProperty is the the media property of a vList member either stored in a variable or obtained from member(vlist).media and encryption key is a linear list containing between 6 and 16 integers (Optional parameter). Returns 1 if the media is intact, 0 if it is corrupt. Utility function helpful in diagnosing a problem with setting the media property of a vList member in a repeat loop. Example: -- one vList member stores the media of several others testList = list (member("vList1").media, member("vlist2").media) member("storage").content = testlist -- later, we want to retrieve the data scratch = new(#vlist) storedVlistMedia = member("storage").content[1] if vList_checkMedia(storedVlistMedia) then scratch.media = storedVlistMedia end if LIST OPERATIONS The following vList commands operate on Lingo lists. concatenate(list, list, ..., list) - Returns a list containing the list elements of the second, third, and so on ... list(s) appended to the end of the first list Appends the elements of the second (or more) list argument(s) to the end of the first list. All the lists must be the same type - property or linear. Concatenates the lists passed in, in place, which destroys the original lists. If there is an error, this command displays an error dialog in authoring mode, which is consistent with Director's handling of errors on list operations while in authoring. However unlike Director, vList does not display the error dialog in projectors or in Shockwave mode. Example: a = [1,2,3] b = [4,5,6] c = concatenate(a,b) put c -- [1,2,3,4,5,6] put a -- [ ] put b -- [ ] insertAt(linearList,positionNumber,anyValue) - where positionNumber is the integer index position to insert the item and anyValue is the data to insert into the list. Returns 0 if successful, or a negative number in case of error (this error code can be misleading, and it is better in case of error to look at the value returned by vList_error or vList_errorString). Also if there is an error, this command displays an error dialog in authoring mode, which is consistent with Director's handling of errors on list operations while in authoring. However unlike Director, vList does not display the error dialog in projectors or in Shockwave mode. Requires Director 8 or above. Inserts a new item into a linear list at the specified position, moving the items after the designated position up one index position. Specifying an index position that is the count of the list plus 1, appends the item to the list. Example: theList = [1,2,3] insertAt(theList,1,"dog") put theList -- ["dog",1,2,3] insertAt(theList,5,"cat") put theList -- ["dog",1,2,3,"cat"] insertAt(theList,3,"canary") put theList -- ["dog",1,"canary",2,3,"cat"] insertPropAt(propertyList,positionNumber,anyProp,anyValue) - where positionNumber is the integer index position to insert the item, anyProp is the property to insert and anyValue is the value to pair with inserted property. Returns 0 if successful, or a negative number in case of error (this error code can be misleading, and it is better in case of error to look at the value returned by vList_error or vList_errorString). Also if there is an error, this command displays an error dialog in authoring mode, which is consistent with Director's handling of errors on list operations while in authoring. However unlike Director, vList does not display the error dialog in projectors or in Shockwave mode. Inserts a new property/value pair into a property list at the specified index position, moving the items after the designated position up one index position. Specifying an index position that is the count of the list plus 1, appends the new property/value pair to the list. Using this command on a sorted list turns the sort flag off. Examples: theList = [#leafColor:"green",#barkColor:"white",#barkTexture:"rough"] insertPropAt(theList,1,#height,53) put theList -- [#height:53,#leafColor:"green",#barkColor:"white",#barkTexture:"rough"] insertPropAt(theList,5,#flowering,0) put theList -- [#height:53,#leafColor:"green",#barkColor:"white",#barkTexture:"rough",#flowering:0] insertPropAt(theList,3,#attractive,1) put theList -- [#height:53,#leafColor:"green",#attractive:1,#barkColor:"white",#barkTexture:"rough",#flowering:0] setPropAt(propertyList,positionNumber,anyProp) - where positionNumber is the integer index position to insert the item and anyProp is the new property. Returns 0 if successful, or a negative number in case of error (this error code can be misleading, and it is better in case of error to look at the value returned by vList_error or vList_errorString). Also if there is an error, this command displays an error dialog in authoring mode, which is consistent with Director's handling of errors on list operations while in authoring. However unlike Director, vList does not display the error dialog in projectors or in Shockwave mode. Changes the property at the specified index position of a property list to the new property passed in. Leaves the value associated with the property unchanged. Using this command on a sorted list turns the sort flag off. Example: theList = [#leafColor:"green",#barkColor:"white"] setPropAt(theList,1,#flowerColor) put theList -- [#flowerColor:"green",#barkColor:"white"] changeProp(propertyList,oldProp,newProp,deepMode) - where oldProp is the property to change, newProp is the new value for the property and deepMode is a boolean, true to do the replace at all levels of a property list with sublists, false to operate on just the top level. Returns the number of properties found and replaced, 0 if no matches for oldProp were found, or a negative number in case of error (this error code can be misleading, and it is better in case of error to look at the value returned by vList_error or vList_errorString). Also if there is an error, this command displays an error dialog in authoring mode, which is consistent with Director's handling of errors on list operations while in authoring. However unlike Director, vList does not display the error dialog in projectors or in Shockwave mode. Changes all of the properties in a property list matching oldProp to newProp in the property passed in. Leaves the value associated with the property unchanged. Operates on the top level of a multi-level list if deepMode is false. If deepMode is true, operates on all levels. Using this command on a sorted list turns the sort flag off. Example: theList = [#leafColor:"green",#barkColor:"white"] numChanged = changeProp (theList,#barkColor,#flowerColor,0) put theList -- [#leafColor:"green",#flowerColor:"white"] put numChanged -- 1 If the properties we want to change are not on the first list level, we have to set the deepMode to true: aPropList = [[#a: 1], [#b: 2, #a: #a]] numChanged = changeProp (aPropList, #a, #c, false) put aPropList -- [[#a: 1], [#b: 2, #a: #a]] put numChanged -- 0 numChanged = changeProp (aPropList, #a, #c, true) put aPropList -- [[#c: 1], [#b: 2, #c: #a]] put numChanged -- 2 appendProp(propertyList,anyProp,anyValue) - where anyProp is the property of the property/value pair to insert and anyValue is the value of the property/value pair to insert. Returns 0 if successful, or a negative number in case of error (this error code can be misleading, and it is better in case of error to look at the value returned by vList_error or vList_errorString). Also if there is an error, this command displays an error dialog in authoring mode, which is consistent with Director's handling of errors on list operations while in authoring. However unlike Director, vList does not display the error dialog in projectors or in Shockwave mode. Appends a new property/value pair to the end of a property list. Example: theList = [#a:"dog",#b:"cat"] appendProp(theList,#y,"mouse") put theList -- [#a:"dog",#b:"cat",#y:"mouse"] unsort(list) - No return. Turns off the sorted flag for the list. Does not actually reorder the list contents. Example: aList = ["jam","bread","toast"] sort(aList) put aList -- ["bread","jam","toast"] put sortP(aList) -- 1 unsort(aList) put sortP(aList) -- 0 put aList -- ["bread","jam","toast"] duplicateSort(list) - Returns a list that is a copy of the one passed in. Copies a list, preserving its sorted state. duplicateSort does not actually sort the contents of the list. Director's duplicate command also makes a copy of a list, but in Director 8, it resets the sorted flag to false for the new list and any nested lists within it. duplicateSort is a fix for that problem in Director 8. It is not necessary for Director 7 or Director 8.5 where the duplicate command works correctly. Example: aList = ["jam","bread","toast"] sort(aList) put aList -- ["bread","jam","toast"] put sortP(aList) -- 1 newList = duplicateSort(aList) put sortP(newList) -- 1 -- Must do this in Director 8 to see problem anotherList = duplicate(aList) put sortP(anotherList) -- 0 CREATING POPULATED LISTS The following methods create lists with a fixed number of identical items initialized with filler data. These methods are especially useful if you know beforehand the size of a Lingo list you want to use. If you create a list with dummy values at initialization time, the entire list will be stored in contiguous memory if there is enough available, which keeps Director's memory unfragmented. You could accomplish the same thing by using Lingo repeat loop to build the dummy list, but the repeat loop method is very slow. The newList commands are much faster than using a Lingo repeat loop, so there is no trade off of a long delay at startup in exchange for efficient memory use. newList(numberOfItems,fillValue) - where numberOfItems is an integer, the number of list items to create and fill with fillValue, and fillValue is an integer or symbol, the value for list items. Returns a linear list with the specified number of items, each filled with an identical value. Example: sectionScores = newList(10,0) put sectionScores -- [0,0,0,0,0,0,0,0,0,0] ticTacToeBoard = newList(9,#empty) put ticTacToeBoard -- [#empty,#empty,#empty,#empty,#empty,#empty,#empty,#empty,#empty] newPropList(numberOfItems,fillProperty,fillValue) - where numberOfItems is an integer, the number of list items to create and fill with the property/value pairs, fillProperty is an integer or symbol, the value to use for the property of the property/value pair, and fillValue is an integer or symbol, the value to use for the value of the property/value pair. Returns a property list with the specified number of items, each filled with an identical property/value. Example: recordSet = newPropList(3,#untitled,0) put recordSet -- [ #untitled: 0, #untitled: 0, #untitled: 0 ] LIST/DATATYPE INFORMATION The following functions return information about Lingo lists and other supported data types. sortP(list) - Returns 1 if the list has its sorted flag set, 0 if not. Returns the state of the list's internal sorted flag. If the flag is false, the actual list contents may or may not be ordered. Example: -- Don't do a time-expensive sort operation unless it is necessary if sortP(myList) = false then sort(myList) isSame(variable,variable) - Returns 1 if the two lists, or other supported data types, point to the same memory location. When you pass data from one handler to another or copy data from one variable to another sometimes Director makes a new copy of it (stored by value) and sometimes it passes a pointer to the memory location of the existing data (stored by reference).This function tells you if two Lingo variables containing data types that are passed by reference are actually pointers to the same memory location, or two separate copies. Some data types passed by reference are image(), rect, list, member.media, member.image, string (D8.5 and up) Some data types passed by value are integer, float, symbol This function is only useful for comparing data passed by reference. If it is passed data types stored by value it compares their contents and works like the = operator. For instance if you use it on two integer variables it simply returns whether their values are equal. A = 5 B = A put isSame(A,B) -- 1 Example: A = list(1,2,4) B = A put isSame(A,B) -- 1 C = duplicate(A) put isSame(A,C) -- 0 numRef(variable) - Returns the number of references to the memory location storing the variable, or 0 if the data type is not stored by reference. This function tells you how many references to a variable currently exist. The information can be useful for memory management because Director cannot release a variable for garbage collection if there are still other references to it.This function uses the same convention for counting references that Director itself does. The data itself counts as one reference. The first set of a variable to the data makes the reference count 2. aList = [1,2,3] put numRef (aList) -- 2 bList = aList put numRef (bList) -- 3 aList = 0 put numRef (bList) -- 2 put bList -- [1, 2, 3] Integer and property Lingo variables are not count referenced, so the method returns 0 for these kinds of variables: put numRef (1) -- 0 put numRef (#Lingo) -- 0 Example: on startMovie var = new(script "parent") alert "Before anotherHandler: " & (numRef(var)) anotherHandler(var) alert "After anotherHandler, its local ref discarded: " & (numRef(var)) end on anotherHandler var local = var alert "In anotherHandler: " & (numRef(local)) end -- Parent script "parent" property foo on new me return me end float32P(float) - Returns 1 if the value is a 32-bit float, 0 if it is a 64-bit float, or some other data type. Returns the type of storage required for the particular floating point number. Function only exists in Director 8.5 and above, which introduced the more compact 32-bit float. In Director 8.5 floats with up to 8 digits before the decimal and 0 after the decimal only require 32 bits of storage. vList Xtra stores 32-bit floats in their native format in vList members and files created under Director 8.5. Example (running under D85): put float32P(123.0) -- 1 put float32P(123.123) -- 0 float32(number) - Returns a 32-bit float, if the value passed in is a float or an integer. Otherwise returns the passed in value unchanged. Converts a float into a value that Director can store in 32 bits. Function only exists in Director 8.5 and above, which introduced the more compact 32-bit float. The passed-in value will be rounded off if it contains too many digits to be stored in 32 bits. Lingo operations on 32-bit values are up to 50% faster than those on 64-bit values. However, Director automatically converts floats to 64-bit, so it is difficult to maintain the smaller storage size if a variable containing a 32-bit float has to be put through a series of Lingo operations. Example (running under D85): put float32P(8.123456789) -- 0 z = float32(8.123456789) put z -- 8.1235 put float32P(z) -- 1 vList_size(list) - Returns the integer size in bytes of the list, or any other supported data type. Returns the projected size of a Lingo list after it has been stored in a vList container and loaded back in to memory. This figure could differ from the list's current size before storage, if the list contains data types such as #script, #xtra, and #window that vList cannot save. Each data reference that cannot be saved, is represented by vList as an 8-byte void value. Examples: put vList_size(myList) -- 88484 put vList_size("dog") -- 60 vList_sizeOnDisk(list) - Returns the Integer file size of the list, or any other supported data type, if it was written out to a file. Returns the space in bytes that a Lingo list currently in memory would take up if it were written out to a vList file. Examples: put vList_sizeOnDisk(myList) -- 88500 put vList_sizeOnDisk(member(32).picture) -- 716 EXPORTING DATA TO SHOCKFILER XTRA ShockFiler Xtra saves data from a Shockwave movie or a projector to a standalone file on an FTP server. vList Xtra includes support for exporting vList data through ShockFiler Xtra to a standalone vList file on an FTP server. propList = vList_to_sf(data,|compressionFlag|,|encryptionKey|) propList = vList_to_sf(data,|optionsList|) - where: data is a Lingo list or other data type; compressionFlag is true to compress the data. Optional parameter; encryptionKey is a linear list of 8-16 integers (encryption key) Optional parameter; optionsList is a property list containing all of, or at minimum, one of, the following: [#compression: 1, #binaryMode: 1, #encryptKey: [1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8] ] Returns a property list containing data packaged in a format that can be used by ShockFiler Xtra. This function packages vList data into a format that ShockFiler Xtra can export to a standalone vList file on an FTP server. The packaged data is returned in a Lingo property list in the format: [#data: binary vList data, #length: size of data in bytes] vlist_to_sf can only accept a total of three parameters. If you just want to pass an encryption key, you can use the original simpler syntax: propList = vList_to_sf ( data, 1, [1,2,3,4,5,6,7,8] ) put propList -- [#data: "", #length: 2233388] -- binary data will display as an empty string due to control chars If you need to pass a binaryMode flag as well, use the newer alternate options list syntax to pass it: propList = vList_to_sf ( data, [#compression: true, #encryptKey: [1,2,3,4,5,6,7,8] , #binaryMode: true] ) All of the following lines are valid syntax: encryptionKey = [1,2,3,4,5,6,7,8,9,10,11,12] aList = vList_to_sf (aLingoValue ) aList = vList_to_sf (aLingoValue, false ) aList = vList_to_sf(aLingoValue, true, encryptionKey] ) aList = vList_to_sf (aLingoValue, [#compression: true, #binaryMode: true] ) aList = vList_to_sf (aLingoValue, [#compression: true, #encryptKey: encryptionKey, #binaryMode: true] ) See the ShockFiler Xtra doc for more details. Example: vlistData = vList_to_sf ( [#name: "Andy", #score: 50] , 1, [1,2,3,4,5,6,7,8] ) -- ShockFiler command sf_Send ("ftp.macromedia.com", "incoming","guest", "mypassword",vlistData, "", "vfile.lst", #bina, [], 0, 0,"") MISCELLANEOUS fpReset( ) - Windows command that resets the floating point register after it has been left in a bad state by a printer driver. This situation caused a vList crash when reading and writing files, and causes the same type of crash in other xtras and Director itself. The crash dialog identifies this type of crash as an "exception 10H". vList now resets the FP register internally so this command is not necessary to protect vList operations. But it can be useful to head off trouble in other xtras or Director. For instance it has been reported to fix a Flash printing problem from a Flash sprite in Director. The following links provide more information on the problem: http://www.aresforact.com/support/1001.htm http://support.microsoft.com/default.aspx?scid=kb;EN-US;q183522 setFileName(memberRef,fileName) - where memberRef is a reference to a member and fileName is a string, name of file to link to in Shockwave, or full path in projector. This is a workaround method to substitute for Lingo's member.fileName property, which no longer works in Shockwave on Mac.Previously, doing the following would link the member to "doc.jpg" in the DSWMEDIA folder: member("pict").fileName = "doc.jpg" Now you can do this instead: setFileName( member("pict") , "doc.jpg" ) This command also works in a projector. It looks in the current movie's folder for the file when running in authoring or in a projector. vList_version( ) - Returns a string containing the version number of vList Xtra. Example: put vList_version() -- "1.8.6" ERROR REPORTING Many vList methods return data, so they cannot also return a status. Do not rely on the return value of any call other than "register" for error returns. Instead, use the vList_error function to get the status of the last vList call. vList_error( ) - Returns the integer number of the last vList error. Returns 0 if the previous vList call was successful, or a negative number if there was a problem. Use vList_errorString(errorNumber) to get a description of the error. Note: This call resets the internal error code, so be sure to store the result of this command in a variable in case you want to pass it later to vList_errorString(). Example: fileIOInstance = new(xtra "fileio") chosenFile = displayOpen(fileIOInstance) fileLink = new xtra("vlist", chosenFile) storedList = read(fileLink) if vList_error() = -2147211504 then alert "Cannot retrieve data. The chosen file exists but it is not a vList file." end if vList_errorString(|errorNumber|) - Returns the string error description. Returns a description of the last error, if no argument is passed. Returns the definition for a specific negative error number if one is passed in. The error description returned is in the format: ErrorOrigin_ErrorDescription (ErrorNumber) kMoaErr_NoErr: (0) kLstErr_Not_A_PropList (-2147211489) The first 4 characters of the error origin tell you whether the error came from MOA, Director's Xtras API, ("kMoa") or from vList itself ("kLst"). The rest of the string after the first underscore and before the space describes the error condition. The number between the parentheses is the error number. Example: put vList_errorString() -- "kMoaMmErr_ArgOutOfRange (-2147229496)" In the example above, vList returned the error from the last vList operation because no argument was passed. put vList_errorString() -- "kLstErr_Not_A_PropList (-2147211489)" In the example above, vList returned the error from the last vList operation because no argument was passed. The error came from vList. put vList_errorString (-2147221484) -- "kMoaErr_InternalError (-2147221484)" In the example above, a particular error number was passed in and vList returned the error description for that error.