4 Replies Latest reply: Jan 9, 2011 8:41 AM by DigitalArchitectCanada RSS

    Failure loading data from Local File

    DigitalArchitectCanada Community Member

      Hi All,


      So I'm assuming that this is just a sandbox violation issue, that alchemy just plain blocks local file system access by anything that isn't an AS3 object capable of doing so (such as the file class.) I'd just like to get a solid confirmation from an employee or someone else who can give me a confirmation on this. Basically here's what I'm doing in C++


      //Get the file class

      flash_filesystem_namespace = AS3_String("flash.filesystem");

      File_class = AS3_NSGetS(flash_filesystem_namespace, "File");

      AS3_Val fileObject = AS3_New(File_class, emptyParams);



      //Get the bytearray class

      flash_utils_namespace = AS3_String("flash.utils");

      ByteArray_class = AS3_NSGetS(flash_utils_namespace, "ByteArray");

      AS3_Val byteArray = AS3_New(ByteArray_class, emptyParams);




      AS3_SetS(fileObject, "nativePath", AS3_String(fileOne.c_str()));     /// ------ fileOne is of type string and I'm passing it in as an arg


      AS3_Val doesFileRefExist = AS3_GetS(fileObject, "exists");

      if(doesFileRefExist == AS3_False()){

           AS3_Call(actionscriptCallbackFunction, parentClass, AS3_Array("StrType", "File Does Not Exist"));



      if(doesFileRefExist == AS3_True()){

           fileObject = AS3_CallS("resolvePath", parentClass, AS3_Array("StrType", fileOne.c_str()));          ---This works



      So that works if I import and use a flash.filesystem.File object to check and see if the file exists locally. However this doesn't work:


      bool doesFileExist(string* fName)


      bool exists = false;


      string tmpfName = *fName;

      fstream fileToCheck;


      if( fileToCheck.is_open() )






      return exists;



      My function to check and see if the file exists always returns false, static of course the file doesn't exist. I've compiled this project into an executable before so I can verify that it's not my code.


      It's also important to note that I'm compiling this into an AIR 2.5 project, so I assumed that my compiled C++ code would inherit the same permissions (local file io). Any clarification/confirmation on this would be great and thanks in advance.

        • 1. Re: Failure loading data from Local File
          DigitalArchitectCanada Community Member

          I found this article:


          http://blogs.adobe.com/cssdk/2010/05/leveraging_cc_libraries_in_the_cs_sdk_using_alchemy.h tml


          Specifically, it mentions the following:


          //======================================================================================== =====================


          In most Alchemy use cases, all we have to do is initialize the C library and then call into the interfaces we defined:

          var loader:CLibInit = new CLibInit();
          var lib:Object = loader.init();


          However, it’s slightly more complex in our case. Alchemy requires that you pass any files needed by the C code as a byte array to the loader before calling your interfaces. Because the C code requires access to the file system (to read the dictionary, grammar rules, etc.), we’re going to need a function something like this:

          private function supplyFile( loader:CLibInit, file:File, fileName:String):void {

          var bytes:ByteArray = new ByteArray();
          var stream:FileStream = new FileStream();
          stream.open(file, FileMode.READ);
          stream.readBytes(bytes, 0, stream.bytesAvailable);
          loader.supplyFile(fileName, bytes);



          And that’s all there is to it. To compile the CS Extension, generate the swc and copy it into the libs/ folder. At runtime, make sure you have the contents of Link Grammar’s data/ folder (which includes 4.0.dict, words/, etc.) copied onto the desktop.

          //======================================================================================== =====================


          Can anyone comment on or add to this?

          • 2. Re: Failure loading data from Local File
            DigitalArchitectCanada Community Member

            Okay so after doing some digging, here it is:




            Near the top of the page, you can see a description of the supplyFile method. However, I learned through experimenting and reading around other blogs that when you pass in the "path" of the file to alchemy, coupled with a bytearray of the file, the "path" is really just a unique identifier for that newly created byte array inside of alchemy/your c/c++ code.


            I just want to say that I really hope the alchemy project stays alive, and also that I believe work should be done to permit local file system access directly through c/c++ using ifstream/fopen ect, not through virtualization. I don't understand why the alchemy code doesn't automatically inherit all sandbox restrictions and permissions from the parent application sandbox but like I said, I hope it's something we'll see in the future.


            I hope this also may be helpful to other people with similar questions.

            • 3. Re: Failure loading data from Local File
              DigitalArchitectCanada Community Member

              Just an update for people who want to know an easier way of doing this, heres some code for passing bytearray to C++ and passing back a pointer to the modified data in C++ to flash, then saving that modified data from alchemy memory to the file system. It's very fast and other tutorials I've seen say it's the fastest method:




              package {

              import flash.display.MovieClip;

              import flash.display.Sprite;

              import flash.events.Event;

              import flash.filesystem.File;

              import flash.filesystem.FileMode;

              import flash.filesystem.FileStream;

              import flash.utils.ByteArray;


              import cmodule.MyAlchemyLib.CLibInit;

              import cmodule.MyAlchemyLib.gstate;


              public class MyAlchemyLibMain extends MovieClip


              private var lib:Object;

              private var loader:CLibInit;

              private var file:File;

              private var dataLength:int;

              private var sysMem:ByteArray;



              public function ScramblrAlchemyMain()


              loader = new CLibInit;


              file = File.desktopDirectory;


              file.addEventListener(Event.SELECT, getFile);

              file.browseForOpen("Find file to load.");




              private function getFile(e:Event):void


              file = e.target as File;


              lib = loader.init();

              file.addEventListener(Event.COMPLETE, fileLoadedLocally);





              private function fileLoadedLocally(e:Event):void


              trace("Data length: " + file.data.length);

              dataLength = file.data.length;

              var fileData:ByteArray = file.data;


              sysMem = gstate.ds;


              lib.processBytes(fileData, dataLength, "My string data", -1, alchemyCallback, this);




              public function alchemyCallback(pointerRef:int):void


              trace("Alchemy called me back baby!")

              trace("Bytes are at: " + pointerRef);


              var alchemyBytes:ByteArray = new ByteArray();

              aalchemyBytes.writeBytes(sysMem, pointerRef, dataLength);




              var sf:File = File.desktopDirectory;

              sf = sf.resolvePath(file.parent.nativePath);

              sf = sf.resolvePath("Modded File.f");


              var fs:FileStream = new FileStream();

              fs.open(sf, FileMode.WRITE);

              fs.writeBytes(alchemyBytes, 0, alchemyBytes.length);


              fs = null;





              CPP Code:
              char * memblock;
              char * moddedMemblock;
              AS3_Val emptyParams = AS3_Array("");
              //Get the file class
              AS3_Val flash_filesystem_namespace;
              AS3_Val File_class;
              //Get the file class
              AS3_Val flash_utils_namespace;
              AS3_Val ByteArray_class;
              int main() {
              //define the methods exposed to ActionScript
              //typed as an ActionScript Function instance
              AS3_Val processFileMethod = AS3_Function( NULL, processBytes );
              // construct an object that holds references to the functions
              AS3_Val result = AS3_Object( "processBytes: AS3ValType", processFileMethod );
              //Release file class class
              //Release byte array class
              // Release
              AS3_Release( processFileMethod );
              // notify that we initialized -- THIS DOES NOT RETURN!
              AS3_LibInit( result );
              // should never get here!
              return 0;
              // Function    : processBytes
              // Description : Alchemy process for processing a single bytearray
              static AS3_Val processBytes(void* self, AS3_Val processArgs)
              //Store the reference to the class passed in here from the main args
              AS3_Val parentClass;
              //Get my string value from flash
              string myStringValue;
              //Mode int
              int mode;
              AS3_Val actionscriptCallbackFunction;
              AS3_Val fileByteArray = AS3_Undefined();
              int currentByteLength;
              AS3_ArrayValue( processArgs, "AS3ValType, IntType, StrType, IntType, AS3ValType, AS3ValType", &fileByteArray, &currentByteLength, &myStringValue, &mode, &actionscriptCallbackFunction, &parentClass);
              // yield...
              memblock = new char[currentByteLength];
              AS3_ByteArray_seek(fileByteArray, 0, SEEK_SET);
              AS3_ByteArray_readBytes(memblock, fileByteArray, currentByteLength);
              unsigned int byteLen;
              byteLen = (unsigned int)currentByteLength;
              //int fMode = AS3_IntValue(mode);
              int fMode = mode;
              //**************************************************************************************** ******
              Modify your byte array instance here however you wish. I've deleted the part of my
              code where I do this because this is nearly a direct copy from a commercial
              application I'm working on. However, in my case I saved my modified byte array
              data into the moddedMemblock char array. Then I do a callback function to AS3
              using AS3_Call and pass AS3_Ptr(moddedMemblock) back to flash. This
              is an integer value that points to the position in memory where this data is being
              stored, inside the alchemy byte array. Then back in flash I create a reference
              to the alchemy byte array and read in the length of bytes I expect to receive
              and save them. Hope this is helpful to some people as I spent a good two days
              researching the different ways to interact with the file system using alchemy.
              NOTE you must pass a reference to the class in which your callback function
              exists. This is necessary so that when alchemy comes back to your flash app,
              it knows what namespace to use to access the function you've asked it to
              call. If you don't do this, you'll get no call back.
              ****************************************************************************************** *****/
              AS3_Call(actionscriptCallbackFunction, parentClass, AS3_Array("AS3ValType", AS3_Ptr(moddedMemblock)));
              //IMPORTANT - You must delete your pointers to clear up the memory you've used, otherwise this is how you get memory leaks.
              delete memblock;
              delete moddedMemblock;
              //Also important, need to release values received from flash otherwise this will result in memory leak as well
              return AS3_Null();
              • 4. Re: Failure loading data from Local File
                DigitalArchitectCanada Community Member

                Sorry all, appears that my text formatting is broken every time I edit it, it reverts to this.