我正在看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(使用前将#替换为@)