2

I'm not much familiar with javascript, but I faced a need to send and receive big static 2D integer arrays (where values are > 255) as base64 strings (this is essential). At the moment I've came up with this straightforward and inefficient solution converting them element-wise and manually constructing strings, which, as far as I understand, should involve a lot of copying of the data and turns to be very slow.

Can it be done in a more efficient way, if possible without usage of some big side libraries like Node.js, etc?

     //----------- serializing/deserializing procedures

    //encoding int contours array to be sent as base64 string
    function getBase64IntArray(arr) {

        var width = arr.length;
        //This works given the inner arrays length never changes.
        var height = arr[0].length; 
        //string that would contain data
        var str = width.toString()+","+height.toString()+","; 

        for(var x = 0; x < height; x++) { 
            for(var y = 0; y < width; y++) {
               str = str + arr[x][y].toString() + ","; 
            }
        }      

        var str64 = btoa(str);
        return str64;
    }//getBase64IntArray

    //deconding this string back to array
    function getIntArrayfromBase64(str64) { 

        var str = atob(str64);
        //first occurence of ","
        var width_str = str.substr(0,str.indexOf(',')); 
        str = str.substr(str.indexOf(',')+1); // cut the beginning
        //again first occurence of ","
        var height_str = str.substr(0,str.indexOf(','));
        str = str.substr(str.indexOf(',')+1); // cut the beginning

        var width = parseInt(width_str);
        var height = parseInt(height_str);

        //declare new array and fill it
        var arr = new Array(height);
        var curr_str = "";

        for(var x = 0; x < height; x++) { 

            arr[x] = new Array(width);

            for(var y = 0; y < width; y++) {
               //first occurence of ","
               curr_str = str.substr(0,str.indexOf(',')); 
               // cut the beginning
               str = str.substr(str.indexOf(',')+1); 
               arr[x][y]=parseInt(curr_str);
            }
        }

        return arr;

    }// getIntArrayfromBase64 

Sending/receiving works:

    //----------- example usage
    function send(){
    //encoding to base64                
    var arr = [
          [1, 2],
          [3, 4]
    ];

    var base64 = getBase64IntArray(arr);                
    webSocket.send(base64);               
    }

    webSocket.onmessage = function(event){

    //reading array as base64 string
    var arr = getIntArrayfromBase64(event.data);
    var width = arr.length;
    var height = arr[0].length; 

    writeResponse("Received "+width+" "+height+" "+arr[0][0]+arr[1][1]);
    };

1 Answer 1

2

How about going through JSON? JSON will add minimal overhead to the wire format, but the serialization/deserialization will be fast, because it's implemented natively.

function getBase64IntArray(arr) { return btoa(JSON.stringify(arr)) }

function getIntArrayfromBase64(str64) { return JSON.parse(atob(str64)) }

Sign up to request clarification or add additional context in comments.

1 Comment

Just one more additional question: is there any way to decode this data in C++ then? What is the conversion algorithm?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.