Search code examples
javascriptangularjsuint8tbinarystream

Binary Stream To Uint8Array - JavaScript


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?


Solution

  • 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.