是否有一个已经发布的 Javascript 解决方案可以在不使用 Node.js 的情况下遍历 Python pickled 对象

2023-12-27

我正在看https://github.com/jlaine/node-jpickle https://github.com/jlaine/node-jpickle遍历 Javascript 中的 pickle 对象,这对于协助将二进制对象从 Python 通过 Ajax 发送到 Javascript 非常有用。不幸的是,它使用 Node.js 来遍历称为 Buffer() 的东西,而我从 Ajax blob 中获取 ArrayBuffer。没问题,互联网上的一些地方有下面的代码,修改 jpickle 来使用它应该很简单:

var ArrayBufferCursor = function() {
  var ArrayBufferCursor = function(arrayBuffer) {
    this.dataview = new DataView(arrayBuffer, 0);
    this.size = arrayBuffer.byteLength;
    this.index = 0;
  }

  ArrayBufferCursor.prototype.next = function(type) {
    switch(type) {
      case 'Uint8':
        var result = this.dataview.getUint8(this.index);
        this.index += 1;
        return result;
      case 'Int16':
        var result = this.dataview.getInt16(this.index, true);
        this.index += 2;
        return result;
      case 'Uint16':
        var result = this.dataview.getUint16(this.index, true);
        this.index += 2;
        return result;
      case 'Int32':
        var result = this.dataview.getInt32(this.index, true);
        this.index += 4;
        return result;
      case 'Uint32':
        var result = this.dataview.getUint32(this.index, true);
        this.index += 4;
        return result;
      case 'Float':
      case 'Float32':
        var result = this.dataview.getFloat32(this.index, true);
        this.index += 4;
        return result;
      case 'Double':
      case 'Float64':
        var result = this.dataview.getFloat64(this.index, true);
        this.index += 8;
        return result;
      default:
        throw new Error("Unknown datatype");
    }
  };

  ArrayBufferCursor.prototype.hasNext = function() {
    return this.index < this.size;
  }

  return ArrayBufferCursor;
});

但这段代码至少有一个拼写错误。例如,也许我应该删除最后一个括号?如果我这样做,那么 Chrome 浏览器会愉快地编译,这应该允许我这样做:

var cursor = new ArrayBufferCursor(arrayBuffer);
firstfloat = cursor.next('Float')

除了 Chrome 抱怨cursor.next不是一个函数。咕噜。我怀疑这段代码中的一个小拼写错误正在阻止它工作,但我无法解决它。有任何想法吗?谢谢


现在看来这很好。除了修复令人困惑的括号之外,要使用pickle,你必须将浮点数设置为BigEndian,而不是Little,这愚弄了我一段时间。

这些游标函数现在允许您迭代 Pickle 对象!

let ArrayBufferCursor = function(arrayBuffer) {
    this.dataview = new DataView(arrayBuffer, 0);
    this.size = arrayBuffer.byteLength;
    this.index = 0;
  }

ArrayBufferCursor.prototype.next = function(type) {
    switch(type) {
      case 'Char8':
        var result = String.fromCharCode(this.dataview.getUint8(this.index));
        this.index += 1;
        return result;
      case 'Uint8':
        var result = this.dataview.getUint8(this.index);
        this.index += 1;
        return result;
      case 'Int16':
        var result = this.dataview.getInt16(this.index, true);
        this.index += 2;
        return result;
      case 'Uint16':
        var result = this.dataview.getUint16(this.index, true);
        this.index += 2;
        return result;
      case 'Int32':
        var result = this.dataview.getInt32(this.index, true);
        this.index += 4;
        return result;
      case 'Uint32':
        var result = this.dataview.getUint32(this.index, true);
        this.index += 4;
        return result;
      case 'Float':
      case 'Float32':
        var result = this.dataview.getFloat32(this.index, false);
        this.index += 4;
        return result;
      case 'Double':
      case 'Float64':
        var result = this.dataview.getFloat64(this.index, false);
        this.index += 8;
        return result;
      default:
        throw new Error("Unknown datatype");
    }
  };

ArrayBufferCursor.prototype.toString = function(n) {
    const slice = new Uint8Array(this.dataview.buffer).subarray(this.index,this.index+n); //from current pointer get the next n bytes                                  //convert to uint8
    const bytesString = String.fromCharCode(...slice)                                           //and then string
    this.index += n;
    return bytesString;
  }

ArrayBufferCursor.prototype.readLine = function() {
    const slice = new Uint8Array(this.dataview.buffer).subarray(this.index)      // is this a data copy or just a pointer? The former could get expensive...
    const n = this.size - this.index - 1                     // is it really "-1" hope so. Anyway, the very last byte wont be a '\n' will it??

    let i = 0
    for (i = 0; i<n; i++) {
       if (slice[i] == 10){                                 //i.e. ascii '\n'
          break;}
    }

    if (i == n) {
        throw "Could not find end of a line in pickle?!";
    }
    const bytesArray = new Uint8Array(this.dataview.buffer).subarray(this.index, this.index+i);
    const bytesString = String.fromCharCode(...bytesArray);
    this.index += i+1;                                 // throw away the '\n'
    return bytesString;
  }

ArrayBufferCursor.prototype.hasNext = function() {
    return this.index < this.size;
  }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否有一个已经发布的 Javascript 解决方案可以在不使用 Node.js 的情况下遍历 Python pickled 对象 的相关文章

随机推荐