A question about Uint8Array

Posted on
  • When I use the constructor

    newArr = new Uint8Array(someInt8Array.buffer, offset, len),

    it doesn't copy the someInt8Array into newArr, but makes the reference to it for newArr and if I change some element of newArr, the element of source array someInt8Array with offset index is changed too!

    In Espruino Reference it says: "If an ArrayBuffer view (eg. Uint8Array rather than ArrayBuffer) is given, it will be completely copied rather than referenced." Does it mean, that someInt8Array must be copied to newArr?

    Is it real bug? Or do I understand it wrong?

  • But you supplied an array buffer, someUint8array.buffer, not an array buffer view.

  • As said, using .buffer means you're using the backing ArrayBuffer, not a view of it.

    Espruino is behaving just like normal Javascript should here. If you want a copy, just remove the .buffer and the array will be copied instead.

    Actually being able to create a view of an existing array is something that's really useful sometimes.

  • @Gordon, are some new exciting things making your regular timezone float (irregular), or some open items?

  • @Gordon
    If I remove the .buffer, the someInt8Array will be copied to newArr completely. But it is needed that only part of source array will be copied with offset to destination array...

  • I have decided the problem by next way: first of all someInt8Array is copied with offset and len to a interim array tempArr and then the last one is copied fully to the newArr.

    tempArr = new Uint8Array(someInt8Array.buffer, offset, len);
    newArr = new Uint8Array(tempArr);

    But it seems me, that is not a finest decision...

  • This isn't Espruino, this is plain old JS. The chrome js console is the same:

    
    var t = new Uint8Array([0,2,4,6,8])
    undefined
    var u = new Uint8Array(t.buffer,2,2)
    undefined
    u
    [4, 6]
    var v= new Uint8Array(t,2,2);
    undefined
    v
    [0, 2, 4, 6, 8]
    
    

    Why they did it that way is unclear to me.

  • The constructor Uint8Array uses second and third parameters when first parameter is ArrayBuffer only. Therefore in second case (string 8 in your code) array v gets the full copy of array t.

    There was a surprise for me when i have found out that in first case (string 4 in your code) array u gets not a copy of t but reference to elements t[1] and t[2]. And if I change u[0] and u[1] t[1] and t[2] are changed too :-0

    In addition the u.buffer consists of all elements of t array :-D and some function may work not quite properly :-( I have found this when I worked with LCD.drawImage()

    Now I have decided a problem by method you can see in post #6 of this conversation.

  • tempArr = new Uint8Array(someInt8Array.buffer, offset, len);
    newArr = new Uint8Array(tempArr);
    

    Seems like a good solution to me - it won't be much slower than if you could have done it directly with the Uint8Array constructor.

    If you want more speed you can make sure you pre-allocate the array:

    newArr = new Uint8Array(len);
    //  ....
    // when you want to copy:
    newArr.set(new Uint8Array(someInt8Array.buffer, offset, len));
    
  • @Gordon
    Sorry, it seems to me there is a little bug in second code: the Uint8Array constructor must have the argument len, isn't that so? Or I have understood nothing...

  • Thanks - yes, absolutely. I've just changed it :)

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

A question about Uint8Array

Posted by Avatar for Uhv @Uhv

Actions