Pages

Aug 24, 2012

NaCl & Writing files outside the sandbox

Wouldn't it be great if you could do some processing in NaCl and save the results to a file outside of the sandbox? Good news! This article shows you how.

Putting things in a sandbox is the easy part; Getting them out is often the difficult part; Especially when you don't want dirt all over the carpet..


In a previous post, I talked about how you can load a file into NaCl from OUTSIDE the Chrome sandbox. Which is a great thing for those of you who want to create content-editors  or content-viewers inside of Native Client.This time, we'll talk about how to get those files from NaCl back out to the disk.

The bad news is that Native Client does not expose an API that allows you to write files outside of the sandbox.

The good news is that HTML5 does.

This means that if you have data inside of NaCl that you want to write to disk, you first need to pass it over to Javascript using the PostMessage API.

1. Saving a file to disk in HTML5

HTML5 exposes a download attribute which does the process of writing a file to disk from Javascript. When used on an anchor, this attribute signifies that the resource it points to should be downloaded by the browser rather than navigating to it. It requires a user click, but will allow the data to be streamed.

Here's a Javascript example of how to create a  BlobBuilder, and create a link that will let you download some arbitrary data

function downloadData function(fileData, outputName){

  var bb = new BlobBuilder();
  bb.append(fileData);


  const MIME_TYPE = 'text/plain';

  var a = document.createElement('a'); //create a new element for the user to click on.
  a.download =  outputName ;
  a.href = window.URL.createObjectURL(bb.getBlob(MIME_TYPE));
  a.textContent = 'Click Here';
  a.dataset.downloadurl = [MIME_TYPE, a.download, a.href].join(':');

  document.getElementById('buttonDiv').appendChild(a);
}


You can set up this process in Javascript before needing to touch Native Client. That way you can get everything working at a functional level, and then just push the data from NaCl into it when ready.

2. Getting binary data from NaCl to Javascript

To get our binary data to Javascript from NaCl,  we need to do 2 things:
  1. Create a varArrayBuffer to hold the binary data
  2. Push the binary data back to java script via PostMessage.
The example code below shows this process, and is using the C Interfaces for PPAPI.
PP_Var v2 = ppb_varArrayBuffer_interface->Create(dataSize);

//we map the array buffer and copy the input data into it.
void* pDst = ppb_varArrayBuffer_interface->Map(v2);
memcpy(pDst,pData,dataSize);
ppb_varArrayBuffer_interface->Unmap(v2);

//send the data to Javascript, using Postmessage
ppb_messaging_interface->PostMessage(appInstance_,v2);


3. Source Code

You can find a working example on my Github repo. This example will allow you to load data from disk, as well as write it back to disk.

Note that this uses the Visual Studio add in (which is not public yet), but you can by-pass that and compile the C files with the make data that comes inside the NaCl SDK.

~Main

You can find Colt McAnlis here:

  

1 comment:

  1. As we know, Big data implementation services is the future of the industries these days, this article helps me to figure out which language I need to learn to pursue the future in this field.

    ReplyDelete