我有一个 CBOR 有效负载,其中包含带有 BYTES 字段的 MAP:
// simplified testcase:
var data = [0xBF, 0x63, 0x72, 0x61, 0x77, 0x58, 0x10, 0x00,
0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF]
CBOR 诊断:
BF # map(*)
63 # text(3)
726177 # "raw"
58 10 # bytes(16)
00FF00FF0000FFFFFFFFFFFF000000FF # [16 bytes]
FF # end of map(*)
或者,用标准对象表示法:{"raw": h'00FF00FF0000FFFFFFFFFFFF000000FF'}
当我在 JavaScript 中解码上述有效负载时(使用 cbor.js):
// prepare an ArrayBuffer to pass to CBOR.decode:
var buf = new ArrayBuffer(data.length)
var bi = new Int8Array(buf)
for(var i = 0; i < data.length; i++) bi[i] = data[i]
var decoded = CBOR.decode(buf)
console.log('decoded:', JSON.stringify(decoded))
console.log('isArray:', Array.isArray(decoded.raw))
“原始”字段不是正确的
Array
(Array.isArray(...)
将返回 true
),而是此类数组的“对象化”版本:
解码:{“原始”:{“0”:0,“1”:255,“2”:0,“3”:255,“4”:0,“5”:0,“6”:255 ,"7":255,"8":255,"9":255,"10":255,"11":255,"12":0,"13":0,"14":0," 15 英寸:255}}
isArray:假
这给我带来了一些问题,因为后来我需要一个正确的 Array (或 TypedArray)类型来传递给 QML JavaScript 引擎,并且不接受“对象化”对象;我必须手动转换为正确的数组:
if(!Array.isArray(texture.raw)) {
console.warn(`Texture data is not an array. Conversion will be slow!`)
var data = new Array(Object.keys(texture.raw).length)
for(var k in texture.raw)
data[k] = texture.raw[k]
root.textureData = data
} else {
root.textureData = texture.raw
}
但这非常慢。
还有什么更好的事情可以做吗?例如更快的转换?给 cbor.js 正确解码的指令?还有别的吗?
你可以添加一个“length”属性,然后用
Array.from()
将其变成真正的数组:
if(!Array.isArray(texture.raw)) {
const rlen = Object.keys(texture.raw).length;
texture.raw.length = rlen;
root.textureData = Array.from(texture.raw);
}
else {
root.textureData = texture.raw
}
请注意,上面的代码基本上与您的代码执行相同的操作,但除非“原始”内容的大小为兆字节,否则它不会很慢。 (在这种情况下,无论你用它做什么,也都会适应这个尺寸。)