1

I'm receiving the following Binary Stream from an HTTP request:

HTTP REQUEST

Document.get({id: $scope.documentId}, function(stream){

});

Angular Factory

.factory('Document', ['$resource', 'DOCUMENTS_CONFIG',
    function($resource, DOCUMENTS_CONFIG) {
        return $resource(DOCUMENTS_CONFIG.DETAIL_URL, {}, {
            get: {
                method: 'GET', 
                params: {}, 
                url: DOCUMENTS_CONFIG.DETAIL_URL,
                isArray: false
            }
        });
    }
]);

Response

console.log(stream) I need to convert this to a Uint8Array. I've tried to convert it to a bas64

// Convert Binary Stream To String
var dataString = JSON.stringify(stream);

// Convert to Base 64 Data
var base64Data = window.btoa(unescape(encodeURIComponent(dataString)));  

When I run this I get an error 'malformed uri exception'. I've also tried window.btoa(dataString) but I get 'Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.'

How can I can convert this to an Uint8Array?

Arthur Weborg
  • 8,280
  • 5
  • 30
  • 67
Jeremy Wagner
  • 485
  • 4
  • 9
  • 19
  • I modified my answer below with the knowledge you've given. Would you happen to be able to share the code you use to make the request as well? is it AJAX? What is the return type expected for that AJAX call? – Arthur Weborg Feb 12 '15 at 17:23
  • 1
    Yes - will share. It's an Angular HTTP request. – Jeremy Wagner Feb 12 '15 at 17:29
  • The HTTP Request has been added – Jeremy Wagner Feb 12 '15 at 17:33
  • Ah, I'm not as familiar with angular (and 10 minutes of searching having a hard time to find the specific documentation for what exactly is being returned), I did modify my answer below to account for a Javascript Object (which is what is printed to the console) instead of a String. – Arthur Weborg Feb 12 '15 at 17:41

1 Answers1

4

So you have a binary stream (the values I am assuming were sent from a byte array of some sort, 0-255). You do not need to do the (the window.btoa(...) because it already is in a state ready for the Uint8Array) before turning it into an Uint8Array.

You simple need to iterate through the Object's indexes (which are stored in key's increasing in value from 0) and set the value of the Uint8Array, grabbing the character code at each index, and setting the Uin8Array cell at that index to the value.

You need to know the number of Keys, this is achievable via Object.keys(stream).length. Then, we iterate our key value (i) and grab the charCode(0) at zero (because the value for each key is a 1-character string) .

var bytes = Object.keys(stream).length;
var myArr = new Uint8Array(bytes)

for(var i = 0; i < bytes; i++){
    myArr[i] = stream[i].charCodeAt(0);
}

I updated your fiddle, you can in the console log how it is converting. I also truncated the string because I got tired of finding all the ' characters and trying to escape them and adding \n characters so it'd all be on one line.

Arthur Weborg
  • 8,280
  • 5
  • 30
  • 67
  • when I try to get base64Data as shown in the code, I get the error 'malformed uri exception' so if I could get the base 64 data, I could use this code but I currently don't even have that – Jeremy Wagner Feb 12 '15 at 16:23
  • If the above doesn't work, Any chance you could post the raw stream string? (instead of the image) – Arthur Weborg Feb 12 '15 at 16:26
  • Yeah - Here is the raw response. I put it in a jsfiddle simply because it's so ~500 lines. http://jsfiddle.net/Lu5sgae8/ – Jeremy Wagner Feb 12 '15 at 16:29
  • Great - when I log just my "stream" variable though it logs as an object, not a string which is why I was using stringify – Jeremy Wagner Feb 12 '15 at 17:26
  • I made modifications to work with a `Javascript Object` instead of a `String` and I think my answer will do the trick. However, there is potential that an angular specific answer would be better. So if my answer does work I would still wait to see if the retag catches someone with more angularjs experience to give an angularjs specific answer (before accrediting a solution). – Arthur Weborg Feb 12 '15 at 17:55
  • Yes, except the length is ~53,000 so it takes a long time – Jeremy Wagner Feb 12 '15 at 17:55
  • Storing the value of the number of keys instead of recomputing it 53,000 times might help, modified my answer accordingly. Though I think that's the extent (of my knowledge since I don't know angular) I'll be able to help at this time. Best of luck! – Arthur Weborg Feb 12 '15 at 18:04
  • Your final solution converted to an Uint8Array in a matter of seconds – Jeremy Wagner Feb 12 '15 at 18:27