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?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.