Buffer.indexOf implementation



  • To manage easily a serial port with UART, I piped the stream of uart port with the parser of the package @serialport/parser-delimiter and discover it was not working. (But working with nodejs).

    To simulate the parser I tried :

    const data = Buffer.from('aaaaaaa\nbbbbbbb\n');
    console.log(data);
    const delimiter = Buffer.from('\n');
    console.log(delimiter);
    const position = data.indexOf(delimiter);
    console.log(position);
    
    [23:52:01] TypeError: undefined not callable (property 'indexOf' of [object Uint8Array])
                   at [anon] internal
                   at [anon] (/indexTest.js:1) strict preventsyield
    [23:52:01]
    [23:52:01] Fatal error, restarting program.
    

    Lack of the support in Buffer of indexOf on Uint8Array.

    Can you do something ?



  • Hi! Try to add this polyfill: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf#Polyfill

    If it works, we can add it to low.js internally...



  • Also, please definitly use the newest low.js version (see https://neonious.com/documentation/changelog ). But this is not the problem you have right now.



  • @neoniousTR

    After some tries and tests, I have a working solution !

    To implement it :

    • I copied the following code in a polyfill.js external file

    • I inserted a require in my module managing serial ports and using the external parser @serialport/parser-readline

    if (!Uint8Array.prototype.indexOf)
    Uint8Array.prototype.indexOf = (function(Object, max, min) {
      "use strict"
      return function indexOf(member, fromIndex) {
        if (this === null || this === undefined)
          throw TypeError("Uint8Array.prototype.indexOf called on null or undefined")
    
        var that = Object(this), Len = that.length >>> 0, i = min(fromIndex | 0, Len)
        if (i < 0) i = max(0, Len + i)
        else if (i >= Len) return -1
    
        if (member === void 0) {        // undefined
          for (; i !== Len; ++i) if (that[i] === void 0 && i in that) return i
        } else if (member !== member) { // NaN
          return -1 // Since NaN !== NaN, it will never be found. Fast-path it.
        } else {                         // all else
            // the argument to search can be String|Buffer|Number with several bytes
            // also we convert in Array to compare easily
            var memberArray = Buffer.from(member);
            for (var ok ; i !== (Len - memberArray.length + 1); ++i) {
                for (var j = 0, ok = true; j < memberArray.length; j++) {
                   if (that[i+j] !== memberArray[j]) {
                       ok = false;
                       break;
                   }
                }
                if(ok) return i;
            }
        }
        return -1 // if the value was not found, then return -1
      }
    })(Object, Math.max, Math.min)
    


  • @ygageot thanks for sharing the tip, it helped. I had exactly the same problem while using @serialport/parser-readline.

    @neoniousTR, any plans to add this to the core?



  • Here you go: https://github.com/neonious/lowjs/commit/1028ffb4bc97030df91cfaa6674f8933ec572ec2

    Will be in PC binaries tomorrow, in ESP32 binaries with the next update.


Log in to reply