JSON and Uint8Array

Posted on
  • Problem with var x=JSON.parse(JSON.stringify(Obj));
    When Obj contains an Uint8Array(N). x is undefined/

    function A(){
     this.A=1;
     this.B= new Uint8Array(16);
     this.s= new Uint8Array(16);
    }
    
    A.prototype.setup=function(){
     var i;
     for(i=0;i<16;i++)this.B[i]=i;
    };
    
    function B(){
     this.B= 2; // new Uint8Array(16);
     this.s= 2; //new Uint8Array(16);
     this.A=1;
    }
    
    
    var a=new A();
    a.setup();
    console.log(a);
    var e=JSON.stringify(a);
    console.log(e);
    var f=JSON.parse(e);
    console.log("f= ",f);
    
    console.log(" ");
    var b=new B();
    console.log(b);
    var e1=JSON.stringify(b);
    console.log(e1);
    var f1=JSON.parse(e1);
    console.log("f1= ",f1);
    

    The output:

    >echo(0);
    { "A": 1,
      "B": new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]),
      "s": new Uint8Array(16)
     }
    {"A":1,"B":new Uint8Array([0,1,2,3,4,5,6,7,8,9,10,11,12­,13,14,15]),"s":new Uint8Array(16)}
    f=  undefined
     
    { "B": 2, "s": 2, "A": 1 }
    {"B":2,"s":2,"A":1}
    f1=  { "B": 2, "s": 2, "A": 1 }
    
    
  • Almost a fix!
    Replace the Uint8Array using E.toString()
    do the JSON
    Replace the strings using E.toUint8Array()

    //jsontest1.js
    //21aug2016
    function A(){
     this.A=1;
     this.B= new Uint8Array(16);
     this.s= new Uint8Array(16);
    }
    
    A.prototype.setup=function(){
     var i;
     for(i=0;i<16;i++)this.B[i]=i;
    };
    
    function B(){
     this.B= 2; // new Uint8Array(16);
     this.s= 2; //new Uint8Array(16);
     this.A=1;
    }
    
    
    var a=new A();
    a.setup();
    console.log(a);
    //Almost a fix
     a.B=E.toString(a.B);
     a.s=E.toString(a.s);
     console.log(a);
    //
    var e=JSON.stringify(a);
    console.log(e);
    var f=JSON.parse(e);
    console.log("f= ",f);
    //Almost a fix
     f.B=E.toUint8Array(f.B);
     f.s=E.toUint8Array(f.s);
    console.log("f= ",f);
    
    console.log(" ");
    var b=new B();
    console.log(b);
    var e1=JSON.stringify(b);
    console.log(e1);
    var f1=JSON.parse(e1);
    console.log("f1= ",f1);
    

    The output:

    >echo(0);
    { "A": 1,
      "B": new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]),
      "s": new Uint8Array(16)
     }
    { "A": 1,
      "B": "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\x0­B\f\r\x0E\x0F",
      "s": "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0­0\x00\x00\x00\x00\x00\x00"
     }
    {"A":1,"B":"\x00\x01\x02\x03\x04\x05\x06­\a\b\t\n\x0B\f\r\x0E\x0F","s":"\x00\x00\­x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\­x00\x00\x00\x00"}
    f=  { "A": 1,
      "B": "\x00\x01\x02\x03\x04\x05\x06a\b\t\n\x0B­\f\r\x0E\x0F",
      "s": "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0­0\x00\x00\x00\x00\x00\x00"
     }
    f=  { "A": 1,
      "B": new Uint8Array([0, 1, 2, 3, 4, 5, 6, 97, 8, 9, 10, 11, 12, 13, 14, 15]),
      "s": new Uint8Array(16)
     }
     
    { "B": 2, "s": 2, "A": 1 }
    {"B":2,"s":2,"A":1}
    f1=  { "B": 2, "s": 2, "A": 1 }
    

    Problem the 7 gets changed to 97


    2 Attachments

  • A fix using atob() and btoa() functions.

    //jsontest3.js
    //21aug2016
    function A(){
     this.A=1;
     this.B= new Uint8Array(16);
     this.s= new Uint8Array(16);
    }
    
    A.prototype.setup=function(){
     var i;
     for(i=0;i<16;i++)this.B[i]=i;
    };
    
    function B(){
     this.B= 2; // new Uint8Array(16);
     this.s= 2; //new Uint8Array(16);
     this.A=1;
    }
    
    
    var a=new A();
    a.setup();
    console.log(a);
    //a fix
     a.B=btoa(a.B);
     a.s=btoa(a.s);
     console.log(a);
    //
    var e=JSON.stringify(a);
    console.log(e);
    var f=JSON.parse(e);
    console.log("f= ",f);
    //a fix
     f.B=E.toUint8Array(atob(f.B));
     f.s=E.toUint8Array(atob(f.s));
    console.log("f= ",f);
    
    console.log(" ");
    var b=new B();
    console.log(b);
    var e1=JSON.stringify(b);
    console.log(e1);
    var f1=JSON.parse(e1);
    console.log("f1= ",f1);
    

    The output:

    >echo(0);
    { "A": 1,
      "B": new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]),
      "s": new Uint8Array(16)
     }
    { "A": 1,
      "B": "AAECAwQFBgcICQoLDA0ODw==",
      "s": "AAAAAAAAAAAAAAAAAAAAAA=="
     }
    {"A":1,"B":"AAECAwQFBgcICQoLDA0ODw==","s­":"AAAAAAAAAAAAAAAAAAAAAA=="}
    f=  { "A": 1,
      "B": "AAECAwQFBgcICQoLDA0ODw==",
      "s": "AAAAAAAAAAAAAAAAAAAAAA=="
     }
    f=  { "A": 1,
      "B": new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]),
      "s": new Uint8Array(16)
     }
     
    { "B": 2, "s": 2, "A": 1 }
    {"B":2,"s":2,"A":1}
    f1=  { "B": 2, "s": 2, "A": 1 }
    

    1 Attachment

  • Thanks - yes, this is a bit of a pain... There's a bug open for it here: https://github.com/espruino/Espruino/iss­ues/489

    Basically the 'standard' JavaScript way of handling Typed Arrays is horrible (turning them into objects), and I don't really want to implement it - but then I don't want to implement something that's not standards compliant either.

    If you want to parse the 'semi-JSON' you get from JSON.stringify with a Uint8Array then (as long as you trust the input!) you can use eval instead...

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

JSON and Uint8Array

Posted by Avatar for ClearMemory041063 @ClearMemory041063

Actions